From 8481ea9c4cbdd188b95c9c8e1daa1fa20d7f5455 Mon Sep 17 00:00:00 2001 From: Lubos Dolezel Date: Tue, 24 Jan 2017 22:22:04 +0100 Subject: [PATCH] Work in progress - committing to back up my work --- CMakeLists.txt | 18 +- cmake/darling_lib.cmake | 7 + cmake/use_ld64.cmake | 4 +- kernel-include/i386/cpu_capabilities.h | 52 +- kernel-include/sys/event.h | 562 +- kernel-include/sys/msg.h | 23 +- platform-include/mach/coalition.h | 128 + platform-include/mach/i386/syscall_sw.h | 7 +- platform-include/mach/kern_return.h | 4 + platform-include/mach/sfi_class.h | 135 + platform-include/mach/thread_switch.h | 7 + platform-include/pthread/introspection.h | 111 + platform-include/pthread/pthread.h | 98 +- platform-include/pthread/pthread_impl.h | 8 + platform-include/pthread/pthread_spis.h | 33 +- platform-include/pthread/qos.h | 14 +- .../libc/include => platform-include}/spawn.h | 71 +- platform-include/sys/_types/_fsobj_id_t.h | 36 + platform-include/sys/attr.h | 109 +- platform-include/sys/cdefs.h | 142 +- platform-include/sys/clonefile.h | 54 + platform-include/sys/coalition.h | 235 + platform-include/sys/event.h | 553 +- platform-include/sys/guarded.h | 121 + platform-include/sys/kdebug.h | 1399 ++- platform-include/sys/kdebug_signpost.h | 75 + platform-include/sys/persona.h | 386 + platform-include/sys/proc_info.h | 107 +- platform-include/sys/reason.h | 226 + platform-include/sys/sfi.h | 114 + platform-include/sys/snapshot.h | 69 + platform-include/sys/stackshot.h | 66 + platform-include/sys/stat.h | 2 +- platform-include/sys/syscall.h | 57 +- platform-include/sys/ulock.h | 117 + platform-include/sys/work_interval.h | 141 + src/CMakeLists.txt | 5 + src/duct/src/CMakeLists.txt | 1 + src/dyld-apple/CMakeLists.txt | 5 + src/external/libplatform/.gitignore | 2 + src/external/libplatform/CMakeLists.txt | 95 + src/external/libplatform/LICENSE | 202 + .../libplatform/include}/_simple.h | 45 +- .../libplatform/include/libkern/OSAtomic.h | 47 + .../include/libkern/OSAtomicDeprecated.h | 1177 +++ .../include/libkern/OSAtomicQueue.h | 191 + .../include/libkern/OSCacheControl.h | 4 +- .../include/libkern/OSSpinLockDeprecated.h | 211 + .../libplatform/include/os/alloc_once_impl.h | 80 + .../libplatform/include}/os/base.h | 0 .../libplatform/include/os/base_private.h | 39 + .../libplatform/include/os/internal/atomic.h | 440 + .../include/os/internal/crashlog.h | 48 + .../include/os/internal/internal_shared.h | 58 + src/external/libplatform/include/os/lock.h | 147 + .../libplatform/include/os/lock_private.h | 650 ++ .../libplatform/include/os/once_private.h | 67 + .../include/os/semaphore_private.h | 96 + .../libplatform/include/platform/compat.h | 73 + .../include/platform/introspection_private.h | 447 + .../libplatform/include/platform/string.h | 101 + .../libplatform}/include/setjmp.h | 16 +- .../libplatform}/include/ucontext.h | 22 +- .../libplatform/internal/os/internal.h | 142 + .../libplatform/internal/os/internal_asm.h | 77 + src/external/libplatform/internal/os/yield.h | 88 + src/external/libplatform/man/atomic.3 | 62 + .../libplatform/man/atomic_deprecated.3 | 232 + .../sys => external/libplatform/man}/cache.3 | 0 .../libplatform/man}/ffs.3 | 49 +- .../libplatform/man}/getcontext.3 | 0 .../libplatform/man}/makecontext.3 | 0 src/external/libplatform/man/manpages.lst | 13 + .../gen => external/libplatform/man}/setjmp.3 | 0 .../libplatform/man/spinlock_deprecated.3 | 54 + .../libplatform/man}/ucontext.3 | 0 .../libplatform/private/libkern/OSAtomic.h | 44 + .../private/libkern/module.modulemap | 6 + .../src/atomics/common}/MKGetTimeBaseInfo.c | 4 + .../libplatform/src/atomics/i386/OSAtomic.S | 366 + .../libplatform/src/atomics/i386/pfz.S | 70 + src/external/libplatform/src/atomics/init.c | 72 + .../libplatform/src/atomics/x86_64/OSAtomic.S | 289 + .../libplatform/src/atomics/x86_64/pfz.S | 68 + .../libplatform/src/cachecontrol/arm/cache.S} | 0 .../src/cachecontrol/arm64/cache.S | 43 + .../src/cachecontrol/generic}/cache.c | 2 - .../libplatform/src/cachecontrol/i386/cache.S | 58 + .../src/cachecontrol/x86_64/cache.S | 56 + .../src/force_libplatform_to_build.c | 6 + src/external/libplatform/src/init.c | 41 + .../src/introspection/introspection.c | 524 + .../introspection/introspection_internal.h | 64 + src/external/libplatform/src/os/alloc_once.c | 158 + src/external/libplatform/src/os/atomic.c | 277 + src/external/libplatform/src/os/atomic_up.c | 33 + src/external/libplatform/src/os/lock.c | 1124 ++ .../libplatform/src/os/lock_internal.h | 61 + src/external/libplatform/src/os/lock_up.c | 29 + src/external/libplatform/src/os/lock_wfe.c | 36 + src/external/libplatform/src/os/resolver.c | 106 + src/external/libplatform/src/os/resolver.h | 126 + src/external/libplatform/src/os/semaphore.c | 77 + .../libplatform/src/setjmp/arm/_longjmp.S} | 0 .../libplatform/src/setjmp/arm/_setjmp.S} | 0 .../libplatform/src/setjmp/arm}/_setjmp.h | 0 .../libplatform/src/setjmp/arm/longjmp.S | 71 + .../libplatform/src/setjmp/arm/setjmp.S | 61 + .../libplatform/src/setjmp/arm64/setjmp.S | 124 + .../src/setjmp/generic/setjmperr.c | 61 + .../libplatform/src/setjmp/generic/sigtramp.c | 124 + .../libplatform/src/setjmp/i386}/_setjmp.S | 6 - .../libplatform/src/setjmp/i386/_sigtramp.S | 251 + .../libplatform/src/setjmp/i386/setjmp.S | 129 + .../libplatform/src/setjmp/x86_64}/_setjmp.S | 0 .../libplatform/src/setjmp/x86_64/_sigtramp.S | 254 + .../libplatform/src/setjmp/x86_64/setjmp.S | 123 + src/external/libplatform/src/simple/asl.c | 327 + src/external/libplatform/src/simple/getenv.c | 51 + .../libplatform/src/simple/string_io.c | 593 ++ .../libplatform/src/string/generic/bzero.c | 71 + .../libplatform/src/string/generic/ffsll.c | 103 + .../libplatform/src/string/generic/flsll.c | 102 + .../libplatform/src/string/generic/memccpy.c | 59 + .../libplatform/src/string/generic}/memchr.c | 22 +- .../libplatform/src/string/generic}/memcmp.c | 29 +- .../libplatform/src/string/generic/memmove.c | 134 + .../src/string/generic/memset_pattern.c | 104 + .../libplatform/src/string/generic/strchr.c | 59 + .../libplatform/src/string/generic}/strcmp.c | 22 + .../libplatform/src/string/generic}/strncmp.c | 20 +- .../src/ucontext/generic/getmcontext.c | 91 + .../src/ucontext/generic/makecontext.c | 223 + .../src/ucontext/generic/setcontext.c | 61 + .../src/ucontext/generic/swapcontext.c | 92 + .../src/ucontext/i386/_ctx_start.S | 77 + .../src/ucontext/i386/_setcontext.S | 43 + .../src/ucontext/i386/getcontext.S | 53 + .../src/ucontext/x86_64/_ctx_start.S | 90 + .../src/ucontext/x86_64/_setcontext.S | 71 + .../src/ucontext/x86_64/getcontext.S | 75 + .../libplatform/xcodeconfig/atomics.xcconfig | 12 + .../xcodeconfig/libplatform.aliases | 1 + .../xcodeconfig/libplatform.xcconfig | 72 + .../libplatform/xcodeconfig/os.xcconfig | 28 + .../libplatform/xcodeconfig/perarch.xcconfig | 27 + .../libplatform/xcodeconfig/static.xcconfig | 9 + src/kernel/CMakeLists.txt | 10 +- src/kernel/emulation/linux/CMakeLists.txt | 5 +- src/kernel/emulation/linux/ioctl/ioctl.c | 3 +- src/kernel/emulation/linux/ioctl/ioctl.h | 1 + src/kernel/emulation/linux/misc/ioctl.c | 2 +- src/kernel/emulation/linux/misc/ioctl.h | 2 +- src/kernel/emulation/linux/stat/common.h | 2 +- src/kernel/emulation/linux/syscalls-table.S | 12 +- src/kernel/emulation/linux/syscalls.c | 2 +- src/kernel/libsyscall/CMakeLists.txt | 1240 +-- src/kernel/libsyscall/bsdsyscalls/SYS.h | 223 + .../_____old_semwait_signal_nocancel.S | 11 + .../bsdsyscalls/_____sigwait_nocancel.S | 11 + .../bsdsyscalls/___abort_with_payload.S | 11 + src/kernel/libsyscall/bsdsyscalls/___accept.S | 21 + .../bsdsyscalls/___accept_nocancel.S | 21 + .../bsdsyscalls/___access_extended.S | 21 + .../bsdsyscalls/___aio_suspend_nocancel.S | 23 + src/kernel/libsyscall/bsdsyscalls/___bind.S | 21 + .../bsdsyscalls/___bsdthread_create.S | 11 + .../libsyscall/bsdsyscalls/___bsdthread_ctl.S | 11 + .../bsdsyscalls/___bsdthread_register.S | 11 + .../bsdsyscalls/___bsdthread_terminate.S | 11 + src/kernel/libsyscall/bsdsyscalls/___chmod.S | 16 + .../bsdsyscalls/___chmod_extended.S | 11 + .../bsdsyscalls/___close_nocancel.S | 23 + .../libsyscall/bsdsyscalls/___coalition.S | 11 + .../bsdsyscalls/___coalition_info.S | 11 + .../libsyscall/bsdsyscalls/___connect.S | 21 + .../bsdsyscalls/___connect_nocancel.S | 21 + .../libsyscall/bsdsyscalls/___copyfile.S | 11 + src/kernel/libsyscall/bsdsyscalls/___csrctl.S | 11 + src/kernel/libsyscall/bsdsyscalls/___delete.S | 11 + .../bsdsyscalls/___disable_threadsignal.S | 11 + src/kernel/libsyscall/bsdsyscalls/___exit.S | 21 + src/kernel/libsyscall/bsdsyscalls/___fchmod.S | 16 + .../bsdsyscalls/___fchmod_extended.S | 11 + src/kernel/libsyscall/bsdsyscalls/___fcntl.S | 16 + .../bsdsyscalls/___fcntl_nocancel.S | 18 + src/kernel/libsyscall/bsdsyscalls/___fork.S | 122 + .../libsyscall/bsdsyscalls/___fs_snapshot.S | 11 + .../libsyscall/bsdsyscalls/___fsgetpath.S | 11 + .../bsdsyscalls/___fstat64_extended.S | 11 + .../bsdsyscalls/___fstat_extended.S | 11 + .../bsdsyscalls/___fsync_nocancel.S | 23 + .../libsyscall/bsdsyscalls/___getattrlist.S | 21 + .../bsdsyscalls/___getdirentries64.S | 11 + .../libsyscall/bsdsyscalls/___gethostuuid.S | 11 + .../libsyscall/bsdsyscalls/___getlogin.S | 11 + .../libsyscall/bsdsyscalls/___getpeername.S | 21 + src/kernel/libsyscall/bsdsyscalls/___getpid.S | 104 + .../libsyscall/bsdsyscalls/___getrlimit.S | 16 + .../libsyscall/bsdsyscalls/___getsgroups.S | 21 + .../libsyscall/bsdsyscalls/___getsockname.S | 21 + src/kernel/libsyscall/bsdsyscalls/___gettid.S | 21 + .../___gettimeofday.S} | 0 .../libsyscall/bsdsyscalls/___getwgroups.S | 21 + .../___guarded_open_dprotected_np.S | 11 + .../bsdsyscalls/___guarded_open_np.S | 11 + .../libsyscall/bsdsyscalls/___identitysvc.S | 11 + .../libsyscall/bsdsyscalls/___initgroups.S | 11 + src/kernel/libsyscall/bsdsyscalls/___ioctl.S | 16 + .../libsyscall/bsdsyscalls/___iopolicysys.S | 11 + .../libsyscall/bsdsyscalls/___kdebug_trace.S | 11 + .../bsdsyscalls/___kdebug_trace64.S | 11 + .../bsdsyscalls/___kdebug_trace_string.S | 41 + .../bsdsyscalls/___kdebug_typefilter.S | 11 + src/kernel/libsyscall/bsdsyscalls/___kill.S | 11 + src/kernel/libsyscall/bsdsyscalls/___lchown.S | 21 + src/kernel/libsyscall/bsdsyscalls/___listen.S | 21 + src/kernel/libsyscall/bsdsyscalls/___lseek.S | 56 + .../bsdsyscalls/___lstat64_extended.S | 11 + .../bsdsyscalls/___lstat_extended.S | 11 + .../libsyscall/bsdsyscalls/___mac_execve.S | 21 + .../libsyscall/bsdsyscalls/___mac_get_fd.S | 11 + .../libsyscall/bsdsyscalls/___mac_get_file.S | 11 + .../libsyscall/bsdsyscalls/___mac_get_link.S | 11 + .../libsyscall/bsdsyscalls/___mac_get_mount.S | 11 + .../libsyscall/bsdsyscalls/___mac_get_pid.S | 11 + .../libsyscall/bsdsyscalls/___mac_get_proc.S | 11 + .../libsyscall/bsdsyscalls/___mac_getfsstat.S | 11 + .../libsyscall/bsdsyscalls/___mac_mount.S | 21 + .../libsyscall/bsdsyscalls/___mac_set_fd.S | 11 + .../libsyscall/bsdsyscalls/___mac_set_file.S | 11 + .../libsyscall/bsdsyscalls/___mac_set_link.S | 11 + .../libsyscall/bsdsyscalls/___mac_set_proc.S | 21 + .../libsyscall/bsdsyscalls/___mac_syscall.S | 21 + .../bsdsyscalls/___microstackshot.S | 11 + .../bsdsyscalls/___mkdir_extended.S | 11 + .../bsdsyscalls/___mkfifo_extended.S | 11 + src/kernel/libsyscall/bsdsyscalls/___mmap.S | 16 + .../libsyscall/bsdsyscalls/___mprotect.S | 21 + src/kernel/libsyscall/bsdsyscalls/___msgctl.S | 21 + .../bsdsyscalls/___msgrcv_nocancel.S | 23 + .../bsdsyscalls/___msgsnd_nocancel.S | 23 + src/kernel/libsyscall/bsdsyscalls/___msgsys.S | 21 + src/kernel/libsyscall/bsdsyscalls/___msync.S | 21 + .../bsdsyscalls/___msync_nocancel.S | 21 + src/kernel/libsyscall/bsdsyscalls/___munmap.S | 11 + .../bsdsyscalls/___old_semwait_signal.S | 11 + src/kernel/libsyscall/bsdsyscalls/___open.S | 21 + .../bsdsyscalls/___open_dprotected_np.S | 11 + .../libsyscall/bsdsyscalls/___open_extended.S | 11 + .../libsyscall/bsdsyscalls/___open_nocancel.S | 21 + src/kernel/libsyscall/bsdsyscalls/___openat.S | 21 + .../bsdsyscalls/___openat_nocancel.S | 21 + .../libsyscall/bsdsyscalls/___persona.S | 11 + src/kernel/libsyscall/bsdsyscalls/___pipe.S | 66 + .../libsyscall/bsdsyscalls/___poll_nocancel.S | 23 + .../libsyscall/bsdsyscalls/___posix_spawn.S | 11 + .../bsdsyscalls/___pread_nocancel.S | 23 + .../libsyscall/bsdsyscalls/___proc_info.S | 11 + .../bsdsyscalls/___process_policy.S | 11 + .../libsyscall/bsdsyscalls/___pselect.S | 11 + .../bsdsyscalls/___pselect_nocancel.S | 11 + .../bsdsyscalls/___psynch_cvbroad.S | 11 + .../bsdsyscalls/___psynch_cvclrprepost.S | 11 + .../bsdsyscalls/___psynch_cvsignal.S | 11 + .../libsyscall/bsdsyscalls/___psynch_cvwait.S | 11 + .../bsdsyscalls/___psynch_mutexdrop.S | 11 + .../bsdsyscalls/___psynch_mutexwait.S | 11 + .../bsdsyscalls/___psynch_rw_downgrade.S | 11 + .../bsdsyscalls/___psynch_rw_longrdlock.S | 11 + .../bsdsyscalls/___psynch_rw_rdlock.S | 11 + .../bsdsyscalls/___psynch_rw_unlock.S | 11 + .../bsdsyscalls/___psynch_rw_unlock2.S | 11 + .../bsdsyscalls/___psynch_rw_upgrade.S | 11 + .../bsdsyscalls/___psynch_rw_wrlock.S | 11 + .../bsdsyscalls/___psynch_rw_yieldwrlock.S | 11 + .../bsdsyscalls/___pthread_canceled.S | 11 + .../libsyscall/bsdsyscalls/___pthread_chdir.S | 11 + .../bsdsyscalls/___pthread_fchdir.S | 11 + .../libsyscall/bsdsyscalls/___pthread_kill.S | 11 + .../bsdsyscalls/___pthread_markcancel.S | 11 + .../bsdsyscalls/___pthread_sigmask.S | 11 + src/kernel/libsyscall/bsdsyscalls/___ptrace.S | 55 + .../bsdsyscalls/___pwrite_nocancel.S | 23 + .../libsyscall/bsdsyscalls/___read_nocancel.S | 23 + .../bsdsyscalls/___readv_nocancel.S | 23 + .../libsyscall/bsdsyscalls/___recvfrom.S | 21 + .../bsdsyscalls/___recvfrom_nocancel.S | 21 + .../libsyscall/bsdsyscalls/___recvmsg.S | 21 + .../bsdsyscalls/___recvmsg_nocancel.S | 21 + src/kernel/libsyscall/bsdsyscalls/___rename.S | 11 + .../libsyscall/bsdsyscalls/___renameat.S | 11 + .../libsyscall/bsdsyscalls/___renameatx_np.S | 11 + src/kernel/libsyscall/bsdsyscalls/___rmdir.S | 11 + src/kernel/libsyscall/bsdsyscalls/___select.S | 21 + .../bsdsyscalls/___select_nocancel.S | 21 + .../libsyscall/bsdsyscalls/___sem_open.S | 21 + .../bsdsyscalls/___sem_wait_nocancel.S | 23 + src/kernel/libsyscall/bsdsyscalls/___semctl.S | 21 + src/kernel/libsyscall/bsdsyscalls/___semsys.S | 21 + .../bsdsyscalls/___semwait_signal.S | 11 + .../bsdsyscalls/___semwait_signal_nocancel.S | 11 + .../libsyscall/bsdsyscalls/___sendmsg.S | 21 + .../bsdsyscalls/___sendmsg_nocancel.S | 21 + src/kernel/libsyscall/bsdsyscalls/___sendto.S | 21 + .../bsdsyscalls/___sendto_nocancel.S | 21 + .../libsyscall/bsdsyscalls/___setattrlist.S | 21 + .../libsyscall/bsdsyscalls/___setlogin.S | 11 + .../libsyscall/bsdsyscalls/___setpriority.S | 11 + .../libsyscall/bsdsyscalls/___setregid.S | 21 + .../libsyscall/bsdsyscalls/___setreuid.S | 21 + .../libsyscall/bsdsyscalls/___setrlimit.S | 16 + .../libsyscall/bsdsyscalls/___setsgroups.S | 21 + src/kernel/libsyscall/bsdsyscalls/___settid.S | 21 + .../bsdsyscalls/___settid_with_pid.S | 11 + .../libsyscall/bsdsyscalls/___settimeofday.S | 11 + .../libsyscall/bsdsyscalls/___setwgroups.S | 21 + .../libsyscall/bsdsyscalls/___sfi_ctl.S | 11 + .../libsyscall/bsdsyscalls/___sfi_pidctl.S | 11 + .../bsdsyscalls/___shared_region_check_np.S | 11 + .../___shared_region_map_and_slide_np.S | 11 + .../libsyscall/bsdsyscalls/___shm_open.S | 21 + src/kernel/libsyscall/bsdsyscalls/___shmctl.S | 21 + src/kernel/libsyscall/bsdsyscalls/___shmsys.S | 21 + .../libsyscall/bsdsyscalls/___sigaction.S | 11 + .../libsyscall/bsdsyscalls/___sigaltstack.S | 51 + .../___sigreturn.S} | 0 .../libsyscall/bsdsyscalls/___sigsuspend.S | 11 + .../bsdsyscalls/___sigsuspend_nocancel.S | 11 + .../libsyscall/bsdsyscalls/___sigwait.S | 11 + .../libsyscall/bsdsyscalls/___socketpair.S | 21 + .../___stack_snapshot_with_config.S | 11 + .../bsdsyscalls/___stat64_extended.S | 11 + .../libsyscall/bsdsyscalls/___stat_extended.S | 11 + .../libsyscall/bsdsyscalls/___syscall.S | 70 + src/kernel/libsyscall/bsdsyscalls/___sysctl.S | 11 + .../libsyscall/bsdsyscalls/___sysctlbyname.S | 11 + .../libsyscall/bsdsyscalls/___telemetry.S | 11 + .../bsdsyscalls/___terminate_with_payload.S | 11 + .../___thread_selfid.S} | 0 .../___thread_selfusage.S} | 0 .../libsyscall/bsdsyscalls/___ulock_wait.S | 11 + .../libsyscall/bsdsyscalls/___ulock_wake.S | 11 + .../bsdsyscalls/___umask_extended.S | 11 + src/kernel/libsyscall/bsdsyscalls/___unlink.S | 11 + .../libsyscall/bsdsyscalls/___unlinkat.S | 11 + src/kernel/libsyscall/bsdsyscalls/___vfork.S | 172 + src/kernel/libsyscall/bsdsyscalls/___wait4.S | 11 + .../bsdsyscalls/___wait4_nocancel.S | 21 + .../bsdsyscalls/___waitid_nocancel.S | 23 + .../bsdsyscalls/___work_interval_ctl.S | 11 + .../bsdsyscalls/___workq_kernreturn.S | 11 + .../libsyscall/bsdsyscalls/___workq_open.S | 11 + .../bsdsyscalls/___write_nocancel.S | 23 + .../bsdsyscalls/___writev_nocancel.S | 23 + src/kernel/libsyscall/bsdsyscalls/_access.S | 11 + src/kernel/libsyscall/bsdsyscalls/_acct.S | 11 + src/kernel/libsyscall/bsdsyscalls/_adjtime.S | 11 + .../libsyscall/bsdsyscalls/_aio_cancel.S | 11 + .../libsyscall/bsdsyscalls/_aio_error.S | 11 + .../libsyscall/bsdsyscalls/_aio_fsync.S | 11 + src/kernel/libsyscall/bsdsyscalls/_aio_read.S | 11 + .../libsyscall/bsdsyscalls/_aio_return.S | 11 + .../libsyscall/bsdsyscalls/_aio_suspend.S | 18 + .../libsyscall/bsdsyscalls/_aio_write.S | 11 + src/kernel/libsyscall/bsdsyscalls/_audit.S | 11 + .../bsdsyscalls/_audit_session_join.S | 11 + .../bsdsyscalls/_audit_session_port.S | 11 + .../bsdsyscalls/_audit_session_self.S | 11 + src/kernel/libsyscall/bsdsyscalls/_auditctl.S | 11 + src/kernel/libsyscall/bsdsyscalls/_auditon.S | 11 + .../bsdsyscalls/_change_fdguard_np.S | 11 + src/kernel/libsyscall/bsdsyscalls/_chdir.S | 11 + src/kernel/libsyscall/bsdsyscalls/_chflags.S | 11 + src/kernel/libsyscall/bsdsyscalls/_chown.S | 11 + src/kernel/libsyscall/bsdsyscalls/_chroot.S | 11 + .../libsyscall/bsdsyscalls/_clonefileat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_close.S | 18 + src/kernel/libsyscall/bsdsyscalls/_connectx.S | 11 + src/kernel/libsyscall/bsdsyscalls/_csops.S | 11 + .../bsdsyscalls/_csops_audittoken.S | 11 + .../libsyscall/bsdsyscalls/_disconnectx.S | 11 + src/kernel/libsyscall/bsdsyscalls/_dup.S | 11 + src/kernel/libsyscall/bsdsyscalls/_dup2.S | 11 + .../libsyscall/bsdsyscalls/_exchangedata.S | 11 + src/kernel/libsyscall/bsdsyscalls/_execve.S | 11 + .../libsyscall/bsdsyscalls/_faccessat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_fchdir.S | 11 + src/kernel/libsyscall/bsdsyscalls/_fchflags.S | 11 + src/kernel/libsyscall/bsdsyscalls/_fchmodat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_fchown.S | 11 + src/kernel/libsyscall/bsdsyscalls/_fchownat.S | 11 + .../libsyscall/bsdsyscalls/_fclonefileat.S | 11 + .../libsyscall/bsdsyscalls/_fdatasync.S | 11 + src/kernel/libsyscall/bsdsyscalls/_ffsctl.S | 11 + .../libsyscall/bsdsyscalls/_fgetattrlist.S | 11 + .../libsyscall/bsdsyscalls/_fgetxattr.S | 11 + src/kernel/libsyscall/bsdsyscalls/_fhopen.S | 11 + .../libsyscall/bsdsyscalls/_fileport_makefd.S | 11 + .../bsdsyscalls/_fileport_makeport.S | 11 + .../libsyscall/bsdsyscalls/_flistxattr.S | 11 + src/kernel/libsyscall/bsdsyscalls/_flock.S | 11 + .../libsyscall/bsdsyscalls/_fpathconf.S | 11 + .../libsyscall/bsdsyscalls/_fremovexattr.S | 11 + src/kernel/libsyscall/bsdsyscalls/_fsctl.S | 11 + .../libsyscall/bsdsyscalls/_fsetattrlist.S | 11 + .../libsyscall/bsdsyscalls/_fsetxattr.S | 11 + .../libsyscall/bsdsyscalls/_fsgetpath.S | 11 + src/kernel/libsyscall/bsdsyscalls/_fstat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_fstat64.S | 21 + src/kernel/libsyscall/bsdsyscalls/_fstatat.S | 11 + .../libsyscall/bsdsyscalls/_fstatat64.S | 21 + src/kernel/libsyscall/bsdsyscalls/_fstatfs.S | 11 + .../libsyscall/bsdsyscalls/_fstatfs64.S | 21 + src/kernel/libsyscall/bsdsyscalls/_fsync.S | 18 + .../libsyscall/bsdsyscalls/_ftruncate.S | 11 + src/kernel/libsyscall/bsdsyscalls/_futimes.S | 11 + .../libsyscall/bsdsyscalls/_getattrlistat.S | 11 + .../libsyscall/bsdsyscalls/_getattrlistbulk.S | 11 + .../libsyscall/bsdsyscalls/_getaudit_addr.S | 11 + src/kernel/libsyscall/bsdsyscalls/_getauid.S | 11 + .../libsyscall/bsdsyscalls/_getdirentries.S | 11 + .../bsdsyscalls/_getdirentriesattr.S | 11 + .../libsyscall/bsdsyscalls/_getdtablesize.S | 11 + src/kernel/libsyscall/bsdsyscalls/_getegid.S | 11 + .../libsyscall/bsdsyscalls/_getentropy.S | 11 + src/kernel/libsyscall/bsdsyscalls/_geteuid.S | 11 + src/kernel/libsyscall/bsdsyscalls/_getfh.S | 11 + .../libsyscall/bsdsyscalls/_getfsstat.S | 11 + .../libsyscall/bsdsyscalls/_getfsstat64.S | 21 + src/kernel/libsyscall/bsdsyscalls/_getgid.S | 11 + .../libsyscall/bsdsyscalls/_getgroups.S | 11 + .../libsyscall/bsdsyscalls/_getitimer.S | 11 + src/kernel/libsyscall/bsdsyscalls/_getpgid.S | 11 + src/kernel/libsyscall/bsdsyscalls/_getpgrp.S | 11 + src/kernel/libsyscall/bsdsyscalls/_getppid.S | 11 + .../libsyscall/bsdsyscalls/_getpriority.S | 11 + .../libsyscall/bsdsyscalls/_getrusage.S | 11 + src/kernel/libsyscall/bsdsyscalls/_getsid.S | 11 + .../libsyscall/bsdsyscalls/_getsockopt.S | 11 + src/kernel/libsyscall/bsdsyscalls/_getuid.S | 11 + src/kernel/libsyscall/bsdsyscalls/_getxattr.S | 11 + .../libsyscall/bsdsyscalls/_grab_pgo_data.S | 11 + .../bsdsyscalls/_guarded_close_np.S | 11 + .../bsdsyscalls/_guarded_kqueue_np.S | 11 + .../bsdsyscalls/_guarded_pwrite_np.S | 11 + .../bsdsyscalls/_guarded_write_np.S | 11 + .../bsdsyscalls/_guarded_writev_np.S | 11 + .../libsyscall/bsdsyscalls/_issetugid.S | 11 + src/kernel/libsyscall/bsdsyscalls/_kas_info.S | 11 + src/kernel/libsyscall/bsdsyscalls/_kevent.S | 11 + src/kernel/libsyscall/bsdsyscalls/_kevent64.S | 11 + .../libsyscall/bsdsyscalls/_kevent_qos.S | 11 + src/kernel/libsyscall/bsdsyscalls/_kqueue.S | 11 + src/kernel/libsyscall/bsdsyscalls/_ledger.S | 11 + src/kernel/libsyscall/bsdsyscalls/_link.S | 11 + src/kernel/libsyscall/bsdsyscalls/_linkat.S | 11 + .../libsyscall/bsdsyscalls/_lio_listio.S | 11 + .../libsyscall/bsdsyscalls/_listxattr.S | 11 + src/kernel/libsyscall/bsdsyscalls/_lstat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_lstat64.S | 21 + src/kernel/libsyscall/bsdsyscalls/_madvise.S | 21 + .../bsdsyscalls/_memorystatus_control.S | 11 + .../bsdsyscalls/_memorystatus_get_level.S | 11 + src/kernel/libsyscall/bsdsyscalls/_mincore.S | 11 + src/kernel/libsyscall/bsdsyscalls/_minherit.S | 11 + src/kernel/libsyscall/bsdsyscalls/_mkdir.S | 11 + src/kernel/libsyscall/bsdsyscalls/_mkdirat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_mkfifo.S | 11 + src/kernel/libsyscall/bsdsyscalls/_mknod.S | 11 + src/kernel/libsyscall/bsdsyscalls/_mlock.S | 11 + src/kernel/libsyscall/bsdsyscalls/_mlockall.S | 11 + src/kernel/libsyscall/bsdsyscalls/_modwatch.S | 11 + src/kernel/libsyscall/bsdsyscalls/_mount.S | 11 + .../bsdsyscalls/_mremap_encrypted.S | 11 + src/kernel/libsyscall/bsdsyscalls/_msgget.S | 11 + src/kernel/libsyscall/bsdsyscalls/_msgrcv.S | 18 + src/kernel/libsyscall/bsdsyscalls/_msgsnd.S | 18 + src/kernel/libsyscall/bsdsyscalls/_munlock.S | 11 + .../libsyscall/bsdsyscalls/_munlockall.S | 11 + .../bsdsyscalls/_necp_client_action.S | 11 + .../bsdsyscalls/_necp_match_policy.S | 11 + .../libsyscall/bsdsyscalls/_necp_open.S | 11 + .../bsdsyscalls/_netagent_trigger.S | 11 + src/kernel/libsyscall/bsdsyscalls/_nfsclnt.S | 11 + src/kernel/libsyscall/bsdsyscalls/_nfssvc.S | 11 + .../libsyscall/bsdsyscalls/_openbyid_np.S | 11 + src/kernel/libsyscall/bsdsyscalls/_pathconf.S | 11 + src/kernel/libsyscall/bsdsyscalls/_peeloff.S | 11 + .../libsyscall/bsdsyscalls/_pid_resume.S | 11 + .../libsyscall/bsdsyscalls/_pid_suspend.S | 11 + src/kernel/libsyscall/bsdsyscalls/_poll.S | 18 + src/kernel/libsyscall/bsdsyscalls/_pread.S | 18 + .../bsdsyscalls/_proc_rlimit_control.S | 11 + .../libsyscall/bsdsyscalls/_proc_trace_log.S | 11 + .../bsdsyscalls/_proc_uuid_policy.S | 11 + src/kernel/libsyscall/bsdsyscalls/_pwrite.S | 18 + .../{sys_x86-64 => bsdsyscalls}/_quota.S | 2 +- src/kernel/libsyscall/bsdsyscalls/_quotactl.S | 11 + src/kernel/libsyscall/bsdsyscalls/_read.S | 18 + src/kernel/libsyscall/bsdsyscalls/_readlink.S | 11 + .../libsyscall/bsdsyscalls/_readlinkat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_readv.S | 18 + src/kernel/libsyscall/bsdsyscalls/_reboot.S | 11 + .../libsyscall/bsdsyscalls/_recvmsg_x.S | 11 + .../libsyscall/bsdsyscalls/_removexattr.S | 11 + src/kernel/libsyscall/bsdsyscalls/_revoke.S | 11 + src/kernel/libsyscall/bsdsyscalls/_searchfs.S | 11 + .../libsyscall/bsdsyscalls/_sem_close.S | 11 + src/kernel/libsyscall/bsdsyscalls/_sem_post.S | 11 + .../libsyscall/bsdsyscalls/_sem_trywait.S | 11 + .../libsyscall/bsdsyscalls/_sem_unlink.S | 11 + src/kernel/libsyscall/bsdsyscalls/_sem_wait.S | 18 + src/kernel/libsyscall/bsdsyscalls/_semget.S | 11 + src/kernel/libsyscall/bsdsyscalls/_semop.S | 11 + src/kernel/libsyscall/bsdsyscalls/_sendfile.S | 11 + .../libsyscall/bsdsyscalls/_sendmsg_x.S | 11 + .../libsyscall/bsdsyscalls/_setaudit_addr.S | 11 + src/kernel/libsyscall/bsdsyscalls/_setauid.S | 11 + src/kernel/libsyscall/bsdsyscalls/_setegid.S | 11 + src/kernel/libsyscall/bsdsyscalls/_seteuid.S | 11 + src/kernel/libsyscall/bsdsyscalls/_setgid.S | 11 + .../libsyscall/bsdsyscalls/_setgroups.S | 11 + .../libsyscall/bsdsyscalls/_setitimer.S | 11 + src/kernel/libsyscall/bsdsyscalls/_setpgid.S | 16 + .../libsyscall/bsdsyscalls/_setprivexec.S | 11 + .../{sys_x86-64 => bsdsyscalls}/_setquota.S | 2 +- src/kernel/libsyscall/bsdsyscalls/_setsid.S | 11 + .../libsyscall/bsdsyscalls/_setsockopt.S | 11 + src/kernel/libsyscall/bsdsyscalls/_setuid.S | 11 + src/kernel/libsyscall/bsdsyscalls/_setxattr.S | 11 + .../libsyscall/bsdsyscalls/_shm_unlink.S | 11 + src/kernel/libsyscall/bsdsyscalls/_shmat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_shmdt.S | 11 + src/kernel/libsyscall/bsdsyscalls/_shmget.S | 11 + src/kernel/libsyscall/bsdsyscalls/_shutdown.S | 11 + .../libsyscall/bsdsyscalls/_sigpending.S | 11 + .../libsyscall/bsdsyscalls/_sigprocmask.S | 11 + src/kernel/libsyscall/bsdsyscalls/_socket.S | 11 + .../libsyscall/bsdsyscalls/_socket_delegate.S | 11 + src/kernel/libsyscall/bsdsyscalls/_stat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_stat64.S | 21 + src/kernel/libsyscall/bsdsyscalls/_statfs.S | 11 + src/kernel/libsyscall/bsdsyscalls/_statfs64.S | 21 + src/kernel/libsyscall/bsdsyscalls/_swapon.S | 11 + src/kernel/libsyscall/bsdsyscalls/_symlink.S | 11 + .../libsyscall/bsdsyscalls/_symlinkat.S | 11 + src/kernel/libsyscall/bsdsyscalls/_sync.S | 11 + .../libsyscall/bsdsyscalls/_system_override.S | 11 + src/kernel/libsyscall/bsdsyscalls/_truncate.S | 11 + src/kernel/libsyscall/bsdsyscalls/_umask.S | 11 + src/kernel/libsyscall/bsdsyscalls/_undelete.S | 11 + src/kernel/libsyscall/bsdsyscalls/_unmount.S | 11 + src/kernel/libsyscall/bsdsyscalls/_usrctl.S | 11 + src/kernel/libsyscall/bsdsyscalls/_utimes.S | 11 + .../libsyscall/bsdsyscalls/_vfs_purge.S | 11 + .../bsdsyscalls/_vm_pressure_monitor.S | 11 + .../libsyscall/bsdsyscalls/_waitevent.S | 11 + src/kernel/libsyscall/bsdsyscalls/_waitid.S | 18 + .../libsyscall/bsdsyscalls/_watchevent.S | 11 + src/kernel/libsyscall/bsdsyscalls/_write.S | 18 + src/kernel/libsyscall/bsdsyscalls/_writev.S | 18 + src/kernel/libsyscall/bsdsyscalls/bak/SYS.h | 223 + .../bak/_____old_semwait_signal_nocancel.S | 11 + .../bsdsyscalls/bak/_____sigwait_nocancel.S | 11 + .../libsyscall/bsdsyscalls/bak/___accept.S | 21 + .../bsdsyscalls/bak/___accept_nocancel.S | 21 + .../bsdsyscalls/bak/___access_extended.S | 21 + .../bsdsyscalls/bak/___aio_suspend_nocancel.S | 23 + .../libsyscall/bsdsyscalls/bak/___bind.S | 21 + .../bsdsyscalls/bak/___bsdthread_create.S | 11 + .../bsdsyscalls/bak/___bsdthread_ctl.S | 11 + .../bsdsyscalls/bak/___bsdthread_register.S | 11 + .../bsdsyscalls/bak/___bsdthread_terminate.S | 11 + .../libsyscall/bsdsyscalls/bak/___chmod.S | 16 + .../bsdsyscalls/bak/___chmod_extended.S | 11 + .../{sys_x86-64 => bsdsyscalls/bak}/___chud.S | 2 +- .../bsdsyscalls/bak/___close_nocancel.S | 23 + .../libsyscall/bsdsyscalls/bak/___coalition.S | 11 + .../bsdsyscalls/bak/___coalition_info.S | 11 + .../libsyscall/bsdsyscalls/bak/___connect.S | 21 + .../bsdsyscalls/bak/___connect_nocancel.S | 21 + .../libsyscall/bsdsyscalls/bak/___copyfile.S | 11 + .../libsyscall/bsdsyscalls/bak/___csrctl.S | 11 + .../libsyscall/bsdsyscalls/bak/___delete.S | 11 + .../bsdsyscalls/bak/___disable_threadsignal.S | 11 + .../libsyscall/bsdsyscalls/bak/___exit.S | 21 + .../libsyscall/bsdsyscalls/bak/___fchmod.S | 16 + .../bsdsyscalls/bak/___fchmod_extended.S | 11 + .../libsyscall/bsdsyscalls/bak/___fcntl.S | 16 + .../bsdsyscalls/bak/___fcntl_nocancel.S | 18 + .../libsyscall/bsdsyscalls/bak/___fork.S | 122 + .../libsyscall/bsdsyscalls/bak/___fsgetpath.S | 11 + .../bsdsyscalls/bak/___fstat64_extended.S | 11 + .../bsdsyscalls/bak/___fstat_extended.S | 11 + .../bsdsyscalls/bak/___fsync_nocancel.S | 23 + .../bsdsyscalls/bak/___getattrlist.S | 21 + .../bsdsyscalls/bak/___getdirentries64.S | 11 + .../bsdsyscalls/bak/___gethostuuid.S | 11 + .../libsyscall/bsdsyscalls/bak/___getlogin.S | 11 + .../bsdsyscalls/bak/___getpeername.S | 21 + .../libsyscall/bsdsyscalls/bak/___getpid.S | 115 + .../libsyscall/bsdsyscalls/bak/___getrlimit.S | 16 + .../bsdsyscalls/bak/___getsgroups.S | 21 + .../bsdsyscalls/bak/___getsockname.S | 21 + .../libsyscall/bsdsyscalls/bak/___gettid.S | 21 + .../bak}/___gettimeofday.S | 4 + .../bsdsyscalls/bak/___getwgroups.S | 21 + .../bak/___guarded_open_dprotected_np.S | 11 + .../bsdsyscalls/bak/___guarded_open_np.S | 11 + .../bsdsyscalls/bak/___identitysvc.S | 11 + .../bsdsyscalls/bak/___initgroups.S | 11 + .../libsyscall/bsdsyscalls/bak/___ioctl.S | 16 + .../bsdsyscalls/bak/___iopolicysys.S | 11 + .../bsdsyscalls/bak/___kdebug_trace.S | 11 + .../bsdsyscalls/bak/___kdebug_trace64.S | 11 + .../bsdsyscalls/bak/___kdebug_trace_string.S | 41 + .../libsyscall/bsdsyscalls/bak/___kill.S | 11 + .../libsyscall/bsdsyscalls/bak/___lchown.S | 21 + .../libsyscall/bsdsyscalls/bak/___listen.S | 21 + .../libsyscall/bsdsyscalls/bak/___lseek.S | 56 + .../bsdsyscalls/bak/___lstat64_extended.S | 11 + .../bsdsyscalls/bak/___lstat_extended.S | 11 + .../bsdsyscalls/bak/___mac_execve.S | 21 + .../bsdsyscalls/bak/___mac_get_fd.S | 11 + .../bsdsyscalls/bak/___mac_get_file.S | 11 + .../bsdsyscalls/bak/___mac_get_link.S | 11 + .../bsdsyscalls/bak/___mac_get_mount.S | 11 + .../bsdsyscalls/bak/___mac_get_pid.S | 11 + .../bsdsyscalls/bak/___mac_get_proc.S | 11 + .../bsdsyscalls/bak/___mac_getfsstat.S | 11 + .../libsyscall/bsdsyscalls/bak/___mac_mount.S | 21 + .../bsdsyscalls/bak/___mac_set_fd.S | 11 + .../bsdsyscalls/bak/___mac_set_file.S | 11 + .../bsdsyscalls/bak/___mac_set_link.S | 11 + .../bsdsyscalls/bak/___mac_set_proc.S | 21 + .../bsdsyscalls/bak/___mac_syscall.S | 21 + .../bsdsyscalls/bak/___microstackshot.S | 11 + .../bsdsyscalls/bak/___mkdir_extended.S | 11 + .../bsdsyscalls/bak/___mkfifo_extended.S | 11 + .../libsyscall/bsdsyscalls/bak/___mmap.S | 16 + .../libsyscall/bsdsyscalls/bak/___mprotect.S | 21 + .../libsyscall/bsdsyscalls/bak/___msgctl.S | 21 + .../bsdsyscalls/bak/___msgrcv_nocancel.S | 23 + .../bsdsyscalls/bak/___msgsnd_nocancel.S | 23 + .../libsyscall/bsdsyscalls/bak/___msgsys.S | 21 + .../libsyscall/bsdsyscalls/bak/___msync.S | 21 + .../bsdsyscalls/bak/___msync_nocancel.S | 21 + .../libsyscall/bsdsyscalls/bak/___munmap.S | 11 + .../bsdsyscalls/bak/___old_semwait_signal.S | 11 + .../libsyscall/bsdsyscalls/bak/___open.S | 21 + .../bsdsyscalls/bak/___open_dprotected_np.S | 11 + .../bsdsyscalls/bak/___open_extended.S | 11 + .../bsdsyscalls/bak/___open_nocancel.S | 21 + .../libsyscall/bsdsyscalls/bak/___openat.S | 21 + .../bsdsyscalls/bak/___openat_nocancel.S | 21 + .../libsyscall/bsdsyscalls/bak/___persona.S | 11 + .../libsyscall/bsdsyscalls/bak/___pipe.S | 66 + .../bsdsyscalls/bak/___poll_nocancel.S | 23 + .../bsdsyscalls/bak/___posix_spawn.S | 11 + .../bsdsyscalls/bak/___pread_nocancel.S | 23 + .../libsyscall/bsdsyscalls/bak/___proc_info.S | 11 + .../bsdsyscalls/bak/___process_policy.S | 11 + .../libsyscall/bsdsyscalls/bak/___pselect.S | 11 + .../bsdsyscalls/bak/___pselect_nocancel.S | 11 + .../bsdsyscalls/bak/___psynch_cvbroad.S | 11 + .../bsdsyscalls/bak/___psynch_cvclrprepost.S | 11 + .../bsdsyscalls/bak/___psynch_cvsignal.S | 11 + .../bsdsyscalls/bak/___psynch_cvwait.S | 11 + .../bsdsyscalls/bak/___psynch_mutexdrop.S | 11 + .../bsdsyscalls/bak/___psynch_mutexwait.S | 11 + .../bsdsyscalls/bak/___psynch_rw_downgrade.S | 11 + .../bsdsyscalls/bak/___psynch_rw_longrdlock.S | 11 + .../bsdsyscalls/bak/___psynch_rw_rdlock.S | 11 + .../bsdsyscalls/bak/___psynch_rw_unlock.S | 11 + .../bsdsyscalls/bak/___psynch_rw_unlock2.S | 11 + .../bsdsyscalls/bak/___psynch_rw_upgrade.S | 11 + .../bsdsyscalls/bak/___psynch_rw_wrlock.S | 11 + .../bak/___psynch_rw_yieldwrlock.S | 11 + .../bsdsyscalls/bak/___pthread_canceled.S | 11 + .../bsdsyscalls/bak/___pthread_chdir.S | 11 + .../bsdsyscalls/bak/___pthread_fchdir.S | 11 + .../bsdsyscalls/bak/___pthread_kill.S | 11 + .../bsdsyscalls/bak/___pthread_markcancel.S | 11 + .../bsdsyscalls/bak/___pthread_sigmask.S | 11 + .../libsyscall/bsdsyscalls/bak/___ptrace.S | 66 + .../bsdsyscalls/bak/___pwrite_nocancel.S | 23 + .../bsdsyscalls/bak/___read_nocancel.S | 23 + .../bsdsyscalls/bak/___readv_nocancel.S | 23 + .../libsyscall/bsdsyscalls/bak/___recvfrom.S | 21 + .../bsdsyscalls/bak/___recvfrom_nocancel.S | 21 + .../libsyscall/bsdsyscalls/bak/___recvmsg.S | 21 + .../bsdsyscalls/bak/___recvmsg_nocancel.S | 21 + .../libsyscall/bsdsyscalls/bak/___rename.S | 11 + .../bak}/___rename_ext.S | 2 +- .../libsyscall/bsdsyscalls/bak/___renameat.S | 11 + .../libsyscall/bsdsyscalls/bak/___rmdir.S | 11 + .../libsyscall/bsdsyscalls/bak/___select.S | 21 + .../bsdsyscalls/bak/___select_nocancel.S | 21 + .../libsyscall/bsdsyscalls/bak/___sem_open.S | 21 + .../bsdsyscalls/bak/___sem_wait_nocancel.S | 23 + .../libsyscall/bsdsyscalls/bak/___semctl.S | 21 + .../libsyscall/bsdsyscalls/bak/___semsys.S | 21 + .../bsdsyscalls/bak/___semwait_signal.S | 11 + .../bak/___semwait_signal_nocancel.S | 11 + .../libsyscall/bsdsyscalls/bak/___sendmsg.S | 21 + .../bsdsyscalls/bak/___sendmsg_nocancel.S | 21 + .../libsyscall/bsdsyscalls/bak/___sendto.S | 21 + .../bsdsyscalls/bak/___sendto_nocancel.S | 21 + .../bsdsyscalls/bak/___setattrlist.S | 21 + .../libsyscall/bsdsyscalls/bak/___setlogin.S | 11 + .../bsdsyscalls/bak/___setpriority.S | 11 + .../libsyscall/bsdsyscalls/bak/___setregid.S | 21 + .../libsyscall/bsdsyscalls/bak/___setreuid.S | 21 + .../libsyscall/bsdsyscalls/bak/___setrlimit.S | 16 + .../bsdsyscalls/bak/___setsgroups.S | 21 + .../libsyscall/bsdsyscalls/bak/___settid.S | 21 + .../bsdsyscalls/bak/___settid_with_pid.S | 11 + .../bsdsyscalls/bak/___settimeofday.S | 11 + .../bsdsyscalls/bak/___setwgroups.S | 21 + .../libsyscall/bsdsyscalls/bak/___sfi_ctl.S | 11 + .../bsdsyscalls/bak/___sfi_pidctl.S | 11 + .../bak/___shared_region_check_np.S | 11 + .../bak/___shared_region_map_and_slide_np.S | 11 + .../libsyscall/bsdsyscalls/bak/___shm_open.S | 21 + .../libsyscall/bsdsyscalls/bak/___shmctl.S | 21 + .../libsyscall/bsdsyscalls/bak/___shmsys.S | 21 + .../libsyscall/bsdsyscalls/bak/___sigaction.S | 11 + .../bsdsyscalls/bak/___sigaltstack.S | 51 + .../bak}/___sigreturn.S | 4 + .../bsdsyscalls/bak/___sigsuspend.S | 11 + .../bsdsyscalls/bak/___sigsuspend_nocancel.S | 11 + .../libsyscall/bsdsyscalls/bak/___sigwait.S | 11 + .../bsdsyscalls/bak/___socketpair.S | 21 + .../bak}/___stack_snapshot.S | 2 +- .../bak/___stack_snapshot_with_config.S | 11 + .../bsdsyscalls/bak/___stat64_extended.S | 11 + .../bsdsyscalls/bak/___stat_extended.S | 11 + .../libsyscall/bsdsyscalls/bak/___syscall.S | 70 + .../libsyscall/bsdsyscalls/bak/___sysctl.S | 11 + .../bsdsyscalls/bak/___sysctlbyname.S | 11 + .../libsyscall/bsdsyscalls/bak/___telemetry.S | 11 + .../bak}/___thread_selfid.S | 4 + .../bak}/___thread_selfusage.S | 4 + .../bsdsyscalls/bak/___umask_extended.S | 11 + .../libsyscall/bsdsyscalls/bak/___unlink.S | 11 + .../libsyscall/bsdsyscalls/bak/___unlinkat.S | 11 + .../libsyscall/bsdsyscalls/bak/___vfork.S | 162 + .../libsyscall/bsdsyscalls/bak/___wait4.S | 11 + .../bsdsyscalls/bak/___wait4_nocancel.S | 21 + .../bsdsyscalls/bak/___waitid_nocancel.S | 23 + .../bsdsyscalls/bak/___work_interval_ctl.S | 11 + .../bsdsyscalls/bak/___workq_kernreturn.S | 11 + .../bsdsyscalls/bak/___workq_open.S | 11 + .../bsdsyscalls/bak/___write_nocancel.S | 23 + .../bsdsyscalls/bak/___writev_nocancel.S | 23 + .../libsyscall/bsdsyscalls/bak/_access.S | 11 + src/kernel/libsyscall/bsdsyscalls/bak/_acct.S | 11 + .../libsyscall/bsdsyscalls/bak/_adjtime.S | 11 + .../libsyscall/bsdsyscalls/bak/_aio_cancel.S | 11 + .../libsyscall/bsdsyscalls/bak/_aio_error.S | 11 + .../libsyscall/bsdsyscalls/bak/_aio_fsync.S | 11 + .../libsyscall/bsdsyscalls/bak/_aio_read.S | 11 + .../libsyscall/bsdsyscalls/bak/_aio_return.S | 11 + .../libsyscall/bsdsyscalls/bak/_aio_suspend.S | 18 + .../libsyscall/bsdsyscalls/bak/_aio_write.S | 11 + .../libsyscall/bsdsyscalls/bak/_audit.S | 11 + .../bsdsyscalls/bak/_audit_session_join.S | 11 + .../bsdsyscalls/bak/_audit_session_port.S | 11 + .../bsdsyscalls/bak/_audit_session_self.S | 11 + .../libsyscall/bsdsyscalls/bak/_auditctl.S | 11 + .../libsyscall/bsdsyscalls/bak/_auditon.S | 11 + .../bsdsyscalls/bak/_change_fdguard_np.S | 11 + .../libsyscall/bsdsyscalls/bak/_chdir.S | 11 + .../libsyscall/bsdsyscalls/bak/_chflags.S | 11 + .../libsyscall/bsdsyscalls/bak/_chown.S | 11 + .../libsyscall/bsdsyscalls/bak/_chroot.S | 11 + .../libsyscall/bsdsyscalls/bak/_close.S | 18 + .../libsyscall/bsdsyscalls/bak/_connectx.S | 11 + .../libsyscall/bsdsyscalls/bak/_csops.S | 11 + .../bsdsyscalls/bak/_csops_audittoken.S | 11 + .../libsyscall/bsdsyscalls/bak/_disconnectx.S | 11 + src/kernel/libsyscall/bsdsyscalls/bak/_dup.S | 11 + src/kernel/libsyscall/bsdsyscalls/bak/_dup2.S | 11 + .../bsdsyscalls/bak/_exchangedata.S | 11 + .../libsyscall/bsdsyscalls/bak/_execve.S | 11 + .../libsyscall/bsdsyscalls/bak/_faccessat.S | 11 + .../libsyscall/bsdsyscalls/bak/_fchdir.S | 11 + .../libsyscall/bsdsyscalls/bak/_fchflags.S | 11 + .../libsyscall/bsdsyscalls/bak/_fchmodat.S | 11 + .../libsyscall/bsdsyscalls/bak/_fchown.S | 11 + .../libsyscall/bsdsyscalls/bak/_fchownat.S | 11 + .../libsyscall/bsdsyscalls/bak/_fdatasync.S | 11 + .../libsyscall/bsdsyscalls/bak/_ffsctl.S | 11 + .../bsdsyscalls/bak/_fgetattrlist.S | 11 + .../libsyscall/bsdsyscalls/bak/_fgetxattr.S | 11 + .../libsyscall/bsdsyscalls/bak/_fhopen.S | 11 + .../bsdsyscalls/bak/_fileport_makefd.S | 11 + .../bsdsyscalls/bak/_fileport_makeport.S | 11 + .../libsyscall/bsdsyscalls/bak/_flistxattr.S | 11 + .../libsyscall/bsdsyscalls/bak/_flock.S | 11 + .../libsyscall/bsdsyscalls/bak/_fpathconf.S | 11 + .../bsdsyscalls/bak/_fremovexattr.S | 11 + .../libsyscall/bsdsyscalls/bak/_fsctl.S | 11 + .../bsdsyscalls/bak/_fsetattrlist.S | 11 + .../libsyscall/bsdsyscalls/bak/_fsetxattr.S | 11 + .../libsyscall/bsdsyscalls/bak/_fstat.S | 11 + .../libsyscall/bsdsyscalls/bak/_fstat64.S | 21 + .../libsyscall/bsdsyscalls/bak/_fstatat.S | 11 + .../libsyscall/bsdsyscalls/bak/_fstatat64.S | 21 + .../libsyscall/bsdsyscalls/bak/_fstatfs.S | 11 + .../libsyscall/bsdsyscalls/bak/_fstatfs64.S | 21 + .../libsyscall/bsdsyscalls/bak/_fsync.S | 18 + .../libsyscall/bsdsyscalls/bak/_ftruncate.S | 11 + .../libsyscall/bsdsyscalls/bak/_futimes.S | 11 + .../bsdsyscalls/bak/_getattrlistat.S | 11 + .../bsdsyscalls/bak/_getattrlistbulk.S | 11 + .../bsdsyscalls/bak/_getaudit_addr.S | 11 + .../libsyscall/bsdsyscalls/bak/_getauid.S | 11 + .../bsdsyscalls/bak/_getdirentries.S | 11 + .../bsdsyscalls/bak/_getdirentriesattr.S | 11 + .../bsdsyscalls/bak/_getdtablesize.S | 11 + .../libsyscall/bsdsyscalls/bak/_getegid.S | 11 + .../libsyscall/bsdsyscalls/bak/_geteuid.S | 11 + .../libsyscall/bsdsyscalls/bak/_getfh.S | 11 + .../libsyscall/bsdsyscalls/bak/_getfsstat.S | 11 + .../libsyscall/bsdsyscalls/bak/_getfsstat64.S | 21 + .../libsyscall/bsdsyscalls/bak/_getgid.S | 11 + .../libsyscall/bsdsyscalls/bak/_getgroups.S | 11 + .../libsyscall/bsdsyscalls/bak/_getitimer.S | 11 + .../libsyscall/bsdsyscalls/bak/_getpgid.S | 11 + .../libsyscall/bsdsyscalls/bak/_getpgrp.S | 11 + .../libsyscall/bsdsyscalls/bak/_getppid.S | 11 + .../libsyscall/bsdsyscalls/bak/_getpriority.S | 11 + .../libsyscall/bsdsyscalls/bak/_getrusage.S | 11 + .../libsyscall/bsdsyscalls/bak/_getsid.S | 11 + .../libsyscall/bsdsyscalls/bak/_getsockopt.S | 11 + .../libsyscall/bsdsyscalls/bak/_getuid.S | 11 + .../libsyscall/bsdsyscalls/bak/_getxattr.S | 11 + .../bsdsyscalls/bak/_grab_pgo_data.S | 11 + .../bsdsyscalls/bak/_guarded_close_np.S | 11 + .../bsdsyscalls/bak/_guarded_kqueue_np.S | 11 + .../bsdsyscalls/bak/_guarded_pwrite_np.S | 11 + .../bsdsyscalls/bak/_guarded_write_np.S | 11 + .../bsdsyscalls/bak/_guarded_writev_np.S | 11 + .../libsyscall/bsdsyscalls/bak/_issetugid.S | 11 + .../libsyscall/bsdsyscalls/bak/_kas_info.S | 11 + .../libsyscall/bsdsyscalls/bak/_kevent.S | 11 + .../libsyscall/bsdsyscalls/bak/_kevent64.S | 11 + .../libsyscall/bsdsyscalls/bak/_kevent_qos.S | 11 + .../libsyscall/bsdsyscalls/bak/_kqueue.S | 11 + .../libsyscall/bsdsyscalls/bak/_ledger.S | 11 + src/kernel/libsyscall/bsdsyscalls/bak/_link.S | 11 + .../libsyscall/bsdsyscalls/bak/_linkat.S | 11 + .../libsyscall/bsdsyscalls/bak/_lio_listio.S | 11 + .../libsyscall/bsdsyscalls/bak/_listxattr.S | 11 + .../libsyscall/bsdsyscalls/bak/_lstat.S | 11 + .../libsyscall/bsdsyscalls/bak/_lstat64.S | 21 + .../libsyscall/bsdsyscalls/bak/_madvise.S | 21 + .../bsdsyscalls/bak/_memorystatus_control.S | 11 + .../bsdsyscalls/bak/_memorystatus_get_level.S | 11 + .../libsyscall/bsdsyscalls/bak/_mincore.S | 11 + .../libsyscall/bsdsyscalls/bak/_minherit.S | 11 + .../libsyscall/bsdsyscalls/bak/_mkdir.S | 11 + .../libsyscall/bsdsyscalls/bak/_mkdirat.S | 11 + .../libsyscall/bsdsyscalls/bak/_mkfifo.S | 11 + .../libsyscall/bsdsyscalls/bak/_mknod.S | 11 + .../libsyscall/bsdsyscalls/bak/_mlock.S | 11 + .../libsyscall/bsdsyscalls/bak/_mlockall.S | 11 + .../libsyscall/bsdsyscalls/bak/_modwatch.S | 11 + .../libsyscall/bsdsyscalls/bak/_mount.S | 11 + .../bsdsyscalls/bak/_mremap_encrypted.S | 11 + .../libsyscall/bsdsyscalls/bak/_msgget.S | 11 + .../libsyscall/bsdsyscalls/bak/_msgrcv.S | 18 + .../libsyscall/bsdsyscalls/bak/_msgsnd.S | 18 + .../libsyscall/bsdsyscalls/bak/_munlock.S | 11 + .../libsyscall/bsdsyscalls/bak/_munlockall.S | 11 + .../bsdsyscalls/bak/_necp_match_policy.S | 11 + .../bsdsyscalls/bak/_netagent_trigger.S | 11 + .../libsyscall/bsdsyscalls/bak/_nfsclnt.S | 11 + .../libsyscall/bsdsyscalls/bak/_nfssvc.S | 11 + .../libsyscall/bsdsyscalls/bak/_openbyid_np.S | 11 + .../libsyscall/bsdsyscalls/bak/_pathconf.S | 11 + .../libsyscall/bsdsyscalls/bak/_peeloff.S | 11 + .../libsyscall/bsdsyscalls/bak/_pid_resume.S | 11 + .../libsyscall/bsdsyscalls/bak/_pid_suspend.S | 11 + src/kernel/libsyscall/bsdsyscalls/bak/_poll.S | 18 + .../libsyscall/bsdsyscalls/bak/_pread.S | 18 + .../bsdsyscalls/bak/_proc_rlimit_control.S | 11 + .../bsdsyscalls/bak/_proc_trace_log.S | 11 + .../bsdsyscalls/bak/_proc_uuid_policy.S | 11 + .../libsyscall/bsdsyscalls/bak/_pwrite.S | 18 + .../libsyscall/bsdsyscalls/bak/_quotactl.S | 11 + src/kernel/libsyscall/bsdsyscalls/bak/_read.S | 18 + .../libsyscall/bsdsyscalls/bak/_readlink.S | 11 + .../libsyscall/bsdsyscalls/bak/_readlinkat.S | 11 + .../libsyscall/bsdsyscalls/bak/_readv.S | 18 + .../libsyscall/bsdsyscalls/bak/_reboot.S | 11 + .../libsyscall/bsdsyscalls/bak/_recvmsg_x.S | 11 + .../libsyscall/bsdsyscalls/bak/_removexattr.S | 11 + .../libsyscall/bsdsyscalls/bak/_revoke.S | 11 + .../libsyscall/bsdsyscalls/bak/_searchfs.S | 11 + .../libsyscall/bsdsyscalls/bak/_sem_close.S | 11 + .../libsyscall/bsdsyscalls/bak/_sem_post.S | 11 + .../libsyscall/bsdsyscalls/bak/_sem_trywait.S | 11 + .../libsyscall/bsdsyscalls/bak/_sem_unlink.S | 11 + .../libsyscall/bsdsyscalls/bak/_sem_wait.S | 18 + .../libsyscall/bsdsyscalls/bak/_semget.S | 11 + .../libsyscall/bsdsyscalls/bak/_semop.S | 11 + .../libsyscall/bsdsyscalls/bak/_sendfile.S | 11 + .../libsyscall/bsdsyscalls/bak/_sendmsg_x.S | 11 + .../bsdsyscalls/bak/_setaudit_addr.S | 11 + .../libsyscall/bsdsyscalls/bak/_setauid.S | 11 + .../libsyscall/bsdsyscalls/bak/_setegid.S | 11 + .../libsyscall/bsdsyscalls/bak/_seteuid.S | 11 + .../libsyscall/bsdsyscalls/bak/_setgid.S | 11 + .../libsyscall/bsdsyscalls/bak/_setgroups.S | 11 + .../libsyscall/bsdsyscalls/bak/_setitimer.S | 11 + .../libsyscall/bsdsyscalls/bak/_setpgid.S | 16 + .../libsyscall/bsdsyscalls/bak/_setprivexec.S | 11 + .../libsyscall/bsdsyscalls/bak/_setsid.S | 11 + .../libsyscall/bsdsyscalls/bak/_setsockopt.S | 11 + .../libsyscall/bsdsyscalls/bak/_setuid.S | 11 + .../libsyscall/bsdsyscalls/bak/_setxattr.S | 11 + .../libsyscall/bsdsyscalls/bak/_shm_unlink.S | 11 + .../libsyscall/bsdsyscalls/bak/_shmat.S | 11 + .../libsyscall/bsdsyscalls/bak/_shmdt.S | 11 + .../libsyscall/bsdsyscalls/bak/_shmget.S | 11 + .../libsyscall/bsdsyscalls/bak/_shutdown.S | 11 + .../libsyscall/bsdsyscalls/bak/_sigpending.S | 11 + .../libsyscall/bsdsyscalls/bak/_sigprocmask.S | 11 + .../libsyscall/bsdsyscalls/bak/_socket.S | 11 + .../bsdsyscalls/bak/_socket_delegate.S | 11 + src/kernel/libsyscall/bsdsyscalls/bak/_stat.S | 11 + .../libsyscall/bsdsyscalls/bak/_stat64.S | 21 + .../libsyscall/bsdsyscalls/bak/_statfs.S | 11 + .../libsyscall/bsdsyscalls/bak/_statfs64.S | 21 + .../libsyscall/bsdsyscalls/bak/_swapon.S | 11 + .../libsyscall/bsdsyscalls/bak/_symlink.S | 11 + .../libsyscall/bsdsyscalls/bak/_symlinkat.S | 11 + src/kernel/libsyscall/bsdsyscalls/bak/_sync.S | 11 + .../bsdsyscalls/bak/_system_override.S | 11 + .../libsyscall/bsdsyscalls/bak/_truncate.S | 11 + .../libsyscall/bsdsyscalls/bak/_umask.S | 11 + .../libsyscall/bsdsyscalls/bak/_undelete.S | 11 + .../libsyscall/bsdsyscalls/bak/_unmount.S | 11 + .../libsyscall/bsdsyscalls/bak/_usrctl.S | 11 + .../libsyscall/bsdsyscalls/bak/_utimes.S | 11 + .../libsyscall/bsdsyscalls/bak/_vfs_purge.S | 11 + .../bsdsyscalls/bak/_vm_pressure_monitor.S | 11 + .../libsyscall/bsdsyscalls/bak/_waitevent.S | 11 + .../libsyscall/bsdsyscalls/bak/_waitid.S | 18 + .../libsyscall/bsdsyscalls/bak/_watchevent.S | 11 + .../libsyscall/bsdsyscalls/bak/_write.S | 18 + .../libsyscall/bsdsyscalls/bak/_writev.S | 18 + .../libsyscall/bsdsyscalls/bak/custom.S | 107 + .../libsyscall/bsdsyscalls/bak/stubs.list | 395 + src/kernel/libsyscall/bsdsyscalls/custom.S | 129 + src/kernel/libsyscall/bsdsyscalls/stubs.list | 404 + src/kernel/libsyscall/custom/SYS.h | 30 +- src/kernel/libsyscall/custom/__fork.s | 15 +- src/kernel/libsyscall/custom/__getpid.s | 9 +- .../libsyscall/custom/__kdebug_trace_string.s | 41 + src/kernel/libsyscall/custom/__ptrace.s | 6 - src/kernel/libsyscall/custom/__vfork.s | 27 +- src/kernel/libsyscall/custom/custom.s | 33 +- src/kernel/libsyscall/sys_i386/SYS.h | 221 - .../____old_semwait_signal_nocancel.S | 11 - .../sys_i386/____sigwait_nocancel.S | 11 - src/kernel/libsyscall/sys_i386/__accept.S | 16 - .../libsyscall/sys_i386/__accept_nocancel.S | 16 - .../libsyscall/sys_i386/__access_extended.S | 16 - .../sys_i386/__aio_suspend_nocancel.S | 18 - src/kernel/libsyscall/sys_i386/__bind.S | 16 - .../libsyscall/sys_i386/__bsdthread_create.S | 11 - .../libsyscall/sys_i386/__bsdthread_ctl.S | 11 - .../sys_i386/__bsdthread_register.S | 11 - .../sys_i386/__bsdthread_terminate.S | 11 - src/kernel/libsyscall/sys_i386/__chmod.S | 16 - .../libsyscall/sys_i386/__chmod_extended.S | 11 - src/kernel/libsyscall/sys_i386/__chud.S | 11 - .../libsyscall/sys_i386/__close_nocancel.S | 18 - src/kernel/libsyscall/sys_i386/__coalition.S | 11 - .../libsyscall/sys_i386/__coalition_info.S | 11 - src/kernel/libsyscall/sys_i386/__connect.S | 16 - .../libsyscall/sys_i386/__connect_nocancel.S | 16 - src/kernel/libsyscall/sys_i386/__copyfile.S | 11 - src/kernel/libsyscall/sys_i386/__csrctl.S | 11 - src/kernel/libsyscall/sys_i386/__delete.S | 11 - .../sys_i386/__disable_threadsignal.S | 11 - src/kernel/libsyscall/sys_i386/__exit.S | 16 - src/kernel/libsyscall/sys_i386/__fchmod.S | 16 - .../libsyscall/sys_i386/__fchmod_extended.S | 11 - src/kernel/libsyscall/sys_i386/__fcntl.S | 16 - .../libsyscall/sys_i386/__fcntl_nocancel.S | 18 - src/kernel/libsyscall/sys_i386/__fork.S | 111 - src/kernel/libsyscall/sys_i386/__fsgetpath.S | 11 - .../libsyscall/sys_i386/__fstat64_extended.S | 11 - .../libsyscall/sys_i386/__fstat_extended.S | 11 - .../libsyscall/sys_i386/__fsync_nocancel.S | 18 - .../libsyscall/sys_i386/__getattrlist.S | 16 - .../libsyscall/sys_i386/__getdirentries64.S | 11 - .../libsyscall/sys_i386/__gethostuuid.S | 11 - src/kernel/libsyscall/sys_i386/__getlcid.S | 11 - src/kernel/libsyscall/sys_i386/__getlogin.S | 11 - .../libsyscall/sys_i386/__getpeername.S | 16 - src/kernel/libsyscall/sys_i386/__getpid.S | 114 - src/kernel/libsyscall/sys_i386/__getrlimit.S | 16 - src/kernel/libsyscall/sys_i386/__getsgroups.S | 16 - .../libsyscall/sys_i386/__getsockname.S | 16 - src/kernel/libsyscall/sys_i386/__gettid.S | 16 - src/kernel/libsyscall/sys_i386/__getwgroups.S | 16 - .../sys_i386/__guarded_open_dprotected_np.S | 11 - .../libsyscall/sys_i386/__guarded_open_np.S | 11 - .../libsyscall/sys_i386/__identitysvc.S | 11 - src/kernel/libsyscall/sys_i386/__initgroups.S | 11 - src/kernel/libsyscall/sys_i386/__ioctl.S | 18 - .../libsyscall/sys_i386/__iopolicysys.S | 11 - .../libsyscall/sys_i386/__kdebug_trace.S | 11 - src/kernel/libsyscall/sys_i386/__kill.S | 11 - src/kernel/libsyscall/sys_i386/__lchown.S | 16 - src/kernel/libsyscall/sys_i386/__listen.S | 16 - src/kernel/libsyscall/sys_i386/__lseek.S | 51 - .../libsyscall/sys_i386/__lstat64_extended.S | 11 - .../libsyscall/sys_i386/__lstat_extended.S | 11 - src/kernel/libsyscall/sys_i386/__mac_execve.S | 16 - src/kernel/libsyscall/sys_i386/__mac_get_fd.S | 11 - .../libsyscall/sys_i386/__mac_get_file.S | 11 - .../libsyscall/sys_i386/__mac_get_lcid.S | 11 - .../libsyscall/sys_i386/__mac_get_lctx.S | 11 - .../libsyscall/sys_i386/__mac_get_link.S | 11 - .../libsyscall/sys_i386/__mac_get_mount.S | 11 - .../libsyscall/sys_i386/__mac_get_pid.S | 11 - .../libsyscall/sys_i386/__mac_get_proc.S | 11 - .../libsyscall/sys_i386/__mac_getfsstat.S | 11 - src/kernel/libsyscall/sys_i386/__mac_mount.S | 16 - src/kernel/libsyscall/sys_i386/__mac_set_fd.S | 11 - .../libsyscall/sys_i386/__mac_set_file.S | 11 - .../libsyscall/sys_i386/__mac_set_lctx.S | 11 - .../libsyscall/sys_i386/__mac_set_link.S | 11 - .../libsyscall/sys_i386/__mac_set_proc.S | 16 - .../libsyscall/sys_i386/__mac_syscall.S | 16 - .../libsyscall/sys_i386/__mkdir_extended.S | 11 - .../libsyscall/sys_i386/__mkfifo_extended.S | 11 - src/kernel/libsyscall/sys_i386/__mmap.S | 16 - src/kernel/libsyscall/sys_i386/__mprotect.S | 16 - src/kernel/libsyscall/sys_i386/__msgctl.S | 16 - .../libsyscall/sys_i386/__msgrcv_nocancel.S | 18 - .../libsyscall/sys_i386/__msgsnd_nocancel.S | 18 - src/kernel/libsyscall/sys_i386/__msgsys.S | 16 - src/kernel/libsyscall/sys_i386/__msync.S | 16 - .../libsyscall/sys_i386/__msync_nocancel.S | 16 - src/kernel/libsyscall/sys_i386/__munmap.S | 11 - .../sys_i386/__old_semwait_signal.S | 11 - src/kernel/libsyscall/sys_i386/__open.S | 16 - .../sys_i386/__open_dprotected_np.S | 11 - .../libsyscall/sys_i386/__open_extended.S | 11 - .../libsyscall/sys_i386/__open_nocancel.S | 16 - src/kernel/libsyscall/sys_i386/__openat.S | 16 - .../libsyscall/sys_i386/__openat_nocancel.S | 16 - src/kernel/libsyscall/sys_i386/__pipe.S | 52 - .../libsyscall/sys_i386/__poll_nocancel.S | 18 - .../libsyscall/sys_i386/__posix_spawn.S | 11 - .../libsyscall/sys_i386/__pread_nocancel.S | 18 - src/kernel/libsyscall/sys_i386/__proc_info.S | 11 - .../libsyscall/sys_i386/__process_policy.S | 11 - .../libsyscall/sys_i386/__psynch_cvbroad.S | 11 - .../sys_i386/__psynch_cvclrprepost.S | 11 - .../libsyscall/sys_i386/__psynch_cvsignal.S | 11 - .../libsyscall/sys_i386/__psynch_cvwait.S | 11 - .../libsyscall/sys_i386/__psynch_mutexdrop.S | 11 - .../libsyscall/sys_i386/__psynch_mutexwait.S | 11 - .../sys_i386/__psynch_rw_downgrade.S | 11 - .../sys_i386/__psynch_rw_longrdlock.S | 11 - .../libsyscall/sys_i386/__psynch_rw_rdlock.S | 11 - .../libsyscall/sys_i386/__psynch_rw_unlock.S | 11 - .../libsyscall/sys_i386/__psynch_rw_unlock2.S | 11 - .../libsyscall/sys_i386/__psynch_rw_upgrade.S | 11 - .../libsyscall/sys_i386/__psynch_rw_wrlock.S | 11 - .../sys_i386/__psynch_rw_yieldwrlock.S | 11 - .../libsyscall/sys_i386/__pthread_canceled.S | 11 - .../libsyscall/sys_i386/__pthread_chdir.S | 11 - .../libsyscall/sys_i386/__pthread_fchdir.S | 11 - .../libsyscall/sys_i386/__pthread_kill.S | 11 - .../sys_i386/__pthread_markcancel.S | 11 - .../libsyscall/sys_i386/__pthread_sigmask.S | 11 - src/kernel/libsyscall/sys_i386/__ptrace.S | 66 - .../libsyscall/sys_i386/__pwrite_nocancel.S | 18 - .../libsyscall/sys_i386/__read_nocancel.S | 18 - .../libsyscall/sys_i386/__readv_nocancel.S | 18 - src/kernel/libsyscall/sys_i386/__recvfrom.S | 16 - .../libsyscall/sys_i386/__recvfrom_nocancel.S | 16 - src/kernel/libsyscall/sys_i386/__recvmsg.S | 16 - .../libsyscall/sys_i386/__recvmsg_nocancel.S | 16 - src/kernel/libsyscall/sys_i386/__rename.S | 11 - src/kernel/libsyscall/sys_i386/__rename_ext.S | 11 - src/kernel/libsyscall/sys_i386/__renameat.S | 11 - src/kernel/libsyscall/sys_i386/__rmdir.S | 11 - src/kernel/libsyscall/sys_i386/__select.S | 16 - .../libsyscall/sys_i386/__select_nocancel.S | 16 - src/kernel/libsyscall/sys_i386/__sem_open.S | 16 - .../libsyscall/sys_i386/__sem_wait_nocancel.S | 18 - src/kernel/libsyscall/sys_i386/__semctl.S | 16 - src/kernel/libsyscall/sys_i386/__semsys.S | 16 - .../libsyscall/sys_i386/__semwait_signal.S | 11 - .../sys_i386/__semwait_signal_nocancel.S | 11 - src/kernel/libsyscall/sys_i386/__sendmsg.S | 16 - .../libsyscall/sys_i386/__sendmsg_nocancel.S | 16 - src/kernel/libsyscall/sys_i386/__sendto.S | 16 - .../libsyscall/sys_i386/__sendto_nocancel.S | 16 - .../libsyscall/sys_i386/__setattrlist.S | 16 - src/kernel/libsyscall/sys_i386/__setlcid.S | 11 - src/kernel/libsyscall/sys_i386/__setlogin.S | 11 - .../libsyscall/sys_i386/__setpriority.S | 11 - src/kernel/libsyscall/sys_i386/__setregid.S | 16 - src/kernel/libsyscall/sys_i386/__setreuid.S | 16 - src/kernel/libsyscall/sys_i386/__setrlimit.S | 16 - src/kernel/libsyscall/sys_i386/__setsgroups.S | 16 - src/kernel/libsyscall/sys_i386/__settid.S | 16 - .../libsyscall/sys_i386/__settid_with_pid.S | 11 - .../libsyscall/sys_i386/__settimeofday.S | 11 - src/kernel/libsyscall/sys_i386/__setwgroups.S | 16 - src/kernel/libsyscall/sys_i386/__sfi_ctl.S | 11 - src/kernel/libsyscall/sys_i386/__sfi_pidctl.S | 11 - .../sys_i386/__shared_region_check_np.S | 11 - .../__shared_region_map_and_slide_np.S | 11 - src/kernel/libsyscall/sys_i386/__shm_open.S | 16 - src/kernel/libsyscall/sys_i386/__shmctl.S | 16 - src/kernel/libsyscall/sys_i386/__shmsys.S | 16 - src/kernel/libsyscall/sys_i386/__sigaction.S | 11 - .../libsyscall/sys_i386/__sigaltstack.S | 51 - src/kernel/libsyscall/sys_i386/__sigsuspend.S | 11 - .../sys_i386/__sigsuspend_nocancel.S | 11 - src/kernel/libsyscall/sys_i386/__sigwait.S | 11 - src/kernel/libsyscall/sys_i386/__socketpair.S | 16 - .../libsyscall/sys_i386/__stack_snapshot.S | 11 - .../libsyscall/sys_i386/__stat64_extended.S | 11 - .../libsyscall/sys_i386/__stat_extended.S | 11 - src/kernel/libsyscall/sys_i386/__syscall.S | 65 - src/kernel/libsyscall/sys_i386/__sysctl.S | 11 - .../libsyscall/sys_i386/__sysctlbyname.S | 11 - src/kernel/libsyscall/sys_i386/__telemetry.S | 11 - .../libsyscall/sys_i386/__umask_extended.S | 11 - src/kernel/libsyscall/sys_i386/__unlink.S | 11 - src/kernel/libsyscall/sys_i386/__unlinkat.S | 11 - src/kernel/libsyscall/sys_i386/__vfork.S | 144 - src/kernel/libsyscall/sys_i386/__wait4.S | 11 - .../libsyscall/sys_i386/__wait4_nocancel.S | 16 - .../libsyscall/sys_i386/__waitid_nocancel.S | 18 - .../libsyscall/sys_i386/__workq_kernreturn.S | 11 - src/kernel/libsyscall/sys_i386/__workq_open.S | 11 - .../libsyscall/sys_i386/__write_nocancel.S | 18 - .../libsyscall/sys_i386/__writev_nocancel.S | 18 - src/kernel/libsyscall/sys_i386/access.S | 11 - src/kernel/libsyscall/sys_i386/acct.S | 11 - src/kernel/libsyscall/sys_i386/adjtime.S | 11 - src/kernel/libsyscall/sys_i386/aio_cancel.S | 11 - src/kernel/libsyscall/sys_i386/aio_error.S | 11 - src/kernel/libsyscall/sys_i386/aio_fsync.S | 11 - src/kernel/libsyscall/sys_i386/aio_read.S | 11 - src/kernel/libsyscall/sys_i386/aio_return.S | 11 - src/kernel/libsyscall/sys_i386/aio_suspend.S | 17 - src/kernel/libsyscall/sys_i386/aio_write.S | 11 - src/kernel/libsyscall/sys_i386/audit.S | 11 - .../libsyscall/sys_i386/audit_session_join.S | 11 - .../libsyscall/sys_i386/audit_session_port.S | 11 - .../libsyscall/sys_i386/audit_session_self.S | 11 - src/kernel/libsyscall/sys_i386/auditctl.S | 11 - src/kernel/libsyscall/sys_i386/auditon.S | 11 - .../libsyscall/sys_i386/change_fdguard_np.S | 11 - src/kernel/libsyscall/sys_i386/chdir.S | 11 - src/kernel/libsyscall/sys_i386/chflags.S | 11 - src/kernel/libsyscall/sys_i386/chown.S | 11 - src/kernel/libsyscall/sys_i386/chroot.S | 11 - src/kernel/libsyscall/sys_i386/close.S | 16 - src/kernel/libsyscall/sys_i386/connectx.S | 11 - src/kernel/libsyscall/sys_i386/csops.S | 11 - .../libsyscall/sys_i386/csops_audittoken.S | 11 - src/kernel/libsyscall/sys_i386/custom.S | 108 - src/kernel/libsyscall/sys_i386/disconnectx.S | 11 - src/kernel/libsyscall/sys_i386/dup.S | 11 - src/kernel/libsyscall/sys_i386/dup2.S | 11 - src/kernel/libsyscall/sys_i386/exchangedata.S | 11 - src/kernel/libsyscall/sys_i386/execve.S | 11 - src/kernel/libsyscall/sys_i386/faccessat.S | 11 - src/kernel/libsyscall/sys_i386/fchdir.S | 11 - src/kernel/libsyscall/sys_i386/fchflags.S | 11 - src/kernel/libsyscall/sys_i386/fchmodat.S | 11 - src/kernel/libsyscall/sys_i386/fchown.S | 11 - src/kernel/libsyscall/sys_i386/fchownat.S | 11 - src/kernel/libsyscall/sys_i386/fdatasync.S | 11 - src/kernel/libsyscall/sys_i386/ffsctl.S | 11 - src/kernel/libsyscall/sys_i386/fgetattrlist.S | 11 - src/kernel/libsyscall/sys_i386/fgetxattr.S | 11 - src/kernel/libsyscall/sys_i386/fhopen.S | 11 - .../libsyscall/sys_i386/fileport_makefd.S | 11 - .../libsyscall/sys_i386/fileport_makeport.S | 11 - src/kernel/libsyscall/sys_i386/flistxattr.S | 11 - src/kernel/libsyscall/sys_i386/flock.S | 11 - src/kernel/libsyscall/sys_i386/fpathconf.S | 11 - src/kernel/libsyscall/sys_i386/fremovexattr.S | 11 - src/kernel/libsyscall/sys_i386/fsctl.S | 11 - src/kernel/libsyscall/sys_i386/fsetattrlist.S | 11 - src/kernel/libsyscall/sys_i386/fsetxattr.S | 11 - src/kernel/libsyscall/sys_i386/fstat.S | 11 - src/kernel/libsyscall/sys_i386/fstat64.S | 16 - src/kernel/libsyscall/sys_i386/fstatat.S | 11 - src/kernel/libsyscall/sys_i386/fstatat64.S | 16 - src/kernel/libsyscall/sys_i386/fstatfs.S | 11 - src/kernel/libsyscall/sys_i386/fstatfs64.S | 16 - src/kernel/libsyscall/sys_i386/fsync.S | 17 - src/kernel/libsyscall/sys_i386/ftruncate.S | 11 - src/kernel/libsyscall/sys_i386/futimes.S | 11 - .../libsyscall/sys_i386/getattrlistat.S | 11 - .../libsyscall/sys_i386/getattrlistbulk.S | 11 - .../libsyscall/sys_i386/getaudit_addr.S | 11 - src/kernel/libsyscall/sys_i386/getauid.S | 11 - .../libsyscall/sys_i386/getdirentries.S | 11 - .../libsyscall/sys_i386/getdirentriesattr.S | 11 - .../libsyscall/sys_i386/getdtablesize.S | 11 - src/kernel/libsyscall/sys_i386/getegid.S | 11 - src/kernel/libsyscall/sys_i386/geteuid.S | 11 - src/kernel/libsyscall/sys_i386/getfh.S | 11 - src/kernel/libsyscall/sys_i386/getfsstat.S | 11 - src/kernel/libsyscall/sys_i386/getfsstat64.S | 16 - src/kernel/libsyscall/sys_i386/getgid.S | 11 - src/kernel/libsyscall/sys_i386/getgroups.S | 11 - src/kernel/libsyscall/sys_i386/getitimer.S | 11 - src/kernel/libsyscall/sys_i386/getpgid.S | 11 - src/kernel/libsyscall/sys_i386/getpgrp.S | 11 - src/kernel/libsyscall/sys_i386/getppid.S | 11 - src/kernel/libsyscall/sys_i386/getpriority.S | 11 - src/kernel/libsyscall/sys_i386/getrusage.S | 11 - src/kernel/libsyscall/sys_i386/getsid.S | 11 - src/kernel/libsyscall/sys_i386/getsockopt.S | 11 - src/kernel/libsyscall/sys_i386/getuid.S | 11 - src/kernel/libsyscall/sys_i386/getxattr.S | 11 - .../libsyscall/sys_i386/guarded_close_np.S | 11 - .../libsyscall/sys_i386/guarded_kqueue_np.S | 11 - .../libsyscall/sys_i386/guarded_pwrite_np.S | 11 - .../libsyscall/sys_i386/guarded_write_np.S | 11 - .../libsyscall/sys_i386/guarded_writev_np.S | 11 - src/kernel/libsyscall/sys_i386/issetugid.S | 11 - src/kernel/libsyscall/sys_i386/kas_info.S | 11 - src/kernel/libsyscall/sys_i386/kevent.S | 11 - src/kernel/libsyscall/sys_i386/kevent64.S | 11 - src/kernel/libsyscall/sys_i386/kqueue.S | 11 - src/kernel/libsyscall/sys_i386/ledger.S | 11 - src/kernel/libsyscall/sys_i386/link.S | 11 - src/kernel/libsyscall/sys_i386/linkat.S | 11 - src/kernel/libsyscall/sys_i386/lio_listio.S | 11 - src/kernel/libsyscall/sys_i386/listxattr.S | 11 - src/kernel/libsyscall/sys_i386/lstat.S | 11 - src/kernel/libsyscall/sys_i386/lstat64.S | 16 - src/kernel/libsyscall/sys_i386/madvise.S | 16 - .../sys_i386/memorystatus_control.S | 11 - .../sys_i386/memorystatus_get_level.S | 11 - src/kernel/libsyscall/sys_i386/mincore.S | 11 - src/kernel/libsyscall/sys_i386/minherit.S | 11 - src/kernel/libsyscall/sys_i386/mkdir.S | 11 - src/kernel/libsyscall/sys_i386/mkdirat.S | 11 - src/kernel/libsyscall/sys_i386/mkfifo.S | 11 - src/kernel/libsyscall/sys_i386/mknod.S | 11 - src/kernel/libsyscall/sys_i386/mlock.S | 11 - src/kernel/libsyscall/sys_i386/mlockall.S | 11 - src/kernel/libsyscall/sys_i386/modwatch.S | 11 - src/kernel/libsyscall/sys_i386/mount.S | 11 - .../libsyscall/sys_i386/mremap_encrypted.S | 11 - src/kernel/libsyscall/sys_i386/msgget.S | 11 - src/kernel/libsyscall/sys_i386/msgrcv.S | 17 - src/kernel/libsyscall/sys_i386/msgsnd.S | 17 - src/kernel/libsyscall/sys_i386/munlock.S | 11 - src/kernel/libsyscall/sys_i386/munlockall.S | 11 - .../libsyscall/sys_i386/necp_match_policy.S | 11 - src/kernel/libsyscall/sys_i386/nfsclnt.S | 11 - src/kernel/libsyscall/sys_i386/nfssvc.S | 11 - src/kernel/libsyscall/sys_i386/openbyid_np.S | 11 - src/kernel/libsyscall/sys_i386/pathconf.S | 11 - src/kernel/libsyscall/sys_i386/peeloff.S | 11 - src/kernel/libsyscall/sys_i386/pid_resume.S | 11 - src/kernel/libsyscall/sys_i386/pid_suspend.S | 11 - src/kernel/libsyscall/sys_i386/poll.S | 17 - src/kernel/libsyscall/sys_i386/pread.S | 17 - .../libsyscall/sys_i386/proc_rlimit_control.S | 11 - .../libsyscall/sys_i386/proc_trace_log.S | 11 - .../libsyscall/sys_i386/proc_uuid_policy.S | 11 - src/kernel/libsyscall/sys_i386/pwrite.S | 17 - src/kernel/libsyscall/sys_i386/quota.S | 11 - src/kernel/libsyscall/sys_i386/quotactl.S | 11 - src/kernel/libsyscall/sys_i386/read.S | 17 - src/kernel/libsyscall/sys_i386/readlink.S | 11 - src/kernel/libsyscall/sys_i386/readlinkat.S | 11 - src/kernel/libsyscall/sys_i386/readv.S | 17 - src/kernel/libsyscall/sys_i386/reboot.S | 11 - src/kernel/libsyscall/sys_i386/recvmsg_x.S | 11 - src/kernel/libsyscall/sys_i386/removexattr.S | 11 - src/kernel/libsyscall/sys_i386/revoke.S | 11 - src/kernel/libsyscall/sys_i386/searchfs.S | 11 - src/kernel/libsyscall/sys_i386/sem_close.S | 11 - src/kernel/libsyscall/sys_i386/sem_post.S | 11 - src/kernel/libsyscall/sys_i386/sem_trywait.S | 11 - src/kernel/libsyscall/sys_i386/sem_unlink.S | 11 - src/kernel/libsyscall/sys_i386/sem_wait.S | 17 - src/kernel/libsyscall/sys_i386/semget.S | 11 - src/kernel/libsyscall/sys_i386/semop.S | 11 - src/kernel/libsyscall/sys_i386/sendfile.S | 11 - src/kernel/libsyscall/sys_i386/sendmsg_x.S | 11 - .../libsyscall/sys_i386/setaudit_addr.S | 11 - src/kernel/libsyscall/sys_i386/setauid.S | 11 - src/kernel/libsyscall/sys_i386/setegid.S | 11 - src/kernel/libsyscall/sys_i386/seteuid.S | 11 - src/kernel/libsyscall/sys_i386/setgid.S | 11 - src/kernel/libsyscall/sys_i386/setgroups.S | 11 - src/kernel/libsyscall/sys_i386/setitimer.S | 11 - src/kernel/libsyscall/sys_i386/setpgid.S | 16 - src/kernel/libsyscall/sys_i386/setprivexec.S | 11 - src/kernel/libsyscall/sys_i386/setquota.S | 11 - src/kernel/libsyscall/sys_i386/setsid.S | 11 - src/kernel/libsyscall/sys_i386/setsockopt.S | 11 - src/kernel/libsyscall/sys_i386/setuid.S | 11 - src/kernel/libsyscall/sys_i386/setxattr.S | 11 - src/kernel/libsyscall/sys_i386/shm_unlink.S | 11 - src/kernel/libsyscall/sys_i386/shmat.S | 11 - src/kernel/libsyscall/sys_i386/shmdt.S | 11 - src/kernel/libsyscall/sys_i386/shmget.S | 11 - src/kernel/libsyscall/sys_i386/shutdown.S | 11 - src/kernel/libsyscall/sys_i386/sigpending.S | 11 - src/kernel/libsyscall/sys_i386/sigprocmask.S | 11 - src/kernel/libsyscall/sys_i386/socket.S | 11 - .../libsyscall/sys_i386/socket_delegate.S | 11 - src/kernel/libsyscall/sys_i386/stat.S | 11 - src/kernel/libsyscall/sys_i386/stat64.S | 16 - src/kernel/libsyscall/sys_i386/statfs.S | 11 - src/kernel/libsyscall/sys_i386/statfs64.S | 16 - src/kernel/libsyscall/sys_i386/stubs.list | 388 - src/kernel/libsyscall/sys_i386/swapon.S | 11 - src/kernel/libsyscall/sys_i386/symlink.S | 11 - src/kernel/libsyscall/sys_i386/symlinkat.S | 11 - src/kernel/libsyscall/sys_i386/sync.S | 11 - .../libsyscall/sys_i386/system_override.S | 11 - src/kernel/libsyscall/sys_i386/truncate.S | 11 - src/kernel/libsyscall/sys_i386/umask.S | 11 - src/kernel/libsyscall/sys_i386/undelete.S | 11 - src/kernel/libsyscall/sys_i386/unmount.S | 11 - src/kernel/libsyscall/sys_i386/utimes.S | 11 - src/kernel/libsyscall/sys_i386/vfs_purge.S | 11 - .../libsyscall/sys_i386/vm_pressure_monitor.S | 11 - src/kernel/libsyscall/sys_i386/waitevent.S | 11 - src/kernel/libsyscall/sys_i386/waitid.S | 17 - src/kernel/libsyscall/sys_i386/watchevent.S | 11 - src/kernel/libsyscall/sys_i386/write.S | 17 - src/kernel/libsyscall/sys_i386/writev.S | 17 - src/kernel/libsyscall/sys_x86-64/SYS.h | 213 - .../_____old_semwait_signal_nocancel.S | 11 - .../sys_x86-64/_____sigwait_nocancel.S | 11 - src/kernel/libsyscall/sys_x86-64/___accept.S | 16 - .../sys_x86-64/___accept_nocancel.S | 16 - .../sys_x86-64/___access_extended.S | 16 - .../sys_x86-64/___aio_suspend_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/___bind.S | 16 - .../sys_x86-64/___bsdthread_create.S | 11 - .../libsyscall/sys_x86-64/___bsdthread_ctl.S | 11 - .../sys_x86-64/___bsdthread_register.S | 11 - .../sys_x86-64/___bsdthread_terminate.S | 11 - src/kernel/libsyscall/sys_x86-64/___chmod.S | 11 - .../libsyscall/sys_x86-64/___chmod_extended.S | 11 - .../libsyscall/sys_x86-64/___close_nocancel.S | 16 - .../libsyscall/sys_x86-64/___coalition.S | 11 - .../libsyscall/sys_x86-64/___coalition_info.S | 11 - src/kernel/libsyscall/sys_x86-64/___connect.S | 16 - .../sys_x86-64/___connect_nocancel.S | 16 - .../libsyscall/sys_x86-64/___copyfile.S | 11 - src/kernel/libsyscall/sys_x86-64/___csrctl.S | 11 - src/kernel/libsyscall/sys_x86-64/___delete.S | 11 - .../sys_x86-64/___disable_threadsignal.S | 11 - src/kernel/libsyscall/sys_x86-64/___exit.S | 16 - src/kernel/libsyscall/sys_x86-64/___fchmod.S | 11 - .../sys_x86-64/___fchmod_extended.S | 11 - src/kernel/libsyscall/sys_x86-64/___fcntl.S | 11 - .../libsyscall/sys_x86-64/___fcntl_nocancel.S | 11 - src/kernel/libsyscall/sys_x86-64/___fork.S | 117 - .../libsyscall/sys_x86-64/___fsgetpath.S | 11 - .../sys_x86-64/___fstat64_extended.S | 11 - .../libsyscall/sys_x86-64/___fstat_extended.S | 11 - .../libsyscall/sys_x86-64/___fsync_nocancel.S | 16 - .../libsyscall/sys_x86-64/___getattrlist.S | 16 - .../sys_x86-64/___getdirentries64.S | 11 - .../libsyscall/sys_x86-64/___gethostuuid.S | 11 - .../libsyscall/sys_x86-64/___getlogin.S | 11 - .../libsyscall/sys_x86-64/___getpeername.S | 16 - src/kernel/libsyscall/sys_x86-64/___getpid.S | 110 - .../libsyscall/sys_x86-64/___getrlimit.S | 11 - .../libsyscall/sys_x86-64/___getsgroups.S | 16 - .../libsyscall/sys_x86-64/___getsockname.S | 16 - src/kernel/libsyscall/sys_x86-64/___gettid.S | 16 - .../libsyscall/sys_x86-64/___getwgroups.S | 16 - .../___guarded_open_dprotected_np.S | 11 - .../sys_x86-64/___guarded_open_np.S | 11 - .../libsyscall/sys_x86-64/___identitysvc.S | 11 - .../libsyscall/sys_x86-64/___initgroups.S | 11 - src/kernel/libsyscall/sys_x86-64/___ioctl.S | 11 - .../libsyscall/sys_x86-64/___iopolicysys.S | 11 - .../libsyscall/sys_x86-64/___kdebug_trace.S | 11 - .../libsyscall/sys_x86-64/___kdebug_trace64.S | 11 - .../sys_x86-64/___kdebug_trace_string.S | 11 - src/kernel/libsyscall/sys_x86-64/___kill.S | 11 - src/kernel/libsyscall/sys_x86-64/___lchown.S | 16 - src/kernel/libsyscall/sys_x86-64/___listen.S | 16 - src/kernel/libsyscall/sys_x86-64/___lseek.S | 47 - .../sys_x86-64/___lstat64_extended.S | 11 - .../libsyscall/sys_x86-64/___lstat_extended.S | 11 - .../libsyscall/sys_x86-64/___mac_execve.S | 16 - .../libsyscall/sys_x86-64/___mac_get_fd.S | 11 - .../libsyscall/sys_x86-64/___mac_get_file.S | 11 - .../libsyscall/sys_x86-64/___mac_get_link.S | 11 - .../libsyscall/sys_x86-64/___mac_get_mount.S | 11 - .../libsyscall/sys_x86-64/___mac_get_pid.S | 11 - .../libsyscall/sys_x86-64/___mac_get_proc.S | 11 - .../libsyscall/sys_x86-64/___mac_getfsstat.S | 11 - .../libsyscall/sys_x86-64/___mac_mount.S | 16 - .../libsyscall/sys_x86-64/___mac_set_fd.S | 11 - .../libsyscall/sys_x86-64/___mac_set_file.S | 11 - .../libsyscall/sys_x86-64/___mac_set_link.S | 11 - .../libsyscall/sys_x86-64/___mac_set_proc.S | 16 - .../libsyscall/sys_x86-64/___mac_syscall.S | 16 - .../libsyscall/sys_x86-64/___microstackshot.S | 11 - .../libsyscall/sys_x86-64/___mkdir_extended.S | 11 - .../sys_x86-64/___mkfifo_extended.S | 11 - src/kernel/libsyscall/sys_x86-64/___mmap.S | 11 - .../libsyscall/sys_x86-64/___mprotect.S | 16 - src/kernel/libsyscall/sys_x86-64/___msgctl.S | 16 - .../sys_x86-64/___msgrcv_nocancel.S | 16 - .../sys_x86-64/___msgsnd_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/___msgsys.S | 16 - src/kernel/libsyscall/sys_x86-64/___msync.S | 16 - .../libsyscall/sys_x86-64/___msync_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/___munmap.S | 11 - .../sys_x86-64/___old_semwait_signal.S | 11 - src/kernel/libsyscall/sys_x86-64/___open.S | 16 - .../sys_x86-64/___open_dprotected_np.S | 11 - .../libsyscall/sys_x86-64/___open_extended.S | 11 - .../libsyscall/sys_x86-64/___open_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/___openat.S | 16 - .../sys_x86-64/___openat_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/___persona.S | 11 - src/kernel/libsyscall/sys_x86-64/___pipe.S | 57 - .../libsyscall/sys_x86-64/___poll_nocancel.S | 16 - .../libsyscall/sys_x86-64/___posix_spawn.S | 11 - .../libsyscall/sys_x86-64/___pread_nocancel.S | 16 - .../libsyscall/sys_x86-64/___proc_info.S | 11 - .../libsyscall/sys_x86-64/___process_policy.S | 11 - src/kernel/libsyscall/sys_x86-64/___pselect.S | 11 - .../sys_x86-64/___pselect_nocancel.S | 11 - .../libsyscall/sys_x86-64/___psynch_cvbroad.S | 11 - .../sys_x86-64/___psynch_cvclrprepost.S | 11 - .../sys_x86-64/___psynch_cvsignal.S | 11 - .../libsyscall/sys_x86-64/___psynch_cvwait.S | 11 - .../sys_x86-64/___psynch_mutexdrop.S | 11 - .../sys_x86-64/___psynch_mutexwait.S | 11 - .../sys_x86-64/___psynch_rw_downgrade.S | 11 - .../sys_x86-64/___psynch_rw_longrdlock.S | 11 - .../sys_x86-64/___psynch_rw_rdlock.S | 11 - .../sys_x86-64/___psynch_rw_unlock.S | 11 - .../sys_x86-64/___psynch_rw_unlock2.S | 11 - .../sys_x86-64/___psynch_rw_upgrade.S | 11 - .../sys_x86-64/___psynch_rw_wrlock.S | 11 - .../sys_x86-64/___psynch_rw_yieldwrlock.S | 11 - .../sys_x86-64/___pthread_canceled.S | 11 - .../libsyscall/sys_x86-64/___pthread_chdir.S | 11 - .../libsyscall/sys_x86-64/___pthread_fchdir.S | 11 - .../libsyscall/sys_x86-64/___pthread_kill.S | 11 - .../sys_x86-64/___pthread_markcancel.S | 11 - .../sys_x86-64/___pthread_sigmask.S | 11 - src/kernel/libsyscall/sys_x86-64/___ptrace.S | 61 - .../sys_x86-64/___pwrite_nocancel.S | 16 - .../libsyscall/sys_x86-64/___read_nocancel.S | 16 - .../libsyscall/sys_x86-64/___readv_nocancel.S | 16 - .../libsyscall/sys_x86-64/___recvfrom.S | 16 - .../sys_x86-64/___recvfrom_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/___recvmsg.S | 16 - .../sys_x86-64/___recvmsg_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/___rename.S | 11 - .../libsyscall/sys_x86-64/___renameat.S | 11 - src/kernel/libsyscall/sys_x86-64/___rmdir.S | 11 - src/kernel/libsyscall/sys_x86-64/___select.S | 16 - .../sys_x86-64/___select_nocancel.S | 16 - .../libsyscall/sys_x86-64/___sem_open.S | 16 - .../sys_x86-64/___sem_wait_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/___semctl.S | 16 - src/kernel/libsyscall/sys_x86-64/___semsys.S | 16 - .../libsyscall/sys_x86-64/___semwait_signal.S | 11 - .../sys_x86-64/___semwait_signal_nocancel.S | 11 - src/kernel/libsyscall/sys_x86-64/___sendmsg.S | 16 - .../sys_x86-64/___sendmsg_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/___sendto.S | 16 - .../sys_x86-64/___sendto_nocancel.S | 16 - .../libsyscall/sys_x86-64/___setattrlist.S | 16 - .../libsyscall/sys_x86-64/___setlogin.S | 11 - .../libsyscall/sys_x86-64/___setpriority.S | 11 - .../libsyscall/sys_x86-64/___setregid.S | 16 - .../libsyscall/sys_x86-64/___setreuid.S | 16 - .../libsyscall/sys_x86-64/___setrlimit.S | 11 - .../libsyscall/sys_x86-64/___setsgroups.S | 16 - src/kernel/libsyscall/sys_x86-64/___settid.S | 16 - .../sys_x86-64/___settid_with_pid.S | 11 - .../libsyscall/sys_x86-64/___settimeofday.S | 11 - .../libsyscall/sys_x86-64/___setwgroups.S | 16 - src/kernel/libsyscall/sys_x86-64/___sfi_ctl.S | 11 - .../libsyscall/sys_x86-64/___sfi_pidctl.S | 11 - .../sys_x86-64/___shared_region_check_np.S | 11 - .../___shared_region_map_and_slide_np.S | 11 - .../libsyscall/sys_x86-64/___shm_open.S | 16 - src/kernel/libsyscall/sys_x86-64/___shmctl.S | 16 - src/kernel/libsyscall/sys_x86-64/___shmsys.S | 16 - .../libsyscall/sys_x86-64/___sigaction.S | 11 - .../libsyscall/sys_x86-64/___sigaltstack.S | 42 - .../libsyscall/sys_x86-64/___sigsuspend.S | 11 - .../sys_x86-64/___sigsuspend_nocancel.S | 11 - src/kernel/libsyscall/sys_x86-64/___sigwait.S | 11 - .../libsyscall/sys_x86-64/___socketpair.S | 16 - .../___stack_snapshot_with_config.S | 11 - .../sys_x86-64/___stat64_extended.S | 11 - .../libsyscall/sys_x86-64/___stat_extended.S | 11 - src/kernel/libsyscall/sys_x86-64/___syscall.S | 61 - src/kernel/libsyscall/sys_x86-64/___sysctl.S | 11 - .../libsyscall/sys_x86-64/___sysctlbyname.S | 11 - .../libsyscall/sys_x86-64/___telemetry.S | 11 - .../libsyscall/sys_x86-64/___umask_extended.S | 11 - src/kernel/libsyscall/sys_x86-64/___unlink.S | 11 - .../libsyscall/sys_x86-64/___unlinkat.S | 11 - src/kernel/libsyscall/sys_x86-64/___vfork.S | 152 - src/kernel/libsyscall/sys_x86-64/___wait4.S | 11 - .../libsyscall/sys_x86-64/___wait4_nocancel.S | 16 - .../sys_x86-64/___waitid_nocancel.S | 16 - .../sys_x86-64/___work_interval_ctl.S | 11 - .../sys_x86-64/___workq_kernreturn.S | 11 - .../libsyscall/sys_x86-64/___workq_open.S | 11 - .../libsyscall/sys_x86-64/___write_nocancel.S | 16 - .../sys_x86-64/___writev_nocancel.S | 16 - src/kernel/libsyscall/sys_x86-64/_access.S | 11 - src/kernel/libsyscall/sys_x86-64/_acct.S | 11 - src/kernel/libsyscall/sys_x86-64/_adjtime.S | 11 - .../libsyscall/sys_x86-64/_aio_cancel.S | 11 - src/kernel/libsyscall/sys_x86-64/_aio_error.S | 11 - src/kernel/libsyscall/sys_x86-64/_aio_fsync.S | 11 - src/kernel/libsyscall/sys_x86-64/_aio_read.S | 11 - .../libsyscall/sys_x86-64/_aio_return.S | 11 - .../libsyscall/sys_x86-64/_aio_suspend.S | 11 - src/kernel/libsyscall/sys_x86-64/_aio_write.S | 11 - src/kernel/libsyscall/sys_x86-64/_audit.S | 11 - .../sys_x86-64/_audit_session_join.S | 11 - .../sys_x86-64/_audit_session_port.S | 11 - .../sys_x86-64/_audit_session_self.S | 11 - src/kernel/libsyscall/sys_x86-64/_auditctl.S | 11 - src/kernel/libsyscall/sys_x86-64/_auditon.S | 11 - .../sys_x86-64/_change_fdguard_np.S | 11 - src/kernel/libsyscall/sys_x86-64/_chdir.S | 11 - src/kernel/libsyscall/sys_x86-64/_chflags.S | 11 - src/kernel/libsyscall/sys_x86-64/_chown.S | 11 - src/kernel/libsyscall/sys_x86-64/_chroot.S | 11 - src/kernel/libsyscall/sys_x86-64/_close.S | 11 - src/kernel/libsyscall/sys_x86-64/_connectx.S | 11 - src/kernel/libsyscall/sys_x86-64/_csops.S | 11 - .../libsyscall/sys_x86-64/_csops_audittoken.S | 11 - .../libsyscall/sys_x86-64/_disconnectx.S | 11 - src/kernel/libsyscall/sys_x86-64/_dup.S | 11 - src/kernel/libsyscall/sys_x86-64/_dup2.S | 11 - .../libsyscall/sys_x86-64/_exchangedata.S | 11 - src/kernel/libsyscall/sys_x86-64/_execve.S | 11 - src/kernel/libsyscall/sys_x86-64/_faccessat.S | 11 - src/kernel/libsyscall/sys_x86-64/_fchdir.S | 11 - src/kernel/libsyscall/sys_x86-64/_fchflags.S | 11 - src/kernel/libsyscall/sys_x86-64/_fchmodat.S | 11 - src/kernel/libsyscall/sys_x86-64/_fchown.S | 11 - src/kernel/libsyscall/sys_x86-64/_fchownat.S | 11 - src/kernel/libsyscall/sys_x86-64/_fdatasync.S | 11 - src/kernel/libsyscall/sys_x86-64/_ffsctl.S | 11 - .../libsyscall/sys_x86-64/_fgetattrlist.S | 11 - src/kernel/libsyscall/sys_x86-64/_fgetxattr.S | 11 - src/kernel/libsyscall/sys_x86-64/_fhopen.S | 11 - .../libsyscall/sys_x86-64/_fileport_makefd.S | 11 - .../sys_x86-64/_fileport_makeport.S | 11 - .../libsyscall/sys_x86-64/_flistxattr.S | 11 - src/kernel/libsyscall/sys_x86-64/_flock.S | 11 - src/kernel/libsyscall/sys_x86-64/_fpathconf.S | 11 - .../libsyscall/sys_x86-64/_fremovexattr.S | 11 - src/kernel/libsyscall/sys_x86-64/_fsctl.S | 11 - .../libsyscall/sys_x86-64/_fsetattrlist.S | 11 - src/kernel/libsyscall/sys_x86-64/_fsetxattr.S | 11 - src/kernel/libsyscall/sys_x86-64/_fstat.S | 11 - src/kernel/libsyscall/sys_x86-64/_fstat64.S | 16 - src/kernel/libsyscall/sys_x86-64/_fstatat.S | 11 - src/kernel/libsyscall/sys_x86-64/_fstatat64.S | 16 - src/kernel/libsyscall/sys_x86-64/_fstatfs.S | 11 - src/kernel/libsyscall/sys_x86-64/_fstatfs64.S | 16 - src/kernel/libsyscall/sys_x86-64/_fsync.S | 11 - src/kernel/libsyscall/sys_x86-64/_ftruncate.S | 11 - src/kernel/libsyscall/sys_x86-64/_futimes.S | 11 - .../libsyscall/sys_x86-64/_getattrlistat.S | 11 - .../libsyscall/sys_x86-64/_getattrlistbulk.S | 11 - .../libsyscall/sys_x86-64/_getaudit_addr.S | 11 - src/kernel/libsyscall/sys_x86-64/_getauid.S | 11 - .../libsyscall/sys_x86-64/_getdirentries.S | 11 - .../sys_x86-64/_getdirentriesattr.S | 11 - .../libsyscall/sys_x86-64/_getdtablesize.S | 11 - src/kernel/libsyscall/sys_x86-64/_getegid.S | 11 - src/kernel/libsyscall/sys_x86-64/_geteuid.S | 11 - src/kernel/libsyscall/sys_x86-64/_getfh.S | 11 - src/kernel/libsyscall/sys_x86-64/_getfsstat.S | 11 - .../libsyscall/sys_x86-64/_getfsstat64.S | 16 - src/kernel/libsyscall/sys_x86-64/_getgid.S | 11 - src/kernel/libsyscall/sys_x86-64/_getgroups.S | 11 - src/kernel/libsyscall/sys_x86-64/_getitimer.S | 11 - src/kernel/libsyscall/sys_x86-64/_getpgid.S | 11 - src/kernel/libsyscall/sys_x86-64/_getpgrp.S | 11 - src/kernel/libsyscall/sys_x86-64/_getppid.S | 11 - .../libsyscall/sys_x86-64/_getpriority.S | 11 - src/kernel/libsyscall/sys_x86-64/_getrusage.S | 11 - src/kernel/libsyscall/sys_x86-64/_getsid.S | 11 - .../libsyscall/sys_x86-64/_getsockopt.S | 11 - src/kernel/libsyscall/sys_x86-64/_getuid.S | 11 - src/kernel/libsyscall/sys_x86-64/_getxattr.S | 11 - .../libsyscall/sys_x86-64/_grab_pgo_data.S | 11 - .../libsyscall/sys_x86-64/_guarded_close_np.S | 11 - .../sys_x86-64/_guarded_kqueue_np.S | 11 - .../sys_x86-64/_guarded_pwrite_np.S | 11 - .../libsyscall/sys_x86-64/_guarded_write_np.S | 11 - .../sys_x86-64/_guarded_writev_np.S | 11 - src/kernel/libsyscall/sys_x86-64/_issetugid.S | 11 - src/kernel/libsyscall/sys_x86-64/_kas_info.S | 11 - src/kernel/libsyscall/sys_x86-64/_kevent.S | 11 - src/kernel/libsyscall/sys_x86-64/_kevent64.S | 11 - .../libsyscall/sys_x86-64/_kevent_qos.S | 11 - src/kernel/libsyscall/sys_x86-64/_kqueue.S | 11 - src/kernel/libsyscall/sys_x86-64/_ledger.S | 11 - src/kernel/libsyscall/sys_x86-64/_link.S | 11 - src/kernel/libsyscall/sys_x86-64/_linkat.S | 11 - .../libsyscall/sys_x86-64/_lio_listio.S | 11 - src/kernel/libsyscall/sys_x86-64/_listxattr.S | 11 - src/kernel/libsyscall/sys_x86-64/_lstat.S | 11 - src/kernel/libsyscall/sys_x86-64/_lstat64.S | 16 - src/kernel/libsyscall/sys_x86-64/_madvise.S | 16 - .../sys_x86-64/_memorystatus_control.S | 11 - .../sys_x86-64/_memorystatus_get_level.S | 11 - src/kernel/libsyscall/sys_x86-64/_mincore.S | 11 - src/kernel/libsyscall/sys_x86-64/_minherit.S | 11 - src/kernel/libsyscall/sys_x86-64/_mkdir.S | 11 - src/kernel/libsyscall/sys_x86-64/_mkdirat.S | 11 - src/kernel/libsyscall/sys_x86-64/_mkfifo.S | 11 - src/kernel/libsyscall/sys_x86-64/_mknod.S | 11 - src/kernel/libsyscall/sys_x86-64/_mlock.S | 11 - src/kernel/libsyscall/sys_x86-64/_mlockall.S | 11 - src/kernel/libsyscall/sys_x86-64/_modwatch.S | 11 - src/kernel/libsyscall/sys_x86-64/_mount.S | 11 - .../libsyscall/sys_x86-64/_mremap_encrypted.S | 11 - src/kernel/libsyscall/sys_x86-64/_msgget.S | 11 - src/kernel/libsyscall/sys_x86-64/_msgrcv.S | 11 - src/kernel/libsyscall/sys_x86-64/_msgsnd.S | 11 - src/kernel/libsyscall/sys_x86-64/_munlock.S | 11 - .../libsyscall/sys_x86-64/_munlockall.S | 11 - .../sys_x86-64/_necp_match_policy.S | 11 - .../libsyscall/sys_x86-64/_netagent_trigger.S | 11 - src/kernel/libsyscall/sys_x86-64/_nfsclnt.S | 11 - src/kernel/libsyscall/sys_x86-64/_nfssvc.S | 11 - .../libsyscall/sys_x86-64/_openbyid_np.S | 11 - src/kernel/libsyscall/sys_x86-64/_pathconf.S | 11 - src/kernel/libsyscall/sys_x86-64/_peeloff.S | 11 - .../libsyscall/sys_x86-64/_pid_resume.S | 11 - .../libsyscall/sys_x86-64/_pid_suspend.S | 11 - src/kernel/libsyscall/sys_x86-64/_poll.S | 11 - src/kernel/libsyscall/sys_x86-64/_pread.S | 11 - .../sys_x86-64/_proc_rlimit_control.S | 11 - .../libsyscall/sys_x86-64/_proc_trace_log.S | 11 - .../libsyscall/sys_x86-64/_proc_uuid_policy.S | 11 - src/kernel/libsyscall/sys_x86-64/_pwrite.S | 11 - src/kernel/libsyscall/sys_x86-64/_quotactl.S | 11 - src/kernel/libsyscall/sys_x86-64/_read.S | 11 - src/kernel/libsyscall/sys_x86-64/_readlink.S | 11 - .../libsyscall/sys_x86-64/_readlinkat.S | 11 - src/kernel/libsyscall/sys_x86-64/_readv.S | 11 - src/kernel/libsyscall/sys_x86-64/_reboot.S | 11 - src/kernel/libsyscall/sys_x86-64/_recvmsg_x.S | 11 - .../libsyscall/sys_x86-64/_removexattr.S | 11 - src/kernel/libsyscall/sys_x86-64/_revoke.S | 11 - src/kernel/libsyscall/sys_x86-64/_searchfs.S | 11 - src/kernel/libsyscall/sys_x86-64/_sem_close.S | 11 - src/kernel/libsyscall/sys_x86-64/_sem_post.S | 11 - .../libsyscall/sys_x86-64/_sem_trywait.S | 11 - .../libsyscall/sys_x86-64/_sem_unlink.S | 11 - src/kernel/libsyscall/sys_x86-64/_sem_wait.S | 11 - src/kernel/libsyscall/sys_x86-64/_semget.S | 11 - src/kernel/libsyscall/sys_x86-64/_semop.S | 11 - src/kernel/libsyscall/sys_x86-64/_sendfile.S | 11 - src/kernel/libsyscall/sys_x86-64/_sendmsg_x.S | 11 - .../libsyscall/sys_x86-64/_setaudit_addr.S | 11 - src/kernel/libsyscall/sys_x86-64/_setauid.S | 11 - src/kernel/libsyscall/sys_x86-64/_setegid.S | 11 - src/kernel/libsyscall/sys_x86-64/_seteuid.S | 11 - src/kernel/libsyscall/sys_x86-64/_setgid.S | 11 - src/kernel/libsyscall/sys_x86-64/_setgroups.S | 11 - src/kernel/libsyscall/sys_x86-64/_setitimer.S | 11 - src/kernel/libsyscall/sys_x86-64/_setpgid.S | 11 - .../libsyscall/sys_x86-64/_setprivexec.S | 11 - src/kernel/libsyscall/sys_x86-64/_setsid.S | 11 - .../libsyscall/sys_x86-64/_setsockopt.S | 11 - src/kernel/libsyscall/sys_x86-64/_setuid.S | 11 - src/kernel/libsyscall/sys_x86-64/_setxattr.S | 11 - .../libsyscall/sys_x86-64/_shm_unlink.S | 11 - src/kernel/libsyscall/sys_x86-64/_shmat.S | 11 - src/kernel/libsyscall/sys_x86-64/_shmdt.S | 11 - src/kernel/libsyscall/sys_x86-64/_shmget.S | 11 - src/kernel/libsyscall/sys_x86-64/_shutdown.S | 11 - .../libsyscall/sys_x86-64/_sigpending.S | 11 - .../libsyscall/sys_x86-64/_sigprocmask.S | 11 - src/kernel/libsyscall/sys_x86-64/_socket.S | 11 - .../libsyscall/sys_x86-64/_socket_delegate.S | 11 - src/kernel/libsyscall/sys_x86-64/_stat.S | 11 - src/kernel/libsyscall/sys_x86-64/_stat64.S | 16 - src/kernel/libsyscall/sys_x86-64/_statfs.S | 11 - src/kernel/libsyscall/sys_x86-64/_statfs64.S | 16 - src/kernel/libsyscall/sys_x86-64/_swapon.S | 11 - src/kernel/libsyscall/sys_x86-64/_symlink.S | 11 - src/kernel/libsyscall/sys_x86-64/_symlinkat.S | 11 - src/kernel/libsyscall/sys_x86-64/_sync.S | 11 - .../libsyscall/sys_x86-64/_system_override.S | 11 - src/kernel/libsyscall/sys_x86-64/_truncate.S | 11 - src/kernel/libsyscall/sys_x86-64/_umask.S | 11 - src/kernel/libsyscall/sys_x86-64/_undelete.S | 11 - src/kernel/libsyscall/sys_x86-64/_unmount.S | 11 - src/kernel/libsyscall/sys_x86-64/_usrctl.S | 11 - src/kernel/libsyscall/sys_x86-64/_utimes.S | 11 - src/kernel/libsyscall/sys_x86-64/_vfs_purge.S | 11 - .../sys_x86-64/_vm_pressure_monitor.S | 11 - src/kernel/libsyscall/sys_x86-64/_waitevent.S | 11 - src/kernel/libsyscall/sys_x86-64/_waitid.S | 11 - .../libsyscall/sys_x86-64/_watchevent.S | 11 - src/kernel/libsyscall/sys_x86-64/_write.S | 11 - src/kernel/libsyscall/sys_x86-64/_writev.S | 11 - src/kernel/libsyscall/sys_x86-64/custom.S | 108 - src/kernel/libsyscall/sys_x86-64/stubs.list | 395 - .../wrappers/__commpage_gettimeofday.c | 56 + .../libsyscall/wrappers/_libc_funcptr.c | 8 +- .../libsyscall/wrappers/_libkernel_init.c | 17 +- .../wrappers/cancelable/fcntl-base.c | 11 +- .../cancelable/pselect-darwinext-cancel.c | 27 + .../wrappers/cancelable/pselect-darwinext.c | 28 + src/kernel/libsyscall/wrappers/clonefile.c | 31 + src/kernel/libsyscall/wrappers/csr.c | 9 +- src/kernel/libsyscall/wrappers/fs_snapshot.c | 121 + src/kernel/libsyscall/wrappers/ioctl.c | 15 +- src/kernel/libsyscall/wrappers/kdebug_trace.c | 179 + .../libsyscall/wrappers/libproc/libproc.c | 115 + .../libsyscall/wrappers/libproc/libproc.h | 14 + .../wrappers/libproc/libproc_internal.h | 15 +- .../libsyscall/wrappers/mach_boottime.c | 29 + .../wrappers/mach_continuous_time.c | 92 + .../libsyscall/wrappers/mach_get_times.c | 80 + .../libsyscall/wrappers/mach_timebase_info.c | 45 + src/kernel/libsyscall/wrappers/persona.c | 91 + .../libsyscall/wrappers/quota_obsolete.c | 44 + src/kernel/libsyscall/wrappers/rename_ext.c | 45 - src/kernel/libsyscall/wrappers/renamex.c | 48 + src/kernel/libsyscall/wrappers/select-base.c | 124 +- .../libsyscall/wrappers/spawn/posix_spawn.c | 286 +- src/kernel/libsyscall/wrappers/spawn/spawn.h | 49 +- .../libsyscall/wrappers/spawn/spawn_private.h | 14 +- src/kernel/libsyscall/wrappers/stackshot.c | 296 + .../libsyscall/wrappers/string/memset.c | 2 + .../wrappers/terminate_with_reason.c | 102 + .../wrappers/thread_register_state.c | 108 + .../libsyscall/wrappers/work_interval.c | 113 + .../libsyscall/xcodescripts/syscalls.master | 70 +- src/kernel/mach_server/client/CMakeLists.txt | 9 +- src/kernel/mach_server/client/mach_time.c | 2 +- src/launchd/liblaunch/CMakeLists.txt | 12 +- src/libc/.gitignore | 11 + src/libc/.upstream_base_commits | 47 + src/libc/CMakeLists.txt | 137 +- src/libc/Libc.xcodeproj/project.pbxproj | 6290 ++++++------ .../contents.xcworkspacedata | 7 - src/libc/Platforms/appletvos/Makefile.inc | 56 + src/libc/Platforms/bridgeos/Makefile.inc | 51 + src/libc/Platforms/iphoneos/Makefile.inc | 18 +- src/libc/Platforms/macosx/Makefile.inc | 17 +- src/libc/Platforms/watchos/Makefile.inc | 56 + src/libc/arm/gen/cpu_number.s | 39 - src/libc/arm/pthreads/init_cpu_capabilities.c | 38 - src/libc/arm/pthreads/pthread_getspecific.s | 42 - src/libc/arm/pthreads/pthread_self.s | 40 - src/libc/arm/pthreads/pthread_set_self.s | 38 - src/libc/arm/pthreads/start_wqthread.s | 45 - src/libc/arm/pthreads/thread_start.s | 45 - src/libc/arm/string/bcopy_CortexA8.s | 863 -- src/libc/arm/string/bcopy_CortexA9.s | 444 - src/libc/arm/string/bcopy_Generic.s | 407 - src/libc/arm/string/bcopy_Swift.s | 318 - src/libc/arm/string/bzero_CortexA8.s | 177 - src/libc/arm/string/bzero_CortexA9.s | 145 - src/libc/arm/string/bzero_Generic.s | 167 - src/libc/arm/string/bzero_Swift.s | 117 - src/libc/arm/string/dyld_resolvers.c | 98 - src/libc/arm/string/ffs.s | 50 - src/libc/arm/string/memcmp.s | 117 - src/libc/arm/string/memset_pattern.s | 336 - src/libc/arm/string/memset_pattern_Swift.s | 275 - src/libc/arm/string/strchr.s | 61 - src/libc/arm/string/strcmp.s | 135 - src/libc/arm/string/strlen.s | 115 - src/libc/arm/string/strncmp.s | 154 - src/libc/arm/string/strnlen.s | 149 - src/libc/arm/string/strstr.s | 149 - src/libc/arm/sys/OSAtomic-v4.c | 315 - src/libc/arm/sys/OSAtomic.c | 25 - src/libc/arm/sys/OSAtomic.h | 180 - src/libc/arm/sys/OSAtomicUP.c | 25 - src/libc/arm/sys/OSAtomic_resolvers.c | 100 - src/libc/arm/sys/OSAtomic_resolvers.h | 59 - src/libc/arm/sys/Spinlocks.c | 25 - src/libc/arm/sys/SpinlocksUP.c | 32 - src/libc/arm/sys/SpinlocksWFE.c | 31 - src/libc/arm/sys/arm_commpage_gettimeofday.c | 92 - src/libc/arm/sys/gcc_atomic.c | 120 - src/libc/arm/sys/longjmp.s | 57 - src/libc/arm/sys/mach_absolute_time.s | 34 - src/libc/arm/sys/setjmp.s | 61 - src/libc/compat-43/CMakeLists.txt | 8 +- src/libc/compat-43/sigcompat.c | 46 +- src/libc/darwin/CMakeLists.txt | 10 +- src/libc/darwin/OSAtomicLoadStoreEx.c | 318 - src/libc/darwin/SpinlocksLoadStoreEx.c | 124 - src/libc/darwin/_dirhelper.c | 373 - src/libc/darwin/atexit_receipt.c | 23 + src/libc/darwin/compatibility_hacks.c | 52 + src/libc/darwin/dirhelper.defs | 35 - src/libc/darwin/dirhelper_priv.h | 51 - src/libc/darwin/init_cpu_capabilities.c | 36 + src/libc/darwin/libc_private.h | 70 + src/libc/darwin/libproc.c | 532 - src/libc/darwin/libproc.h | 121 - src/libc/darwin/libproc_internal.h | 97 - src/libc/darwin/proc_listpidspath.c | 612 -- src/libc/db/btree/FreeBSD/bt_seq.c | 2 +- src/libc/db/hash/FreeBSD/ndbm.c | 5 +- src/libc/db/mpool/FreeBSD/mpool.c | 3 +- src/libc/derived/i386/libc-features.h | 29 + src/libc/derived/libc-features.h | 5 + src/libc/derived/x86_64/libc-features.h | 29 + src/libc/emulated/brk.c | 3 +- src/libc/emulated/lchmod.c | 9 +- src/libc/fbsdcompat/_fbsd_compat_.h | 13 +- src/libc/fbsdcompat/libc_private.h | 135 - src/libc/fbsdcompat/sys/cdefs.h | 2 - src/libc/gdtoa/CMakeLists.txt | 3 +- src/libc/gdtoa/FreeBSD/gdtoa-gethex.c | 4 +- src/libc/gdtoa/FreeBSD/gdtoa-hd_init.c | 23 +- src/libc/gdtoa/FreeBSD/gdtoa-hexnan.c | 4 +- src/libc/gdtoa/FreeBSD/gdtoa-strtod.c | 4 +- src/libc/gdtoa/FreeBSD/gdtoa-strtodg.c | 10 +- src/libc/gdtoa/FreeBSD/gdtoa-strtof.c | 2 +- src/libc/gdtoa/FreeBSD/gdtoa-strtopdd.c | 4 +- src/libc/gdtoa/FreeBSD/gdtoa.h | 2 +- src/libc/gdtoa/FreeBSD/gdtoa_fltrnds.h | 3 +- src/libc/gdtoa/FreeBSD/gdtoaimp.h | 6 +- src/libc/gdtoa/FreeBSD/glue.c | 6 - src/libc/gen/CMakeLists.txt | 133 +- src/libc/gen/FreeBSD/arc4random.3 | 115 +- src/libc/gen/FreeBSD/arc4random.c.orig | 477 + src/libc/gen/FreeBSD/assert.c | 2 +- src/libc/gen/FreeBSD/basename.3 | 108 +- src/libc/gen/FreeBSD/basename.c | 55 +- src/libc/gen/FreeBSD/clock.3 | 5 +- src/libc/gen/FreeBSD/ctermid.3 | 40 +- src/libc/gen/FreeBSD/daemon.3 | 20 + src/libc/gen/FreeBSD/dirname.3 | 13 + src/libc/gen/FreeBSD/dirname.c | 32 +- src/libc/gen/FreeBSD/err.c | 30 +- src/libc/gen/FreeBSD/fmtmsg.c | 2 +- src/libc/gen/FreeBSD/fnmatch.c | 9 +- src/libc/gen/FreeBSD/getbsize.3 | 40 +- src/libc/gen/FreeBSD/getbsize.c | 6 +- src/libc/gen/FreeBSD/getcwd.c | 2 +- src/libc/gen/FreeBSD/getlogin.c | 41 +- src/libc/gen/FreeBSD/pause.c | 10 +- src/libc/gen/FreeBSD/pselect.3 | 127 - src/libc/gen/FreeBSD/pselect.c | 88 - src/libc/gen/FreeBSD/raise.3 | 13 +- src/libc/gen/FreeBSD/raise.c | 47 - src/libc/gen/FreeBSD/readpassphrase.3 | 116 +- src/libc/gen/FreeBSD/readpassphrase.c | 176 +- src/libc/gen/FreeBSD/scandir.3 | 3 +- src/libc/gen/FreeBSD/sleep.c | 7 +- src/libc/gen/FreeBSD/sysconf.c | 88 +- src/libc/gen/FreeBSD/sysctl.3 | 645 +- src/libc/gen/FreeBSD/sysctl.c | 7 +- src/libc/gen/FreeBSD/sysctlbyname.c | 19 +- src/libc/gen/FreeBSD/sysctlnametomib.c | 5 +- src/libc/gen/FreeBSD/termios.c | 7 +- src/libc/gen/FreeBSD/times.3 | 17 +- src/libc/gen/FreeBSD/unvis.3 | 173 +- src/libc/gen/FreeBSD/unvis.c | 507 +- src/libc/gen/FreeBSD/usleep.3 | 38 +- src/libc/gen/FreeBSD/usleep.c | 7 +- src/libc/gen/FreeBSD/vis.3 | 356 +- src/libc/gen/FreeBSD/vis.c | 740 +- src/libc/gen/FreeBSD/wordexp.3 | 206 + src/libc/gen/FreeBSD/wordexp.c | 600 ++ src/libc/gen/NetBSD/rb.c | 1440 +++ src/libc/gen/NetBSD/rbtree.3 | 261 + src/libc/gen/NetBSD/utmpx.c | 53 +- src/libc/gen/_simple.c | 722 -- src/libc/gen/asl.3 | 1111 -- src/libc/gen/asl.c | 2187 ---- src/libc/gen/asl_core.c | 894 -- src/libc/gen/asl_core.h | 117 - src/libc/gen/asl_fd.c | 289 - src/libc/gen/asl_file.c | 2136 ---- src/libc/gen/asl_file.h | 150 - src/libc/gen/asl_ipc.defs | 99 - src/libc/gen/asl_legacy1.c | 836 -- src/libc/gen/asl_legacy1.h | 85 - src/libc/gen/asl_msg.c | 2613 ----- src/libc/gen/asl_msg.h | 127 - src/libc/gen/asl_private.h | 100 - src/libc/gen/asl_store.c | 935 -- src/libc/gen/asl_store.h | 84 - src/libc/gen/asl_util.c | 259 - src/libc/gen/assumes.c | 305 - src/libc/gen/assumes.h | 227 - src/libc/gen/backtrace.c | 8 +- src/libc/gen/clock_gettime.3 | 186 + src/libc/gen/clock_gettime.c | 225 + src/libc/gen/compat.5 | 1 - src/libc/gen/confstr.3 | 32 + src/libc/gen/confstr.c | 48 +- src/libc/gen/crypt.c | 41 +- src/libc/gen/directory.3 | 153 +- src/libc/gen/disklabel.c | 17 +- src/libc/gen/fts.3 | 40 +- src/libc/gen/fts.c | 904 +- src/libc/gen/get_compat.c | 6 +- src/libc/gen/getttyent.3 | 10 +- src/libc/gen/getttyent.c | 12 +- src/libc/gen/getusershell.c | 20 +- src/libc/gen/isinf.c | 32 - src/libc/gen/isnan.c | 32 - src/libc/gen/magazine_malloc.c | 8199 --------------- src/libc/gen/magmallocProvider.d | 17 - src/libc/gen/malloc.3 | 283 - src/libc/gen/malloc.c | 1528 --- src/libc/gen/malloc_printf.h | 33 - src/libc/gen/malloc_size.3 | 55 - src/libc/gen/malloc_zone_malloc.3 | 163 - src/libc/gen/nanosleep.c | 18 +- src/libc/gen/platfunc.c | 73 - src/libc/gen/platfunc.h | 131 - src/libc/gen/raise.c | 40 + src/libc/gen/scalable_malloc.c | 4222 -------- src/libc/gen/scalable_malloc.h | 60 - src/libc/gen/setlogin.c | 17 +- src/libc/gen/stack_logging.c | 335 - src/libc/gen/stack_logging.h | 123 - src/libc/gen/stack_logging_disk.c | 1729 ---- src/libc/gen/strtofflags.c | 4 + src/libc/gen/syslog.3 | 323 - src/libc/gen/syslog.c | 207 - src/libc/gen/tcsetattr.3 | 2 +- src/libc/gen/thread_stack_pcs.c | 1 + src/libc/gen/tzset.3 | 17 +- src/libc/gen/uname.c | 9 +- src/libc/gen/utmpx-darwin.c | 185 +- src/libc/gen/utmpx-darwin.h | 14 +- src/libc/gen/wordexp.3 | 183 - src/libc/gen/wordexp.c | 372 - src/libc/gmon/gmon.c | 22 - src/libc/i386/CMakeLists.txt | 51 +- src/libc/i386/gen/_ctx_start.S | 82 - src/libc/i386/gen/_setcontext.S | 54 - src/libc/i386/gen/cpu_number.S | 68 - src/libc/i386/gen/getcontext.S | 59 - src/libc/i386/gen/getmcontext.c | 82 - src/libc/i386/gen/icacheinval.S | 64 - src/libc/i386/gen/makecontext.c | 191 - src/libc/i386/gen/mcount.S | 5 - src/libc/i386/gen/setcontext.c | 42 - src/libc/i386/gen/setjmperr.c | 58 - src/libc/i386/gen/swapcontext.c | 81 - .../i386/pthreads/init_cpu_capabilities.c | 37 - src/libc/i386/pthreads/preempt.S | 83 - src/libc/i386/pthreads/pthread_getspecific.S | 37 - src/libc/i386/pthreads/pthread_mutex_lock.S | 68 - src/libc/i386/pthreads/pthread_self.S | 36 - src/libc/i386/pthreads/pthread_set_self.S | 42 - src/libc/i386/pthreads/start_wqthread.S | 48 - src/libc/i386/pthreads/thread_start.S | 49 - src/libc/i386/string/__bzero.S | 8 - src/libc/i386/string/bcopy.c | 48 - src/libc/i386/string/bcopy_scalar.S | 135 - src/libc/i386/string/bcopy_sse2.S | 472 - src/libc/i386/string/bcopy_sse3x.S | 811 -- src/libc/i386/string/bcopy_sse42.S | 310 - src/libc/i386/string/bzero.c | 46 - src/libc/i386/string/bzero_scalar.S | 115 - src/libc/i386/string/bzero_sse2.S | 162 - src/libc/i386/string/bzero_sse42.S | 151 - src/libc/i386/string/ffs.S | 56 - src/libc/i386/string/longcopy_sse3x.S | 230 - src/libc/i386/string/memcmp.S | 190 - src/libc/i386/string/memcpy.c | 48 - src/libc/i386/string/memmove.c | 48 - src/libc/i386/string/memset.S | 247 - src/libc/i386/string/memset_pattern_sse2.S | 193 - src/libc/i386/string/strcmp.S | 149 - src/libc/i386/string/strcpy.S | 10 +- src/libc/i386/string/strlcat.S | 6 +- src/libc/i386/string/strlcpy.S | 6 +- src/libc/i386/string/strlen.S | 7 +- src/libc/i386/string/strncmp.S | 196 - src/libc/i386/string/strncpy.S | 21 +- src/libc/i386/sys/OSAtomic.S | 460 - src/libc/i386/sys/_sigtramp.S | 256 - src/libc/i386/sys/atomic.c | 100 - src/libc/i386/sys/i386_gettimeofday_asm.S | 80 - src/libc/i386/sys/mach_absolute_time.c | 40 - src/libc/i386/sys/mach_absolute_time_asm.S | 148 - src/libc/i386/sys/setjmp.S | 147 - src/libc/i386/sys/spinlocks.c | 50 - src/libc/i386/sys/spinlocks_asm.S | 130 - src/libc/include/CrashReporterClient.h | 44 - src/libc/include/FreeBSD/nl_types.h | 5 +- src/libc/include/NSSystemDirectories.h | 110 - src/libc/include/NetBSD/utmpx.h | 15 +- src/libc/include/_locale.h | 4 +- src/libc/include/_structs.h | 25 - src/libc/include/_types/_intmax_t.h | 40 + src/libc/include/_types/_nl_item.h | 32 + src/libc/include/_types/_uint16_t.h | 32 + src/libc/include/_types/_uint32_t.h | 32 + src/libc/include/_types/_uint64_t.h | 32 + src/libc/include/_types/_uint8_t.h | 32 + src/libc/include/_types/_uintmax_t.h | 40 + src/libc/include/_types/_wctrans_t.h | 32 + src/libc/include/_types/_wctype_t.h | 32 + src/libc/include/_wctype.h | 46 +- src/libc/include/alloca.h | 6 +- src/libc/include/arpa/inet.h | 97 + src/libc/include/asl.h | 578 -- src/libc/include/assert.h | 13 +- src/libc/include/bitstring.h | 93 +- src/libc/include/ctype.h | 96 +- src/libc/include/err.h | 4 +- src/libc/include/fts.h | 28 +- src/libc/include/glob.h | 6 +- src/libc/include/i386/libc-features.h | 27 - src/libc/include/inttypes.h | 116 +- src/libc/include/langinfo.h | 6 +- src/libc/include/libc-features.h | 8 - src/libc/include/libgen.h | 11 + src/libc/include/libkern/OSAtomic.h | 748 -- .../include/libkern/OSMemoryNotification.h | 121 - .../include/libkern/OSThermalNotification.h | 39 +- src/libc/include/limits.h | 6 + src/libc/include/malloc/malloc.h | 268 - src/libc/include/monetary.h | 12 +- src/libc/include/monitor.h | 15 + src/libc/include/ndbm.h | 12 +- src/libc/include/paths.h | 1 - src/libc/include/printf.h | 284 + src/libc/include/protocols/timed.h | 4 +- src/libc/include/pthread_spinlock.h | 1 + src/libc/include/readpassphrase.h | 47 +- src/libc/include/regex.h | 13 +- src/libc/include/runetype.h | 31 +- src/libc/include/search.h | 6 +- src/libc/include/secure/_common.h | 2 +- src/libc/include/secure/_stdio.h | 31 +- src/libc/include/secure/_string.h | 178 +- src/libc/include/signal.h | 16 +- src/libc/include/spawn_private.h | 56 - src/libc/include/stddef.h | 76 +- src/libc/include/stdint.h | 92 +- src/libc/include/stdio.h | 111 +- src/libc/include/stdlib.h | 180 +- src/libc/include/string.h | 120 +- src/libc/include/strings.h | 8 +- src/libc/include/sys/acl.h | 2 + src/libc/include/sys/cdefs.h | 37 +- src/libc/include/sys/rbtree.h | 106 + src/libc/include/sys/statvfs.h | 11 +- src/libc/include/termios.h | 6 +- src/libc/include/time.h | 83 +- src/libc/include/unistd.h | 172 +- src/libc/include/utime.h | 6 +- src/libc/include/utmp.h | 6 +- src/libc/include/vis.h | 62 +- src/libc/include/wchar.h | 36 +- src/libc/include/wctype.h | 30 +- src/libc/include/wordexp.h | 15 +- src/libc/include/x86-64/libc-features.h | 28 - src/libc/include/xlocale/__wctype.h | 28 +- src/libc/include/xlocale/_ctype.h | 61 +- src/libc/include/xlocale/_stdio.h | 46 +- src/libc/include/xlocale/_wctype.h | 14 +- src/libc/locale/FreeBSD/ascii.c | 11 +- src/libc/locale/FreeBSD/big5.c | 2 +- src/libc/locale/FreeBSD/collate.c | 7 +- src/libc/locale/FreeBSD/euc.c | 2 +- src/libc/locale/FreeBSD/gb18030.c | 4 +- src/libc/locale/FreeBSD/gb2312.c | 4 +- src/libc/locale/FreeBSD/gbk.c | 2 +- src/libc/locale/FreeBSD/isspecial.3 | 5 +- src/libc/locale/FreeBSD/ldpart.c | 6 +- src/libc/locale/FreeBSD/localeconv.c | 2 - src/libc/locale/FreeBSD/mblocal.h | 30 +- src/libc/locale/FreeBSD/mbtowc.c | 2 +- src/libc/locale/FreeBSD/mskanji.c | 2 +- src/libc/locale/FreeBSD/none.c | 22 +- src/libc/locale/FreeBSD/setlocale.3 | 24 +- src/libc/locale/FreeBSD/setlocale.c | 45 +- src/libc/locale/FreeBSD/setlocale.h | 1 + src/libc/locale/FreeBSD/setrunelocale.c | 6 +- src/libc/locale/FreeBSD/table.c | 2 +- src/libc/locale/FreeBSD/utf2.c | 2 +- src/libc/locale/FreeBSD/utf8.c | 127 +- src/libc/locale/rune.3 | 3 + src/libc/locale/runedepreciated.c | 4 +- src/libc/locale/xlocale.c | 18 +- src/libc/locale/xlocale_private.h | 33 +- src/libc/man/FreeBSD/environ.7 | 291 + src/libc/man/environ.7 | 215 - src/libc/man/manpages.lst | 81 +- src/libc/net/FreeBSD/addr2ascii.c | 22 +- src/libc/net/FreeBSD/linkaddr.c | 26 +- src/libc/net/FreeBSD/sourcefilter.c | 3 +- src/libc/net/inet_ntop.c | 61 +- src/libc/net/rcmdsh.3 | 116 - src/libc/os/CMakeLists.txt | 2 +- src/libc/os/activity.h | 573 -- src/libc/os/alloc_once_impl.c | 42 - src/libc/os/alloc_once_impl.h | 10 - src/libc/os/alloc_once_private.h | 75 +- src/libc/os/assumes.c | 32 - src/libc/os/assumes.h | 11 +- src/libc/os/availability.h | 81 - src/libc/os/base_private.h | 4 - src/libc/os/debug_private.c | 6 +- src/libc/os/object.h | 109 +- src/libc/os/overflow.h | 152 + src/libc/platform/CMakeLists.txt | 9 - src/libc/platform/OSAtomic.c | 33 - src/libc/platform/TODO | 4 - src/libc/posix1e/acl_file.c | 3 + src/libc/posix1e/acl_perm.c | 3 + src/libc/posix1e/acl_translate.c | 6 +- src/libc/posix1e/aclvar.h | 3 +- src/libc/pthreads/CMakeLists.txt | 47 - src/libc/pthreads/mk_pthread_impl.c | 110 - src/libc/pthreads/plockstat.d | 24 - src/libc/pthreads/posix_sched.h | 69 - src/libc/pthreads/pthread.3 | 442 - src/libc/pthreads/pthread.c | 3634 ------- src/libc/pthreads/pthread.h | 532 - src/libc/pthreads/pthread_atfork.3 | 57 - src/libc/pthreads/pthread_attr.3 | 277 - src/libc/pthreads/pthread_attr_init_destroy.3 | 64 - .../pthread_attr_set_getdetachstate.3 | 86 - .../pthread_attr_set_getinheritsched.3 | 85 - .../pthreads/pthread_attr_set_getschedparam.3 | 81 - .../pthread_attr_set_getschedpolicy.3 | 73 - src/libc/pthreads/pthread_attr_set_getscope.3 | 75 - .../pthreads/pthread_attr_set_getstackaddr.3 | 74 - .../pthreads/pthread_attr_set_getstacksize.3 | 78 - src/libc/pthreads/pthread_cancel.3 | 77 - src/libc/pthreads/pthread_cancelable.c | 320 - src/libc/pthreads/pthread_cleanup_pop.3 | 66 - src/libc/pthreads/pthread_cleanup_push.3 | 71 - src/libc/pthreads/pthread_cond.c | 1103 -- src/libc/pthreads/pthread_cond_broadcast.3 | 69 - src/libc/pthreads/pthread_cond_destroy.3 | 73 - src/libc/pthreads/pthread_cond_init.3 | 81 - src/libc/pthreads/pthread_cond_signal.3 | 68 - src/libc/pthreads/pthread_cond_timedwait.3 | 109 - src/libc/pthreads/pthread_cond_wait.3 | 80 - src/libc/pthreads/pthread_condattr.3 | 87 - src/libc/pthreads/pthread_create.3 | 123 - src/libc/pthreads/pthread_detach.3 | 89 - src/libc/pthreads/pthread_equal.3 | 69 - src/libc/pthreads/pthread_exit.3 | 104 - src/libc/pthreads/pthread_getschedparam.3 | 96 - src/libc/pthreads/pthread_getspecific.3 | 83 - src/libc/pthreads/pthread_impl.h | 58 - src/libc/pthreads/pthread_internals.h | 707 -- src/libc/pthreads/pthread_join.3 | 103 - src/libc/pthreads/pthread_key_create.3 | 108 - src/libc/pthreads/pthread_key_delete.3 | 98 - src/libc/pthreads/pthread_machdep.h | 304 - src/libc/pthreads/pthread_mutex.c | 1353 --- src/libc/pthreads/pthread_mutex_destroy.3 | 72 - src/libc/pthreads/pthread_mutex_init.3 | 78 - src/libc/pthreads/pthread_mutex_lock.3 | 74 - src/libc/pthreads/pthread_mutex_trylock.3 | 75 - src/libc/pthreads/pthread_mutex_unlock.3 | 81 - src/libc/pthreads/pthread_mutexattr.3 | 302 - src/libc/pthreads/pthread_once.3 | 102 - src/libc/pthreads/pthread_rwlock.c | 1880 ---- src/libc/pthreads/pthread_rwlock_destroy.3 | 82 - src/libc/pthreads/pthread_rwlock_init.3 | 102 - src/libc/pthreads/pthread_rwlock_rdlock.3 | 126 - src/libc/pthreads/pthread_rwlock_unlock.3 | 81 - src/libc/pthreads/pthread_rwlock_wrlock.3 | 106 - .../pthreads/pthread_rwlockattr_destroy.3 | 70 - .../pthreads/pthread_rwlockattr_getpshared.3 | 83 - src/libc/pthreads/pthread_rwlockattr_init.3 | 69 - .../pthreads/pthread_rwlockattr_setpshared.3 | 91 - src/libc/pthreads/pthread_self.3 | 59 - src/libc/pthreads/pthread_setcancelstate.3 | 207 - src/libc/pthreads/pthread_setspecific.3 | 95 - src/libc/pthreads/pthread_spinlock.h | 103 - src/libc/pthreads/pthread_spis.h | 77 - src/libc/pthreads/pthread_tsd.c | 256 - src/libc/pthreads/pthread_workqueue.h | 90 - src/libc/pthreads/sched.h | 44 - src/libc/pthreads/stack.s | 125 - src/libc/pthreads/tests/Makefile | 26 - src/libc/pthreads/tests/pthread_atfork_test.c | 65 - src/libc/pthreads/thread_setup.c | 253 - src/libc/regex/TRE/lib/regexec.c | 31 +- src/libc/regex/TRE/lib/tre-compile.c | 44 +- src/libc/regex/TRE/lib/tre-internal.h | 2 + src/libc/regex/TRE/lib/tre-match-backtrack.c | 2 +- src/libc/regex/TRE/lib/tre-match-parallel.c | 139 +- src/libc/regex/TRE/lib/tre-match-utils.h | 67 +- src/libc/regex/TRE/lib/tre-mem.c | 4 +- src/libc/regex/TRE/lib/tre-parse.c | 6 +- src/libc/regex/TRE/tre-0.8.0.tar.bz2 | Bin 0 -> 380714 bytes src/libc/secure/CMakeLists.txt | 1 - src/libc/secure/chk_fail.c | 16 +- src/libc/secure/memcpy_chk.c | 13 +- src/libc/secure/memmove_chk.c | 7 +- src/libc/secure/memset_chk.c | 7 +- src/libc/secure/secure.c | 30 - src/libc/secure/secure.h | 2 +- src/libc/secure/snprintf_chk.c | 15 +- src/libc/secure/sprintf_chk.c | 19 +- src/libc/secure/stpcpy_chk.c | 17 +- src/libc/secure/stpncpy_chk.c | 24 +- src/libc/secure/strcat_chk.c | 31 +- src/libc/secure/strcpy_chk.c | 17 +- src/libc/secure/strlcat_chk.c | 9 +- src/libc/secure/strncat_chk.c | 40 +- src/libc/secure/strncpy_chk.c | 23 +- src/libc/secure/vsnprintf_chk.c | 15 +- src/libc/secure/vsprintf_chk.c | 19 +- src/libc/stdio/CMakeLists.txt | 5 + src/libc/stdio/FreeBSD/_flock_stub.c | 56 +- src/libc/stdio/FreeBSD/fclose.c | 5 +- src/libc/stdio/FreeBSD/fflush.c | 10 +- src/libc/stdio/FreeBSD/findfp.c | 84 +- src/libc/stdio/FreeBSD/fopen.3 | 12 +- src/libc/stdio/FreeBSD/fread.c | 59 +- src/libc/stdio/FreeBSD/freopen.c | 9 +- src/libc/stdio/FreeBSD/fseek.c | 6 +- src/libc/stdio/FreeBSD/fwrite.c | 35 +- src/libc/stdio/FreeBSD/getdelim.c | 10 +- src/libc/stdio/FreeBSD/getline.3 | 33 +- src/libc/stdio/FreeBSD/gets.c | 2 +- src/libc/stdio/FreeBSD/local.h | 22 +- src/libc/stdio/FreeBSD/makebuf.c | 7 +- src/libc/stdio/FreeBSD/mktemp.3 | 141 +- src/libc/stdio/FreeBSD/mktemp.c | 186 +- src/libc/stdio/FreeBSD/printf.3 | 207 +- src/libc/stdio/FreeBSD/printfcommon.h | 6 +- src/libc/stdio/FreeBSD/printflocal.h | 15 +- src/libc/stdio/FreeBSD/refill.c | 3 +- src/libc/stdio/FreeBSD/rewind.c | 3 +- src/libc/stdio/FreeBSD/tmpfile.c | 7 +- src/libc/stdio/FreeBSD/ungetc.c | 4 +- src/libc/stdio/FreeBSD/vasprintf.c | 24 +- src/libc/stdio/FreeBSD/vdprintf.c | 16 +- src/libc/stdio/FreeBSD/vfprintf.c | 40 +- src/libc/stdio/FreeBSD/vfscanf.c | 6 +- src/libc/stdio/FreeBSD/vfwprintf.c | 21 +- src/libc/stdio/FreeBSD/vfwscanf.c | 6 +- src/libc/stdio/FreeBSD/vsnprintf.c | 23 +- src/libc/stdio/FreeBSD/vsprintf.c | 3 +- src/libc/stdio/FreeBSD/wprintf.3 | 72 +- src/libc/stdio/FreeBSD/wsetup.c | 3 +- src/libc/stdio/FreeBSD/xprintf.c | 1199 +++ src/libc/stdio/FreeBSD/xprintf_errno.c | 66 + src/libc/stdio/FreeBSD/xprintf_float.c | 445 + src/libc/stdio/FreeBSD/xprintf_hexdump.c | 98 + src/libc/stdio/FreeBSD/xprintf_int.c | 498 + src/libc/stdio/FreeBSD/xprintf_private.h | 171 + src/libc/stdio/FreeBSD/xprintf_quote.c | 99 + src/libc/stdio/FreeBSD/xprintf_str.c | 201 + src/libc/stdio/FreeBSD/xprintf_time.c | 123 + src/libc/stdio/FreeBSD/xprintf_vis.c | 79 + src/libc/stdio/xprintf.3 | 64 + src/libc/stdio/xprintf.5 | 533 + src/libc/stdio/xprintf_all_in_one.c | 129 + src/libc/stdio/xprintf_comp.3 | 66 + src/libc/stdio/xprintf_comp.c | 86 + src/libc/stdio/xprintf_domain.3 | 219 + src/libc/stdio/xprintf_domain.c | 245 + src/libc/stdio/xprintf_domain.h | 63 + src/libc/stdio/xprintf_exec.3 | 57 + src/libc/stdio/xprintf_exec.c | 177 + src/libc/stdlib/CMakeLists.txt | 1 + src/libc/stdlib/FreeBSD/abort.c | 59 +- src/libc/stdlib/FreeBSD/atof.3 | 10 +- src/libc/stdlib/FreeBSD/atoi.3 | 10 +- src/libc/stdlib/FreeBSD/exit.c | 13 +- src/libc/stdlib/FreeBSD/getenv.3 | 107 +- src/libc/stdlib/FreeBSD/getenv.c | 48 +- src/libc/stdlib/FreeBSD/getopt_long.3 | 15 +- src/libc/stdlib/FreeBSD/psort.c | 26 +- src/libc/stdlib/FreeBSD/psort_b.c | 431 +- src/libc/stdlib/FreeBSD/psort_r.c | 431 +- src/libc/stdlib/FreeBSD/putenv.c | 43 +- src/libc/stdlib/FreeBSD/rand.3 | 3 +- src/libc/stdlib/FreeBSD/rand.c | 9 +- src/libc/stdlib/FreeBSD/random.c | 57 +- src/libc/stdlib/FreeBSD/reallocf.c | 11 +- src/libc/stdlib/FreeBSD/realpath.3 | 10 + src/libc/stdlib/FreeBSD/realpath.c | 8 +- src/libc/stdlib/FreeBSD/setenv.c | 95 +- src/libc/stdlib/FreeBSD/system.c | 16 +- src/libc/stdlib/NetBSD/strfmon.c | 4 +- src/libc/stdlib/grantpt.c | 9 +- src/libc/stdtime/FreeBSD/ctime.3 | 5 + src/libc/stdtime/FreeBSD/localtime.c | 159 +- src/libc/stdtime/FreeBSD/private.h | 2 +- src/libc/stdtime/FreeBSD/strftime.c | 2 +- src/libc/stdtime/FreeBSD/strptime.3 | 54 +- src/libc/stdtime/FreeBSD/strptime.c | 625 +- src/libc/stdtime/FreeBSD/tzfile.h | 4 + src/libc/stdtime/getdate.c | 15 +- src/libc/string/CMakeLists.txt | 48 +- src/libc/string/FreeBSD/bcmp.3 | 17 +- src/libc/string/FreeBSD/bcmp.c | 55 - src/libc/string/FreeBSD/bcopy.3 | 16 +- src/libc/string/FreeBSD/bcopy.c | 32 - src/libc/string/FreeBSD/bzero.3 | 6 + src/libc/string/FreeBSD/bzero.c | 0 src/libc/string/FreeBSD/memccpy.3 | 12 +- src/libc/string/FreeBSD/memccpy.c | 52 - src/libc/string/FreeBSD/memcmp.3 | 10 +- src/libc/string/FreeBSD/memcpy.3 | 18 +- src/libc/string/FreeBSD/memcpy.c | 5 - src/libc/string/FreeBSD/memmove.3 | 14 +- src/libc/string/FreeBSD/memmove.c | 5 - src/libc/string/FreeBSD/memset.3 | 7 +- src/libc/string/FreeBSD/memset.c | 128 - src/libc/string/FreeBSD/strchr.c | 5 - src/libc/string/FreeBSD/strcpy.3 | 83 +- src/libc/string/FreeBSD/strcspn.3 | 91 - src/libc/string/FreeBSD/strerror.c | 25 +- src/libc/string/FreeBSD/strpbrk.3 | 19 +- src/libc/string/FreeBSD/strspn.3 | 64 +- src/libc/string/FreeBSD/strstr.3 | 52 +- src/libc/string/FreeBSD/timingsafe_bcmp.3 | 65 + src/libc/string/FreeBSD/timingsafe_bcmp.c | 32 + src/libc/string/FreeBSD/wcscoll.c | 1 - src/libc/string/NetBSD/memset_s.3 | 147 + src/libc/string/NetBSD/memset_s.c | 71 + src/libc/string/bcopy.c | 28 + src/libc/string/memset_pattern.c | 71 - src/libc/string/strlcat.c | 4 +- src/libc/sys/CLIB-LIST | 679 -- src/libc/sys/CMakeLists.txt | 22 +- src/libc/sys/MISSING-MANPAGE | 9 - src/libc/sys/MISSING_SYSCALLS | 8 - src/libc/sys/OSMemoryNotification.c | 110 +- src/libc/sys/OSThermalNotification.c | 14 +- src/libc/sys/OpenBSD/stack_protector.c | 6 +- src/libc/sys/REQUIRED-MACROS | 3 - src/libc/sys/SYSCALL-LIST | 148 - src/libc/sys/__libc_init.c | 84 - src/libc/sys/_libc_fork_child.c | 13 +- src/libc/sys/_libc_init.c | 81 + src/libc/sys/atomic.3 | 246 - src/libc/sys/barrier.3 | 24 - src/libc/sys/context-stubs.c | 31 - src/libc/sys/crt_externs.c | 14 +- src/libc/sys/errno.c | 47 - src/libc/sys/fork.c | 15 +- src/libc/sys/getiopolicy_np.3 | 188 - src/libc/sys/getiopolicy_np.c | 67 - src/libc/sys/gettimeofday.c | 5 +- src/libc/sys/posix_spawn.c | 1382 +-- src/libc/sys/pthread_kill.2 | 81 - src/libc/sys/pthread_sigmask.2 | 104 - src/libc/sys/sigaction.c | 16 +- src/libc/sys/sigcatch.c | 37 - src/libc/sys/sigcatch.h | 45 - src/libc/sys/sigtramp.c | 259 - src/libc/sys/slot_name.c | 66 - src/libc/sys/spinlock.3 | 45 - src/libc/threads/CMakeLists.txt | 17 - src/libc/threads/cprocs.c | 163 - src/libc/threads/cthread_internals.h | 144 - src/libc/threads/cthreads.c | 205 - src/libc/threads/cthreads.h | 308 - src/libc/threads/mig_support.c | 96 - src/libc/util/logout.c | 14 +- src/libc/util/mkpath_np.c | 99 +- src/libc/uuid/uuidsrc/gen_uuid.c | 6 +- src/libc/x86_64/CMakeLists.txt | 104 +- src/libc/x86_64/gen/_ctx_start.S | 90 - src/libc/x86_64/gen/_setcontext.S | 71 - src/libc/x86_64/gen/cpu_number.S | 54 - src/libc/x86_64/gen/getcontext.S | 76 - src/libc/x86_64/gen/getmcontext.c | 82 - src/libc/x86_64/gen/icacheinval.S | 56 - src/libc/x86_64/gen/makecontext.c | 209 - src/libc/x86_64/gen/mcount.S | 4 +- src/libc/x86_64/gen/setcontext.c | 45 - src/libc/x86_64/gen/setjmperr.c | 58 - src/libc/x86_64/gen/swapcontext.c | 81 - src/libc/x86_64/pthreads/preempt.S | 65 - .../x86_64/pthreads/pthread_getspecific.S | 32 - src/libc/x86_64/pthreads/pthread_mutex_lock.S | 57 - src/libc/x86_64/pthreads/pthread_self.S | 32 - src/libc/x86_64/pthreads/pthread_set_self.S | 35 - src/libc/x86_64/pthreads/start_wqthread.S | 39 - src/libc/x86_64/pthreads/thread_start.S | 39 - src/libc/x86_64/string/__bzero.S | 3 - src/libc/x86_64/string/bcopy.c | 40 - src/libc/x86_64/string/bcopy_sse3x.S | 806 -- src/libc/x86_64/string/bcopy_sse42.S | 300 - src/libc/x86_64/string/bzero.c | 40 - src/libc/x86_64/string/bzero_sse2.S | 161 - src/libc/x86_64/string/bzero_sse42.S | 148 - src/libc/x86_64/string/ffs.S | 63 - src/libc/x86_64/string/longcopy_sse3x.S | 204 - src/libc/x86_64/string/memcmp.S | 174 - src/libc/x86_64/string/memcpy.c | 40 - src/libc/x86_64/string/memmove.c | 40 - src/libc/x86_64/string/memset.S | 342 - src/libc/x86_64/string/strcmp.S | 136 - src/libc/x86_64/string/strcpy.S | 261 +- src/libc/x86_64/string/strlcat.S | 254 - src/libc/x86_64/string/strlcpy.S | 167 - src/libc/x86_64/string/strlen.S | 156 +- src/libc/x86_64/string/strncmp.S | 174 - src/libc/x86_64/string/strncpy.S | 2 + src/libc/x86_64/string/strnlen.S | 126 + src/libc/x86_64/sys/OSAtomic.S | 378 - src/libc/x86_64/sys/_sigtramp.S | 257 - src/libc/x86_64/sys/atomic.c | 76 - src/libc/x86_64/sys/i386_gettimeofday_asm.S | 89 - src/libc/x86_64/sys/nanotime.S | 58 - src/libc/x86_64/sys/setjmp.S | 142 - src/libc/x86_64/sys/spinlocks.c | 53 - src/libc/x86_64/sys/spinlocks_asm.S | 132 - src/libc/xcodescripts/Libc.order | 100 + src/libc/xcodescripts/abort_unsupported.sh | 11 + src/libc/xcodescripts/alias.list | 14 + src/libc/xcodescripts/build_linklists.sh | 32 +- src/libc/xcodescripts/clean_simulator.sh | 7 - src/libc/xcodescripts/eos.xcconfig | 31 + src/libc/xcodescripts/force_libc_to_build.sh | 2 +- src/libc/xcodescripts/generate_features.pl | 53 +- src/libc/xcodescripts/headers.sh | 181 +- src/libc/xcodescripts/libc.xcconfig | 79 +- src/libc/xcodescripts/libc_static.xcconfig | 21 + src/libc/xcodescripts/manpages.sh | 15 +- src/libc/xcodescripts/mig_headers.sh | 13 - .../xcodescripts/patch_headers_variants.pl | 5 + src/libc/xcodescripts/sim-compat-symlink.sh | 9 + src/libc/xcodescripts/skip_installhdrs.sh | 7 + src/libc/xcodescripts/variants.xcconfig | 47 +- src/libm/CMakeLists.txt | 1 + src/libmacho/CMakeLists.txt | 3 + src/libmalloc/.clang-format | 126 + src/libmalloc/.gitignore | 3 + src/libmalloc/CMakeLists.txt | 23 +- src/libmalloc/include/malloc/malloc.h | 3 +- .../libmalloc.xcodeproj/project.pbxproj | 686 +- src/libmalloc/private/malloc_private.h | 54 + src/libmalloc/private/stack_logging.h | 148 + src/libmalloc/src/base.h | 128 + src/libmalloc/src/bitarray.c | 603 +- src/libmalloc/src/bitarray.h | 57 +- src/libmalloc/src/debug.h | 62 + src/libmalloc/src/empty.s | 34 + src/libmalloc/src/frozen_malloc.c | 178 + src/libmalloc/src/frozen_malloc.h | 36 + src/libmalloc/src/internal.h | 123 + src/libmalloc/src/legacy_malloc.c | 67 + src/libmalloc/src/legacy_malloc.h | 31 + src/libmalloc/src/locking.h | 104 + src/libmalloc/src/magazine_inline.h | 504 + src/libmalloc/src/magazine_large.c | 764 ++ src/libmalloc/src/magazine_lite.c | 359 + src/libmalloc/src/magazine_malloc.c | 9129 +++-------------- src/libmalloc/src/magazine_malloc.h | 304 + src/libmalloc/src/magazine_small.c | 2116 ++++ src/libmalloc/src/magazine_tiny.c | 2158 ++++ src/libmalloc/src/magazine_zone.h | 579 ++ src/libmalloc/src/malloc.c | 1668 ++- src/libmalloc/src/malloc_internal.h | 99 - src/libmalloc/src/malloc_printf.h | 33 - src/libmalloc/src/nano_malloc.c | 1218 +-- src/libmalloc/src/nano_malloc.h | 44 + src/libmalloc/src/nano_zone.h | 151 + src/libmalloc/src/platform.h | 109 + src/libmalloc/src/printf.h | 31 + src/libmalloc/src/purgeable_malloc.c | 423 + src/libmalloc/src/purgeable_malloc.h | 32 + src/libmalloc/src/scalable_malloc.h | 60 - src/libmalloc/src/stack_logging.c | 305 - src/libmalloc/src/stack_logging.h | 136 - src/libmalloc/src/stack_logging_disk.c | 1587 ++- src/libmalloc/src/stack_logging_internal.h | 61 + src/libmalloc/src/thresholds.h | 133 + src/libmalloc/src/trace.h | 62 + src/libmalloc/xcodeconfig/interposable.list | 1 + src/libmalloc/xcodeconfig/libmalloc.xcconfig | 40 +- .../xcodeconfig/libmalloc_eos.xcconfig | 1 + .../xcodeconfig/libmalloc_static.xcconfig | 11 + src/libmalloc/xcodescripts/install-codes.sh | 7 + src/libmalloc/xcodescripts/manpages.sh | 5 +- src/libmalloc/xcodescripts/reindent.sh | 27 + src/libsystem/alloc_once_private.h | 42 +- 2524 files changed, 70199 insertions(+), 107922 deletions(-) create mode 100644 platform-include/mach/coalition.h create mode 100644 platform-include/mach/sfi_class.h create mode 100644 platform-include/pthread/introspection.h rename {src/libc/include => platform-include}/spawn.h (83%) create mode 100644 platform-include/sys/_types/_fsobj_id_t.h create mode 100644 platform-include/sys/clonefile.h create mode 100644 platform-include/sys/coalition.h create mode 100644 platform-include/sys/guarded.h create mode 100644 platform-include/sys/kdebug_signpost.h create mode 100644 platform-include/sys/persona.h create mode 100644 platform-include/sys/reason.h create mode 100644 platform-include/sys/sfi.h create mode 100644 platform-include/sys/snapshot.h create mode 100644 platform-include/sys/stackshot.h create mode 100644 platform-include/sys/ulock.h create mode 100644 platform-include/sys/work_interval.h create mode 100644 src/external/libplatform/.gitignore create mode 100644 src/external/libplatform/CMakeLists.txt create mode 100644 src/external/libplatform/LICENSE rename src/{libc/gen => external/libplatform/include}/_simple.h (80%) create mode 100644 src/external/libplatform/include/libkern/OSAtomic.h create mode 100644 src/external/libplatform/include/libkern/OSAtomicDeprecated.h create mode 100644 src/external/libplatform/include/libkern/OSAtomicQueue.h rename src/{libc => external/libplatform}/include/libkern/OSCacheControl.h (90%) create mode 100644 src/external/libplatform/include/libkern/OSSpinLockDeprecated.h create mode 100644 src/external/libplatform/include/os/alloc_once_impl.h rename src/{libc => external/libplatform/include}/os/base.h (100%) create mode 100644 src/external/libplatform/include/os/base_private.h create mode 100644 src/external/libplatform/include/os/internal/atomic.h create mode 100644 src/external/libplatform/include/os/internal/crashlog.h create mode 100644 src/external/libplatform/include/os/internal/internal_shared.h create mode 100644 src/external/libplatform/include/os/lock.h create mode 100644 src/external/libplatform/include/os/lock_private.h create mode 100644 src/external/libplatform/include/os/once_private.h create mode 100644 src/external/libplatform/include/os/semaphore_private.h create mode 100644 src/external/libplatform/include/platform/compat.h create mode 100644 src/external/libplatform/include/platform/introspection_private.h create mode 100644 src/external/libplatform/include/platform/string.h rename src/{libc => external/libplatform}/include/setjmp.h (82%) rename src/{libc => external/libplatform}/include/ucontext.h (77%) create mode 100644 src/external/libplatform/internal/os/internal.h create mode 100644 src/external/libplatform/internal/os/internal_asm.h create mode 100644 src/external/libplatform/internal/os/yield.h create mode 100644 src/external/libplatform/man/atomic.3 create mode 100644 src/external/libplatform/man/atomic_deprecated.3 rename src/{libc/sys => external/libplatform/man}/cache.3 (100%) rename src/{libc/string/FreeBSD => external/libplatform/man}/ffs.3 (81%) rename src/{libc/gen/FreeBSD => external/libplatform/man}/getcontext.3 (100%) rename src/{libc/gen/FreeBSD => external/libplatform/man}/makecontext.3 (100%) create mode 100644 src/external/libplatform/man/manpages.lst rename src/{libc/gen => external/libplatform/man}/setjmp.3 (100%) create mode 100644 src/external/libplatform/man/spinlock_deprecated.3 rename src/{libc/gen/FreeBSD => external/libplatform/man}/ucontext.3 (100%) create mode 100644 src/external/libplatform/private/libkern/OSAtomic.h create mode 100644 src/external/libplatform/private/libkern/module.modulemap rename src/{libc/darwin => external/libplatform/src/atomics/common}/MKGetTimeBaseInfo.c (97%) create mode 100644 src/external/libplatform/src/atomics/i386/OSAtomic.S create mode 100644 src/external/libplatform/src/atomics/i386/pfz.S create mode 100644 src/external/libplatform/src/atomics/init.c create mode 100644 src/external/libplatform/src/atomics/x86_64/OSAtomic.S create mode 100644 src/external/libplatform/src/atomics/x86_64/pfz.S rename src/{libc/arm/gen/icacheinval.s => external/libplatform/src/cachecontrol/arm/cache.S} (100%) create mode 100644 src/external/libplatform/src/cachecontrol/arm64/cache.S rename src/{libc/gen => external/libplatform/src/cachecontrol/generic}/cache.c (98%) create mode 100644 src/external/libplatform/src/cachecontrol/i386/cache.S create mode 100644 src/external/libplatform/src/cachecontrol/x86_64/cache.S create mode 100644 src/external/libplatform/src/force_libplatform_to_build.c create mode 100644 src/external/libplatform/src/init.c create mode 100644 src/external/libplatform/src/introspection/introspection.c create mode 100644 src/external/libplatform/src/introspection/introspection_internal.h create mode 100644 src/external/libplatform/src/os/alloc_once.c create mode 100644 src/external/libplatform/src/os/atomic.c create mode 100644 src/external/libplatform/src/os/atomic_up.c create mode 100644 src/external/libplatform/src/os/lock.c create mode 100644 src/external/libplatform/src/os/lock_internal.h create mode 100644 src/external/libplatform/src/os/lock_up.c create mode 100644 src/external/libplatform/src/os/lock_wfe.c create mode 100644 src/external/libplatform/src/os/resolver.c create mode 100644 src/external/libplatform/src/os/resolver.h create mode 100644 src/external/libplatform/src/os/semaphore.c rename src/{libc/arm/sys/_longjmp.s => external/libplatform/src/setjmp/arm/_longjmp.S} (100%) rename src/{libc/arm/sys/_setjmp.s => external/libplatform/src/setjmp/arm/_setjmp.S} (100%) rename src/{libc/arm/sys => external/libplatform/src/setjmp/arm}/_setjmp.h (100%) create mode 100644 src/external/libplatform/src/setjmp/arm/longjmp.S create mode 100644 src/external/libplatform/src/setjmp/arm/setjmp.S create mode 100644 src/external/libplatform/src/setjmp/arm64/setjmp.S create mode 100644 src/external/libplatform/src/setjmp/generic/setjmperr.c create mode 100644 src/external/libplatform/src/setjmp/generic/sigtramp.c rename src/{libc/i386/sys => external/libplatform/src/setjmp/i386}/_setjmp.S (96%) create mode 100644 src/external/libplatform/src/setjmp/i386/_sigtramp.S create mode 100644 src/external/libplatform/src/setjmp/i386/setjmp.S rename src/{libc/x86_64/sys => external/libplatform/src/setjmp/x86_64}/_setjmp.S (100%) create mode 100644 src/external/libplatform/src/setjmp/x86_64/_sigtramp.S create mode 100644 src/external/libplatform/src/setjmp/x86_64/setjmp.S create mode 100644 src/external/libplatform/src/simple/asl.c create mode 100644 src/external/libplatform/src/simple/getenv.c create mode 100644 src/external/libplatform/src/simple/string_io.c create mode 100644 src/external/libplatform/src/string/generic/bzero.c create mode 100644 src/external/libplatform/src/string/generic/ffsll.c create mode 100644 src/external/libplatform/src/string/generic/flsll.c create mode 100644 src/external/libplatform/src/string/generic/memccpy.c rename src/{libc/string/FreeBSD => external/libplatform/src/string/generic}/memchr.c (87%) rename src/{libc/string/FreeBSD => external/libplatform/src/string/generic}/memcmp.c (86%) create mode 100644 src/external/libplatform/src/string/generic/memmove.c create mode 100644 src/external/libplatform/src/string/generic/memset_pattern.c create mode 100644 src/external/libplatform/src/string/generic/strchr.c rename src/{libc/string/FreeBSD => external/libplatform/src/string/generic}/strcmp.c (82%) rename src/{libc/string/FreeBSD => external/libplatform/src/string/generic}/strncmp.c (87%) create mode 100644 src/external/libplatform/src/ucontext/generic/getmcontext.c create mode 100644 src/external/libplatform/src/ucontext/generic/makecontext.c create mode 100644 src/external/libplatform/src/ucontext/generic/setcontext.c create mode 100644 src/external/libplatform/src/ucontext/generic/swapcontext.c create mode 100644 src/external/libplatform/src/ucontext/i386/_ctx_start.S create mode 100644 src/external/libplatform/src/ucontext/i386/_setcontext.S create mode 100644 src/external/libplatform/src/ucontext/i386/getcontext.S create mode 100644 src/external/libplatform/src/ucontext/x86_64/_ctx_start.S create mode 100644 src/external/libplatform/src/ucontext/x86_64/_setcontext.S create mode 100644 src/external/libplatform/src/ucontext/x86_64/getcontext.S create mode 100644 src/external/libplatform/xcodeconfig/atomics.xcconfig create mode 100644 src/external/libplatform/xcodeconfig/libplatform.aliases create mode 100644 src/external/libplatform/xcodeconfig/libplatform.xcconfig create mode 100644 src/external/libplatform/xcodeconfig/os.xcconfig create mode 100644 src/external/libplatform/xcodeconfig/perarch.xcconfig create mode 100644 src/external/libplatform/xcodeconfig/static.xcconfig create mode 100644 src/kernel/libsyscall/bsdsyscalls/SYS.h create mode 100644 src/kernel/libsyscall/bsdsyscalls/_____old_semwait_signal_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_____sigwait_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___abort_with_payload.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___accept.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___accept_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___access_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___aio_suspend_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___bind.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___bsdthread_create.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___bsdthread_ctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___bsdthread_register.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___bsdthread_terminate.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___chmod.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___chmod_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___close_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___coalition.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___coalition_info.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___connect.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___connect_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___copyfile.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___csrctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___delete.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___disable_threadsignal.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___exit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fchmod.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fchmod_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fcntl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fcntl_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fork.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fs_snapshot.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fsgetpath.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fstat64_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fstat_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___fsync_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___getattrlist.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___getdirentries64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___gethostuuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___getlogin.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___getpeername.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___getpid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___getrlimit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___getsgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___getsockname.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___gettid.S rename src/kernel/libsyscall/{sys_i386/__gettimeofday.S => bsdsyscalls/___gettimeofday.S} (100%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/___getwgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___guarded_open_dprotected_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___guarded_open_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___identitysvc.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___initgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___ioctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___iopolicysys.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___kdebug_trace.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___kdebug_trace64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___kdebug_trace_string.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___kdebug_typefilter.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___kill.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___lchown.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___listen.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___lseek.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___lstat64_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___lstat_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_execve.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_get_fd.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_get_file.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_get_link.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_get_mount.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_get_pid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_get_proc.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_getfsstat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_mount.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_set_fd.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_set_file.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_set_link.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_set_proc.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mac_syscall.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___microstackshot.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mkdir_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mkfifo_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mmap.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___mprotect.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___msgctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___msgrcv_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___msgsnd_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___msgsys.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___msync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___msync_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___munmap.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___old_semwait_signal.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___open.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___open_dprotected_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___open_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___open_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___openat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___openat_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___persona.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pipe.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___poll_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___posix_spawn.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pread_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___proc_info.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___process_policy.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pselect.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pselect_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_cvbroad.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_cvclrprepost.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_cvsignal.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_cvwait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_mutexdrop.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_mutexwait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_rw_downgrade.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_rw_longrdlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_rw_rdlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_rw_unlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_rw_unlock2.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_rw_upgrade.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_rw_wrlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___psynch_rw_yieldwrlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pthread_canceled.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pthread_chdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pthread_fchdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pthread_kill.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pthread_markcancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pthread_sigmask.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___ptrace.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___pwrite_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___read_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___readv_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___recvfrom.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___recvfrom_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___recvmsg.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___recvmsg_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___rename.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___renameat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___renameatx_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___rmdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___select.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___select_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sem_open.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sem_wait_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___semctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___semsys.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___semwait_signal.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___semwait_signal_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sendmsg.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sendmsg_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sendto.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sendto_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___setattrlist.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___setlogin.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___setpriority.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___setregid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___setreuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___setrlimit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___setsgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___settid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___settid_with_pid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___settimeofday.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___setwgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sfi_ctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sfi_pidctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___shared_region_check_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___shared_region_map_and_slide_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___shm_open.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___shmctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___shmsys.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sigaction.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sigaltstack.S rename src/kernel/libsyscall/{sys_i386/__sigreturn.S => bsdsyscalls/___sigreturn.S} (100%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sigsuspend.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sigsuspend_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sigwait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___socketpair.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___stack_snapshot_with_config.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___stat64_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___stat_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___syscall.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sysctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___sysctlbyname.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___telemetry.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___terminate_with_payload.S rename src/kernel/libsyscall/{sys_i386/__thread_selfid.S => bsdsyscalls/___thread_selfid.S} (100%) rename src/kernel/libsyscall/{sys_i386/__thread_selfusage.S => bsdsyscalls/___thread_selfusage.S} (100%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/___ulock_wait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___ulock_wake.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___umask_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___unlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___unlinkat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___vfork.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___wait4.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___wait4_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___waitid_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___work_interval_ctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___workq_kernreturn.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___workq_open.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___write_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/___writev_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_access.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_acct.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_adjtime.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_aio_cancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_aio_error.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_aio_fsync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_aio_read.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_aio_return.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_aio_suspend.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_aio_write.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_audit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_audit_session_join.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_audit_session_port.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_audit_session_self.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_auditctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_auditon.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_change_fdguard_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_chdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_chflags.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_chown.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_chroot.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_clonefileat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_close.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_connectx.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_csops.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_csops_audittoken.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_disconnectx.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_dup.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_dup2.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_exchangedata.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_execve.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_faccessat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fchdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fchflags.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fchmodat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fchown.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fchownat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fclonefileat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fdatasync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_ffsctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fgetattrlist.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fgetxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fhopen.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fileport_makefd.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fileport_makeport.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_flistxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_flock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fpathconf.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fremovexattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fsctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fsetattrlist.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fsetxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fsgetpath.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fstat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fstat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fstatat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fstatat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fstatfs.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fstatfs64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_fsync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_ftruncate.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_futimes.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getattrlistat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getattrlistbulk.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getaudit_addr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getauid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getdirentries.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getdirentriesattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getdtablesize.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getegid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getentropy.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_geteuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getfh.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getfsstat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getfsstat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getgid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getitimer.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getpgid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getpgrp.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getppid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getpriority.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getrusage.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getsid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getsockopt.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_getxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_grab_pgo_data.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_guarded_close_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_guarded_kqueue_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_guarded_pwrite_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_guarded_write_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_guarded_writev_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_issetugid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_kas_info.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_kevent.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_kevent64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_kevent_qos.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_kqueue.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_ledger.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_link.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_linkat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_lio_listio.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_listxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_lstat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_lstat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_madvise.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_memorystatus_control.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_memorystatus_get_level.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_mincore.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_minherit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_mkdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_mkdirat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_mkfifo.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_mknod.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_mlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_mlockall.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_modwatch.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_mount.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_mremap_encrypted.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_msgget.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_msgrcv.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_msgsnd.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_munlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_munlockall.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_necp_client_action.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_necp_match_policy.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_necp_open.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_netagent_trigger.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_nfsclnt.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_nfssvc.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_openbyid_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_pathconf.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_peeloff.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_pid_resume.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_pid_suspend.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_poll.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_pread.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_proc_rlimit_control.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_proc_trace_log.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_proc_uuid_policy.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_pwrite.S rename src/kernel/libsyscall/{sys_x86-64 => bsdsyscalls}/_quota.S (84%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/_quotactl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_read.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_readlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_readlinkat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_readv.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_reboot.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_recvmsg_x.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_removexattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_revoke.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_searchfs.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sem_close.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sem_post.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sem_trywait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sem_unlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sem_wait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_semget.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_semop.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sendfile.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sendmsg_x.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setaudit_addr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setauid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setegid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_seteuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setgid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setitimer.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setpgid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setprivexec.S rename src/kernel/libsyscall/{sys_x86-64 => bsdsyscalls}/_setquota.S (85%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setsid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setsockopt.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_setxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_shm_unlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_shmat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_shmdt.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_shmget.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_shutdown.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sigpending.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sigprocmask.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_socket.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_socket_delegate.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_stat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_stat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_statfs.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_statfs64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_swapon.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_symlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_symlinkat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_sync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_system_override.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_truncate.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_umask.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_undelete.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_unmount.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_usrctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_utimes.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_vfs_purge.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_vm_pressure_monitor.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_waitevent.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_waitid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_watchevent.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_write.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/_writev.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/SYS.h create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_____old_semwait_signal_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_____sigwait_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___accept.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___accept_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___access_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___aio_suspend_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___bind.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_create.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_ctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_register.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_terminate.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___chmod.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___chmod_extended.S rename src/kernel/libsyscall/{sys_x86-64 => bsdsyscalls/bak}/___chud.S (84%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___close_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___coalition.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___coalition_info.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___connect.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___connect_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___copyfile.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___csrctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___delete.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___disable_threadsignal.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___exit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___fchmod.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___fchmod_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___fcntl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___fcntl_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___fork.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___fsgetpath.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___fstat64_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___fstat_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___fsync_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___getattrlist.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___getdirentries64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___gethostuuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___getlogin.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___getpeername.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___getpid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___getrlimit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___getsgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___getsockname.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___gettid.S rename src/kernel/libsyscall/{sys_x86-64 => bsdsyscalls/bak}/___gettimeofday.S (96%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___getwgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___guarded_open_dprotected_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___guarded_open_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___identitysvc.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___initgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___ioctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___iopolicysys.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace_string.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___kill.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___lchown.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___listen.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___lseek.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___lstat64_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___lstat_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_execve.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_fd.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_file.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_link.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_mount.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_pid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_proc.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_getfsstat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_mount.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_fd.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_file.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_link.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_proc.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mac_syscall.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___microstackshot.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mkdir_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mkfifo_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mmap.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___mprotect.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___msgctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___msgrcv_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___msgsnd_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___msgsys.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___msync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___msync_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___munmap.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___old_semwait_signal.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___open.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___open_dprotected_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___open_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___open_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___openat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___openat_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___persona.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pipe.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___poll_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___posix_spawn.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pread_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___proc_info.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___process_policy.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pselect.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pselect_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvbroad.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvclrprepost.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvsignal.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvwait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_mutexdrop.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_mutexwait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_downgrade.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_longrdlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_rdlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_unlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_unlock2.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_upgrade.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_wrlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_yieldwrlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pthread_canceled.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pthread_chdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pthread_fchdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pthread_kill.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pthread_markcancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pthread_sigmask.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___ptrace.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___pwrite_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___read_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___readv_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___recvfrom.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___recvfrom_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___recvmsg.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___recvmsg_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___rename.S rename src/kernel/libsyscall/{sys_x86-64 => bsdsyscalls/bak}/___rename_ext.S (85%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___renameat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___rmdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___select.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___select_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sem_open.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sem_wait_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___semctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___semsys.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___semwait_signal.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___semwait_signal_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sendmsg.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sendmsg_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sendto.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sendto_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___setattrlist.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___setlogin.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___setpriority.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___setregid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___setreuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___setrlimit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___setsgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___settid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___settid_with_pid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___settimeofday.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___setwgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sfi_ctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sfi_pidctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___shared_region_check_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___shared_region_map_and_slide_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___shm_open.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___shmctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___shmsys.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sigaction.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sigaltstack.S rename src/kernel/libsyscall/{sys_x86-64 => bsdsyscalls/bak}/___sigreturn.S (96%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sigsuspend.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sigsuspend_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sigwait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___socketpair.S rename src/kernel/libsyscall/{sys_x86-64 => bsdsyscalls/bak}/___stack_snapshot.S (86%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___stack_snapshot_with_config.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___stat64_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___stat_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___syscall.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sysctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___sysctlbyname.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___telemetry.S rename src/kernel/libsyscall/{sys_x86-64 => bsdsyscalls/bak}/___thread_selfid.S (95%) rename src/kernel/libsyscall/{sys_x86-64 => bsdsyscalls/bak}/___thread_selfusage.S (95%) create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___umask_extended.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___unlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___unlinkat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___vfork.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___wait4.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___wait4_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___waitid_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___work_interval_ctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___workq_kernreturn.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___workq_open.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___write_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/___writev_nocancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_access.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_acct.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_adjtime.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_aio_cancel.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_aio_error.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_aio_fsync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_aio_read.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_aio_return.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_aio_suspend.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_aio_write.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_audit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_join.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_port.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_self.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_auditctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_auditon.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_change_fdguard_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_chdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_chflags.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_chown.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_chroot.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_close.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_connectx.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_csops.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_csops_audittoken.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_disconnectx.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_dup.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_dup2.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_exchangedata.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_execve.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_faccessat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fchdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fchflags.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fchmodat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fchown.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fchownat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fdatasync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_ffsctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fgetattrlist.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fgetxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fhopen.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fileport_makefd.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fileport_makeport.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_flistxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_flock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fpathconf.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fremovexattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fsctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fsetattrlist.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fsetxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fstat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fstat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fstatat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fstatat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fstatfs.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fstatfs64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_fsync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_ftruncate.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_futimes.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getattrlistat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getattrlistbulk.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getaudit_addr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getauid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getdirentries.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getdirentriesattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getdtablesize.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getegid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_geteuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getfh.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getfsstat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getfsstat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getgid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getitimer.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getpgid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getpgrp.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getppid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getpriority.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getrusage.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getsid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getsockopt.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_getxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_grab_pgo_data.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_guarded_close_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_guarded_kqueue_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_guarded_pwrite_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_guarded_write_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_guarded_writev_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_issetugid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_kas_info.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_kevent.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_kevent64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_kevent_qos.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_kqueue.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_ledger.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_link.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_linkat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_lio_listio.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_listxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_lstat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_lstat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_madvise.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_memorystatus_control.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_memorystatus_get_level.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_mincore.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_minherit.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_mkdir.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_mkdirat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_mkfifo.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_mknod.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_mlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_mlockall.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_modwatch.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_mount.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_mremap_encrypted.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_msgget.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_msgrcv.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_msgsnd.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_munlock.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_munlockall.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_necp_match_policy.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_netagent_trigger.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_nfsclnt.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_nfssvc.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_openbyid_np.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_pathconf.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_peeloff.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_pid_resume.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_pid_suspend.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_poll.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_pread.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_proc_rlimit_control.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_proc_trace_log.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_proc_uuid_policy.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_pwrite.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_quotactl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_read.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_readlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_readlinkat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_readv.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_reboot.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_recvmsg_x.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_removexattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_revoke.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_searchfs.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sem_close.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sem_post.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sem_trywait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sem_unlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sem_wait.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_semget.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_semop.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sendfile.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sendmsg_x.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setaudit_addr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setauid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setegid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_seteuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setgid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setgroups.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setitimer.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setpgid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setprivexec.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setsid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setsockopt.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setuid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_setxattr.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_shm_unlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_shmat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_shmdt.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_shmget.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_shutdown.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sigpending.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sigprocmask.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_socket.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_socket_delegate.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_stat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_stat64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_statfs.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_statfs64.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_swapon.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_symlink.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_symlinkat.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_sync.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_system_override.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_truncate.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_umask.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_undelete.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_unmount.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_usrctl.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_utimes.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_vfs_purge.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_vm_pressure_monitor.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_waitevent.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_waitid.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_watchevent.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_write.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/_writev.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/custom.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/bak/stubs.list create mode 100644 src/kernel/libsyscall/bsdsyscalls/custom.S create mode 100644 src/kernel/libsyscall/bsdsyscalls/stubs.list create mode 100644 src/kernel/libsyscall/custom/__kdebug_trace_string.s delete mode 100644 src/kernel/libsyscall/sys_i386/SYS.h delete mode 100644 src/kernel/libsyscall/sys_i386/____old_semwait_signal_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/____sigwait_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__accept.S delete mode 100644 src/kernel/libsyscall/sys_i386/__accept_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__access_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__aio_suspend_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__bind.S delete mode 100644 src/kernel/libsyscall/sys_i386/__bsdthread_create.S delete mode 100644 src/kernel/libsyscall/sys_i386/__bsdthread_ctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__bsdthread_register.S delete mode 100644 src/kernel/libsyscall/sys_i386/__bsdthread_terminate.S delete mode 100644 src/kernel/libsyscall/sys_i386/__chmod.S delete mode 100644 src/kernel/libsyscall/sys_i386/__chmod_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__chud.S delete mode 100644 src/kernel/libsyscall/sys_i386/__close_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__coalition.S delete mode 100644 src/kernel/libsyscall/sys_i386/__coalition_info.S delete mode 100644 src/kernel/libsyscall/sys_i386/__connect.S delete mode 100644 src/kernel/libsyscall/sys_i386/__connect_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__copyfile.S delete mode 100644 src/kernel/libsyscall/sys_i386/__csrctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__delete.S delete mode 100644 src/kernel/libsyscall/sys_i386/__disable_threadsignal.S delete mode 100644 src/kernel/libsyscall/sys_i386/__exit.S delete mode 100644 src/kernel/libsyscall/sys_i386/__fchmod.S delete mode 100644 src/kernel/libsyscall/sys_i386/__fchmod_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__fcntl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__fcntl_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__fork.S delete mode 100644 src/kernel/libsyscall/sys_i386/__fsgetpath.S delete mode 100644 src/kernel/libsyscall/sys_i386/__fstat64_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__fstat_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__fsync_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getattrlist.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getdirentries64.S delete mode 100644 src/kernel/libsyscall/sys_i386/__gethostuuid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getlcid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getlogin.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getpeername.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getpid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getrlimit.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getsgroups.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getsockname.S delete mode 100644 src/kernel/libsyscall/sys_i386/__gettid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__getwgroups.S delete mode 100644 src/kernel/libsyscall/sys_i386/__guarded_open_dprotected_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/__guarded_open_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/__identitysvc.S delete mode 100644 src/kernel/libsyscall/sys_i386/__initgroups.S delete mode 100644 src/kernel/libsyscall/sys_i386/__ioctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__iopolicysys.S delete mode 100644 src/kernel/libsyscall/sys_i386/__kdebug_trace.S delete mode 100644 src/kernel/libsyscall/sys_i386/__kill.S delete mode 100644 src/kernel/libsyscall/sys_i386/__lchown.S delete mode 100644 src/kernel/libsyscall/sys_i386/__listen.S delete mode 100644 src/kernel/libsyscall/sys_i386/__lseek.S delete mode 100644 src/kernel/libsyscall/sys_i386/__lstat64_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__lstat_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_execve.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_get_fd.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_get_file.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_get_lcid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_get_lctx.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_get_link.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_get_mount.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_get_pid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_get_proc.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_getfsstat.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_mount.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_set_fd.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_set_file.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_set_lctx.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_set_link.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_set_proc.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mac_syscall.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mkdir_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mkfifo_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mmap.S delete mode 100644 src/kernel/libsyscall/sys_i386/__mprotect.S delete mode 100644 src/kernel/libsyscall/sys_i386/__msgctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__msgrcv_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__msgsnd_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__msgsys.S delete mode 100644 src/kernel/libsyscall/sys_i386/__msync.S delete mode 100644 src/kernel/libsyscall/sys_i386/__msync_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__munmap.S delete mode 100644 src/kernel/libsyscall/sys_i386/__old_semwait_signal.S delete mode 100644 src/kernel/libsyscall/sys_i386/__open.S delete mode 100644 src/kernel/libsyscall/sys_i386/__open_dprotected_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/__open_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__open_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__openat.S delete mode 100644 src/kernel/libsyscall/sys_i386/__openat_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__pipe.S delete mode 100644 src/kernel/libsyscall/sys_i386/__poll_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__posix_spawn.S delete mode 100644 src/kernel/libsyscall/sys_i386/__pread_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__proc_info.S delete mode 100644 src/kernel/libsyscall/sys_i386/__process_policy.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_cvbroad.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_cvclrprepost.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_cvsignal.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_cvwait.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_mutexdrop.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_mutexwait.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_rw_downgrade.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_rw_longrdlock.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_rw_rdlock.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_rw_unlock.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_rw_unlock2.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_rw_upgrade.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_rw_wrlock.S delete mode 100644 src/kernel/libsyscall/sys_i386/__psynch_rw_yieldwrlock.S delete mode 100644 src/kernel/libsyscall/sys_i386/__pthread_canceled.S delete mode 100644 src/kernel/libsyscall/sys_i386/__pthread_chdir.S delete mode 100644 src/kernel/libsyscall/sys_i386/__pthread_fchdir.S delete mode 100644 src/kernel/libsyscall/sys_i386/__pthread_kill.S delete mode 100644 src/kernel/libsyscall/sys_i386/__pthread_markcancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__pthread_sigmask.S delete mode 100644 src/kernel/libsyscall/sys_i386/__ptrace.S delete mode 100644 src/kernel/libsyscall/sys_i386/__pwrite_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__read_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__readv_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__recvfrom.S delete mode 100644 src/kernel/libsyscall/sys_i386/__recvfrom_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__recvmsg.S delete mode 100644 src/kernel/libsyscall/sys_i386/__recvmsg_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__rename.S delete mode 100644 src/kernel/libsyscall/sys_i386/__rename_ext.S delete mode 100644 src/kernel/libsyscall/sys_i386/__renameat.S delete mode 100644 src/kernel/libsyscall/sys_i386/__rmdir.S delete mode 100644 src/kernel/libsyscall/sys_i386/__select.S delete mode 100644 src/kernel/libsyscall/sys_i386/__select_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sem_open.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sem_wait_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__semctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__semsys.S delete mode 100644 src/kernel/libsyscall/sys_i386/__semwait_signal.S delete mode 100644 src/kernel/libsyscall/sys_i386/__semwait_signal_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sendmsg.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sendmsg_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sendto.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sendto_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__setattrlist.S delete mode 100644 src/kernel/libsyscall/sys_i386/__setlcid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__setlogin.S delete mode 100644 src/kernel/libsyscall/sys_i386/__setpriority.S delete mode 100644 src/kernel/libsyscall/sys_i386/__setregid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__setreuid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__setrlimit.S delete mode 100644 src/kernel/libsyscall/sys_i386/__setsgroups.S delete mode 100644 src/kernel/libsyscall/sys_i386/__settid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__settid_with_pid.S delete mode 100644 src/kernel/libsyscall/sys_i386/__settimeofday.S delete mode 100644 src/kernel/libsyscall/sys_i386/__setwgroups.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sfi_ctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sfi_pidctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__shared_region_check_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/__shared_region_map_and_slide_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/__shm_open.S delete mode 100644 src/kernel/libsyscall/sys_i386/__shmctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__shmsys.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sigaction.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sigaltstack.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sigsuspend.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sigsuspend_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sigwait.S delete mode 100644 src/kernel/libsyscall/sys_i386/__socketpair.S delete mode 100644 src/kernel/libsyscall/sys_i386/__stack_snapshot.S delete mode 100644 src/kernel/libsyscall/sys_i386/__stat64_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__stat_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__syscall.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sysctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/__sysctlbyname.S delete mode 100644 src/kernel/libsyscall/sys_i386/__telemetry.S delete mode 100644 src/kernel/libsyscall/sys_i386/__umask_extended.S delete mode 100644 src/kernel/libsyscall/sys_i386/__unlink.S delete mode 100644 src/kernel/libsyscall/sys_i386/__unlinkat.S delete mode 100644 src/kernel/libsyscall/sys_i386/__vfork.S delete mode 100644 src/kernel/libsyscall/sys_i386/__wait4.S delete mode 100644 src/kernel/libsyscall/sys_i386/__wait4_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__waitid_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__workq_kernreturn.S delete mode 100644 src/kernel/libsyscall/sys_i386/__workq_open.S delete mode 100644 src/kernel/libsyscall/sys_i386/__write_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/__writev_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/access.S delete mode 100644 src/kernel/libsyscall/sys_i386/acct.S delete mode 100644 src/kernel/libsyscall/sys_i386/adjtime.S delete mode 100644 src/kernel/libsyscall/sys_i386/aio_cancel.S delete mode 100644 src/kernel/libsyscall/sys_i386/aio_error.S delete mode 100644 src/kernel/libsyscall/sys_i386/aio_fsync.S delete mode 100644 src/kernel/libsyscall/sys_i386/aio_read.S delete mode 100644 src/kernel/libsyscall/sys_i386/aio_return.S delete mode 100644 src/kernel/libsyscall/sys_i386/aio_suspend.S delete mode 100644 src/kernel/libsyscall/sys_i386/aio_write.S delete mode 100644 src/kernel/libsyscall/sys_i386/audit.S delete mode 100644 src/kernel/libsyscall/sys_i386/audit_session_join.S delete mode 100644 src/kernel/libsyscall/sys_i386/audit_session_port.S delete mode 100644 src/kernel/libsyscall/sys_i386/audit_session_self.S delete mode 100644 src/kernel/libsyscall/sys_i386/auditctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/auditon.S delete mode 100644 src/kernel/libsyscall/sys_i386/change_fdguard_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/chdir.S delete mode 100644 src/kernel/libsyscall/sys_i386/chflags.S delete mode 100644 src/kernel/libsyscall/sys_i386/chown.S delete mode 100644 src/kernel/libsyscall/sys_i386/chroot.S delete mode 100644 src/kernel/libsyscall/sys_i386/close.S delete mode 100644 src/kernel/libsyscall/sys_i386/connectx.S delete mode 100644 src/kernel/libsyscall/sys_i386/csops.S delete mode 100644 src/kernel/libsyscall/sys_i386/csops_audittoken.S delete mode 100644 src/kernel/libsyscall/sys_i386/custom.S delete mode 100644 src/kernel/libsyscall/sys_i386/disconnectx.S delete mode 100644 src/kernel/libsyscall/sys_i386/dup.S delete mode 100644 src/kernel/libsyscall/sys_i386/dup2.S delete mode 100644 src/kernel/libsyscall/sys_i386/exchangedata.S delete mode 100644 src/kernel/libsyscall/sys_i386/execve.S delete mode 100644 src/kernel/libsyscall/sys_i386/faccessat.S delete mode 100644 src/kernel/libsyscall/sys_i386/fchdir.S delete mode 100644 src/kernel/libsyscall/sys_i386/fchflags.S delete mode 100644 src/kernel/libsyscall/sys_i386/fchmodat.S delete mode 100644 src/kernel/libsyscall/sys_i386/fchown.S delete mode 100644 src/kernel/libsyscall/sys_i386/fchownat.S delete mode 100644 src/kernel/libsyscall/sys_i386/fdatasync.S delete mode 100644 src/kernel/libsyscall/sys_i386/ffsctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/fgetattrlist.S delete mode 100644 src/kernel/libsyscall/sys_i386/fgetxattr.S delete mode 100644 src/kernel/libsyscall/sys_i386/fhopen.S delete mode 100644 src/kernel/libsyscall/sys_i386/fileport_makefd.S delete mode 100644 src/kernel/libsyscall/sys_i386/fileport_makeport.S delete mode 100644 src/kernel/libsyscall/sys_i386/flistxattr.S delete mode 100644 src/kernel/libsyscall/sys_i386/flock.S delete mode 100644 src/kernel/libsyscall/sys_i386/fpathconf.S delete mode 100644 src/kernel/libsyscall/sys_i386/fremovexattr.S delete mode 100644 src/kernel/libsyscall/sys_i386/fsctl.S delete mode 100644 src/kernel/libsyscall/sys_i386/fsetattrlist.S delete mode 100644 src/kernel/libsyscall/sys_i386/fsetxattr.S delete mode 100644 src/kernel/libsyscall/sys_i386/fstat.S delete mode 100644 src/kernel/libsyscall/sys_i386/fstat64.S delete mode 100644 src/kernel/libsyscall/sys_i386/fstatat.S delete mode 100644 src/kernel/libsyscall/sys_i386/fstatat64.S delete mode 100644 src/kernel/libsyscall/sys_i386/fstatfs.S delete mode 100644 src/kernel/libsyscall/sys_i386/fstatfs64.S delete mode 100644 src/kernel/libsyscall/sys_i386/fsync.S delete mode 100644 src/kernel/libsyscall/sys_i386/ftruncate.S delete mode 100644 src/kernel/libsyscall/sys_i386/futimes.S delete mode 100644 src/kernel/libsyscall/sys_i386/getattrlistat.S delete mode 100644 src/kernel/libsyscall/sys_i386/getattrlistbulk.S delete mode 100644 src/kernel/libsyscall/sys_i386/getaudit_addr.S delete mode 100644 src/kernel/libsyscall/sys_i386/getauid.S delete mode 100644 src/kernel/libsyscall/sys_i386/getdirentries.S delete mode 100644 src/kernel/libsyscall/sys_i386/getdirentriesattr.S delete mode 100644 src/kernel/libsyscall/sys_i386/getdtablesize.S delete mode 100644 src/kernel/libsyscall/sys_i386/getegid.S delete mode 100644 src/kernel/libsyscall/sys_i386/geteuid.S delete mode 100644 src/kernel/libsyscall/sys_i386/getfh.S delete mode 100644 src/kernel/libsyscall/sys_i386/getfsstat.S delete mode 100644 src/kernel/libsyscall/sys_i386/getfsstat64.S delete mode 100644 src/kernel/libsyscall/sys_i386/getgid.S delete mode 100644 src/kernel/libsyscall/sys_i386/getgroups.S delete mode 100644 src/kernel/libsyscall/sys_i386/getitimer.S delete mode 100644 src/kernel/libsyscall/sys_i386/getpgid.S delete mode 100644 src/kernel/libsyscall/sys_i386/getpgrp.S delete mode 100644 src/kernel/libsyscall/sys_i386/getppid.S delete mode 100644 src/kernel/libsyscall/sys_i386/getpriority.S delete mode 100644 src/kernel/libsyscall/sys_i386/getrusage.S delete mode 100644 src/kernel/libsyscall/sys_i386/getsid.S delete mode 100644 src/kernel/libsyscall/sys_i386/getsockopt.S delete mode 100644 src/kernel/libsyscall/sys_i386/getuid.S delete mode 100644 src/kernel/libsyscall/sys_i386/getxattr.S delete mode 100644 src/kernel/libsyscall/sys_i386/guarded_close_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/guarded_kqueue_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/guarded_pwrite_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/guarded_write_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/guarded_writev_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/issetugid.S delete mode 100644 src/kernel/libsyscall/sys_i386/kas_info.S delete mode 100644 src/kernel/libsyscall/sys_i386/kevent.S delete mode 100644 src/kernel/libsyscall/sys_i386/kevent64.S delete mode 100644 src/kernel/libsyscall/sys_i386/kqueue.S delete mode 100644 src/kernel/libsyscall/sys_i386/ledger.S delete mode 100644 src/kernel/libsyscall/sys_i386/link.S delete mode 100644 src/kernel/libsyscall/sys_i386/linkat.S delete mode 100644 src/kernel/libsyscall/sys_i386/lio_listio.S delete mode 100644 src/kernel/libsyscall/sys_i386/listxattr.S delete mode 100644 src/kernel/libsyscall/sys_i386/lstat.S delete mode 100644 src/kernel/libsyscall/sys_i386/lstat64.S delete mode 100644 src/kernel/libsyscall/sys_i386/madvise.S delete mode 100644 src/kernel/libsyscall/sys_i386/memorystatus_control.S delete mode 100644 src/kernel/libsyscall/sys_i386/memorystatus_get_level.S delete mode 100644 src/kernel/libsyscall/sys_i386/mincore.S delete mode 100644 src/kernel/libsyscall/sys_i386/minherit.S delete mode 100644 src/kernel/libsyscall/sys_i386/mkdir.S delete mode 100644 src/kernel/libsyscall/sys_i386/mkdirat.S delete mode 100644 src/kernel/libsyscall/sys_i386/mkfifo.S delete mode 100644 src/kernel/libsyscall/sys_i386/mknod.S delete mode 100644 src/kernel/libsyscall/sys_i386/mlock.S delete mode 100644 src/kernel/libsyscall/sys_i386/mlockall.S delete mode 100644 src/kernel/libsyscall/sys_i386/modwatch.S delete mode 100644 src/kernel/libsyscall/sys_i386/mount.S delete mode 100644 src/kernel/libsyscall/sys_i386/mremap_encrypted.S delete mode 100644 src/kernel/libsyscall/sys_i386/msgget.S delete mode 100644 src/kernel/libsyscall/sys_i386/msgrcv.S delete mode 100644 src/kernel/libsyscall/sys_i386/msgsnd.S delete mode 100644 src/kernel/libsyscall/sys_i386/munlock.S delete mode 100644 src/kernel/libsyscall/sys_i386/munlockall.S delete mode 100644 src/kernel/libsyscall/sys_i386/necp_match_policy.S delete mode 100644 src/kernel/libsyscall/sys_i386/nfsclnt.S delete mode 100644 src/kernel/libsyscall/sys_i386/nfssvc.S delete mode 100644 src/kernel/libsyscall/sys_i386/openbyid_np.S delete mode 100644 src/kernel/libsyscall/sys_i386/pathconf.S delete mode 100644 src/kernel/libsyscall/sys_i386/peeloff.S delete mode 100644 src/kernel/libsyscall/sys_i386/pid_resume.S delete mode 100644 src/kernel/libsyscall/sys_i386/pid_suspend.S delete mode 100644 src/kernel/libsyscall/sys_i386/poll.S delete mode 100644 src/kernel/libsyscall/sys_i386/pread.S delete mode 100644 src/kernel/libsyscall/sys_i386/proc_rlimit_control.S delete mode 100644 src/kernel/libsyscall/sys_i386/proc_trace_log.S delete mode 100644 src/kernel/libsyscall/sys_i386/proc_uuid_policy.S delete mode 100644 src/kernel/libsyscall/sys_i386/pwrite.S delete mode 100644 src/kernel/libsyscall/sys_i386/quota.S delete mode 100644 src/kernel/libsyscall/sys_i386/quotactl.S delete mode 100644 src/kernel/libsyscall/sys_i386/read.S delete mode 100644 src/kernel/libsyscall/sys_i386/readlink.S delete mode 100644 src/kernel/libsyscall/sys_i386/readlinkat.S delete mode 100644 src/kernel/libsyscall/sys_i386/readv.S delete mode 100644 src/kernel/libsyscall/sys_i386/reboot.S delete mode 100644 src/kernel/libsyscall/sys_i386/recvmsg_x.S delete mode 100644 src/kernel/libsyscall/sys_i386/removexattr.S delete mode 100644 src/kernel/libsyscall/sys_i386/revoke.S delete mode 100644 src/kernel/libsyscall/sys_i386/searchfs.S delete mode 100644 src/kernel/libsyscall/sys_i386/sem_close.S delete mode 100644 src/kernel/libsyscall/sys_i386/sem_post.S delete mode 100644 src/kernel/libsyscall/sys_i386/sem_trywait.S delete mode 100644 src/kernel/libsyscall/sys_i386/sem_unlink.S delete mode 100644 src/kernel/libsyscall/sys_i386/sem_wait.S delete mode 100644 src/kernel/libsyscall/sys_i386/semget.S delete mode 100644 src/kernel/libsyscall/sys_i386/semop.S delete mode 100644 src/kernel/libsyscall/sys_i386/sendfile.S delete mode 100644 src/kernel/libsyscall/sys_i386/sendmsg_x.S delete mode 100644 src/kernel/libsyscall/sys_i386/setaudit_addr.S delete mode 100644 src/kernel/libsyscall/sys_i386/setauid.S delete mode 100644 src/kernel/libsyscall/sys_i386/setegid.S delete mode 100644 src/kernel/libsyscall/sys_i386/seteuid.S delete mode 100644 src/kernel/libsyscall/sys_i386/setgid.S delete mode 100644 src/kernel/libsyscall/sys_i386/setgroups.S delete mode 100644 src/kernel/libsyscall/sys_i386/setitimer.S delete mode 100644 src/kernel/libsyscall/sys_i386/setpgid.S delete mode 100644 src/kernel/libsyscall/sys_i386/setprivexec.S delete mode 100644 src/kernel/libsyscall/sys_i386/setquota.S delete mode 100644 src/kernel/libsyscall/sys_i386/setsid.S delete mode 100644 src/kernel/libsyscall/sys_i386/setsockopt.S delete mode 100644 src/kernel/libsyscall/sys_i386/setuid.S delete mode 100644 src/kernel/libsyscall/sys_i386/setxattr.S delete mode 100644 src/kernel/libsyscall/sys_i386/shm_unlink.S delete mode 100644 src/kernel/libsyscall/sys_i386/shmat.S delete mode 100644 src/kernel/libsyscall/sys_i386/shmdt.S delete mode 100644 src/kernel/libsyscall/sys_i386/shmget.S delete mode 100644 src/kernel/libsyscall/sys_i386/shutdown.S delete mode 100644 src/kernel/libsyscall/sys_i386/sigpending.S delete mode 100644 src/kernel/libsyscall/sys_i386/sigprocmask.S delete mode 100644 src/kernel/libsyscall/sys_i386/socket.S delete mode 100644 src/kernel/libsyscall/sys_i386/socket_delegate.S delete mode 100644 src/kernel/libsyscall/sys_i386/stat.S delete mode 100644 src/kernel/libsyscall/sys_i386/stat64.S delete mode 100644 src/kernel/libsyscall/sys_i386/statfs.S delete mode 100644 src/kernel/libsyscall/sys_i386/statfs64.S delete mode 100644 src/kernel/libsyscall/sys_i386/stubs.list delete mode 100644 src/kernel/libsyscall/sys_i386/swapon.S delete mode 100644 src/kernel/libsyscall/sys_i386/symlink.S delete mode 100644 src/kernel/libsyscall/sys_i386/symlinkat.S delete mode 100644 src/kernel/libsyscall/sys_i386/sync.S delete mode 100644 src/kernel/libsyscall/sys_i386/system_override.S delete mode 100644 src/kernel/libsyscall/sys_i386/truncate.S delete mode 100644 src/kernel/libsyscall/sys_i386/umask.S delete mode 100644 src/kernel/libsyscall/sys_i386/undelete.S delete mode 100644 src/kernel/libsyscall/sys_i386/unmount.S delete mode 100644 src/kernel/libsyscall/sys_i386/utimes.S delete mode 100644 src/kernel/libsyscall/sys_i386/vfs_purge.S delete mode 100644 src/kernel/libsyscall/sys_i386/vm_pressure_monitor.S delete mode 100644 src/kernel/libsyscall/sys_i386/waitevent.S delete mode 100644 src/kernel/libsyscall/sys_i386/waitid.S delete mode 100644 src/kernel/libsyscall/sys_i386/watchevent.S delete mode 100644 src/kernel/libsyscall/sys_i386/write.S delete mode 100644 src/kernel/libsyscall/sys_i386/writev.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/SYS.h delete mode 100644 src/kernel/libsyscall/sys_x86-64/_____old_semwait_signal_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_____sigwait_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___accept.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___accept_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___access_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___aio_suspend_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___bind.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___bsdthread_create.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___bsdthread_ctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___bsdthread_register.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___bsdthread_terminate.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___chmod.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___chmod_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___close_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___coalition.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___coalition_info.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___connect.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___connect_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___copyfile.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___csrctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___delete.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___disable_threadsignal.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___exit.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___fchmod.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___fchmod_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___fcntl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___fcntl_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___fork.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___fsgetpath.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___fstat64_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___fstat_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___fsync_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___getattrlist.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___getdirentries64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___gethostuuid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___getlogin.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___getpeername.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___getpid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___getrlimit.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___getsgroups.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___getsockname.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___gettid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___getwgroups.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___guarded_open_dprotected_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___guarded_open_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___identitysvc.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___initgroups.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___ioctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___iopolicysys.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___kdebug_trace.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___kdebug_trace64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___kdebug_trace_string.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___kill.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___lchown.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___listen.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___lseek.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___lstat64_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___lstat_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_execve.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_get_fd.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_get_file.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_get_link.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_get_mount.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_get_pid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_get_proc.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_getfsstat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_mount.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_set_fd.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_set_file.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_set_link.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_set_proc.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mac_syscall.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___microstackshot.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mkdir_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mkfifo_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mmap.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___mprotect.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___msgctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___msgrcv_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___msgsnd_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___msgsys.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___msync.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___msync_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___munmap.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___old_semwait_signal.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___open.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___open_dprotected_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___open_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___open_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___openat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___openat_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___persona.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pipe.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___poll_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___posix_spawn.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pread_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___proc_info.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___process_policy.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pselect.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pselect_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_cvbroad.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_cvclrprepost.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_cvsignal.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_cvwait.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_mutexdrop.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_mutexwait.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_rw_downgrade.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_rw_longrdlock.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_rw_rdlock.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_rw_unlock.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_rw_unlock2.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_rw_upgrade.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_rw_wrlock.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___psynch_rw_yieldwrlock.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pthread_canceled.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pthread_chdir.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pthread_fchdir.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pthread_kill.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pthread_markcancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pthread_sigmask.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___ptrace.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___pwrite_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___read_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___readv_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___recvfrom.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___recvfrom_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___recvmsg.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___recvmsg_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___rename.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___renameat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___rmdir.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___select.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___select_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sem_open.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sem_wait_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___semctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___semsys.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___semwait_signal.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___semwait_signal_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sendmsg.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sendmsg_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sendto.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sendto_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___setattrlist.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___setlogin.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___setpriority.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___setregid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___setreuid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___setrlimit.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___setsgroups.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___settid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___settid_with_pid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___settimeofday.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___setwgroups.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sfi_ctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sfi_pidctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___shared_region_check_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___shared_region_map_and_slide_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___shm_open.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___shmctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___shmsys.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sigaction.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sigaltstack.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sigsuspend.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sigsuspend_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sigwait.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___socketpair.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___stack_snapshot_with_config.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___stat64_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___stat_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___syscall.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sysctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___sysctlbyname.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___telemetry.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___umask_extended.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___unlink.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___unlinkat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___vfork.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___wait4.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___wait4_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___waitid_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___work_interval_ctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___workq_kernreturn.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___workq_open.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___write_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/___writev_nocancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_access.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_acct.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_adjtime.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_aio_cancel.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_aio_error.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_aio_fsync.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_aio_read.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_aio_return.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_aio_suspend.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_aio_write.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_audit.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_audit_session_join.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_audit_session_port.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_audit_session_self.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_auditctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_auditon.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_change_fdguard_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_chdir.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_chflags.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_chown.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_chroot.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_close.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_connectx.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_csops.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_csops_audittoken.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_disconnectx.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_dup.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_dup2.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_exchangedata.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_execve.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_faccessat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fchdir.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fchflags.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fchmodat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fchown.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fchownat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fdatasync.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_ffsctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fgetattrlist.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fgetxattr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fhopen.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fileport_makefd.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fileport_makeport.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_flistxattr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_flock.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fpathconf.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fremovexattr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fsctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fsetattrlist.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fsetxattr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fstat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fstat64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fstatat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fstatat64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fstatfs.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fstatfs64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_fsync.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_ftruncate.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_futimes.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getattrlistat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getattrlistbulk.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getaudit_addr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getauid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getdirentries.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getdirentriesattr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getdtablesize.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getegid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_geteuid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getfh.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getfsstat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getfsstat64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getgid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getgroups.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getitimer.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getpgid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getpgrp.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getppid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getpriority.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getrusage.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getsid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getsockopt.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getuid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_getxattr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_grab_pgo_data.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_guarded_close_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_guarded_kqueue_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_guarded_pwrite_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_guarded_write_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_guarded_writev_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_issetugid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_kas_info.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_kevent.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_kevent64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_kevent_qos.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_kqueue.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_ledger.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_link.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_linkat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_lio_listio.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_listxattr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_lstat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_lstat64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_madvise.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_memorystatus_control.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_memorystatus_get_level.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_mincore.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_minherit.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_mkdir.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_mkdirat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_mkfifo.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_mknod.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_mlock.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_mlockall.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_modwatch.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_mount.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_mremap_encrypted.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_msgget.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_msgrcv.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_msgsnd.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_munlock.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_munlockall.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_necp_match_policy.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_netagent_trigger.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_nfsclnt.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_nfssvc.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_openbyid_np.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_pathconf.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_peeloff.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_pid_resume.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_pid_suspend.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_poll.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_pread.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_proc_rlimit_control.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_proc_trace_log.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_proc_uuid_policy.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_pwrite.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_quotactl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_read.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_readlink.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_readlinkat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_readv.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_reboot.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_recvmsg_x.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_removexattr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_revoke.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_searchfs.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sem_close.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sem_post.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sem_trywait.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sem_unlink.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sem_wait.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_semget.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_semop.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sendfile.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sendmsg_x.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setaudit_addr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setauid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setegid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_seteuid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setgid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setgroups.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setitimer.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setpgid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setprivexec.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setsid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setsockopt.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setuid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_setxattr.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_shm_unlink.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_shmat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_shmdt.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_shmget.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_shutdown.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sigpending.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sigprocmask.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_socket.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_socket_delegate.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_stat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_stat64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_statfs.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_statfs64.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_swapon.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_symlink.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_symlinkat.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_sync.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_system_override.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_truncate.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_umask.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_undelete.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_unmount.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_usrctl.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_utimes.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_vfs_purge.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_vm_pressure_monitor.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_waitevent.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_waitid.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_watchevent.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_write.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/_writev.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/custom.S delete mode 100644 src/kernel/libsyscall/sys_x86-64/stubs.list create mode 100644 src/kernel/libsyscall/wrappers/cancelable/pselect-darwinext-cancel.c create mode 100644 src/kernel/libsyscall/wrappers/cancelable/pselect-darwinext.c create mode 100644 src/kernel/libsyscall/wrappers/clonefile.c create mode 100644 src/kernel/libsyscall/wrappers/fs_snapshot.c create mode 100644 src/kernel/libsyscall/wrappers/kdebug_trace.c create mode 100644 src/kernel/libsyscall/wrappers/mach_boottime.c create mode 100644 src/kernel/libsyscall/wrappers/mach_continuous_time.c create mode 100644 src/kernel/libsyscall/wrappers/mach_get_times.c create mode 100644 src/kernel/libsyscall/wrappers/mach_timebase_info.c create mode 100644 src/kernel/libsyscall/wrappers/persona.c create mode 100644 src/kernel/libsyscall/wrappers/quota_obsolete.c delete mode 100644 src/kernel/libsyscall/wrappers/rename_ext.c create mode 100644 src/kernel/libsyscall/wrappers/renamex.c create mode 100644 src/kernel/libsyscall/wrappers/stackshot.c create mode 100644 src/kernel/libsyscall/wrappers/terminate_with_reason.c create mode 100644 src/kernel/libsyscall/wrappers/thread_register_state.c create mode 100644 src/kernel/libsyscall/wrappers/work_interval.c create mode 100644 src/libc/.gitignore create mode 100644 src/libc/.upstream_base_commits delete mode 100644 src/libc/Libc.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 src/libc/Platforms/appletvos/Makefile.inc create mode 100644 src/libc/Platforms/bridgeos/Makefile.inc create mode 100644 src/libc/Platforms/watchos/Makefile.inc delete mode 100644 src/libc/arm/gen/cpu_number.s delete mode 100644 src/libc/arm/pthreads/init_cpu_capabilities.c delete mode 100644 src/libc/arm/pthreads/pthread_getspecific.s delete mode 100644 src/libc/arm/pthreads/pthread_self.s delete mode 100644 src/libc/arm/pthreads/pthread_set_self.s delete mode 100644 src/libc/arm/pthreads/start_wqthread.s delete mode 100644 src/libc/arm/pthreads/thread_start.s delete mode 100644 src/libc/arm/string/bcopy_CortexA8.s delete mode 100644 src/libc/arm/string/bcopy_CortexA9.s delete mode 100644 src/libc/arm/string/bcopy_Generic.s delete mode 100644 src/libc/arm/string/bcopy_Swift.s delete mode 100644 src/libc/arm/string/bzero_CortexA8.s delete mode 100644 src/libc/arm/string/bzero_CortexA9.s delete mode 100644 src/libc/arm/string/bzero_Generic.s delete mode 100644 src/libc/arm/string/bzero_Swift.s delete mode 100644 src/libc/arm/string/dyld_resolvers.c delete mode 100644 src/libc/arm/string/ffs.s delete mode 100644 src/libc/arm/string/memcmp.s delete mode 100755 src/libc/arm/string/memset_pattern.s delete mode 100644 src/libc/arm/string/memset_pattern_Swift.s delete mode 100644 src/libc/arm/string/strchr.s delete mode 100644 src/libc/arm/string/strcmp.s delete mode 100644 src/libc/arm/string/strlen.s delete mode 100644 src/libc/arm/string/strncmp.s delete mode 100644 src/libc/arm/string/strnlen.s delete mode 100644 src/libc/arm/string/strstr.s delete mode 100644 src/libc/arm/sys/OSAtomic-v4.c delete mode 100644 src/libc/arm/sys/OSAtomic.c delete mode 100644 src/libc/arm/sys/OSAtomic.h delete mode 100644 src/libc/arm/sys/OSAtomicUP.c delete mode 100644 src/libc/arm/sys/OSAtomic_resolvers.c delete mode 100644 src/libc/arm/sys/OSAtomic_resolvers.h delete mode 100644 src/libc/arm/sys/Spinlocks.c delete mode 100644 src/libc/arm/sys/SpinlocksUP.c delete mode 100644 src/libc/arm/sys/SpinlocksWFE.c delete mode 100644 src/libc/arm/sys/arm_commpage_gettimeofday.c delete mode 100644 src/libc/arm/sys/gcc_atomic.c delete mode 100644 src/libc/arm/sys/longjmp.s delete mode 100644 src/libc/arm/sys/mach_absolute_time.s delete mode 100644 src/libc/arm/sys/setjmp.s delete mode 100644 src/libc/darwin/OSAtomicLoadStoreEx.c delete mode 100644 src/libc/darwin/SpinlocksLoadStoreEx.c delete mode 100644 src/libc/darwin/_dirhelper.c create mode 100644 src/libc/darwin/atexit_receipt.c create mode 100644 src/libc/darwin/compatibility_hacks.c delete mode 100644 src/libc/darwin/dirhelper.defs delete mode 100644 src/libc/darwin/dirhelper_priv.h create mode 100644 src/libc/darwin/init_cpu_capabilities.c create mode 100644 src/libc/darwin/libc_private.h delete mode 100644 src/libc/darwin/libproc.c delete mode 100644 src/libc/darwin/libproc.h delete mode 100644 src/libc/darwin/libproc_internal.h delete mode 100644 src/libc/darwin/proc_listpidspath.c create mode 100644 src/libc/derived/i386/libc-features.h create mode 100644 src/libc/derived/libc-features.h create mode 100644 src/libc/derived/x86_64/libc-features.h delete mode 100644 src/libc/fbsdcompat/libc_private.h create mode 100644 src/libc/gen/FreeBSD/arc4random.c.orig delete mode 100644 src/libc/gen/FreeBSD/pselect.3 delete mode 100644 src/libc/gen/FreeBSD/pselect.c delete mode 100644 src/libc/gen/FreeBSD/raise.c create mode 100644 src/libc/gen/FreeBSD/wordexp.3 create mode 100644 src/libc/gen/FreeBSD/wordexp.c create mode 100644 src/libc/gen/NetBSD/rb.c create mode 100644 src/libc/gen/NetBSD/rbtree.3 delete mode 100644 src/libc/gen/_simple.c delete mode 100644 src/libc/gen/asl.3 delete mode 100644 src/libc/gen/asl.c delete mode 100644 src/libc/gen/asl_core.c delete mode 100644 src/libc/gen/asl_core.h delete mode 100644 src/libc/gen/asl_fd.c delete mode 100644 src/libc/gen/asl_file.c delete mode 100644 src/libc/gen/asl_file.h delete mode 100644 src/libc/gen/asl_ipc.defs delete mode 100644 src/libc/gen/asl_legacy1.c delete mode 100644 src/libc/gen/asl_legacy1.h delete mode 100644 src/libc/gen/asl_msg.c delete mode 100644 src/libc/gen/asl_msg.h delete mode 100644 src/libc/gen/asl_private.h delete mode 100644 src/libc/gen/asl_store.c delete mode 100644 src/libc/gen/asl_store.h delete mode 100644 src/libc/gen/asl_util.c delete mode 100644 src/libc/gen/assumes.c delete mode 100644 src/libc/gen/assumes.h create mode 100644 src/libc/gen/clock_gettime.3 create mode 100644 src/libc/gen/clock_gettime.c delete mode 100644 src/libc/gen/isinf.c delete mode 100644 src/libc/gen/isnan.c delete mode 100644 src/libc/gen/magazine_malloc.c delete mode 100644 src/libc/gen/magmallocProvider.d delete mode 100644 src/libc/gen/malloc.3 delete mode 100644 src/libc/gen/malloc.c delete mode 100644 src/libc/gen/malloc_printf.h delete mode 100644 src/libc/gen/malloc_size.3 delete mode 100644 src/libc/gen/malloc_zone_malloc.3 delete mode 100644 src/libc/gen/platfunc.c delete mode 100644 src/libc/gen/platfunc.h create mode 100644 src/libc/gen/raise.c delete mode 100644 src/libc/gen/scalable_malloc.c delete mode 100644 src/libc/gen/scalable_malloc.h delete mode 100644 src/libc/gen/stack_logging.c delete mode 100644 src/libc/gen/stack_logging.h delete mode 100644 src/libc/gen/stack_logging_disk.c delete mode 100644 src/libc/gen/syslog.3 delete mode 100644 src/libc/gen/syslog.c delete mode 100644 src/libc/gen/wordexp.3 delete mode 100644 src/libc/gen/wordexp.c delete mode 100644 src/libc/i386/gen/_ctx_start.S delete mode 100644 src/libc/i386/gen/_setcontext.S delete mode 100644 src/libc/i386/gen/cpu_number.S delete mode 100644 src/libc/i386/gen/getcontext.S delete mode 100644 src/libc/i386/gen/getmcontext.c delete mode 100644 src/libc/i386/gen/icacheinval.S delete mode 100644 src/libc/i386/gen/makecontext.c delete mode 100644 src/libc/i386/gen/setcontext.c delete mode 100644 src/libc/i386/gen/setjmperr.c delete mode 100644 src/libc/i386/gen/swapcontext.c delete mode 100644 src/libc/i386/pthreads/init_cpu_capabilities.c delete mode 100644 src/libc/i386/pthreads/preempt.S delete mode 100644 src/libc/i386/pthreads/pthread_getspecific.S delete mode 100644 src/libc/i386/pthreads/pthread_mutex_lock.S delete mode 100644 src/libc/i386/pthreads/pthread_self.S delete mode 100644 src/libc/i386/pthreads/pthread_set_self.S delete mode 100644 src/libc/i386/pthreads/start_wqthread.S delete mode 100644 src/libc/i386/pthreads/thread_start.S delete mode 100644 src/libc/i386/string/__bzero.S delete mode 100644 src/libc/i386/string/bcopy.c delete mode 100644 src/libc/i386/string/bcopy_scalar.S delete mode 100644 src/libc/i386/string/bcopy_sse2.S delete mode 100644 src/libc/i386/string/bcopy_sse3x.S delete mode 100644 src/libc/i386/string/bcopy_sse42.S delete mode 100644 src/libc/i386/string/bzero.c delete mode 100644 src/libc/i386/string/bzero_scalar.S delete mode 100644 src/libc/i386/string/bzero_sse2.S delete mode 100644 src/libc/i386/string/bzero_sse42.S delete mode 100644 src/libc/i386/string/ffs.S delete mode 100644 src/libc/i386/string/longcopy_sse3x.S delete mode 100644 src/libc/i386/string/memcmp.S delete mode 100644 src/libc/i386/string/memcpy.c delete mode 100644 src/libc/i386/string/memmove.c delete mode 100644 src/libc/i386/string/memset.S delete mode 100644 src/libc/i386/string/memset_pattern_sse2.S delete mode 100644 src/libc/i386/string/strcmp.S delete mode 100644 src/libc/i386/string/strncmp.S delete mode 100644 src/libc/i386/sys/OSAtomic.S delete mode 100644 src/libc/i386/sys/_sigtramp.S delete mode 100644 src/libc/i386/sys/atomic.c delete mode 100644 src/libc/i386/sys/i386_gettimeofday_asm.S delete mode 100644 src/libc/i386/sys/mach_absolute_time.c delete mode 100644 src/libc/i386/sys/mach_absolute_time_asm.S delete mode 100644 src/libc/i386/sys/setjmp.S delete mode 100644 src/libc/i386/sys/spinlocks.c delete mode 100644 src/libc/i386/sys/spinlocks_asm.S delete mode 100644 src/libc/include/CrashReporterClient.h delete mode 100644 src/libc/include/NSSystemDirectories.h delete mode 100644 src/libc/include/_structs.h create mode 100644 src/libc/include/_types/_intmax_t.h create mode 100644 src/libc/include/_types/_nl_item.h create mode 100644 src/libc/include/_types/_uint16_t.h create mode 100644 src/libc/include/_types/_uint32_t.h create mode 100644 src/libc/include/_types/_uint64_t.h create mode 100644 src/libc/include/_types/_uint8_t.h create mode 100644 src/libc/include/_types/_uintmax_t.h create mode 100644 src/libc/include/_types/_wctrans_t.h create mode 100644 src/libc/include/_types/_wctype_t.h create mode 100644 src/libc/include/arpa/inet.h delete mode 100644 src/libc/include/asl.h delete mode 100644 src/libc/include/i386/libc-features.h delete mode 100644 src/libc/include/libc-features.h delete mode 100644 src/libc/include/libkern/OSAtomic.h delete mode 100644 src/libc/include/libkern/OSMemoryNotification.h delete mode 100644 src/libc/include/malloc/malloc.h create mode 100644 src/libc/include/printf.h create mode 120000 src/libc/include/pthread_spinlock.h delete mode 100644 src/libc/include/spawn_private.h create mode 100644 src/libc/include/sys/rbtree.h delete mode 100644 src/libc/include/x86-64/libc-features.h create mode 100644 src/libc/man/FreeBSD/environ.7 delete mode 100644 src/libc/man/environ.7 delete mode 100644 src/libc/net/rcmdsh.3 delete mode 100644 src/libc/os/activity.h delete mode 100644 src/libc/os/alloc_once_impl.c delete mode 100644 src/libc/os/alloc_once_impl.h mode change 100644 => 120000 src/libc/os/alloc_once_private.h delete mode 100644 src/libc/os/availability.h delete mode 100644 src/libc/os/base_private.h mode change 100644 => 120000 src/libc/os/object.h create mode 100644 src/libc/os/overflow.h delete mode 100644 src/libc/platform/CMakeLists.txt delete mode 100644 src/libc/platform/OSAtomic.c delete mode 100644 src/libc/platform/TODO delete mode 100644 src/libc/pthreads/CMakeLists.txt delete mode 100644 src/libc/pthreads/mk_pthread_impl.c delete mode 100644 src/libc/pthreads/plockstat.d delete mode 100644 src/libc/pthreads/posix_sched.h delete mode 100644 src/libc/pthreads/pthread.3 delete mode 100644 src/libc/pthreads/pthread.c delete mode 100644 src/libc/pthreads/pthread.h delete mode 100644 src/libc/pthreads/pthread_atfork.3 delete mode 100644 src/libc/pthreads/pthread_attr.3 delete mode 100644 src/libc/pthreads/pthread_attr_init_destroy.3 delete mode 100644 src/libc/pthreads/pthread_attr_set_getdetachstate.3 delete mode 100644 src/libc/pthreads/pthread_attr_set_getinheritsched.3 delete mode 100644 src/libc/pthreads/pthread_attr_set_getschedparam.3 delete mode 100644 src/libc/pthreads/pthread_attr_set_getschedpolicy.3 delete mode 100644 src/libc/pthreads/pthread_attr_set_getscope.3 delete mode 100644 src/libc/pthreads/pthread_attr_set_getstackaddr.3 delete mode 100644 src/libc/pthreads/pthread_attr_set_getstacksize.3 delete mode 100644 src/libc/pthreads/pthread_cancel.3 delete mode 100644 src/libc/pthreads/pthread_cancelable.c delete mode 100644 src/libc/pthreads/pthread_cleanup_pop.3 delete mode 100644 src/libc/pthreads/pthread_cleanup_push.3 delete mode 100644 src/libc/pthreads/pthread_cond.c delete mode 100644 src/libc/pthreads/pthread_cond_broadcast.3 delete mode 100644 src/libc/pthreads/pthread_cond_destroy.3 delete mode 100644 src/libc/pthreads/pthread_cond_init.3 delete mode 100644 src/libc/pthreads/pthread_cond_signal.3 delete mode 100644 src/libc/pthreads/pthread_cond_timedwait.3 delete mode 100644 src/libc/pthreads/pthread_cond_wait.3 delete mode 100644 src/libc/pthreads/pthread_condattr.3 delete mode 100644 src/libc/pthreads/pthread_create.3 delete mode 100644 src/libc/pthreads/pthread_detach.3 delete mode 100644 src/libc/pthreads/pthread_equal.3 delete mode 100644 src/libc/pthreads/pthread_exit.3 delete mode 100644 src/libc/pthreads/pthread_getschedparam.3 delete mode 100644 src/libc/pthreads/pthread_getspecific.3 delete mode 100644 src/libc/pthreads/pthread_impl.h delete mode 100644 src/libc/pthreads/pthread_internals.h delete mode 100644 src/libc/pthreads/pthread_join.3 delete mode 100644 src/libc/pthreads/pthread_key_create.3 delete mode 100644 src/libc/pthreads/pthread_key_delete.3 delete mode 100644 src/libc/pthreads/pthread_machdep.h delete mode 100644 src/libc/pthreads/pthread_mutex.c delete mode 100644 src/libc/pthreads/pthread_mutex_destroy.3 delete mode 100644 src/libc/pthreads/pthread_mutex_init.3 delete mode 100644 src/libc/pthreads/pthread_mutex_lock.3 delete mode 100644 src/libc/pthreads/pthread_mutex_trylock.3 delete mode 100644 src/libc/pthreads/pthread_mutex_unlock.3 delete mode 100644 src/libc/pthreads/pthread_mutexattr.3 delete mode 100644 src/libc/pthreads/pthread_once.3 delete mode 100644 src/libc/pthreads/pthread_rwlock.c delete mode 100644 src/libc/pthreads/pthread_rwlock_destroy.3 delete mode 100644 src/libc/pthreads/pthread_rwlock_init.3 delete mode 100644 src/libc/pthreads/pthread_rwlock_rdlock.3 delete mode 100644 src/libc/pthreads/pthread_rwlock_unlock.3 delete mode 100644 src/libc/pthreads/pthread_rwlock_wrlock.3 delete mode 100644 src/libc/pthreads/pthread_rwlockattr_destroy.3 delete mode 100644 src/libc/pthreads/pthread_rwlockattr_getpshared.3 delete mode 100644 src/libc/pthreads/pthread_rwlockattr_init.3 delete mode 100644 src/libc/pthreads/pthread_rwlockattr_setpshared.3 delete mode 100644 src/libc/pthreads/pthread_self.3 delete mode 100644 src/libc/pthreads/pthread_setcancelstate.3 delete mode 100644 src/libc/pthreads/pthread_setspecific.3 delete mode 100644 src/libc/pthreads/pthread_spinlock.h delete mode 100644 src/libc/pthreads/pthread_spis.h delete mode 100644 src/libc/pthreads/pthread_tsd.c delete mode 100644 src/libc/pthreads/pthread_workqueue.h delete mode 100644 src/libc/pthreads/sched.h delete mode 100644 src/libc/pthreads/stack.s delete mode 100644 src/libc/pthreads/tests/Makefile delete mode 100644 src/libc/pthreads/tests/pthread_atfork_test.c delete mode 100644 src/libc/pthreads/thread_setup.c create mode 100644 src/libc/regex/TRE/tre-0.8.0.tar.bz2 delete mode 100644 src/libc/secure/secure.c create mode 100644 src/libc/stdio/FreeBSD/xprintf.c create mode 100644 src/libc/stdio/FreeBSD/xprintf_errno.c create mode 100644 src/libc/stdio/FreeBSD/xprintf_float.c create mode 100644 src/libc/stdio/FreeBSD/xprintf_hexdump.c create mode 100644 src/libc/stdio/FreeBSD/xprintf_int.c create mode 100644 src/libc/stdio/FreeBSD/xprintf_private.h create mode 100644 src/libc/stdio/FreeBSD/xprintf_quote.c create mode 100644 src/libc/stdio/FreeBSD/xprintf_str.c create mode 100644 src/libc/stdio/FreeBSD/xprintf_time.c create mode 100644 src/libc/stdio/FreeBSD/xprintf_vis.c create mode 100644 src/libc/stdio/xprintf.3 create mode 100644 src/libc/stdio/xprintf.5 create mode 100644 src/libc/stdio/xprintf_all_in_one.c create mode 100644 src/libc/stdio/xprintf_comp.3 create mode 100644 src/libc/stdio/xprintf_comp.c create mode 100644 src/libc/stdio/xprintf_domain.3 create mode 100644 src/libc/stdio/xprintf_domain.c create mode 100644 src/libc/stdio/xprintf_domain.h create mode 100644 src/libc/stdio/xprintf_exec.3 create mode 100644 src/libc/stdio/xprintf_exec.c mode change 120000 => 100644 src/libc/stdlib/FreeBSD/psort_b.c mode change 120000 => 100644 src/libc/stdlib/FreeBSD/psort_r.c delete mode 100644 src/libc/string/FreeBSD/bcmp.c delete mode 100644 src/libc/string/FreeBSD/bcopy.c delete mode 100644 src/libc/string/FreeBSD/bzero.c delete mode 100644 src/libc/string/FreeBSD/memccpy.c delete mode 100644 src/libc/string/FreeBSD/memcpy.c delete mode 100644 src/libc/string/FreeBSD/memmove.c delete mode 100644 src/libc/string/FreeBSD/memset.c delete mode 100644 src/libc/string/FreeBSD/strchr.c delete mode 100644 src/libc/string/FreeBSD/strcspn.3 create mode 100644 src/libc/string/FreeBSD/timingsafe_bcmp.3 create mode 100644 src/libc/string/FreeBSD/timingsafe_bcmp.c create mode 100644 src/libc/string/NetBSD/memset_s.3 create mode 100644 src/libc/string/NetBSD/memset_s.c create mode 100644 src/libc/string/bcopy.c delete mode 100644 src/libc/string/memset_pattern.c delete mode 100644 src/libc/sys/CLIB-LIST delete mode 100644 src/libc/sys/MISSING-MANPAGE delete mode 100644 src/libc/sys/MISSING_SYSCALLS delete mode 100644 src/libc/sys/REQUIRED-MACROS delete mode 100644 src/libc/sys/SYSCALL-LIST delete mode 100644 src/libc/sys/__libc_init.c create mode 100644 src/libc/sys/_libc_init.c delete mode 100644 src/libc/sys/atomic.3 delete mode 100644 src/libc/sys/barrier.3 delete mode 100644 src/libc/sys/context-stubs.c delete mode 100644 src/libc/sys/errno.c delete mode 100644 src/libc/sys/getiopolicy_np.3 delete mode 100644 src/libc/sys/getiopolicy_np.c delete mode 100644 src/libc/sys/pthread_kill.2 delete mode 100644 src/libc/sys/pthread_sigmask.2 delete mode 100644 src/libc/sys/sigcatch.c delete mode 100644 src/libc/sys/sigcatch.h delete mode 100644 src/libc/sys/sigtramp.c delete mode 100644 src/libc/sys/slot_name.c delete mode 100644 src/libc/sys/spinlock.3 delete mode 100644 src/libc/threads/CMakeLists.txt delete mode 100644 src/libc/threads/cprocs.c delete mode 100644 src/libc/threads/cthread_internals.h delete mode 100644 src/libc/threads/cthreads.c delete mode 100644 src/libc/threads/cthreads.h delete mode 100644 src/libc/threads/mig_support.c delete mode 100644 src/libc/x86_64/gen/_ctx_start.S delete mode 100644 src/libc/x86_64/gen/_setcontext.S delete mode 100644 src/libc/x86_64/gen/cpu_number.S delete mode 100644 src/libc/x86_64/gen/getcontext.S delete mode 100644 src/libc/x86_64/gen/getmcontext.c delete mode 100644 src/libc/x86_64/gen/icacheinval.S delete mode 100644 src/libc/x86_64/gen/makecontext.c delete mode 100644 src/libc/x86_64/gen/setcontext.c delete mode 100644 src/libc/x86_64/gen/setjmperr.c delete mode 100644 src/libc/x86_64/gen/swapcontext.c delete mode 100644 src/libc/x86_64/pthreads/preempt.S delete mode 100644 src/libc/x86_64/pthreads/pthread_getspecific.S delete mode 100644 src/libc/x86_64/pthreads/pthread_mutex_lock.S delete mode 100644 src/libc/x86_64/pthreads/pthread_self.S delete mode 100644 src/libc/x86_64/pthreads/pthread_set_self.S delete mode 100644 src/libc/x86_64/pthreads/start_wqthread.S delete mode 100644 src/libc/x86_64/pthreads/thread_start.S delete mode 100644 src/libc/x86_64/string/__bzero.S delete mode 100644 src/libc/x86_64/string/bcopy.c delete mode 100644 src/libc/x86_64/string/bcopy_sse3x.S delete mode 100644 src/libc/x86_64/string/bcopy_sse42.S delete mode 100644 src/libc/x86_64/string/bzero.c delete mode 100644 src/libc/x86_64/string/bzero_sse2.S delete mode 100644 src/libc/x86_64/string/bzero_sse42.S delete mode 100644 src/libc/x86_64/string/ffs.S delete mode 100644 src/libc/x86_64/string/longcopy_sse3x.S delete mode 100644 src/libc/x86_64/string/memcmp.S delete mode 100644 src/libc/x86_64/string/memcpy.c delete mode 100644 src/libc/x86_64/string/memmove.c delete mode 100644 src/libc/x86_64/string/memset.S delete mode 100644 src/libc/x86_64/string/strcmp.S delete mode 100644 src/libc/x86_64/string/strlcat.S delete mode 100644 src/libc/x86_64/string/strlcpy.S delete mode 100644 src/libc/x86_64/string/strncmp.S create mode 100644 src/libc/x86_64/string/strnlen.S delete mode 100644 src/libc/x86_64/sys/OSAtomic.S delete mode 100644 src/libc/x86_64/sys/_sigtramp.S delete mode 100644 src/libc/x86_64/sys/atomic.c delete mode 100644 src/libc/x86_64/sys/i386_gettimeofday_asm.S delete mode 100644 src/libc/x86_64/sys/nanotime.S delete mode 100644 src/libc/x86_64/sys/setjmp.S delete mode 100644 src/libc/x86_64/sys/spinlocks.c delete mode 100644 src/libc/x86_64/sys/spinlocks_asm.S create mode 100644 src/libc/xcodescripts/Libc.order create mode 100755 src/libc/xcodescripts/abort_unsupported.sh create mode 100644 src/libc/xcodescripts/alias.list delete mode 100644 src/libc/xcodescripts/clean_simulator.sh create mode 100644 src/libc/xcodescripts/eos.xcconfig mode change 100644 => 100755 src/libc/xcodescripts/headers.sh create mode 100644 src/libc/xcodescripts/libc_static.xcconfig delete mode 100644 src/libc/xcodescripts/mig_headers.sh create mode 100755 src/libc/xcodescripts/sim-compat-symlink.sh create mode 100644 src/libc/xcodescripts/skip_installhdrs.sh create mode 100644 src/libmalloc/.clang-format create mode 100644 src/libmalloc/.gitignore create mode 100644 src/libmalloc/private/malloc_private.h create mode 100644 src/libmalloc/private/stack_logging.h create mode 100644 src/libmalloc/src/base.h create mode 100644 src/libmalloc/src/debug.h create mode 100644 src/libmalloc/src/empty.s create mode 100644 src/libmalloc/src/frozen_malloc.c create mode 100644 src/libmalloc/src/frozen_malloc.h create mode 100644 src/libmalloc/src/internal.h create mode 100644 src/libmalloc/src/legacy_malloc.c create mode 100644 src/libmalloc/src/legacy_malloc.h create mode 100644 src/libmalloc/src/locking.h create mode 100644 src/libmalloc/src/magazine_inline.h create mode 100644 src/libmalloc/src/magazine_large.c create mode 100644 src/libmalloc/src/magazine_lite.c create mode 100644 src/libmalloc/src/magazine_malloc.h create mode 100644 src/libmalloc/src/magazine_small.c create mode 100644 src/libmalloc/src/magazine_tiny.c create mode 100644 src/libmalloc/src/magazine_zone.h delete mode 100644 src/libmalloc/src/malloc_internal.h delete mode 100644 src/libmalloc/src/malloc_printf.h create mode 100644 src/libmalloc/src/nano_malloc.h create mode 100644 src/libmalloc/src/nano_zone.h create mode 100644 src/libmalloc/src/platform.h create mode 100644 src/libmalloc/src/printf.h create mode 100644 src/libmalloc/src/purgeable_malloc.c create mode 100644 src/libmalloc/src/purgeable_malloc.h delete mode 100644 src/libmalloc/src/scalable_malloc.h delete mode 100644 src/libmalloc/src/stack_logging.c delete mode 100644 src/libmalloc/src/stack_logging.h create mode 100644 src/libmalloc/src/stack_logging_internal.h create mode 100644 src/libmalloc/src/thresholds.h create mode 100644 src/libmalloc/src/trace.h create mode 100644 src/libmalloc/xcodeconfig/interposable.list create mode 100644 src/libmalloc/xcodeconfig/libmalloc_static.xcconfig create mode 100644 src/libmalloc/xcodescripts/install-codes.sh create mode 100755 src/libmalloc/xcodescripts/reindent.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 95dee8333..11f2dc3bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,21 +15,21 @@ if (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "i686|i386") message(FATAL_ERROR "This software can only be built on x86-64 systems") endif (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "i686|i386") -if (NOT BITS) - message(FATAL_ERROR "BITS is not specified (32/64)") -endif (NOT BITS) +#if (NOT BITS) +# message(FATAL_ERROR "BITS is not specified (32/64)") +#endif (NOT BITS) -SET(IGNORED_WARNINGS "") +SET(IGNORED_WARNINGS "-Wno-nullability-completeness") if (${CMAKE_C_COMPILER_ID} STREQUAL "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS "3.9") SET(IGNORED_WARNINGS "${IGNORED_WARNINGS} -Wno-expansion-to-defined") endif (${CMAKE_C_COMPILER_ID} STREQUAL "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS "3.9") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m${BITS} ${IGNORED_WARNINGS}") -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m${BITS} ${IGNORED_WARNINGS}") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${IGNORED_WARNINGS}") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${IGNORED_WARNINGS}") -SET(CMAKE_ASM_FLAGS "-m${BITS}") -SET(CMAKE_ASM-ATT_FLAGS "-m${BITS}") +#SET(CMAKE_ASM_FLAGS "-m${BITS}") +#SET(CMAKE_ASM-ATT_FLAGS "-m${BITS}") message(STATUS "Building for ${CMAKE_SYSTEM_PROCESSOR}, CFLAGS: ${CMAKE_C_FLAGS}, libdir: ${CMAKE_INSTALL_LIBDIR}") @@ -47,7 +47,7 @@ if (BITS EQUAL 32) else() set(SUFFIX "64") - add_definitions(-DTARGET_CPU_X86_64=1 -D__LITTLE_ENDIAN__) + #add_definitions(-DTARGET_CPU_X86_64=1 -D__LITTLE_ENDIAN__) endif() diff --git a/cmake/darling_lib.cmake b/cmake/darling_lib.cmake index cfaa6cf73..c5ed4fe7c 100644 --- a/cmake/darling_lib.cmake +++ b/cmake/darling_lib.cmake @@ -29,3 +29,10 @@ FUNCTION(add_darling_library name) use_ld64(${name}) ENDFUNCTION(add_darling_library) +FUNCTION(make_fat) + set_property(TARGET ${ARGV} APPEND_STRING PROPERTY + LINK_FLAGS " -arch i386 -arch x86_64") + set_property(TARGET ${ARGV} APPEND_STRING PROPERTY + COMPILE_FLAGS " -B ${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/misc/ -arch i386 -arch x86_64") +ENDFUNCTION(make_fat) + diff --git a/cmake/use_ld64.cmake b/cmake/use_ld64.cmake index 5b67b987f..1400c049c 100644 --- a/cmake/use_ld64.cmake +++ b/cmake/use_ld64.cmake @@ -1,6 +1,8 @@ FUNCTION(use_ld64 target) set_property(TARGET ${target} APPEND_STRING PROPERTY - LINK_FLAGS " -B ${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/ld64/src/ -target x86_64-apple-darwin11 \ + LINK_FLAGS " -B ${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/ld64/src/ \ + -B ${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/misc/ \ + -target x86_64-apple-darwin11 \ -Wl,-dylib_file,/usr/lib/system/libsystem_c.dylib:${CMAKE_BINARY_DIR}/src/libc/libsystem_c.dylib \ -Wl,-dylib_file,/usr/lib/system/libsystem_kernel.dylib:${CMAKE_BINARY_DIR}/src/kernel/libsystem_kernel.dylib \ -Wl,-dylib_file,/usr/lib/system/libunwind.dylib:${CMAKE_BINARY_DIR}/src/libunwind/libunwind.dylib \ diff --git a/kernel-include/i386/cpu_capabilities.h b/kernel-include/i386/cpu_capabilities.h index de6d31e54..868e1b4fd 100644 --- a/kernel-include/i386/cpu_capabilities.h +++ b/kernel-include/i386/cpu_capabilities.h @@ -57,28 +57,39 @@ #define kSlow 0x00004000 /* tsc < nanosecond */ #define kUP 0x00008000 /* set if (kNumCPUs == 1) */ #define kNumCPUs 0x00FF0000 /* number of CPUs (see _NumCPUs() below) */ +#define kNumCPUsShift 16 #define kHasAVX1_0 0x01000000 #define kHasRDRAND 0x02000000 #define kHasF16C 0x04000000 #define kHasENFSTRG 0x08000000 -#define kNumCPUsShift 16 /* see _NumCPUs() below */ +#define kHasFMA 0x10000000 +#define kHasAVX2_0 0x20000000 +#define kHasBMI1 0x40000000 +#define kHasBMI2 0x80000000 +/* Extending into 64-bits from here: */ +#define kHasRTM 0x0000000100000000ULL +#define kHasHLE 0x0000000200000000ULL +#define kHasRDSEED 0x0000000800000000ULL +#define kHasADX 0x0000000400000000ULL +#define kHasMPX 0x0000001000000000ULL +#define kHasSGX 0x0000002000000000ULL + #ifndef __ASSEMBLER__ #include __BEGIN_DECLS -extern int _get_cpu_capabilities( void ); +extern uint64_t _get_cpu_capabilities( void ); __END_DECLS -inline static +__inline static int _NumCPUs( void ) { - return (_get_cpu_capabilities() & kNumCPUs) >> kNumCPUsShift; + return (int) (_get_cpu_capabilities() & kNumCPUs) >> kNumCPUsShift; } #endif /* __ASSEMBLER__ */ -#ifndef DARLING /* The following macro is used to generate the 64-bit commpage address for a given * routine, based on its 32-bit address. This is used in the kernel to compile * the 64-bit commpage. Since the kernel can be a 32-bit object, cpu_capabilities.h @@ -152,13 +163,16 @@ int _NumCPUs( void ) /* data in the comm page */ -#define _COMM_PAGE_SIGNATURE (_COMM_PAGE_START_ADDRESS+0x000) /* first few bytes are a signature */ +#define _COMM_PAGE_SIGNATURE (_COMM_PAGE_START_ADDRESS+0x000) /* first 16 bytes are a signature */ +#define _COMM_PAGE_SIGNATURELEN (0x10) +#define _COMM_PAGE_CPU_CAPABILITIES64 (_COMM_PAGE_START_ADDRESS+0x010) /* uint64_t _cpu_capabilities */ +#define _COMM_PAGE_UNUSED (_COMM_PAGE_START_ADDRESS+0x018) /* 6 unused bytes */ #define _COMM_PAGE_VERSION (_COMM_PAGE_START_ADDRESS+0x01E) /* 16-bit version# */ -#define _COMM_PAGE_THIS_VERSION 12 /* version of the commarea format */ +#define _COMM_PAGE_THIS_VERSION 13 /* in ver 13, _COMM_PAGE_NT_SHIFT defaults to 0 (was 32) */ -#define _COMM_PAGE_CPU_CAPABILITIES (_COMM_PAGE_START_ADDRESS+0x020) /* uint32_t _cpu_capabilities */ +#define _COMM_PAGE_CPU_CAPABILITIES (_COMM_PAGE_START_ADDRESS+0x020) /* uint32_t _cpu_capabilities (retained for compatibility) */ #define _COMM_PAGE_NCPUS (_COMM_PAGE_START_ADDRESS+0x022) /* uint8_t number of configured CPUs (hw.logicalcpu at boot time) */ -#define _COMM_PAGE_UNUSED0 (_COMM_PAGE_START_ADDRESS+0x024) /* 2 unused bytes, reserved for future expansion of cpu_capabilities */ +#define _COMM_PAGE_UNUSED0 (_COMM_PAGE_START_ADDRESS+0x024) /* 2 unused bytes, previouly reserved for expansion of cpu_capabilities */ #define _COMM_PAGE_CACHE_LINESIZE (_COMM_PAGE_START_ADDRESS+0x026) /* uint16_t cache line size */ #define _COMM_PAGE_SCHED_GEN (_COMM_PAGE_START_ADDRESS+0x028) /* uint32_t scheduler generation number (count of pre-emptions) */ @@ -172,7 +186,10 @@ int _NumCPUs( void ) #define _COMM_PAGE_MEMORY_SIZE (_COMM_PAGE_START_ADDRESS+0x038) /* uint64_t max memory size */ #define _COMM_PAGE_CPUFAMILY (_COMM_PAGE_START_ADDRESS+0x040) /* uint32_t hw.cpufamily, x86*/ -#define _COMM_PAGE_UNUSED2 (_COMM_PAGE_START_ADDRESS+0x044) /* [0x44,0x50) unused */ +#define _COMM_PAGE_KDEBUG_ENABLE (_COMM_PAGE_START_ADDRESS+0x044) /* uint32_t export "kdebug_enable" to userspace */ +#define _COMM_PAGE_ATM_DIAGNOSTIC_CONFIG (_COMM_PAGE_START_ADDRESS+0x48) /* uint32_t export "atm_diagnostic_config" to userspace */ + +#define _COMM_PAGE_UNUSED2 (_COMM_PAGE_START_ADDRESS+0x04C) /* [0x4C,0x50) unused */ #define _COMM_PAGE_TIME_DATA_START (_COMM_PAGE_START_ADDRESS+0x050) /* base of offsets below (_NT_SCALE etc) */ #define _COMM_PAGE_NT_TSC_BASE (_COMM_PAGE_START_ADDRESS+0x050) /* used by nanotime() */ @@ -183,6 +200,14 @@ int _NumCPUs( void ) #define _COMM_PAGE_GTOD_GENERATION (_COMM_PAGE_START_ADDRESS+0x06c) /* used by gettimeofday() */ #define _COMM_PAGE_GTOD_NS_BASE (_COMM_PAGE_START_ADDRESS+0x070) /* used by gettimeofday() */ #define _COMM_PAGE_GTOD_SEC_BASE (_COMM_PAGE_START_ADDRESS+0x078) /* used by gettimeofday() */ + +/* NOTE: APPROX_TIME must be aligned to 64-byte cache line size: */ +#define _COMM_PAGE_APPROX_TIME (_COMM_PAGE_START_ADDRESS+0x080) /* used by mach_approximate_time() */ +#define _COMM_PAGE_APPROX_TIME_SUPPORTED (_COMM_PAGE_START_ADDRESS+0x088) /* used by mach_approximate_time() */ + +/* Align following entries to next cache line */ +#define _COMM_PAGE_CONT_TIMEBASE (_COMM_PAGE_START_ADDRESS+0x0C0) /* used by mach_continuous_time() */ +#define _COMM_PAGE_BOOTTIME_USEC (_COMM_PAGE_START_ADDRESS+0x0C8) /* uint64_t boottime */ #define _COMM_PAGE_END (_COMM_PAGE_START_ADDRESS+0xfff) /* end of common page */ @@ -219,7 +244,6 @@ int _NumCPUs( void ) #define _COMM_TEXT_PFZ_START_OFFSET (0xc00) /* offset for Preemption Free Zone */ #define _COMM_TEXT_PFZ_ENQUEUE_OFFSET (0xc00) /* internal FIFO enqueue */ #define _COMM_TEXT_PFZ_DEQUEUE_OFFSET (0xc80) /* internal FIFO dequeue */ -#define _COMM_TEXT_PFZ_MUTEX_LOCK_OFFSET (0xd00) /* internal pthread_mutex_lock() */ #define _COMM_TEXT_UNUSED_OFFSET (0xd80) /* end of routines in text page */ #define _COMM_TEXT_PFZ_END_OFFSET (0xfff) /* offset for end of PFZ */ @@ -231,7 +255,6 @@ int _NumCPUs( void ) #define _COMM_PAGE_PFZ_ENQUEUE (_COMM_PAGE_TEXT_START+_COMM_TEXT_PFZ_ENQUEUE_OFFSET) #define _COMM_PAGE_PFZ_DEQUEUE (_COMM_PAGE_TEXT_START+_COMM_TEXT_PFZ_DEQUEUE_OFFSET) -#define _COMM_PAGE_PFZ_MUTEX_LOCK (_COMM_PAGE_TEXT_START+_COMM_TEXT_PFZ_MUTEX_LOCK_OFFSET) #define _COMM_PAGE_UNUSED6 (_COMM_PAGE_TEXT_START+_COMM_TEXT_UNUSED_OFFSET) #define _COMM_PAGE_PFZ_END (_COMM_PAGE_TEXT_START+_COMM_TEXT_PFZ_END_OFFSET) @@ -256,7 +279,6 @@ symbol_name: nop CREATE_COMM_PAGE_SYMBOL(___backoff, _COMM_PAGE_BACKOFF) CREATE_COMM_PAGE_SYMBOL(___pfz_enqueue, _COMM_PAGE_PFZ_ENQUEUE) CREATE_COMM_PAGE_SYMBOL(___pfz_dequeue, _COMM_PAGE_PFZ_DEQUEUE) - CREATE_COMM_PAGE_SYMBOL(___pfz_mutex_lock, _COMM_PAGE_PFZ_MUTEX_LOCK) CREATE_COMM_PAGE_SYMBOL(___end_comm_page, _COMM_PAGE_END) .data /* Required to make a well behaved symbol file */ @@ -265,9 +287,5 @@ symbol_name: nop #endif /* __COMM_PAGE_SYMBOLS */ #endif /* __ASSEMBLER__ */ -#else -# include -#endif /* DARLING */ - #endif /* _I386_CPU_CAPABILITIES_H */ #endif /* PRIVATE */ diff --git a/kernel-include/sys/event.h b/kernel-include/sys/event.h index d22d5efb2..8e43692bd 100644 --- a/kernel-include/sys/event.h +++ b/kernel-include/sys/event.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2012 Apple Inc. All rights reserved. + * Copyright (c) 2003-2016 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -75,9 +75,11 @@ #ifdef PRIVATE #define EVFILT_SOCK (-13) /* Socket events */ +#define EVFILT_MEMORYSTATUS (-14) /* Memorystatus events */ #endif /* PRIVATE */ +#define EVFILT_EXCEPT (-15) /* Exception events */ -#define EVFILT_SYSCOUNT 13 +#define EVFILT_SYSCOUNT 15 #define EVFILT_THREADMARKER EVFILT_SYSCOUNT /* Internal use only */ #pragma pack(4) @@ -108,7 +110,19 @@ struct user32_kevent { uint16_t flags; /* general flags */ uint32_t fflags; /* filter-specific flags */ int32_t data; /* filter-specific data */ - user32_addr_t udata; /* opaque user data identifier */ + user32_addr_t udata; /* opaque user data identifier */ +}; + +struct kevent_internal_s { + uint64_t ident; /* identifier for this event */ + int16_t filter; /* filter for event */ + uint16_t flags; /* general flags */ + int32_t qos; /* quality of service */ + uint32_t fflags; /* filter-specific flags */ +// uint32_t xflags; /* extra filter-specific flags */ + int64_t data; /* filter-specific data */ + uint64_t udata; /* opaque user data identifier */ + uint64_t ext[4]; /* filter-specific extensions */ }; #endif @@ -125,6 +139,20 @@ struct kevent64_s { uint64_t ext[2]; /* filter-specific extensions */ }; +#ifdef PRIVATE +struct kevent_qos_s { + uint64_t ident; /* identifier for this event */ + int16_t filter; /* filter for event */ + uint16_t flags; /* general flags */ + int32_t qos; /* quality of service */ + uint64_t udata; /* opaque user data identifier */ + uint32_t fflags; /* filter-specific flags */ + uint32_t xflags; /* extra filter-specific flags */ + int64_t data; /* filter-specific data */ + uint64_t ext[4]; /* filter-specific extensions */ +}; +#endif /* PRIVATE */ + #define EV_SET(kevp, a, b, c, d, e, f) do { \ struct kevent *__kevp__ = (kevp); \ __kevp__->ident = (a); \ @@ -147,45 +175,121 @@ struct kevent64_s { __kevp__->ext[1] = (h); \ } while(0) + +/* kevent system call flags */ +#define KEVENT_FLAG_NONE 0x000 /* no flag value */ +#define KEVENT_FLAG_IMMEDIATE 0x001 /* immediate timeout */ +#define KEVENT_FLAG_ERROR_EVENTS 0x002 /* output events only include change errors */ + +#ifdef PRIVATE + +/* + * Rather than provide an EV_SET_QOS macro for kevent_qos_t structure + * initialization, we encourage use of named field initialization support + * instead. + */ + +#define KEVENT_FLAG_STACK_EVENTS 0x004 /* output events treated as stack (grows down) */ +#define KEVENT_FLAG_STACK_DATA 0x008 /* output data allocated as stack (grows down) */ +#define KEVENT_FLAG_WORKQ 0x020 /* interact with the default workq kq */ +#define KEVENT_FLAG_WORKQ_MANAGER 0x200 /* current thread is the workq manager */ + +#ifdef XNU_KERNEL_PRIVATE + +#define KEVENT_FLAG_LEGACY32 0x040 /* event data in legacy 32-bit format */ +#define KEVENT_FLAG_LEGACY64 0x080 /* event data in legacy 64-bit format */ +#define KEVENT_FLAG_KERNEL 0x100 /* caller is in-kernel */ +#define KEVENT_FLAG_USER (KEVENT_FLAG_IMMEDIATE | KEVENT_FLAG_ERROR_EVENTS | \ + KEVENT_FLAG_STACK_EVENTS | KEVENT_FLAG_STACK_DATA | \ + KEVENT_FLAG_WORKQ) + +/* + * Since some filter ops are not part of the standard sysfilt_ops, we + * use kn_filtid starting from EVFILT_SYSCOUNT to identify these cases. + * This is to let kn_fops() get the correct fops for all cases. +*/ +#define EVFILTID_KQREAD (EVFILT_SYSCOUNT) +#define EVFILTID_PIPE_R (EVFILT_SYSCOUNT + 1) +#define EVFILTID_PIPE_W (EVFILT_SYSCOUNT + 2) +#define EVFILTID_PTSD (EVFILT_SYSCOUNT + 3) +#define EVFILTID_SOREAD (EVFILT_SYSCOUNT + 4) +#define EVFILTID_SOWRITE (EVFILT_SYSCOUNT + 5) +#define EVFILTID_SCK (EVFILT_SYSCOUNT + 6) +#define EVFILTID_SOEXCEPT (EVFILT_SYSCOUNT + 7) +#define EVFILTID_SPEC (EVFILT_SYSCOUNT + 8) +#define EVFILTID_BPFREAD (EVFILT_SYSCOUNT + 9) +#define EVFILTID_NECP_FD (EVFILT_SYSCOUNT + 10) +#define EVFILTID_FSEVENT (EVFILT_SYSCOUNT + 13) +#define EVFILTID_VN (EVFILT_SYSCOUNT + 14) + +#define EVFILTID_MAX (EVFILT_SYSCOUNT + 15) + +#endif /* XNU_KERNEL_PRIVATE */ + +#define EV_SET_QOS 0 + +#endif /* PRIVATE */ + /* actions */ -#define EV_ADD 0x0001 /* add event to kq (implies enable) */ -#define EV_DELETE 0x0002 /* delete event from kq */ -#define EV_ENABLE 0x0004 /* enable event */ -#define EV_DISABLE 0x0008 /* disable event (not reported) */ -#define EV_RECEIPT 0x0040 /* force EV_ERROR on success, data == 0 */ +#define EV_ADD 0x0001 /* add event to kq (implies enable) */ +#define EV_DELETE 0x0002 /* delete event from kq */ +#define EV_ENABLE 0x0004 /* enable event */ +#define EV_DISABLE 0x0008 /* disable event (not reported) */ /* flags */ -#define EV_ONESHOT 0x0010 /* only report one occurrence */ -#define EV_CLEAR 0x0020 /* clear event state after reporting */ -#define EV_DISPATCH 0x0080 /* disable event after reporting */ +#define EV_ONESHOT 0x0010 /* only report one occurrence */ +#define EV_CLEAR 0x0020 /* clear event state after reporting */ +#define EV_RECEIPT 0x0040 /* force immediate event output */ + /* ... with or without EV_ERROR */ + /* ... use KEVENT_FLAG_ERROR_EVENTS */ + /* on syscalls supporting flags */ + +#define EV_DISPATCH 0x0080 /* disable event after reporting */ +#define EV_UDATA_SPECIFIC 0x0100 /* unique kevent per udata value */ -#define EV_SYSFLAGS 0xF000 /* reserved by system */ -#define EV_FLAG0 0x1000 /* filter-specific flag */ -#define EV_FLAG1 0x2000 /* filter-specific flag */ +#define EV_DISPATCH2 (EV_DISPATCH | EV_UDATA_SPECIFIC) + /* ... in combination with EV_DELETE */ + /* will defer delete until udata-specific */ + /* event enabled. EINPROGRESS will be */ + /* returned to indicate the deferral */ + +#define EV_VANISHED 0x0200 /* report that source has vanished */ + /* ... only valid with EV_DISPATCH2 */ + +#define EV_SYSFLAGS 0xF000 /* reserved by system */ +#define EV_FLAG0 0x1000 /* filter-specific flag */ +#define EV_FLAG1 0x2000 /* filter-specific flag */ /* returned values */ -#define EV_EOF 0x8000 /* EOF detected */ -#define EV_ERROR 0x4000 /* error, data contains errno */ +#define EV_EOF 0x8000 /* EOF detected */ +#define EV_ERROR 0x4000 /* error, data contains errno */ /* * Filter specific flags for EVFILT_READ * * The default behavior for EVFILT_READ is to make the "read" determination - * relative to the current file descriptor read pointer. The EV_POLL - * flag indicates the determination should be made via poll(2) semantics - * (which always returns true for regular files - regardless of the amount - * of unread data in the file). + * relative to the current file descriptor read pointer. + * + * The EV_POLL flag indicates the determination should be made via poll(2) + * semantics. These semantics dictate always returning true for regular files, + * regardless of the amount of unread data in the file. * - * On input, EV_OOBAND specifies that only OOB data should be looked for. - * The returned data count is the number of bytes beyond the current OOB marker. + * On input, EV_OOBAND specifies that filter should actively return in the + * presence of OOB on the descriptor. It implies that filter will return + * if there is OOB data available to read OR when any other condition + * for the read are met (for example number of bytes regular data becomes >= + * low-watermark). + * If EV_OOBAND is not set on input, it implies that the filter should not actively + * return for out of band data on the descriptor. The filter will then only return + * when some other condition for read is met (ex: when number of regular data bytes + * >=low-watermark OR when socket can't receive more data (SS_CANTRCVMORE)). * - * On output, EV_OOBAND indicates that OOB data is present + * On output, EV_OOBAND indicates the presence of OOB data on the descriptor. * If it was not specified as an input parameter, then the data count is the - * number of bytes before the current OOB marker. If at the marker, the - * data count indicates the number of bytes available after it. In either - * case, it's the amount of data one could expect to receive next. + * number of bytes before the current OOB marker, else data count is the number + * of bytes beyond OOB marker. */ -#define EV_POLL EV_FLAG0 +#define EV_POLL EV_FLAG0 #define EV_OOBAND EV_FLAG1 /* @@ -218,6 +322,10 @@ struct kevent64_s { * realtive to the current file descriptor read pointer. */ #define NOTE_LOWAT 0x00000001 /* low water mark */ + +/* data/hint flags for EVFILT_EXCEPT, shared with userspace */ +#define NOTE_OOB 0x00000002 /* OOB data */ + /* * data/hint fflags for EVFILT_VNODE, shared with userspace */ @@ -229,6 +337,7 @@ struct kevent64_s { #define NOTE_RENAME 0x00000020 /* vnode was renamed */ #define NOTE_REVOKE 0x00000040 /* vnode access was revoked */ #define NOTE_NONE 0x00000080 /* No specific vnode event: to test for EVFILT_READ activation*/ +#define NOTE_FUNLOCK 0x00000100 /* vnode was unlocked by flock(2) */ /* * data/hint fflags for EVFILT_PROC, shared with userspace @@ -237,30 +346,56 @@ struct kevent64_s { * that hangs off the proc structure. They also both play games with the hint * passed to KNOTE(). If NOTE_SIGNAL is passed as a hint, then the lower bits * of the hint contain the signal. IF NOTE_FORK is passed, then the lower bits - * contain the PID of the child. + * contain the PID of the child (but the pid does not get passed through in + * the actual kevent). */ -#define NOTE_EXIT 0x80000000 /* process exited */ -#define NOTE_FORK 0x40000000 /* process forked */ -#define NOTE_EXEC 0x20000000 /* process exec'd */ -#define NOTE_REAP 0x10000000 /* process reaped */ -#define NOTE_SIGNAL 0x08000000 /* shared with EVFILT_SIGNAL */ -#define NOTE_EXITSTATUS 0x04000000 /* exit status to be returned, valid for child process only */ -#define NOTE_RESOURCEEND 0x02000000 /* resource limit reached, resource type returned */ - -#if CONFIG_EMBEDDED -/* 0x01000000 is reserved for future use */ - -/* App states notification */ -#define NOTE_APPACTIVE 0x00800000 /* app went to active state */ -#define NOTE_APPBACKGROUND 0x00400000 /* app went to background */ -#define NOTE_APPNONUI 0x00200000 /* app went to active with no UI */ -#define NOTE_APPINACTIVE 0x00100000 /* app went to inactive state */ -#define NOTE_APPALLSTATES 0x00f00000 -#endif /* CONFIG_EMBEDDED */ - -#define NOTE_PDATAMASK 0x000fffff /* mask for pid/signal */ +enum { + eNoteReapDeprecated __deprecated_enum_msg("This kqueue(2) EVFILT_PROC flag is deprecated") = 0x10000000 +}; + +#define NOTE_EXIT 0x80000000 /* process exited */ +#define NOTE_FORK 0x40000000 /* process forked */ +#define NOTE_EXEC 0x20000000 /* process exec'd */ +#define NOTE_REAP ((unsigned int)eNoteReapDeprecated /* 0x10000000 */) /* process reaped */ +#define NOTE_SIGNAL 0x08000000 /* shared with EVFILT_SIGNAL */ +#define NOTE_EXITSTATUS 0x04000000 /* exit status to be returned, valid for child process only */ +#define NOTE_EXIT_DETAIL 0x02000000 /* provide details on reasons for exit */ + +#define NOTE_PDATAMASK 0x000fffff /* mask for signal & exit status */ #define NOTE_PCTRLMASK (~NOTE_PDATAMASK) +/* + * If NOTE_EXITSTATUS is present, provide additional info about exiting process. + */ +enum { + eNoteExitReparentedDeprecated __deprecated_enum_msg("This kqueue(2) EVFILT_PROC flag is no longer sent") = 0x00080000 +}; +#define NOTE_EXIT_REPARENTED ((unsigned int)eNoteExitReparentedDeprecated) /* exited while reparented */ + +/* + * If NOTE_EXIT_DETAIL is present, these bits indicate specific reasons for exiting. + */ +#define NOTE_EXIT_DETAIL_MASK 0x00070000 +#define NOTE_EXIT_DECRYPTFAIL 0x00010000 +#define NOTE_EXIT_MEMORY 0x00020000 +#define NOTE_EXIT_CSERROR 0x00040000 + +#ifdef PRIVATE + +/* + * If NOTE_EXIT_MEMORY is present, these bits indicate specific jetsam condition. + */ +#define NOTE_EXIT_MEMORY_DETAIL_MASK 0xfe000000 +#define NOTE_EXIT_MEMORY_VMPAGESHORTAGE 0x80000000 /* jetsam condition: lowest jetsam priority proc killed due to vm page shortage */ +#define NOTE_EXIT_MEMORY_VMTHRASHING 0x40000000 /* jetsam condition: lowest jetsam priority proc killed due to vm thrashing */ +#define NOTE_EXIT_MEMORY_HIWAT 0x20000000 /* jetsam condition: process reached its high water mark */ +#define NOTE_EXIT_MEMORY_PID 0x10000000 /* jetsam condition: special pid kill requested */ +#define NOTE_EXIT_MEMORY_IDLE 0x08000000 /* jetsam condition: idle process cleaned up */ +#define NOTE_EXIT_MEMORY_VNODE 0X04000000 /* jetsam condition: virtual node kill */ +#define NOTE_EXIT_MEMORY_FCTHRASHING 0x02000000 /* jetsam condition: lowest jetsam priority proc killed due to filecache thrashing */ + +#endif + /* * data/hint fflags for EVFILT_VM, shared with userspace. */ @@ -269,6 +404,27 @@ struct kevent64_s { #define NOTE_VM_PRESSURE_SUDDEN_TERMINATE 0x20000000 /* will quit immediately on memory pressure */ #define NOTE_VM_ERROR 0x10000000 /* there was an error */ +#ifdef PRIVATE + +/* + * data/hint fflags for EVFILT_MEMORYSTATUS, shared with userspace. + */ +#define NOTE_MEMORYSTATUS_PRESSURE_NORMAL 0x00000001 /* system memory pressure has returned to normal */ +#define NOTE_MEMORYSTATUS_PRESSURE_WARN 0x00000002 /* system memory pressure has changed to the warning state */ +#define NOTE_MEMORYSTATUS_PRESSURE_CRITICAL 0x00000004 /* system memory pressure has changed to the critical state */ +#define NOTE_MEMORYSTATUS_LOW_SWAP 0x00000008 /* system is in a low-swap state */ +#define NOTE_MEMORYSTATUS_PROC_LIMIT_WARN 0x00000010 /* process memory limit has hit a warning state */ +#define NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL 0x00000020 /* process memory limit has hit a critical state - soft limit */ + +typedef enum vm_pressure_level { + kVMPressureNormal = 0, + kVMPressureWarning = 1, + kVMPressureUrgent = 2, + kVMPressureCritical = 3, +} vm_pressure_level_t; + +#endif + /* * data/hint fflags for EVFILT_TIMER, shared with userspace. * The default is a (repeating) interval timer with the data @@ -281,6 +437,10 @@ struct kevent64_s { #define NOTE_NSECONDS 0x00000004 /* data is nanoseconds */ #define NOTE_ABSOLUTE 0x00000008 /* absolute timeout */ /* ... implicit EV_ONESHOT */ +#define NOTE_LEEWAY 0x00000010 /* ext[1] holds leeway for power aware timers */ +#define NOTE_CRITICAL 0x00000020 /* system does minimal timer coalescing */ +#define NOTE_BACKGROUND 0x00000040 /* system does maximum timer coalescing */ +#define NOTE_MACH_CONTINUOUS_TIME 0x00000080 /* use continuous time base */ #ifdef PRIVATE /* * data/hint fflags for EVFILT_SOCK, shared with userspace. @@ -295,6 +455,18 @@ struct kevent64_s { #define NOTE_SUSPEND 0x00000040 /* output queue suspended */ #define NOTE_RESUME 0x00000080 /* output queue resumed */ #define NOTE_KEEPALIVE 0x00000100 /* TCP Keepalive received */ +#define NOTE_ADAPTIVE_WTIMO 0x00000200 /* TCP adaptive write timeout */ +#define NOTE_ADAPTIVE_RTIMO 0x00000400 /* TCP adaptive read timeout */ +#define NOTE_CONNECTED 0x00000800 /* socket is connected */ +#define NOTE_DISCONNECTED 0x00001000 /* socket is disconnected */ +#define NOTE_CONNINFO_UPDATED 0x00002000 /* connection info was updated */ +#define NOTE_NOTIFY_ACK 0x00004000 /* notify acknowledgement */ + +#define EVFILT_SOCK_LEVEL_TRIGGER_MASK \ + (NOTE_READCLOSED | NOTE_WRITECLOSED | NOTE_SUSPEND | NOTE_RESUME | NOTE_CONNECTED | NOTE_DISCONNECTED) + +#define EVFILT_SOCK_ALL_MASK \ + (NOTE_CONNRESET | NOTE_READCLOSED | NOTE_WRITECLOSED | NOTE_TIMEOUT | NOTE_NOSRCADDR | NOTE_IFDENIED | NOTE_SUSPEND | NOTE_RESUME | NOTE_KEEPALIVE | NOTE_ADAPTIVE_WTIMO | NOTE_ADAPTIVE_RTIMO | NOTE_CONNECTED | NOTE_DISCONNECTED | NOTE_CONNINFO_UPDATED | NOTE_NOTIFY_ACK) #endif /* PRIVATE */ @@ -313,6 +485,19 @@ struct kevent64_s { * receive the message and the requested (or default) message trailers. In addition, * the fflags field contains the return code normally returned by mach_msg(). * + * If MACH_RCV_MSG is specified, and the ext[1] field specifies a zero length, the + * system call argument specifying an ouput area (kevent_qos) will be consulted. If + * the system call specified an output data area, the user-space address + * of the received message is carved from that provided output data area (if enough + * space remains there). The address and length of each received message is + * returned in the ext[0] and ext[1] fields (respectively) of the corresponding kevent. + * + * IF_MACH_RCV_VOUCHER_CONTENT is specified, the contents of the message voucher is + * extracted (as specified in the xflags field) and stored in ext[2] up to ext[3] + * length. If the input length is zero, and the system call provided a data area, + * the space for the voucher content is carved from the provided space and its + * address and length is returned in ext[2] and ext[3] respectively. + * * If no message receipt options were provided in the fflags field on setup, no * message is received by this call. Instead, on output, the data field simply * contains the name of the actual port detected with a message waiting. @@ -338,8 +523,9 @@ SLIST_HEAD(klist, knote); #ifdef KERNEL -#ifdef KERNEL_PRIVATE +#ifdef XNU_KERNEL_PRIVATE #include +#include #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_KQUEUE); @@ -347,64 +533,209 @@ MALLOC_DECLARE(M_KQUEUE); TAILQ_HEAD(kqtailq, knote); /* a list of "queued" events */ -struct knote { - int kn_inuse; /* inuse count */ - struct kqtailq *kn_tq; /* pointer to tail queue */ - TAILQ_ENTRY(knote) kn_tqe; /* linkage for tail queue */ - struct kqueue *kn_kq; /* which kqueue we are on */ - SLIST_ENTRY(knote) kn_link; /* linkage for search list */ - SLIST_ENTRY(knote) kn_selnext; /* klist element chain */ +/* Bit size for packed field within knote */ +#define KNOTE_KQ_BITSIZE 40 + + +/* index into various kq queues */ +typedef uint8_t kq_index_t; +typedef uint16_t kn_status_t; + +#define KN_ACTIVE 0x0001 /* event has been triggered */ +#define KN_QUEUED 0x0002 /* event is on queue */ +#define KN_DISABLED 0x0004 /* event is disabled */ +#define KN_DROPPING 0x0008 /* knote is being dropped */ +#define KN_USEWAIT 0x0010 /* wait for knote use */ +#define KN_ATTACHING 0x0020 /* event is pending attach */ +#define KN_STAYACTIVE 0x0040 /* force event to stay active */ +#define KN_DEFERDELETE 0x0080 /* defer delete until re-enabled */ +#define KN_ATTACHED 0x0100 /* currently attached to source */ +#define KN_DISPATCH 0x0200 /* disables as part of deliver */ +#define KN_UDATA_SPECIFIC 0x0400 /* udata is part of matching */ +#define KN_SUPPRESSED 0x0800 /* event is suppressed during delivery */ +#define KN_STOLENDROP 0x1000 /* someone stole the drop privilege */ +#define KN_REQVANISH 0x2000 /* requested EV_VANISH */ +#define KN_VANISHED 0x4000 /* has vanished */ + +#define KN_DISPATCH2 (KN_DISPATCH | KN_UDATA_SPECIFIC) + /* combination defines deferred-delete mode enabled */ + +struct __attribute__((__packed__)) knote { + uint16_t kn_inuse; /* inuse count */ + kn_status_t kn_status; /* status bits */ + int kn_hookid; + TAILQ_ENTRY(knote) kn_tqe; /* linkage for tail queue */ + SLIST_ENTRY(knote) kn_link; /* linkage for search list */ + SLIST_ENTRY(knote) kn_selnext; /* klist element chain */ union { - struct fileproc *p_fp; /* file data pointer */ - struct proc *p_proc; /* proc pointer */ - struct ipc_pset *p_pset; /* pset pointer */ + struct fileproc *p_fp; /* file data pointer */ + struct proc *p_proc; /* proc pointer */ + struct ipc_mqueue *p_mqueue; /* pset pointer */ } kn_ptr; - struct filterops *kn_fop; - int kn_status; /* status bits */ - int kn_sfflags; /* saved filter flags */ - struct kevent64_s kn_kevent; - void *kn_hook; - int kn_hookid; - int64_t kn_sdata; /* saved data field */ - -#define KN_ACTIVE 0x01 /* event has been triggered */ -#define KN_QUEUED 0x02 /* event is on queue */ -#define KN_DISABLED 0x04 /* event is disabled */ -#define KN_DROPPING 0x08 /* knote is being dropped */ -#define KN_USEWAIT 0x10 /* wait for knote use */ -#define KN_ATTACHING 0x20 /* event is pending attach */ -#define KN_STAYQUEUED 0x40 /* force event to stay on queue */ + uint64_t kn_req_index:4, /* requested qos index */ + kn_qos_index:4, /* in-use qos index */ + kn_qos_override:4, /* qos override index */ + kn_reserved:4, /* reserved bits */ + kn_filtid:8, /* filter id to index filter ops */ + kn_kq_packed:KNOTE_KQ_BITSIZE; /* packed pointer for kq */ + + int kn_sfflags; /* saved filter flags */ + union { + void *kn_hook; + uint64_t kn_hook_data; + }; + int64_t kn_sdata; /* saved data field */ + struct kevent_internal_s kn_kevent; #define kn_id kn_kevent.ident #define kn_filter kn_kevent.filter #define kn_flags kn_kevent.flags +#define kn_qos kn_kevent.qos +#define kn_udata kn_kevent.udata #define kn_fflags kn_kevent.fflags +#define kn_xflags kn_kevent.xflags #define kn_data kn_kevent.data -#define kn_udata kn_kevent.udata #define kn_ext kn_kevent.ext #define kn_fp kn_ptr.p_fp }; -/* Hint values for f_touch filter operation */ -#define EVENT_REGISTER 1 -#define EVENT_PROCESS 2 +static inline struct kqueue *knote_get_kq(struct knote *kn) +{ + if (!(kn->kn_kq_packed)) + return 0; + else + return (struct kqueue *)((uintptr_t)(kn->kn_kq_packed) + (uintptr_t)VM_MIN_KERNEL_AND_KEXT_ADDRESS); +} + +static inline void knote_set_kq(struct knote *kn, void *kq) +{ + if (!kq) + kn->kn_kq_packed = 0; + else { + uint64_t offset = ((uintptr_t)kq - (uintptr_t)VM_MIN_KERNEL_AND_KEXT_ADDRESS); + kn->kn_kq_packed = offset; + } +} + +struct filt_process_s { + int fp_fd; + unsigned int fp_flags; + user_addr_t fp_data_out; + user_size_t fp_data_size; + user_size_t fp_data_resid; +}; +typedef struct filt_process_s *filt_process_data_t; + +/* + * Filter operators + * + * These routines, provided by each filter, are called to attach, detach, deliver events, + * change/update filter registration and process/deliver events. They are called with the + * with a use-count referenced knote, with the kq unlocked. Here are more details: + * + * f_isfd - + * identifies if the "ident" field in the kevent structure is a file-descriptor. + * + * If so, the knote is associated with the file descriptor prior to attach and + * auto-removed when the file descriptor is closed (this latter behavior may change + * for EV_DISPATCH2 kevent types to allow delivery of events identifying unintended + * closes). + * + * Otherwise the knote is hashed by the ident and has no auto-close behavior. + * + * f_attach - + * called to attach the knote to the underlying object that will be delivering events + * through it when EV_ADD is supplied and no existing matching event is found + * + * provided a knote that is pre-attached to the fd or hashed (see above) but is + * specially marked to avoid concurrent access until the attach is complete. The + * kevent structure embedded in this knote has been filled in with a sanitized + * version of the user-supplied kevent data. However, the user-supplied filter-specific + * flags (fflags) and data fields have been moved into the knote's kn_sfflags and kn_sdata + * fields respectively. These are usually interpretted as a set of "interest" flags and + * data by each filter - to be matched against delivered events. + * + * The attach operator indicated errors by setting the EV_ERROR flog in the flags field + * embedded in the knote's kevent structure - with the specific error indicated in the + * corresponding data field. + * + * The return value indicates if the knote should already be considered "activated" at + * the time of attach (one or more of the interest events has already occured). + * + * f_detach - + * called to disassociate the knote from the underlying object delivering events + * the filter should not attempt to deliver events through this knote after this + * operation returns control to the kq system. + * + * f_event - + * if the knote() function (or KNOTE() macro) is called against a list of knotes, + * this operator will be called on each knote in the list. + * + * The "hint" parameter is completely filter-specific, but usually indicates an + * event or set of events that have occured against the source object associated + * with the list. + * + * The return value indicates if the knote should already be considered "activated" at + * the time of attach (one or more of the interest events has already occured). + * + * f_process - + * called when attempting to deliver triggered events to user-space. + * + * If the knote was previously activated, this operator will be called when a + * thread is trying to deliver events to user-space. The filter gets one last + * chance to determine if the event/events are still interesting for this knote + * (are the conditions still right to deliver an event). If so, the filter + * fills in the output kevent structure with the information to be delivered. + * + * The input context/data parameter is used during event delivery. Some + * filters allow additional data delivery as part of event delivery. This + * context field indicates if space was made available for these additional + * items and how that space is to be allocated/carved-out. + * + * The filter may set EV_CLEAR or EV_ONESHOT in the output flags field to indicate + * special post-delivery dispositions for the knote. + * + * EV_CLEAR - indicates that all matching events have been delivered. Even + * though there were events to deliver now, there will not be any + * more until some additional events are delivered to the knote + * via the f_event operator, or the interest set is changed via + * the f_touch operator. The knote can remain deactivated after + * processing this event delivery. + * + * EV_ONESHOT - indicates that this is the last event to be delivered via + * this knote. It will automatically be deleted upon delivery + * (or if in dispatch-mode, upon re-enablement after this delivery). + * + * The return value indicates if the knote has delivered an output event. + * Unless one of the special output flags was set in the output kevent, a non- + * zero return value ALSO indicates that the knote should be re-activated + * for future event processing (in case it delivers level-based or a multi-edge + * type events like message queues that already exist). + * + * NOTE: In the future, the boolean may change to an enum that allows more + * explicit indication of just delivering a current event vs delivering + * an event with more events still pending. + * + * f_peek - + * For knotes marked KN_STAYACTIVE, indicate if the knote is truly active at + * the moment (not used for event delivery, but for status checks). + */ struct filterops { int f_isfd; /* true if ident == filedescriptor */ int (*f_attach)(struct knote *kn); void (*f_detach)(struct knote *kn); int (*f_event)(struct knote *kn, long hint); - /* Optional f_touch operation, called only if !f_isfd && non-NULL */ - void (*f_touch)(struct knote *kn, struct kevent64_s *kev, long type); - /* Optional f_peek operation, called only if KN_STAYQUEUED is set */ + int (*f_touch)(struct knote *kn, struct kevent_internal_s *kev); + int (*f_process)(struct knote *kn, struct filt_process_s *data, struct kevent_internal_s *kev); unsigned (*f_peek)(struct knote *kn); }; struct proc; -struct wait_queue; +struct waitq; SLIST_HEAD(klist, knote); -extern void knote_init(void) __attribute__((section("__TEXT, initcode"))); +extern void knote_init(void); extern void klist_init(struct klist *list); #define KNOTE(list, hint) knote(list, hint) @@ -415,27 +746,68 @@ extern void klist_init(struct klist *list); extern void knote(struct klist *list, long hint); extern int knote_attach(struct klist *list, struct knote *kn); extern int knote_detach(struct klist *list, struct knote *kn); -extern int knote_link_wait_queue(struct knote *kn, struct wait_queue *wq, wait_queue_link_t wql); -extern int knote_unlink_wait_queue(struct knote *kn, struct wait_queue *wq, wait_queue_link_t *wqlp); -extern void knote_fdclose(struct proc *p, int fd); -extern void knote_markstayqueued(struct knote *kn); +extern void knote_vanish(struct klist *list); +extern int knote_link_waitq(struct knote *kn, struct waitq *wq, uint64_t *reserved_link); +extern int knote_unlink_waitq(struct knote *kn, struct waitq *wq); +extern void knote_fdclose(struct proc *p, int fd, int force); +extern void knote_markstayactive(struct knote *kn); +extern void knote_clearstayactive(struct knote *kn); +extern void knote_adjust_qos(struct knote *kn, int qos, int override); +extern struct filterops *knote_fops(struct knote *kn); -#endif /* !KERNEL_PRIVATE */ +#elif defined(KERNEL_PRIVATE) /* !XNU_KERNEL_PRIVATE: kexts still need a klist structure definition */ + +#include +struct proc; +struct knote; +SLIST_HEAD(klist, knote); + +#endif /* !XNU_KERNEL_PRIVATE && KERNEL_PRIVATE */ + +#ifdef KERNEL_PRIVATE +#ifdef PRIVATE + +/* make these private functions available to the pthread kext */ +extern int kevent_qos_internal(struct proc *p, int fd, + user_addr_t changelist, int nchanges, + user_addr_t eventlist, int nevents, + user_addr_t data_out, user_size_t *data_available, + unsigned int flags, int32_t *retval); + +extern int kevent_qos_internal_bind(struct proc *p, + int fd, thread_t thread, unsigned int flags); +extern int kevent_qos_internal_unbind(struct proc *p, + int fd, thread_t thread, unsigned int flags); + +#endif /* PRIVATE */ +#endif /* KERNEL_PRIVATE */ #else /* KERNEL */ +#include struct timespec; __BEGIN_DECLS int kqueue(void); -int kevent(int kq, const struct kevent *changelist, int nchanges, - struct kevent *eventlist, int nevents, - const struct timespec *timeout); -int kevent64(int kq, const struct kevent64_s *changelist, - int nchanges, struct kevent64_s *eventlist, - int nevents, unsigned int flags, - const struct timespec *timeout); +int kevent(int kq, + const struct kevent *changelist, int nchanges, + struct kevent *eventlist, int nevents, + const struct timespec *timeout); +int kevent64(int kq, + const struct kevent64_s *changelist, int nchanges, + struct kevent64_s *eventlist, int nevents, + unsigned int flags, + const struct timespec *timeout); + +#ifdef PRIVATE +int kevent_qos(int kq, + const struct kevent_qos_s *changelist, int nchanges, + struct kevent_qos_s *eventlist, int nevents, + void *data_out, size_t *data_available, + unsigned int flags); +#endif /* PRIVATE */ + __END_DECLS diff --git a/kernel-include/sys/msg.h b/kernel-include/sys/msg.h index 9d856a984..6f530fa66 100644 --- a/kernel-include/sys/msg.h +++ b/kernel-include/sys/msg.h @@ -74,25 +74,10 @@ * NOTE: The definition of the key_t type is implicit from the * inclusion of */ -#ifndef _PID_T -typedef __darwin_pid_t pid_t; -#define _PID_T -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef __darwin_time_t time_t; -#endif - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __darwin_ssize_t ssize_t; -#endif +#include +#include +#include +#include /* [XSI] Used for the number of messages in the message queue */ typedef unsigned long msgqnum_t; diff --git a/platform-include/mach/coalition.h b/platform-include/mach/coalition.h new file mode 100644 index 000000000..e548852dd --- /dev/null +++ b/platform-include/mach/coalition.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_COALITION_H_ +#define _MACH_COALITION_H_ + +/* code shared by userspace and xnu */ + +#define COALITION_CREATE_FLAGS_MASK ((uint32_t)0xF1) +#define COALITION_CREATE_FLAGS_PRIVILEGED ((uint32_t)0x01) + +#define COALITION_CREATE_FLAGS_TYPE_MASK ((uint32_t)0xF0) +#define COALITION_CREATE_FLAGS_TYPE_SHIFT (4) + +#define COALITION_CREATE_FLAGS_GET_TYPE(flags) \ + (((flags) & COALITION_CREATE_FLAGS_TYPE_MASK) >> COALITION_CREATE_FLAGS_TYPE_SHIFT) + +#define COALITION_CREATE_FLAGS_SET_TYPE(flags, type) \ + do { \ + flags &= ~COALITION_CREATE_FLAGS_TYPE_MASK; \ + flags |= (((type) << COALITION_CREATE_FLAGS_TYPE_SHIFT) \ + & COALITION_CREATE_FLAGS_TYPE_MASK); \ + } while (0) + + +#define COALITION_TYPE_RESOURCE (0) +#define COALITION_TYPE_JETSAM (1) +#define COALITION_TYPE_MAX (1) + +#define COALITION_NUM_TYPES (COALITION_TYPE_MAX + 1) + +#define COALITION_TASKROLE_UNDEF (0) +#define COALITION_TASKROLE_LEADER (1) +#define COALITION_TASKROLE_XPC (2) +#define COALITION_TASKROLE_EXT (3) + +#define COALITION_NUM_TASKROLES (4) + +#define COALITION_ROLEMASK_ALLROLES ((1 << COALITION_NUM_TASKROLES) - 1) +#define COALITION_ROLEMASK_UNDEF (1 << COALITION_TASKROLE_UNDEF) +#define COALITION_ROLEMASK_LEADER (1 << COALITION_TASKROLE_LEADER) +#define COALITION_ROLEMASK_XPC (1 << COALITION_TASKROLE_XPC) +#define COALITION_ROLEMASK_EXT (1 << COALITION_TASKROLE_EXT) + +#define COALITION_SORT_NOSORT (0) +#define COALITION_SORT_DEFAULT (1) +#define COALITION_SORT_MEM_ASC (2) +#define COALITION_SORT_MEM_DEC (3) +#define COALITION_SORT_USER_ASC (4) +#define COALITION_SORT_USER_DEC (5) + +#define COALITION_NUM_SORT (6) + +struct coalition_resource_usage { + uint64_t tasks_started; + uint64_t tasks_exited; + uint64_t time_nonempty; + uint64_t cpu_time; + uint64_t interrupt_wakeups; + uint64_t platform_idle_wakeups; + uint64_t bytesread; + uint64_t byteswritten; + uint64_t gpu_time; + uint64_t cpu_time_billed_to_me; + uint64_t cpu_time_billed_to_others; + uint64_t energy; + uint64_t logical_immediate_writes; + uint64_t logical_deferred_writes; + uint64_t logical_invalidated_writes; + uint64_t logical_metadata_writes; +}; + +#ifdef PRIVATE +/* definitions shared by only xnu + Libsyscall */ + +/* Syscall flavors */ +#define COALITION_OP_CREATE 1 +#define COALITION_OP_TERMINATE 2 +#define COALITION_OP_REAP 3 + +/* coalition_info flavors */ +#define COALITION_INFO_RESOURCE_USAGE 1 + +/* structure returned from libproc coalition listing interface */ +struct procinfo_coalinfo { + uint64_t coalition_id; + uint32_t coalition_type; + uint32_t coalition_tasks; +}; + +#endif /* PRIVATE */ + +#ifdef XNU_KERNEL_PRIVATE +#if COALITION_DEBUG +#define coal_dbg(fmt, ...) \ + printf("%s: " fmt "\n", __func__, ## __VA_ARGS__) +#else +#define coal_dbg(fmt, ...) +#endif + +#endif + +#endif /* _MACH_COALITION_H_ */ diff --git a/platform-include/mach/i386/syscall_sw.h b/platform-include/mach/i386/syscall_sw.h index 16a59a367..df81e959d 100644 --- a/platform-include/mach/i386/syscall_sw.h +++ b/platform-include/mach/i386/syscall_sw.h @@ -85,12 +85,7 @@ #else // DARLING #define UNIX_SYSCALL_TRAP \ - calll 1f ;\ - 1: ;\ - popl %ebx ;\ - 2: ;\ - addl $_GLOBAL_OFFSET_TABLE_+(2b-1b), %ebx ;\ - call __darling_bsd_syscall@PLT + call __darling_bsd_syscall #define MACHDEP_SYSCALL_TRAP \ ud2 diff --git a/platform-include/mach/kern_return.h b/platform-include/mach/kern_return.h index bfedcc3ec..f0fa37d27 100644 --- a/platform-include/mach/kern_return.h +++ b/platform-include/mach/kern_return.h @@ -319,6 +319,10 @@ /* The requested property cannot be changed at this time. */ +#define KERN_INSUFFICIENT_BUFFER_SIZE 52 + /* The provided buffer is of insufficient size for the requested data. + */ + #define KERN_RETURN_MAX 0x100 /* Maximum return value allowable */ diff --git a/platform-include/mach/sfi_class.h b/platform-include/mach/sfi_class.h new file mode 100644 index 000000000..8f856435b --- /dev/null +++ b/platform-include/mach/sfi_class.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_SFI_CLASS_H_ +#define _MACH_SFI_CLASS_H_ + +#include +#include + +#define SFI_CLASS_DEFINITIONS 20140526 + +/* + * SFI Classes are used to categorized threads, and map + * them to "off-time" windows. + * + * Threads classified approximately in this order, so + * there's an implicit requirement that lowest duty cycle + * (largest off-time) are a lower class, and increasing + * SFI classes increase the duty cycle (if SFI is enabled + * at all). + */ +typedef uint32_t sfi_class_id_t; + +#ifdef XNU_KERNEL_PRIVATE + +/* + * Total number of classes supported including SFI_CLASS_UNSPECIFIED. + * If new class is defined increase this number. + */ +#define MAX_SFI_CLASS_ID 0x00000011 + +/* + * Threads may initially start out unspecified + */ +#define SFI_CLASS_UNSPECIFIED 0x00000000 + +#endif /* XNU_KERNEL_PRIVATE */ + +/* + * Threads are placed in this class as a result of placing threads or + * processes in a background state using APIs such as setpriority(2), + * specifying PRIO_DARWIN_THREAD or PRIO_DARWIN_PROCESS. + */ +#define SFI_CLASS_DARWIN_BG 0x00000001 + +/* + * Threads are placed in this class as a result of an application + * entering "Nap mode". + */ +#define SFI_CLASS_APP_NAP 0x00000002 + +/* + * Threads are placed in this class by making per coalition (by + * calling coalition_set_sfi_class(cid, SFI_CLASS_MANAGED)) or per + * process selection (by calling process_set_sfi_class(pid, + * SFI_CLASS_MANAGED)). FOCAL/NONFOCAL is a function of a task's + * role. + */ +#define SFI_CLASS_MANAGED_FOCAL 0x00000003 + +#define SFI_CLASS_MANAGED_NONFOCAL 0x00000004 + +#define SFI_CLASS_MANAGED SFI_CLASS_MANAGED_FOCAL + +/* + * Coalitions/processes that have not been explicitly tagged + * and are not opted into one of the special classes below + * fall into the default categories. FOCAL/NONFOCAL is a function + * of a task's role. + */ +#define SFI_CLASS_DEFAULT_FOCAL 0x00000005 + +#define SFI_CLASS_DEFAULT_NONFOCAL 0x00000006 + +#define SFI_CLASS_DEFAULT SFI_CLASS_DEFAULT_FOCAL + +/* + * Threads that are part of the kernel task should be duty-cycled + * only as an extreme last resort, since they must be preempted + * while locks may be held in kernel mode. + */ +#define SFI_CLASS_KERNEL 0x00000007 + +/* + * Threads that must not be part of "Selective Forced Idle" are + * placed in this class. Real time threads, threads of + * processes such as WindowServer that are critical to good user + * experience, should be placed in this class. + */ +#define SFI_CLASS_OPTED_OUT 0x00000008 + +/* + * Threads running in various QOS classes + */ +#define SFI_CLASS_UTILITY 0x00000009 +#define SFI_CLASS_LEGACY_FOCAL 0x0000000A +#define SFI_CLASS_LEGACY_NONFOCAL 0x0000000B +#define SFI_CLASS_USER_INITIATED_FOCAL 0x0000000C +#define SFI_CLASS_USER_INITIATED_NONFOCAL 0x0000000D +#define SFI_CLASS_USER_INTERACTIVE_FOCAL 0x0000000E +#define SFI_CLASS_USER_INTERACTIVE_NONFOCAL 0x0000000F +#define SFI_CLASS_MAINTENANCE 0x00000010 + +/* + * Windows that are specified smaller than MIN_SFI_WINDOW_USEC + * will be automatically rounded up. + */ +#define MIN_SFI_WINDOW_USEC 500 + +#endif /* _MACH_SFI_CLASS_H_ */ diff --git a/platform-include/mach/thread_switch.h b/platform-include/mach/thread_switch.h index 3892e29af..abce09f6e 100644 --- a/platform-include/mach/thread_switch.h +++ b/platform-include/mach/thread_switch.h @@ -71,6 +71,13 @@ #define SWITCH_OPTION_NONE 0 #define SWITCH_OPTION_DEPRESS 1 #define SWITCH_OPTION_WAIT 2 +#ifdef PRIVATE +/* Workqueue should not consider thread blocked, and option_time is in us */ +#define SWITCH_OPTION_DISPATCH_CONTENTION 3 +/* Handoff to lock owner and temporarily grant matching IO throttling policy */ +#define SWITCH_OPTION_OSLOCK_DEPRESS 4 +#define SWITCH_OPTION_OSLOCK_WAIT 5 +#endif /* PRIVATE */ #define valid_switch_option(opt) (0 <= (opt) && (opt) <= 5) diff --git a/platform-include/pthread/introspection.h b/platform-include/pthread/introspection.h new file mode 100644 index 000000000..366c7baad --- /dev/null +++ b/platform-include/pthread/introspection.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __PTHREAD_INTROSPECTION__ +#define __PTHREAD_INTROSPECTION__ + +#include +#include +#include + +/*! + * @header + * + * @abstract + * Introspection API for libpthread. + * + * This should only be used for introspection and debugging tools. Do not rely + * on it in shipping code. + */ + +__BEGIN_DECLS + +/*! + * @typedef pthread_introspection_hook_t + * + * @abstract + * A function pointer called at various points in a PThread's lifetime. The + * function must be able to be called in contexts with invalid thread state. + * + * @param event + * One of the events in pthread_introspection_event_t. + * + * @param thread + * pthread_t associated with the event. + * + * @param addr + * Address associated with the event, e.g. stack address. + * + * @param size + * Size associated with the event, e.g. stack size. + */ +typedef void (*pthread_introspection_hook_t)(unsigned int event, + pthread_t thread, void *addr, size_t size); + +/*! + * @enum pthread_introspection_event_t + * + * @constant PTHREAD_INTROSPECTION_THREAD_CREATE + * pthread_t was created. + * + * @constant PTHREAD_INTROSPECTION_THREAD_START + * Thread has started and stack was allocated. + * + * @constant PTHREAD_INTROSPECTION_THREAD_TERMINATE + * Thread is about to be terminated and stack will be deallocated. + * + * @constant PTHREAD_INTROSPECTION_THREAD_DESTROY + * pthread_t is about to be destroyed. + */ +enum { + PTHREAD_INTROSPECTION_THREAD_CREATE = 1, + PTHREAD_INTROSPECTION_THREAD_START, + PTHREAD_INTROSPECTION_THREAD_TERMINATE, + PTHREAD_INTROSPECTION_THREAD_DESTROY, +}; + +/*! + * @function pthread_introspection_hook_install + * + * @abstract + * Install introspection hook function into libpthread. + * + * @discussion + * The caller is responsible for implementing chaining to the hook that was + * previously installed (if any). + * + * @param hook + * Pointer to hook function. + * + * @result + * Previously installed hook function or NULL. + */ + +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +__attribute__((__nonnull__, __warn_unused_result__)) +extern pthread_introspection_hook_t +pthread_introspection_hook_install(pthread_introspection_hook_t hook); + +__END_DECLS + +#endif diff --git a/platform-include/pthread/pthread.h b/platform-include/pthread/pthread.h index 41691767b..b0b9534be 100644 --- a/platform-include/pthread/pthread.h +++ b/platform-include/pthread/pthread.h @@ -102,6 +102,9 @@ #include #include +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull begin") +#endif __BEGIN_DECLS /* * Threads @@ -150,7 +153,6 @@ __BEGIN_DECLS #define PTHREAD_SCOPE_SYSTEM 1 #define PTHREAD_SCOPE_PROCESS 2 -/* We only support PTHREAD_PROCESS_PRIVATE */ #define PTHREAD_PROCESS_SHARED 1 #define PTHREAD_PROCESS_PRIVATE 2 @@ -187,6 +189,10 @@ __BEGIN_DECLS # endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ #endif +/* */ +#define _PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT \ + defined(SWIFT_CLASS_EXTRA) && (!defined(SWIFT_SDK_OVERLAY_PTHREAD_EPOCH) || (SWIFT_SDK_OVERLAY_PTHREAD_EPOCH < 1)) + /* * Condition variable attributes */ @@ -207,7 +213,8 @@ __BEGIN_DECLS * Prototypes for all PTHREAD interfaces */ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_atfork(void (*)(void), void (*)(void), void (*)(void)); +int pthread_atfork(void (* _Nullable)(void), void (* _Nullable)(void), + void (* _Nullable)(void)); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_attr_destroy(pthread_attr_t *); @@ -232,11 +239,12 @@ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_attr_getscope(const pthread_attr_t * __restrict, int * __restrict); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_attr_getstack(const pthread_attr_t * __restrict, void ** __restrict, - size_t * __restrict); +int pthread_attr_getstack(const pthread_attr_t * __restrict, + void * _Nullable * _Nonnull __restrict, size_t * __restrict); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_attr_getstackaddr(const pthread_attr_t * __restrict, void ** __restrict); +int pthread_attr_getstackaddr(const pthread_attr_t * __restrict, + void * _Nullable * _Nonnull __restrict); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_attr_getstacksize(const pthread_attr_t * __restrict, size_t * __restrict); @@ -282,15 +290,19 @@ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_cond_destroy(pthread_cond_t *); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_cond_init(pthread_cond_t * __restrict, - const pthread_condattr_t * __restrict) __DARWIN_ALIAS(pthread_cond_init); +int pthread_cond_init( + pthread_cond_t * __restrict, + const pthread_condattr_t * _Nullable __restrict) + __DARWIN_ALIAS(pthread_cond_init); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_cond_signal(pthread_cond_t *); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_cond_timedwait(pthread_cond_t * __restrict, pthread_mutex_t * __restrict, - const struct timespec * __restrict) __DARWIN_ALIAS_C(pthread_cond_timedwait); +int pthread_cond_timedwait( + pthread_cond_t * __restrict, pthread_mutex_t * __restrict, + const struct timespec * _Nullable __restrict) + __DARWIN_ALIAS_C(pthread_cond_timedwait); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_cond_wait(pthread_cond_t * __restrict, @@ -310,33 +322,42 @@ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_condattr_setpshared(pthread_condattr_t *, int); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_create(pthread_t * __restrict, const pthread_attr_t * __restrict, - void *(*)(void *), void * __restrict); +#if !_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT +int pthread_create(pthread_t _Nullable * _Nonnull __restrict, + const pthread_attr_t * _Nullable __restrict, + void * _Nullable (* _Nonnull)(void * _Nullable), + void * _Nullable __restrict); +#else +int pthread_create(pthread_t * __restrict, + const pthread_attr_t * _Nullable __restrict, + void *(* _Nonnull)(void *), void * _Nullable __restrict); +#endif // _PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_detach(pthread_t); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_equal(pthread_t, pthread_t); +int pthread_equal(pthread_t _Nullable, pthread_t _Nullable); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -void pthread_exit(void *) __dead2; +void pthread_exit(void * _Nullable) __dead2; __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_getconcurrency(void); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_getschedparam(pthread_t , int * __restrict, - struct sched_param * __restrict); +int pthread_getschedparam(pthread_t , int * _Nullable __restrict, + struct sched_param * _Nullable __restrict); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -void* pthread_getspecific(pthread_key_t); +void* _Nullable pthread_getspecific(pthread_key_t); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_join(pthread_t , void **) __DARWIN_ALIAS_C(pthread_join); +int pthread_join(pthread_t , void * _Nullable * _Nullable) + __DARWIN_ALIAS_C(pthread_join); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_key_create(pthread_key_t *, void (*)(void *)); +int pthread_key_create(pthread_key_t *, void (* _Nullable)(void *)); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_key_delete(pthread_key_t); @@ -350,7 +371,7 @@ int pthread_mutex_getprioceiling(const pthread_mutex_t * __restrict, __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_mutex_init(pthread_mutex_t * __restrict, - const pthread_mutexattr_t * __restrict); + const pthread_mutexattr_t * _Nullable __restrict); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_mutex_lock(pthread_mutex_t *); @@ -399,15 +420,17 @@ int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_mutexattr_settype(pthread_mutexattr_t *, int); +__SWIFT_UNAVAILABLE_MSG("Use lazily initialized globals instead") __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_once(pthread_once_t *, void (*)(void)); +int pthread_once(pthread_once_t *, void (* _Nonnull)(void)); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_rwlock_destroy(pthread_rwlock_t * ) __DARWIN_ALIAS(pthread_rwlock_destroy); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_rwlock_init(pthread_rwlock_t * __restrict, - const pthread_rwlockattr_t * __restrict) __DARWIN_ALIAS(pthread_rwlock_init); + const pthread_rwlockattr_t * _Nullable __restrict) + __DARWIN_ALIAS(pthread_rwlock_init); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_rwlock_rdlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_rdlock); @@ -441,10 +464,12 @@ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) pthread_t pthread_self(void); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_setcancelstate(int , int *) __DARWIN_ALIAS(pthread_setcancelstate); +int pthread_setcancelstate(int , int * _Nullable) + __DARWIN_ALIAS(pthread_setcancelstate); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_setcanceltype(int , int *) __DARWIN_ALIAS(pthread_setcanceltype); +int pthread_setcanceltype(int , int * _Nullable) + __DARWIN_ALIAS(pthread_setcanceltype); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_setconcurrency(int); @@ -453,7 +478,7 @@ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_setschedparam(pthread_t, int, const struct sched_param *); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_setspecific(pthread_key_t , const void *); +int pthread_setspecific(pthread_key_t , const void * _Nullable); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) void pthread_testcancel(void) __DARWIN_ALIAS(pthread_testcancel); @@ -465,7 +490,7 @@ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_is_threaded_np(void); __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2) -int pthread_threadid_np(pthread_t,__uint64_t*); +int pthread_threadid_np(pthread_t _Nullable,__uint64_t* _Nullable); /*SPI to set and get pthread name*/ __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2) @@ -490,30 +515,41 @@ void* pthread_get_stackaddr_np(pthread_t); /* Like pthread_cond_signal(), but only wake up the specified pthread */ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_cond_signal_thread_np(pthread_cond_t *, pthread_t); +int pthread_cond_signal_thread_np(pthread_cond_t *, pthread_t _Nullable); /* Like pthread_cond_timedwait, but use a relative timeout */ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_cond_timedwait_relative_np(pthread_cond_t *, pthread_mutex_t *, - const struct timespec *); + const struct timespec * _Nullable); /* Like pthread_create(), but leaves the thread suspended */ __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_create_suspended_np(pthread_t *, const pthread_attr_t *, - void *(*)(void *), void *); +#if !_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT +int pthread_create_suspended_np( + pthread_t _Nullable * _Nonnull, const pthread_attr_t * _Nullable, + void * _Nullable (* _Nonnull)(void * _Nullable), void * _Nullable); +#else +int pthread_create_suspended_np(pthread_t *, const pthread_attr_t * _Nullable, + void *(* _Nonnull)(void *), void * _Nullable); +#endif __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) int pthread_kill(pthread_t, int); __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) -pthread_t pthread_from_mach_thread_np(mach_port_t); +_Nullable pthread_t pthread_from_mach_thread_np(mach_port_t); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) -int pthread_sigmask(int, const sigset_t *, sigset_t *) __DARWIN_ALIAS(pthread_sigmask); +int pthread_sigmask(int, const sigset_t * _Nullable, sigset_t * _Nullable) + __DARWIN_ALIAS(pthread_sigmask); __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) void pthread_yield_np(void); #endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ __END_DECLS +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull end") +#endif + #endif /* _PTHREAD_H */ diff --git a/platform-include/pthread/pthread_impl.h b/platform-include/pthread/pthread_impl.h index 887b56d2c..35d32d302 100644 --- a/platform-include/pthread/pthread_impl.h +++ b/platform-include/pthread/pthread_impl.h @@ -29,6 +29,10 @@ /* This whole header file will disappear, so don't depend on it... */ +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull begin") +#endif + #ifndef __POSIX_LIB__ /* @@ -55,4 +59,8 @@ #endif /* __POSIX_LIB__ */ +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull end") +#endif + #endif /* _PTHREAD_IMPL_H_ */ diff --git a/platform-include/pthread/pthread_spis.h b/platform-include/pthread/pthread_spis.h index b76c23892..95362753a 100644 --- a/platform-include/pthread/pthread_spis.h +++ b/platform-include/pthread/pthread_spis.h @@ -46,7 +46,7 @@ */ /* - * Extension SPIs. + * Extension SPIs; installed to /usr/include. */ #ifndef _PTHREAD_SPIS_H @@ -55,6 +55,9 @@ #include +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull begin") +#endif __BEGIN_DECLS #if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) @@ -73,6 +76,34 @@ int pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *, int ); #endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ +__OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_NA) +void _pthread_mutex_enable_legacy_mode(void); + +/* + * A version of pthread_create that is safely callable from an injected mach thread. + * + * The _create introspection hook will not fire for threads created from this function. + * + * It is not safe to call this function concurrently. + */ +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) +__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +#if !_PTHREAD_SWIFT_IMPORTER_NULLABILITY_COMPAT +int pthread_create_from_mach_thread( + pthread_t _Nullable * _Nonnull __restrict, + const pthread_attr_t * _Nullable __restrict, + void * _Nullable (* _Nonnull)(void * _Nullable), + void * _Nullable __restrict); +#else +int pthread_create_from_mach_thread(pthread_t * __restrict, + const pthread_attr_t * _Nullable __restrict, + void *(* _Nonnull)(void *), void * _Nullable __restrict); +#endif + + __END_DECLS +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull end") +#endif #endif /* _PTHREAD_SPIS_H */ diff --git a/platform-include/pthread/qos.h b/platform-include/pthread/qos.h index fa0f832f7..04e6b6f3f 100644 --- a/platform-include/pthread/qos.h +++ b/platform-include/pthread/qos.h @@ -33,6 +33,9 @@ #ifndef KERNEL +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull begin") +#endif __BEGIN_DECLS /*! @@ -107,8 +110,8 @@ pthread_attr_set_qos_class_np(pthread_attr_t *__attr, __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) int pthread_attr_get_qos_class_np(pthread_attr_t * __restrict __attr, - qos_class_t * __restrict __qos_class, - int * __restrict __relative_priority); + qos_class_t * _Nullable __restrict __qos_class, + int * _Nullable __restrict __relative_priority); /*! * @function pthread_set_qos_class_self_np @@ -179,8 +182,8 @@ pthread_set_qos_class_self_np(qos_class_t __qos_class, __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) int pthread_get_qos_class_np(pthread_t __pthread, - qos_class_t * __restrict __qos_class, - int * __restrict __relative_priority); + qos_class_t * _Nullable __restrict __qos_class, + int * _Nullable __restrict __relative_priority); /*! * @typedef pthread_override_t @@ -288,6 +291,9 @@ int pthread_override_qos_class_end_np(pthread_override_t __override); __END_DECLS +#if __has_feature(assume_nonnull) +_Pragma("clang assume_nonnull end") +#endif #endif // KERNEL diff --git a/src/libc/include/spawn.h b/platform-include/spawn.h similarity index 83% rename from src/libc/include/spawn.h rename to platform-include/spawn.h index 5553b63e7..663dd3ca5 100644 --- a/src/libc/include/spawn.h +++ b/platform-include/spawn.h @@ -29,9 +29,9 @@ * [SPN] Support for _POSIX_SPAWN */ -#include +#include #include <_types.h> -#include /* shared types */ +#include /* shared types */ #include @@ -39,20 +39,9 @@ * [SPN] Inclusion of the header may make visible symbols defined * in the , , and headers. */ -#ifndef _PID_T -typedef __darwin_pid_t pid_t; -#define _PID_T -#endif - -#ifndef _SIGSET_T -#define _SIGSET_T -typedef __darwin_sigset_t sigset_t; -#endif - -#ifndef _MODE_T -typedef __darwin_mode_t mode_t; -#define _MODE_T -#endif +#include +#include +#include /* * Opaque types for use with posix_spawn() family functions. Internals are @@ -67,38 +56,72 @@ __BEGIN_DECLS * gcc under c99 mode won't compile "[ __restrict]" by itself. As a workaround, * a dummy argument name is added. */ + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn(pid_t * __restrict, const char * __restrict, const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, char *const __argv[ __restrict], char *const __envp[ __restrict]) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnp(pid_t * __restrict, const char * __restrict, const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, char *const __argv[ __restrict], char *const __envp[ __restrict]) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_addopen( posix_spawn_file_actions_t * __restrict, int, const char * __restrict, int, mode_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_init(posix_spawn_file_actions_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_destroy(posix_spawnattr_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict, sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getflags(const posix_spawnattr_t * __restrict, short * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict, pid_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict, sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_init(posix_spawnattr_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict, const sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setflags(posix_spawnattr_t *, short) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict, const sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); @@ -122,24 +145,32 @@ __END_DECLS #include #include -#ifndef _SIZE_T -typedef __darwin_size_t size_t; -#define _SIZE_T -#endif +#include __BEGIN_DECLS +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getbinpref_np(const posix_spawnattr_t * __restrict, size_t, cpu_type_t *__restrict, size_t *__restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setauditsessionport_np(posix_spawnattr_t *__restrict, mach_port_t) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict, size_t, cpu_type_t *__restrict, size_t *__restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setexceptionports_np(posix_spawnattr_t *__restrict, exception_mask_t, mach_port_t, exception_behavior_t, thread_state_flavor_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setspecialport_np(posix_spawnattr_t *__restrict, mach_port_t, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_addinherit_np(posix_spawn_file_actions_t *, int) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); diff --git a/platform-include/sys/_types/_fsobj_id_t.h b/platform-include/sys/_types/_fsobj_id_t.h new file mode 100644 index 000000000..20e1bcff9 --- /dev/null +++ b/platform-include/sys/_types/_fsobj_id_t.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifndef _FSOBJ_ID_T +#define _FSOBJ_ID_T + +typedef struct fsobj_id { + u_int32_t fid_objno; + u_int32_t fid_generation; +} fsobj_id_t; + +#endif /* _FSOBJ_ID_T */ diff --git a/platform-include/sys/attr.h b/platform-include/sys/attr.h index 20519361f..d3bf9580a 100644 --- a/platform-include/sys/attr.h +++ b/platform-include/sys/attr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2010 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -49,8 +49,14 @@ /* The following option only valid when requesting ATTR_CMN_RETURNED_ATTRS */ #define FSOPT_PACK_INVAL_ATTRS 0x00000008 +#ifdef PRIVATE +#define FSOPT_EXCHANGE_DATA_ONLY 0x0000010 +#endif #define FSOPT_ATTR_CMN_EXTENDED 0x00000020 +#ifdef PRIVATE +#define FSOPT_LIST_SNAPSHOT 0x00000040 +#endif /* PRIVATE */ /* we currently aren't anywhere near this amount for a valid * fssearchblock.sizeofsearchparams1 or fssearchblock.sizeofsearchparams2 @@ -69,10 +75,7 @@ typedef u_int32_t fsfile_type_t; typedef u_int32_t fsvolid_t; -typedef struct fsobj_id { - u_int32_t fid_objno; - u_int32_t fid_generation; -} fsobj_id_t; +#include /* file object id type */ typedef u_int32_t attrgroup_t; @@ -217,6 +220,15 @@ typedef struct vol_capabilities_attr { * only legitimate attributes for obtaining object IDs from this volume and the * 32-bit fid_objno fields of the fsobj_id_t returned by ATTR_CMN_OBJID, * ATTR_CMN_OBJPERMID, and ATTR_CMN_PAROBJID are undefined. + * + * VOL_CAP_FMT_DIR_HARDLINKS: When set, the volume supports directory + * hard links. + * + * VOL_CAP_FMT_DOCUMENT_ID: When set, the volume supports document IDs + * (an ID which persists across object ID changes) for document revisions. + * + * VOL_CAP_FMT_WRITE_GENERATION_COUNT: When set, the volume supports write + * generation counts (a count of how many times an object has been modified) */ #define VOL_CAP_FMT_PERSISTENTOBJECTIDS 0x00000001 #define VOL_CAP_FMT_SYMBOLICLINKS 0x00000002 @@ -236,6 +248,9 @@ typedef struct vol_capabilities_attr { #define VOL_CAP_FMT_NO_VOLUME_SIZES 0x00008000 #define VOL_CAP_FMT_DECMPFS_COMPRESSION 0x00010000 #define VOL_CAP_FMT_64BIT_OBJECT_IDS 0x00020000 +#define VOL_CAP_FMT_DIR_HARDLINKS 0x00040000 +#define VOL_CAP_FMT_DOCUMENT_ID 0x00080000 +#define VOL_CAP_FMT_WRITE_GENERATION_COUNT 0x00100000 /* @@ -294,6 +309,15 @@ typedef struct vol_capabilities_attr { * * VOL_CAP_INT_NAMEDSTREAMS: When set, the volume supports * native named streams. + * + * VOL_CAP_INT_CLONE: When set, the volume supports clones. + * + * VOL_CAP_INT_RENAME_SWAP: When set, the volume supports swapping + * file system objects. + * + * VOL_CAP_INT_RENAME_EXCL: When set, the volume supports an + * exclusive rename operation. + * */ #define VOL_CAP_INT_SEARCHFS 0x00000001 #define VOL_CAP_INT_ATTRLIST 0x00000002 @@ -310,6 +334,17 @@ typedef struct vol_capabilities_attr { #define VOL_CAP_INT_MANLOCK 0x00001000 #define VOL_CAP_INT_NAMEDSTREAMS 0x00002000 #define VOL_CAP_INT_EXTENDED_ATTR 0x00004000 +#ifdef PRIVATE +/* Volume supports kqueue notifications for remote events */ +#define VOL_CAP_INT_REMOTE_EVENT 0x00008000 +#endif /* PRIVATE */ +#define VOL_CAP_INT_CLONE 0x00010000 +#ifdef PRIVATE +/* Volume supports snapshots */ +#define VOL_CAP_INT_SNAPSHOT 0x00020000 +#endif /* PRIVATE */ +#define VOL_CAP_INT_RENAME_SWAP 0x00040000 +#define VOL_CAP_INT_RENAME_EXCL 0x00080000 typedef struct vol_attributes_attr { attribute_set_t validattr; @@ -366,6 +401,27 @@ typedef struct vol_attributes_attr { #define ATTR_CMN_RETURNED_ATTRS 0x80000000 #define ATTR_CMN_VALIDMASK 0xFFFFFFFF +/* + * The settable ATTR_CMN_* attributes include the following: + * ATTR_CMN_SCRIPT + * ATTR_CMN_CRTIME + * ATTR_CMN_MODTIME + * ATTR_CMN_CHGTIME + * + * ATTR_CMN_ACCTIME + * ATTR_CMN_BKUPTIME + * ATTR_CMN_FNDRINFO + * ATTR_CMN_OWNERID + * + * ATTR_CMN_GRPID + * ATTR_CMN_ACCESSMASK + * ATTR_CMN_FLAGS + * + * ATTR_CMN_EXTENDED_SECURITY + * ATTR_CMN_UUID + * + * ATTR_CMN_GRPUUID + */ #define ATTR_CMN_SETMASK 0x01C7FF00 #define ATTR_CMN_VOLSETMASK 0x00006700 @@ -392,6 +448,12 @@ typedef struct vol_attributes_attr { #define ATTR_VOL_INFO 0x80000000 #define ATTR_VOL_VALIDMASK 0xC007FFFF + +/* + * The list of settable ATTR_VOL_* attributes include the following: + * ATTR_VOL_NAME + * ATTR_VOL_INFO + */ #define ATTR_VOL_SETMASK 0x80002000 @@ -419,6 +481,10 @@ typedef struct vol_attributes_attr { #define ATTR_FILE_RSRCALLOCSIZE 0x00002000 #define ATTR_FILE_VALIDMASK 0x000037FF +/* + * Settable ATTR_FILE_* attributes include: + * ATTR_FILE_DEVTYPE + */ #define ATTR_FILE_SETMASK 0x00000020 #define ATTR_FORK_TOTALSIZE 0x00000001 @@ -466,6 +532,39 @@ struct fssearchblock { struct attrlist searchattrs; }; +#ifdef KERNEL +/* LP64 version of fssearchblock. all pointers and longs + * grow when we're dealing with a 64-bit process. + * WARNING - keep in sync with fssearchblock + */ + +struct user64_fssearchblock { + user64_addr_t returnattrs; + user64_addr_t returnbuffer; + user64_size_t returnbuffersize; + user64_ulong_t maxmatches; + struct user64_timeval timelimit; + user64_addr_t searchparams1; + user64_size_t sizeofsearchparams1; + user64_addr_t searchparams2; + user64_size_t sizeofsearchparams2; + struct attrlist searchattrs; +}; + +struct user32_fssearchblock { + user32_addr_t returnattrs; + user32_addr_t returnbuffer; + user32_size_t returnbuffersize; + user32_ulong_t maxmatches; + struct user32_timeval timelimit; + user32_addr_t searchparams1; + user32_size_t sizeofsearchparams1; + user32_addr_t searchparams2; + user32_size_t sizeofsearchparams2; + struct attrlist searchattrs; +}; + +#endif /* KERNEL */ struct searchstate { uint32_t ss_union_flags; // for SRCHFS_START diff --git a/platform-include/sys/cdefs.h b/platform-include/sys/cdefs.h index cca5e4603..522437e05 100644 --- a/platform-include/sys/cdefs.h +++ b/platform-include/sys/cdefs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2012 Apple Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -81,6 +81,26 @@ #warning "Unsupported compiler detected" #endif +/* + * Compatibility with compilers and environments that don't support compiler + * feature checking function-like macros. + */ +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif +#ifndef __has_include +#define __has_include(x) 0 +#endif +#ifndef __has_feature +#define __has_feature(x) 0 +#endif +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif +#ifndef __has_extension +#define __has_extension(x) 0 +#endif + /* * The __CONCAT macro is used to concatenate parts of symbol names, e.g. * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. @@ -155,26 +175,17 @@ */ #define __deprecated __attribute__((deprecated)) -#ifdef __has_extension - #if __has_extension(attribute_deprecated_with_message) - #define __deprecated_msg(_msg) __attribute__((deprecated(_msg))) - #else - #define __deprecated_msg(_msg) __attribute__((deprecated)) - #endif -#elif defined(__GNUC__) && ((__GNUC__ >= 5) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))) - #define __deprecated_msg(_msg) __attribute__((deprecated(_msg))) +#if __has_extension(attribute_deprecated_with_message) || \ + (defined(__GNUC__) && ((__GNUC__ >= 5) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)))) + #define __deprecated_msg(_msg) __attribute__((deprecated(_msg))) #else - #define __deprecated_msg(_msg) __attribute__((deprecated)) + #define __deprecated_msg(_msg) __attribute__((deprecated)) #endif -#ifdef __has_extension - #if __has_extension(enumerator_attributes) - #define __deprecated_enum_msg(_msg) __deprecated_msg(_msg) - #else - #define __deprecated_enum_msg(_msg) - #endif +#if __has_extension(enumerator_attributes) + #define __deprecated_enum_msg(_msg) __deprecated_msg(_msg) #else - #define __deprecated_enum_msg(_msg) + #define __deprecated_enum_msg(_msg) #endif /* __unavailable causes the compiler to error out when encountering @@ -198,6 +209,74 @@ #define __restrict restrict #endif +/* Compatibility with compilers and environments that don't support the + * nullability feature. + */ + +#if !__has_feature(nullability) +#ifndef __nullable +#define __nullable +#endif +#ifndef __nonnull +#define __nonnull +#endif +#ifndef __null_unspecified +#define __null_unspecified +#endif +#ifndef _Nullable +#define _Nullable +#endif +#ifndef _Nonnull +#define _Nonnull +#endif +#ifndef _Null_unspecified +#define _Null_unspecified +#endif +#endif + +/* + * __disable_tail_calls causes the compiler to not perform tail call + * optimization inside the marked function. + */ +#if __has_attribute(disable_tail_calls) +#define __disable_tail_calls __attribute__((__disable_tail_calls__)) +#else +#define __disable_tail_calls +#endif + +/* + * __not_tail_called causes the compiler to prevent tail call optimization + * on statically bound calls to the function. It has no effect on indirect + * calls. Virtual functions, objective-c methods, and functions marked as + * "always_inline" cannot be marked as __not_tail_called. + */ +#if __has_attribute(not_tail_called) +#define __not_tail_called __attribute__((__not_tail_called__)) +#else +#define __not_tail_called +#endif + +/* + * __result_use_check warns callers of a function that not using the function + * return value is a bug, i.e. dismissing malloc() return value results in a + * memory leak. + */ +#if __has_attribute(warn_unused_result) +#define __result_use_check __attribute__((__warn_unused_result__)) +#else +#define __result_use_check +#endif + +/* + * __swift_unavailable causes the compiler to mark a symbol as specifically + * unavailable in Swift, regardless of any other availability in C. + */ +#if __has_feature(attribute_availability_swift) +#define __swift_unavailable(_msg) __attribute__((__availability__(swift, unavailable, message=_msg))) +#else +#define __swift_unavailable(_msg) +#endif + /* Declaring inline functions within headers is error-prone due to differences * across various versions of the C language and extensions. __header_inline * can be used to declare inline functions within system headers. In cases @@ -270,6 +349,8 @@ */ #define __printflike(fmtarg, firstvararg) \ __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#define __printf0like(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf0__, fmtarg, firstvararg))) #define __scanflike(fmtarg, firstvararg) \ __attribute__((__format__ (__scanf__, fmtarg, firstvararg))) @@ -485,7 +566,6 @@ /* * symbol versioning macros */ -#ifndef DARLING__DISABLED #define __DARWIN_ALIAS(sym) __asm("_" __STRING(sym) __DARWIN_SUF_UNIX03) #define __DARWIN_ALIAS_C(sym) __asm("_" __STRING(sym) __DARWIN_SUF_NON_CANCELABLE __DARWIN_SUF_UNIX03) #define __DARWIN_ALIAS_I(sym) __asm("_" __STRING(sym) __DARWIN_SUF_64_BIT_INO_T __DARWIN_SUF_UNIX03) @@ -500,29 +580,6 @@ #define __DARWIN_EXTSN(sym) __asm("_" __STRING(sym) __DARWIN_SUF_EXTSN) #define __DARWIN_EXTSN_C(sym) __asm("_" __STRING(sym) __DARWIN_SUF_EXTSN __DARWIN_SUF_NON_CANCELABLE) -#else // DARLING -/* - * Darling doesn't use underscore prefixing for symbols just like the rest of the Linux world. - * Using prefixing causes symbol naming conflicts, i.e. the following declarations result in the same symbol name: - * * pthread_testcancel() asm("_pthread_testcancel"); - * * _pthread_testcancel() - * while on OS X, the latter would have symbol name __pthread_testcancel(). - */ -#define __DARWIN_ALIAS(sym) __asm(__STRING(sym) __DARWIN_SUF_UNIX03) -#define __DARWIN_ALIAS_C(sym) __asm(__STRING(sym) __DARWIN_SUF_NON_CANCELABLE __DARWIN_SUF_UNIX03) -#define __DARWIN_ALIAS_I(sym) __asm(__STRING(sym) __DARWIN_SUF_64_BIT_INO_T __DARWIN_SUF_UNIX03) -#define __DARWIN_NOCANCEL(sym) __asm(__STRING(sym) __DARWIN_SUF_NON_CANCELABLE) -#define __DARWIN_INODE64(sym) __asm(__STRING(sym) __DARWIN_SUF_64_BIT_INO_T) - -#define __DARWIN_1050(sym) __asm(__STRING(sym) __DARWIN_SUF_1050) -#define __DARWIN_1050ALIAS(sym) __asm(__STRING(sym) __DARWIN_SUF_1050 __DARWIN_SUF_UNIX03) -#define __DARWIN_1050ALIAS_C(sym) __asm(__STRING(sym) __DARWIN_SUF_1050 __DARWIN_SUF_NON_CANCELABLE __DARWIN_SUF_UNIX03) -#define __DARWIN_1050ALIAS_I(sym) __asm(__STRING(sym) __DARWIN_SUF_1050 __DARWIN_SUF_64_BIT_INO_T __DARWIN_SUF_UNIX03) -#define __DARWIN_1050INODE64(sym) __asm(__STRING(sym) __DARWIN_SUF_1050 __DARWIN_SUF_64_BIT_INO_T) - -#define __DARWIN_EXTSN(sym) __asm(__STRING(sym) __DARWIN_SUF_EXTSN) -#define __DARWIN_EXTSN_C(sym) __asm(__STRING(sym) __DARWIN_SUF_EXTSN __DARWIN_SUF_NON_CANCELABLE) -#endif // DARLING /* * symbol release macros @@ -534,7 +591,7 @@ #elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) #define __DARWIN_ALIAS_STARTING(_mac, _iphone, x) __DARWIN_ALIAS_STARTING_MAC_##_mac(x) #else -#define __DARWIN_ALIAS_STARTING(_mac, _iphone, x) +#define __DARWIN_ALIAS_STARTING(_mac, _iphone, x) x #endif @@ -704,4 +761,5 @@ #error Unsupported architecture #endif + #endif /* !_CDEFS_H_ */ diff --git a/platform-include/sys/clonefile.h b/platform-include/sys/clonefile.h new file mode 100644 index 000000000..17773fd3a --- /dev/null +++ b/platform-include/sys/clonefile.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015-2016 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_CLONEFILE_H_ +#define _SYS_CLONEFILE_H_ + +/* Options for clonefile calls */ +#define CLONE_NOFOLLOW 0x0001 /* Don't follow symbolic links */ + +#ifndef KERNEL + +#include +#include +#include <_types/_uint32_t.h> +#include + +__BEGIN_DECLS + +int clonefileat(int, const char *, int, const char *, uint32_t) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +int fclonefileat(int, int, const char *, uint32_t) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +int clonefile(const char *, const char *, uint32_t) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +__END_DECLS + +#endif /* KERNEL */ + +#endif /* _SYS_CLONEFILE_H_ */ diff --git a/platform-include/sys/coalition.h b/platform-include/sys/coalition.h new file mode 100644 index 000000000..cf2811c5b --- /dev/null +++ b/platform-include/sys/coalition.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_COALITION_H_ +#define _SYS_COALITION_H_ + +#include +#include +#include + +#include + +__BEGIN_DECLS + +#ifndef KERNEL +/* Userspace syscall prototypes */ + +/* Syscalls */ +int coalition_create(uint64_t *cid_out, uint32_t flags); +int coalition_terminate(uint64_t cid, uint32_t flags); +int coalition_reap(uint64_t cid, uint32_t flags); + +/* Wrappers around __coalition_info syscall (with proper struct types) */ +int coalition_info_resource_usage(uint64_t cid, struct coalition_resource_usage *cru, size_t sz); + +#else /* KERNEL */ + +#if CONFIG_COALITIONS +/* in-kernel BSD interfaces */ + +/* + * coalition_id: + * Get the unique 64-bit identifier associated with the given coalition + */ +uint64_t coalition_id(coalition_t coal); + + +/* + * coalitions_get_list: + * Get a list of coalitions as procinfo_coalinfo structures + * + * This interface is primarily to support libproc. + * + * Parameters: + * type : The COALITION_TYPE of the coalitions to investigate. + * Valid types can be found in + * coal_list : Pointer to an array of procinfo_coalinfo structures + * that will be filled with information about each + * coalition whose type matches 'type' + * NOTE: This can be NULL to perform a simple query of + * the total number of coalitions. + * list_sz : The size (in number of structures) of 'coal_list' + * + * Returns: 0 if no coalitions matching 'type' are found + * Otherwise: the number of coalitions whose type matches + * the 'type' parameter (all coalitions if type == -1) + */ +extern int coalitions_get_list(int type, struct procinfo_coalinfo *coal_list, int list_sz); + + +/* + * coalition_is_leader: + * Determine if a task is a coalition leader. + * + * Parameters: + * task : The task to investigate + * coal_type : The COALITION_TYPE of the coalition to investigate. + * Valid types can be found in + * coal : If 'task' is a valid task, and is a member of a coalition + * of type 'coal_type', then 'coal' will be filled in with + * the corresponding coalition_t object. + * NOTE: This will be filled in whether or not the 'task' is + * a leader in the coalition. However, if 'task' is + * not a member of a coalition of type 'coal_type' then + * 'coal' will be filled in with COALITION_NULL. + * NOTE: This can be NULL + * + * Returns: TRUE if 'task' is a coalition leader, FALSE otherwise. + */ +extern boolean_t coalition_is_leader(task_t task, int coal_type, coalition_t *coal); + +/* + * coalition_get_leader: + * Get a task reference on the leader of a given coalition + * + * Parameters: + * coal : The coalition to investigate + * + * Returns: A referenced task pointer of the leader of the given coalition. + * This could be TASK_NULL if the coalition doesn't have a leader. + * If the return value is non-null, the caller is responsible to call + * task_deallocate on the returned value. + */ +extern task_t coalition_get_leader(coalition_t coal); + + +/* + * coalition_get_task_count: + * Sum up the number of tasks in the given coalition + * + * Parameters: + * coal : The coalition to investigate + * + * Returns: The number of tasks in the coalition + */ +extern int coalition_get_task_count(coalition_t coal); + +/* + * coalition_get_page_count: + * Sum up the page count for each task in the coalition specified by 'coal' + * + * Parameters: + * coal : The coalition to investigate + * ntasks : If non-NULL, this will be filled in with the number of + * tasks in the coalition. + * + * Returns: The sum of all pages used by all members of the coalition + */ +extern uint64_t coalition_get_page_count(coalition_t coal, int *ntasks); + +/* + * coalition_get_pid_list: + * Gather a list of constituent PIDs of tasks within a coalition playing a + * given role. + * + * Parameters: + * coal : The coalition to investigate + * rolemask : The set of coalition task roles used to filter the list + * of PIDs returned in 'pid_list'. Roles can be combined + * using the COALITION_ROLEMASK_* tokens found in + * . Each PID returned is guaranteed to + * be tagged with one of the task roles specified by this + * mask. + * sort_order : The order in which the returned PIDs should be sorted + * by default this is in descending page count. + * pid_list : Pointer to an array of PIDs that will be filled with + * members of the coalition tagged with the given 'taskrole' + * list_sz : The size (in number of PIDs) of 'pid_list' + * + * Note: + * This function will return the list of PIDs in a sorted order. By default + * the PIDs will be sorted by task page count in descending order. In the + * future it may be possible for user space to specify a level of importance + * for each coalition member. If there is a user space specified importance, + * then the list of PIDs returned will be sorted in _ascending_ importance, + * i.e., pid_list[0] will be the least important task (or the largest consumer + * of memory). The desired sort order can be specified using the + * COALITION_SORT_* definitions in osfmk/mach/coalition.h + * + * It is also possible to return an unsorted list of PIDs using the special + * sort type 'COALITION_SORT_NOSORT' + * + * Returns: < 0 on ERROR + * 0 if 'coal' contains no tasks whose role is 'taskrole' + * (or if the coalition is being deallocated) + * Otherwise: the number of PIDs in the coalition whose role is + * 'taskrole'. NOTE: This may be larger or smaller than + * the 'pid_list' array. + * + */ +extern int coalition_get_pid_list(coalition_t coal, uint32_t rolemask, + int sort_order, int *pid_list, int list_sz); + +#else /* !CONFIG_COALITIONS */ +static inline uint64_t coalition_id(__unused coalition_t coal) +{ + return 0; +} + +static inline int coalitions_get_list(__unused int type, + __unused struct procinfo_coalinfo *coal_list, + __unused int list_sz) +{ + return 0; +} + +static inline boolean_t coalition_is_leader(__unused task_t task, + __unused int coal_type, + coalition_t *coal) +{ + *coal = COALITION_NULL; + return FALSE; +} + +static inline int coalition_get_task_count(__unused coalition_t coal) +{ + return 0; +} + +static inline uint64_t coalition_get_page_count(__unused coalition_t coal, + __unused int *ntasks) +{ + return 0; +} + +static inline int coalition_get_pid_list(__unused coalition_t coal, + __unused uint32_t rolemask, + __unused int sort_order, + __unused int *pid_list, + __unused int list_sz) +{ + return 0; +} +#endif + +#endif /* KERNEL */ + +__END_DECLS + +#endif /* _SYS_COALITION_H_ */ diff --git a/platform-include/sys/event.h b/platform-include/sys/event.h index 0744cf70b..8e43692bd 100644 --- a/platform-include/sys/event.h +++ b/platform-include/sys/event.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2012 Apple Inc. All rights reserved. + * Copyright (c) 2003-2016 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -73,8 +73,13 @@ /* (-11) unused */ #define EVFILT_VM (-12) /* Virtual memory events */ +#ifdef PRIVATE +#define EVFILT_SOCK (-13) /* Socket events */ +#define EVFILT_MEMORYSTATUS (-14) /* Memorystatus events */ +#endif /* PRIVATE */ +#define EVFILT_EXCEPT (-15) /* Exception events */ -#define EVFILT_SYSCOUNT 14 +#define EVFILT_SYSCOUNT 15 #define EVFILT_THREADMARKER EVFILT_SYSCOUNT /* Internal use only */ #pragma pack(4) @@ -88,6 +93,39 @@ struct kevent { void *udata; /* opaque user data identifier */ }; +#ifdef KERNEL_PRIVATE + +struct user64_kevent { + uint64_t ident; /* identifier for this event */ + int16_t filter; /* filter for event */ + uint16_t flags; /* general flags */ + uint32_t fflags; /* filter-specific flags */ + int64_t data; /* filter-specific data */ + user_addr_t udata; /* opaque user data identifier */ +}; + +struct user32_kevent { + uint32_t ident; /* identifier for this event */ + int16_t filter; /* filter for event */ + uint16_t flags; /* general flags */ + uint32_t fflags; /* filter-specific flags */ + int32_t data; /* filter-specific data */ + user32_addr_t udata; /* opaque user data identifier */ +}; + +struct kevent_internal_s { + uint64_t ident; /* identifier for this event */ + int16_t filter; /* filter for event */ + uint16_t flags; /* general flags */ + int32_t qos; /* quality of service */ + uint32_t fflags; /* filter-specific flags */ +// uint32_t xflags; /* extra filter-specific flags */ + int64_t data; /* filter-specific data */ + uint64_t udata; /* opaque user data identifier */ + uint64_t ext[4]; /* filter-specific extensions */ +}; + +#endif #pragma pack() @@ -101,6 +139,20 @@ struct kevent64_s { uint64_t ext[2]; /* filter-specific extensions */ }; +#ifdef PRIVATE +struct kevent_qos_s { + uint64_t ident; /* identifier for this event */ + int16_t filter; /* filter for event */ + uint16_t flags; /* general flags */ + int32_t qos; /* quality of service */ + uint64_t udata; /* opaque user data identifier */ + uint32_t fflags; /* filter-specific flags */ + uint32_t xflags; /* extra filter-specific flags */ + int64_t data; /* filter-specific data */ + uint64_t ext[4]; /* filter-specific extensions */ +}; +#endif /* PRIVATE */ + #define EV_SET(kevp, a, b, c, d, e, f) do { \ struct kevent *__kevp__ = (kevp); \ __kevp__->ident = (a); \ @@ -123,45 +175,121 @@ struct kevent64_s { __kevp__->ext[1] = (h); \ } while(0) + +/* kevent system call flags */ +#define KEVENT_FLAG_NONE 0x000 /* no flag value */ +#define KEVENT_FLAG_IMMEDIATE 0x001 /* immediate timeout */ +#define KEVENT_FLAG_ERROR_EVENTS 0x002 /* output events only include change errors */ + +#ifdef PRIVATE + +/* + * Rather than provide an EV_SET_QOS macro for kevent_qos_t structure + * initialization, we encourage use of named field initialization support + * instead. + */ + +#define KEVENT_FLAG_STACK_EVENTS 0x004 /* output events treated as stack (grows down) */ +#define KEVENT_FLAG_STACK_DATA 0x008 /* output data allocated as stack (grows down) */ +#define KEVENT_FLAG_WORKQ 0x020 /* interact with the default workq kq */ +#define KEVENT_FLAG_WORKQ_MANAGER 0x200 /* current thread is the workq manager */ + +#ifdef XNU_KERNEL_PRIVATE + +#define KEVENT_FLAG_LEGACY32 0x040 /* event data in legacy 32-bit format */ +#define KEVENT_FLAG_LEGACY64 0x080 /* event data in legacy 64-bit format */ +#define KEVENT_FLAG_KERNEL 0x100 /* caller is in-kernel */ +#define KEVENT_FLAG_USER (KEVENT_FLAG_IMMEDIATE | KEVENT_FLAG_ERROR_EVENTS | \ + KEVENT_FLAG_STACK_EVENTS | KEVENT_FLAG_STACK_DATA | \ + KEVENT_FLAG_WORKQ) + +/* + * Since some filter ops are not part of the standard sysfilt_ops, we + * use kn_filtid starting from EVFILT_SYSCOUNT to identify these cases. + * This is to let kn_fops() get the correct fops for all cases. +*/ +#define EVFILTID_KQREAD (EVFILT_SYSCOUNT) +#define EVFILTID_PIPE_R (EVFILT_SYSCOUNT + 1) +#define EVFILTID_PIPE_W (EVFILT_SYSCOUNT + 2) +#define EVFILTID_PTSD (EVFILT_SYSCOUNT + 3) +#define EVFILTID_SOREAD (EVFILT_SYSCOUNT + 4) +#define EVFILTID_SOWRITE (EVFILT_SYSCOUNT + 5) +#define EVFILTID_SCK (EVFILT_SYSCOUNT + 6) +#define EVFILTID_SOEXCEPT (EVFILT_SYSCOUNT + 7) +#define EVFILTID_SPEC (EVFILT_SYSCOUNT + 8) +#define EVFILTID_BPFREAD (EVFILT_SYSCOUNT + 9) +#define EVFILTID_NECP_FD (EVFILT_SYSCOUNT + 10) +#define EVFILTID_FSEVENT (EVFILT_SYSCOUNT + 13) +#define EVFILTID_VN (EVFILT_SYSCOUNT + 14) + +#define EVFILTID_MAX (EVFILT_SYSCOUNT + 15) + +#endif /* XNU_KERNEL_PRIVATE */ + +#define EV_SET_QOS 0 + +#endif /* PRIVATE */ + /* actions */ -#define EV_ADD 0x0001 /* add event to kq (implies enable) */ -#define EV_DELETE 0x0002 /* delete event from kq */ -#define EV_ENABLE 0x0004 /* enable event */ -#define EV_DISABLE 0x0008 /* disable event (not reported) */ -#define EV_RECEIPT 0x0040 /* force EV_ERROR on success, data == 0 */ +#define EV_ADD 0x0001 /* add event to kq (implies enable) */ +#define EV_DELETE 0x0002 /* delete event from kq */ +#define EV_ENABLE 0x0004 /* enable event */ +#define EV_DISABLE 0x0008 /* disable event (not reported) */ /* flags */ -#define EV_ONESHOT 0x0010 /* only report one occurrence */ -#define EV_CLEAR 0x0020 /* clear event state after reporting */ -#define EV_DISPATCH 0x0080 /* disable event after reporting */ +#define EV_ONESHOT 0x0010 /* only report one occurrence */ +#define EV_CLEAR 0x0020 /* clear event state after reporting */ +#define EV_RECEIPT 0x0040 /* force immediate event output */ + /* ... with or without EV_ERROR */ + /* ... use KEVENT_FLAG_ERROR_EVENTS */ + /* on syscalls supporting flags */ + +#define EV_DISPATCH 0x0080 /* disable event after reporting */ +#define EV_UDATA_SPECIFIC 0x0100 /* unique kevent per udata value */ -#define EV_SYSFLAGS 0xF000 /* reserved by system */ -#define EV_FLAG0 0x1000 /* filter-specific flag */ -#define EV_FLAG1 0x2000 /* filter-specific flag */ +#define EV_DISPATCH2 (EV_DISPATCH | EV_UDATA_SPECIFIC) + /* ... in combination with EV_DELETE */ + /* will defer delete until udata-specific */ + /* event enabled. EINPROGRESS will be */ + /* returned to indicate the deferral */ + +#define EV_VANISHED 0x0200 /* report that source has vanished */ + /* ... only valid with EV_DISPATCH2 */ + +#define EV_SYSFLAGS 0xF000 /* reserved by system */ +#define EV_FLAG0 0x1000 /* filter-specific flag */ +#define EV_FLAG1 0x2000 /* filter-specific flag */ /* returned values */ -#define EV_EOF 0x8000 /* EOF detected */ -#define EV_ERROR 0x4000 /* error, data contains errno */ +#define EV_EOF 0x8000 /* EOF detected */ +#define EV_ERROR 0x4000 /* error, data contains errno */ /* * Filter specific flags for EVFILT_READ * * The default behavior for EVFILT_READ is to make the "read" determination - * relative to the current file descriptor read pointer. The EV_POLL - * flag indicates the determination should be made via poll(2) semantics - * (which always returns true for regular files - regardless of the amount - * of unread data in the file). + * relative to the current file descriptor read pointer. + * + * The EV_POLL flag indicates the determination should be made via poll(2) + * semantics. These semantics dictate always returning true for regular files, + * regardless of the amount of unread data in the file. * - * On input, EV_OOBAND specifies that only OOB data should be looked for. - * The returned data count is the number of bytes beyond the current OOB marker. + * On input, EV_OOBAND specifies that filter should actively return in the + * presence of OOB on the descriptor. It implies that filter will return + * if there is OOB data available to read OR when any other condition + * for the read are met (for example number of bytes regular data becomes >= + * low-watermark). + * If EV_OOBAND is not set on input, it implies that the filter should not actively + * return for out of band data on the descriptor. The filter will then only return + * when some other condition for read is met (ex: when number of regular data bytes + * >=low-watermark OR when socket can't receive more data (SS_CANTRCVMORE)). * - * On output, EV_OOBAND indicates that OOB data is present + * On output, EV_OOBAND indicates the presence of OOB data on the descriptor. * If it was not specified as an input parameter, then the data count is the - * number of bytes before the current OOB marker. If at the marker, the - * data count indicates the number of bytes available after it. In either - * case, it's the amount of data one could expect to receive next. + * number of bytes before the current OOB marker, else data count is the number + * of bytes beyond OOB marker. */ -#define EV_POLL EV_FLAG0 +#define EV_POLL EV_FLAG0 #define EV_OOBAND EV_FLAG1 /* @@ -194,6 +322,10 @@ struct kevent64_s { * realtive to the current file descriptor read pointer. */ #define NOTE_LOWAT 0x00000001 /* low water mark */ + +/* data/hint flags for EVFILT_EXCEPT, shared with userspace */ +#define NOTE_OOB 0x00000002 /* OOB data */ + /* * data/hint fflags for EVFILT_VNODE, shared with userspace */ @@ -205,6 +337,7 @@ struct kevent64_s { #define NOTE_RENAME 0x00000020 /* vnode was renamed */ #define NOTE_REVOKE 0x00000040 /* vnode access was revoked */ #define NOTE_NONE 0x00000080 /* No specific vnode event: to test for EVFILT_READ activation*/ +#define NOTE_FUNLOCK 0x00000100 /* vnode was unlocked by flock(2) */ /* * data/hint fflags for EVFILT_PROC, shared with userspace @@ -247,6 +380,21 @@ enum { #define NOTE_EXIT_MEMORY 0x00020000 #define NOTE_EXIT_CSERROR 0x00040000 +#ifdef PRIVATE + +/* + * If NOTE_EXIT_MEMORY is present, these bits indicate specific jetsam condition. + */ +#define NOTE_EXIT_MEMORY_DETAIL_MASK 0xfe000000 +#define NOTE_EXIT_MEMORY_VMPAGESHORTAGE 0x80000000 /* jetsam condition: lowest jetsam priority proc killed due to vm page shortage */ +#define NOTE_EXIT_MEMORY_VMTHRASHING 0x40000000 /* jetsam condition: lowest jetsam priority proc killed due to vm thrashing */ +#define NOTE_EXIT_MEMORY_HIWAT 0x20000000 /* jetsam condition: process reached its high water mark */ +#define NOTE_EXIT_MEMORY_PID 0x10000000 /* jetsam condition: special pid kill requested */ +#define NOTE_EXIT_MEMORY_IDLE 0x08000000 /* jetsam condition: idle process cleaned up */ +#define NOTE_EXIT_MEMORY_VNODE 0X04000000 /* jetsam condition: virtual node kill */ +#define NOTE_EXIT_MEMORY_FCTHRASHING 0x02000000 /* jetsam condition: lowest jetsam priority proc killed due to filecache thrashing */ + +#endif /* * data/hint fflags for EVFILT_VM, shared with userspace. @@ -256,6 +404,26 @@ enum { #define NOTE_VM_PRESSURE_SUDDEN_TERMINATE 0x20000000 /* will quit immediately on memory pressure */ #define NOTE_VM_ERROR 0x10000000 /* there was an error */ +#ifdef PRIVATE + +/* + * data/hint fflags for EVFILT_MEMORYSTATUS, shared with userspace. + */ +#define NOTE_MEMORYSTATUS_PRESSURE_NORMAL 0x00000001 /* system memory pressure has returned to normal */ +#define NOTE_MEMORYSTATUS_PRESSURE_WARN 0x00000002 /* system memory pressure has changed to the warning state */ +#define NOTE_MEMORYSTATUS_PRESSURE_CRITICAL 0x00000004 /* system memory pressure has changed to the critical state */ +#define NOTE_MEMORYSTATUS_LOW_SWAP 0x00000008 /* system is in a low-swap state */ +#define NOTE_MEMORYSTATUS_PROC_LIMIT_WARN 0x00000010 /* process memory limit has hit a warning state */ +#define NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL 0x00000020 /* process memory limit has hit a critical state - soft limit */ + +typedef enum vm_pressure_level { + kVMPressureNormal = 0, + kVMPressureWarning = 1, + kVMPressureUrgent = 2, + kVMPressureCritical = 3, +} vm_pressure_level_t; + +#endif /* * data/hint fflags for EVFILT_TIMER, shared with userspace. @@ -272,6 +440,35 @@ enum { #define NOTE_LEEWAY 0x00000010 /* ext[1] holds leeway for power aware timers */ #define NOTE_CRITICAL 0x00000020 /* system does minimal timer coalescing */ #define NOTE_BACKGROUND 0x00000040 /* system does maximum timer coalescing */ +#define NOTE_MACH_CONTINUOUS_TIME 0x00000080 /* use continuous time base */ +#ifdef PRIVATE +/* + * data/hint fflags for EVFILT_SOCK, shared with userspace. + * + */ +#define NOTE_CONNRESET 0x00000001 /* Received RST */ +#define NOTE_READCLOSED 0x00000002 /* Read side is shutdown */ +#define NOTE_WRITECLOSED 0x00000004 /* Write side is shutdown */ +#define NOTE_TIMEOUT 0x00000008 /* timeout: rexmt, keep-alive or persist */ +#define NOTE_NOSRCADDR 0x00000010 /* source address not available */ +#define NOTE_IFDENIED 0x00000020 /* interface denied connection */ +#define NOTE_SUSPEND 0x00000040 /* output queue suspended */ +#define NOTE_RESUME 0x00000080 /* output queue resumed */ +#define NOTE_KEEPALIVE 0x00000100 /* TCP Keepalive received */ +#define NOTE_ADAPTIVE_WTIMO 0x00000200 /* TCP adaptive write timeout */ +#define NOTE_ADAPTIVE_RTIMO 0x00000400 /* TCP adaptive read timeout */ +#define NOTE_CONNECTED 0x00000800 /* socket is connected */ +#define NOTE_DISCONNECTED 0x00001000 /* socket is disconnected */ +#define NOTE_CONNINFO_UPDATED 0x00002000 /* connection info was updated */ +#define NOTE_NOTIFY_ACK 0x00004000 /* notify acknowledgement */ + +#define EVFILT_SOCK_LEVEL_TRIGGER_MASK \ + (NOTE_READCLOSED | NOTE_WRITECLOSED | NOTE_SUSPEND | NOTE_RESUME | NOTE_CONNECTED | NOTE_DISCONNECTED) + +#define EVFILT_SOCK_ALL_MASK \ + (NOTE_CONNRESET | NOTE_READCLOSED | NOTE_WRITECLOSED | NOTE_TIMEOUT | NOTE_NOSRCADDR | NOTE_IFDENIED | NOTE_SUSPEND | NOTE_RESUME | NOTE_KEEPALIVE | NOTE_ADAPTIVE_WTIMO | NOTE_ADAPTIVE_RTIMO | NOTE_CONNECTED | NOTE_DISCONNECTED | NOTE_CONNINFO_UPDATED | NOTE_NOTIFY_ACK) + +#endif /* PRIVATE */ /* * data/hint fflags for EVFILT_MACHPORT, shared with userspace. @@ -288,6 +485,19 @@ enum { * receive the message and the requested (or default) message trailers. In addition, * the fflags field contains the return code normally returned by mach_msg(). * + * If MACH_RCV_MSG is specified, and the ext[1] field specifies a zero length, the + * system call argument specifying an ouput area (kevent_qos) will be consulted. If + * the system call specified an output data area, the user-space address + * of the received message is carved from that provided output data area (if enough + * space remains there). The address and length of each received message is + * returned in the ext[0] and ext[1] fields (respectively) of the corresponding kevent. + * + * IF_MACH_RCV_VOUCHER_CONTENT is specified, the contents of the message voucher is + * extracted (as specified in the xflags field) and stored in ext[2] up to ext[3] + * length. If the input length is zero, and the system call provided a data area, + * the space for the voucher content is carved from the provided space and its + * address and length is returned in ext[2] and ext[3] respectively. + * * If no message receipt options were provided in the fflags field on setup, no * message is received by this call. Instead, on output, the data field simply * contains the name of the actual port detected with a message waiting. @@ -304,27 +514,304 @@ enum { +#ifndef KERNEL /* Temporay solution for BootX to use inode.h till kqueue moves to vfs layer */ #include struct knote; SLIST_HEAD(klist, knote); +#endif +#ifdef KERNEL +#ifdef XNU_KERNEL_PRIVATE +#include +#include + +#ifdef MALLOC_DECLARE +MALLOC_DECLARE(M_KQUEUE); +#endif + +TAILQ_HEAD(kqtailq, knote); /* a list of "queued" events */ + +/* Bit size for packed field within knote */ +#define KNOTE_KQ_BITSIZE 40 + + +/* index into various kq queues */ +typedef uint8_t kq_index_t; +typedef uint16_t kn_status_t; + +#define KN_ACTIVE 0x0001 /* event has been triggered */ +#define KN_QUEUED 0x0002 /* event is on queue */ +#define KN_DISABLED 0x0004 /* event is disabled */ +#define KN_DROPPING 0x0008 /* knote is being dropped */ +#define KN_USEWAIT 0x0010 /* wait for knote use */ +#define KN_ATTACHING 0x0020 /* event is pending attach */ +#define KN_STAYACTIVE 0x0040 /* force event to stay active */ +#define KN_DEFERDELETE 0x0080 /* defer delete until re-enabled */ +#define KN_ATTACHED 0x0100 /* currently attached to source */ +#define KN_DISPATCH 0x0200 /* disables as part of deliver */ +#define KN_UDATA_SPECIFIC 0x0400 /* udata is part of matching */ +#define KN_SUPPRESSED 0x0800 /* event is suppressed during delivery */ +#define KN_STOLENDROP 0x1000 /* someone stole the drop privilege */ +#define KN_REQVANISH 0x2000 /* requested EV_VANISH */ +#define KN_VANISHED 0x4000 /* has vanished */ + +#define KN_DISPATCH2 (KN_DISPATCH | KN_UDATA_SPECIFIC) + /* combination defines deferred-delete mode enabled */ + +struct __attribute__((__packed__)) knote { + uint16_t kn_inuse; /* inuse count */ + kn_status_t kn_status; /* status bits */ + int kn_hookid; + TAILQ_ENTRY(knote) kn_tqe; /* linkage for tail queue */ + SLIST_ENTRY(knote) kn_link; /* linkage for search list */ + SLIST_ENTRY(knote) kn_selnext; /* klist element chain */ + union { + struct fileproc *p_fp; /* file data pointer */ + struct proc *p_proc; /* proc pointer */ + struct ipc_mqueue *p_mqueue; /* pset pointer */ + } kn_ptr; + uint64_t kn_req_index:4, /* requested qos index */ + kn_qos_index:4, /* in-use qos index */ + kn_qos_override:4, /* qos override index */ + kn_reserved:4, /* reserved bits */ + kn_filtid:8, /* filter id to index filter ops */ + kn_kq_packed:KNOTE_KQ_BITSIZE; /* packed pointer for kq */ + + int kn_sfflags; /* saved filter flags */ + union { + void *kn_hook; + uint64_t kn_hook_data; + }; + int64_t kn_sdata; /* saved data field */ + struct kevent_internal_s kn_kevent; + +#define kn_id kn_kevent.ident +#define kn_filter kn_kevent.filter +#define kn_flags kn_kevent.flags +#define kn_qos kn_kevent.qos +#define kn_udata kn_kevent.udata +#define kn_fflags kn_kevent.fflags +#define kn_xflags kn_kevent.xflags +#define kn_data kn_kevent.data +#define kn_ext kn_kevent.ext +#define kn_fp kn_ptr.p_fp +}; + +static inline struct kqueue *knote_get_kq(struct knote *kn) +{ + if (!(kn->kn_kq_packed)) + return 0; + else + return (struct kqueue *)((uintptr_t)(kn->kn_kq_packed) + (uintptr_t)VM_MIN_KERNEL_AND_KEXT_ADDRESS); +} + +static inline void knote_set_kq(struct knote *kn, void *kq) +{ + if (!kq) + kn->kn_kq_packed = 0; + else { + uint64_t offset = ((uintptr_t)kq - (uintptr_t)VM_MIN_KERNEL_AND_KEXT_ADDRESS); + kn->kn_kq_packed = offset; + } +} + +struct filt_process_s { + int fp_fd; + unsigned int fp_flags; + user_addr_t fp_data_out; + user_size_t fp_data_size; + user_size_t fp_data_resid; +}; +typedef struct filt_process_s *filt_process_data_t; + +/* + * Filter operators + * + * These routines, provided by each filter, are called to attach, detach, deliver events, + * change/update filter registration and process/deliver events. They are called with the + * with a use-count referenced knote, with the kq unlocked. Here are more details: + * + * f_isfd - + * identifies if the "ident" field in the kevent structure is a file-descriptor. + * + * If so, the knote is associated with the file descriptor prior to attach and + * auto-removed when the file descriptor is closed (this latter behavior may change + * for EV_DISPATCH2 kevent types to allow delivery of events identifying unintended + * closes). + * + * Otherwise the knote is hashed by the ident and has no auto-close behavior. + * + * f_attach - + * called to attach the knote to the underlying object that will be delivering events + * through it when EV_ADD is supplied and no existing matching event is found + * + * provided a knote that is pre-attached to the fd or hashed (see above) but is + * specially marked to avoid concurrent access until the attach is complete. The + * kevent structure embedded in this knote has been filled in with a sanitized + * version of the user-supplied kevent data. However, the user-supplied filter-specific + * flags (fflags) and data fields have been moved into the knote's kn_sfflags and kn_sdata + * fields respectively. These are usually interpretted as a set of "interest" flags and + * data by each filter - to be matched against delivered events. + * + * The attach operator indicated errors by setting the EV_ERROR flog in the flags field + * embedded in the knote's kevent structure - with the specific error indicated in the + * corresponding data field. + * + * The return value indicates if the knote should already be considered "activated" at + * the time of attach (one or more of the interest events has already occured). + * + * f_detach - + * called to disassociate the knote from the underlying object delivering events + * the filter should not attempt to deliver events through this knote after this + * operation returns control to the kq system. + * + * f_event - + * if the knote() function (or KNOTE() macro) is called against a list of knotes, + * this operator will be called on each knote in the list. + * + * The "hint" parameter is completely filter-specific, but usually indicates an + * event or set of events that have occured against the source object associated + * with the list. + * + * The return value indicates if the knote should already be considered "activated" at + * the time of attach (one or more of the interest events has already occured). + * + * f_process - + * called when attempting to deliver triggered events to user-space. + * + * If the knote was previously activated, this operator will be called when a + * thread is trying to deliver events to user-space. The filter gets one last + * chance to determine if the event/events are still interesting for this knote + * (are the conditions still right to deliver an event). If so, the filter + * fills in the output kevent structure with the information to be delivered. + * + * The input context/data parameter is used during event delivery. Some + * filters allow additional data delivery as part of event delivery. This + * context field indicates if space was made available for these additional + * items and how that space is to be allocated/carved-out. + * + * The filter may set EV_CLEAR or EV_ONESHOT in the output flags field to indicate + * special post-delivery dispositions for the knote. + * + * EV_CLEAR - indicates that all matching events have been delivered. Even + * though there were events to deliver now, there will not be any + * more until some additional events are delivered to the knote + * via the f_event operator, or the interest set is changed via + * the f_touch operator. The knote can remain deactivated after + * processing this event delivery. + * + * EV_ONESHOT - indicates that this is the last event to be delivered via + * this knote. It will automatically be deleted upon delivery + * (or if in dispatch-mode, upon re-enablement after this delivery). + * + * The return value indicates if the knote has delivered an output event. + * Unless one of the special output flags was set in the output kevent, a non- + * zero return value ALSO indicates that the knote should be re-activated + * for future event processing (in case it delivers level-based or a multi-edge + * type events like message queues that already exist). + * + * NOTE: In the future, the boolean may change to an enum that allows more + * explicit indication of just delivering a current event vs delivering + * an event with more events still pending. + * + * f_peek - + * For knotes marked KN_STAYACTIVE, indicate if the knote is truly active at + * the moment (not used for event delivery, but for status checks). + */ + +struct filterops { + int f_isfd; /* true if ident == filedescriptor */ + int (*f_attach)(struct knote *kn); + void (*f_detach)(struct knote *kn); + int (*f_event)(struct knote *kn, long hint); + int (*f_touch)(struct knote *kn, struct kevent_internal_s *kev); + int (*f_process)(struct knote *kn, struct filt_process_s *data, struct kevent_internal_s *kev); + unsigned (*f_peek)(struct knote *kn); +}; + +struct proc; +struct waitq; + +SLIST_HEAD(klist, knote); +extern void knote_init(void); +extern void klist_init(struct klist *list); + +#define KNOTE(list, hint) knote(list, hint) +#define KNOTE_ATTACH(list, kn) knote_attach(list, kn) +#define KNOTE_DETACH(list, kn) knote_detach(list, kn) + + +extern void knote(struct klist *list, long hint); +extern int knote_attach(struct klist *list, struct knote *kn); +extern int knote_detach(struct klist *list, struct knote *kn); +extern void knote_vanish(struct klist *list); +extern int knote_link_waitq(struct knote *kn, struct waitq *wq, uint64_t *reserved_link); +extern int knote_unlink_waitq(struct knote *kn, struct waitq *wq); +extern void knote_fdclose(struct proc *p, int fd, int force); +extern void knote_markstayactive(struct knote *kn); +extern void knote_clearstayactive(struct knote *kn); +extern void knote_adjust_qos(struct knote *kn, int qos, int override); +extern struct filterops *knote_fops(struct knote *kn); + +#elif defined(KERNEL_PRIVATE) /* !XNU_KERNEL_PRIVATE: kexts still need a klist structure definition */ + +#include +struct proc; +struct knote; +SLIST_HEAD(klist, knote); + +#endif /* !XNU_KERNEL_PRIVATE && KERNEL_PRIVATE */ + +#ifdef KERNEL_PRIVATE +#ifdef PRIVATE + +/* make these private functions available to the pthread kext */ +extern int kevent_qos_internal(struct proc *p, int fd, + user_addr_t changelist, int nchanges, + user_addr_t eventlist, int nevents, + user_addr_t data_out, user_size_t *data_available, + unsigned int flags, int32_t *retval); + +extern int kevent_qos_internal_bind(struct proc *p, + int fd, thread_t thread, unsigned int flags); +extern int kevent_qos_internal_unbind(struct proc *p, + int fd, thread_t thread, unsigned int flags); + +#endif /* PRIVATE */ +#endif /* KERNEL_PRIVATE */ + +#else /* KERNEL */ + +#include struct timespec; __BEGIN_DECLS int kqueue(void); -int kevent(int kq, const struct kevent *changelist, int nchanges, - struct kevent *eventlist, int nevents, - const struct timespec *timeout); -int kevent64(int kq, const struct kevent64_s *changelist, - int nchanges, struct kevent64_s *eventlist, - int nevents, unsigned int flags, - const struct timespec *timeout); +int kevent(int kq, + const struct kevent *changelist, int nchanges, + struct kevent *eventlist, int nevents, + const struct timespec *timeout); +int kevent64(int kq, + const struct kevent64_s *changelist, int nchanges, + struct kevent64_s *eventlist, int nevents, + unsigned int flags, + const struct timespec *timeout); + +#ifdef PRIVATE +int kevent_qos(int kq, + const struct kevent_qos_s *changelist, int nchanges, + struct kevent_qos_s *eventlist, int nevents, + void *data_out, size_t *data_available, + unsigned int flags); +#endif /* PRIVATE */ + __END_DECLS +#endif /* KERNEL */ #endif /* !_SYS_EVENT_H_ */ diff --git a/platform-include/sys/guarded.h b/platform-include/sys/guarded.h new file mode 100644 index 000000000..6fa6a7752 --- /dev/null +++ b/platform-include/sys/guarded.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_GUARDED_H_ +#define _SYS_GUARDED_H_ + +#include +#include + +#include +#ifdef PRIVATE + +__BEGIN_DECLS + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) + +#ifndef _GUARDID_T +#define _GUARDID_T +typedef __uint64_t guardid_t; +#endif /* _GUARDID_T */ + +#if !defined(KERNEL) +extern int guarded_open_np(const char *path, + const guardid_t *guard, u_int guardflags, int flags, ...); +extern int guarded_open_dprotected_np(const char *path, + const guardid_t *guard, u_int guardflags, int flags, + int dpclass, int dpflags, ...); +extern int guarded_kqueue_np(const guardid_t *guard, u_int guardflags); +extern int guarded_close_np(int fd, const guardid_t *guard); +extern int change_fdguard_np(int fd, const guardid_t *guard, u_int guardflags, + const guardid_t *nguard, u_int nguardflags, int *fdflagsp); +extern ssize_t guarded_write_np(int fd, const guardid_t *guard, const void *buf, size_t nbyte); +extern ssize_t guarded_pwrite_np(int fd, const guardid_t *guard, const void *buf, size_t nbyte, off_t offset); +extern ssize_t guarded_writev_np(int fd, const guardid_t *guard, const struct iovec *iovp, int iovcnt); +#endif /* KERNEL */ + +/* + * Guard types. + * + * GUARD_TYPE_FD: Guarded file descriptor. + */ +#define GUARD_TYPE_FD 0x2 + +/* + * File descriptor guard flavors. + */ + +/* + * Forbid close(2), and the implicit close() that a dup2(2) may do. + * Forces close-on-fork to be set immutably too. + */ +#define GUARD_CLOSE (1u << 0) + +/* + * Forbid dup(2), dup2(2), and fcntl(2) subcodes F_DUPFD, F_DUPFD_CLOEXEC + * on a guarded fd. Also forbids open's of a guarded fd via /dev/fd/ + * (an implicit dup.) + */ +#define GUARD_DUP (1u << 1) + +/* + * Forbid sending a guarded fd via a socket + */ +#define GUARD_SOCKET_IPC (1u << 2) + +/* + * Forbid creating a fileport from a guarded fd + */ +#define GUARD_FILEPORT (1u << 3) + +/* + * Forbid writes on a guarded fd + */ +#define GUARD_WRITE (1u << 4) + +/* + * Violating a guard results in an error (EPERM), and potentially + * an exception with one or more of the following bits set. + */ +enum guard_exception_codes { + kGUARD_EXC_CLOSE = 1u << 0, /* close of a guarded fd */ + kGUARD_EXC_DUP = 1u << 1, /* dup of a guarded fd */ + kGUARD_EXC_NOCLOEXEC = 1u << 2, /* clear close-on-exec */ + kGUARD_EXC_SOCKET_IPC = 1u << 3, /* sendmsg of a guarded fd */ + kGUARD_EXC_FILEPORT = 1u << 4, /* fileport_makeport .. */ + kGUARD_EXC_MISMATCH = 1u << 5, /* wrong guard for guarded fd */ + kGUARD_EXC_WRITE = 1u << 6 /* write on a guarded fd */ +}; + +#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ + +__END_DECLS + +#endif /* PRIVATE */ + +#endif /* !_SYS_GUARDED_H_ */ diff --git a/platform-include/sys/kdebug.h b/platform-include/sys/kdebug.h index a05acfc36..42b8c92f1 100644 --- a/platform-include/sys/kdebug.h +++ b/platform-include/sys/kdebug.h @@ -1,8 +1,8 @@ /* - * Copyright (c) 2000-2014 Apple Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,14 +22,12 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ -/* Copyright (c) 1997 Apple Computer, Inc. All rights reserved. - * - * kdebug.h - kernel_debug definitions - * +/* + * kdebug.h - kernel_debug definitions */ #ifndef BSD_SYS_KDEBUG_H @@ -43,127 +41,317 @@ __BEGIN_DECLS #include #include -#if defined(KERNEL_BUILD) -#include -#endif /* KERNEL_BUILD */ +#ifndef KERNEL +#include +#endif -typedef enum -{ - KD_CALLBACK_KDEBUG_ENABLED, // Trace is now enabled. No arguments - KD_CALLBACK_KDEBUG_DISABLED, // Trace is now disabled. No arguments - KD_CALLBACK_SYNC_FLUSH, // Request the latest entries from the IOP, and block until complete. No arguments - KD_CALLBACK_TYPEFILTER_CHANGED, // Typefilter is enabled. A read-only pointer to the typefilter is provided, but is only valid while in the callback. +#ifdef XNU_KERNEL_PRIVATE +#include /* __improbable */ +#endif + +/* + * Kdebug is a facility for tracing events occurring on a system. + * + * All events are tagged with a 32-bit debugid: + * + * +----------------+----------------+----------------------------+----+ + * | Class (8) | Subclass (8) | Code (14) |Func| + * | | | |(2) | + * +----------------+----------------+----------------------------+----+ + * \_________________________________/ + * ClassSubclass (CSC) + * \________________________________________________________________00_/ + * Eventid + * \___________________________________________________________________/ + * Debugid + * + * The eventid is a hierarchical ID, indicating which components an event is + * referring to. The debugid includes an eventid and two function qualifier + * bits, to determine the structural significance of an event (whether it + * starts or ends an interval). + */ + +#define KDBG_CLASS_MASK (0xff000000) +#define KDBG_CLASS_OFFSET (24) +#define KDBG_CLASS_MAX (0xff) + +#define KDBG_SUBCLASS_MASK (0x00ff0000) +#define KDBG_SUBCLASS_OFFSET (16) +#define KDBG_SUBCLASS_MAX (0xff) + +/* class and subclass mask */ +#define KDBG_CSC_MASK (0xffff0000) +#define KDBG_CSC_OFFSET (KDBG_SUBCLASS_OFFSET) +#define KDBG_CSC_MAX (0xffff) + +#define KDBG_CODE_MASK (0x0000fffc) +#define KDBG_CODE_OFFSET (2) +#define KDBG_CODE_MAX (0x3fff) + +#define KDBG_EVENTID_MASK (0xfffffffc) +#define KDBG_FUNC_MASK (0x00000003) + +/* Generate an eventid corresponding to Class, SubClass, and Code. */ +#define KDBG_EVENTID(Class, SubClass, Code) \ + ((((Class) & 0xff) << KDBG_CLASS_OFFSET) | \ + (((SubClass) & 0xff) << KDBG_SUBCLASS_OFFSET) | \ + (((Code) & 0x3fff) << KDBG_CODE_OFFSET)) +/* Deprecated macro using old naming convention. */ +#define KDBG_CODE(Class, SubClass, Code) \ + KDBG_EVENTID(Class, SubClass, Code) + +/* Extract pieces of the debug code. */ +#define KDBG_EXTRACT_CLASS(Debugid) \ + ((uint8_t)(((Debugid) & KDBG_CLASS_MASK) >> KDBG_CLASS_OFFSET)) +#define KDBG_EXTRACT_SUBCLASS(Debugid) \ + ((uint8_t)(((Debugid) & KDBG_SUBCLASS_MASK) >> KDBG_SUBCLASS_OFFSET)) +#define KDBG_EXTRACT_CSC(Debugid) \ + ((uint16_t)(((Debugid) & KDBG_CSC_MASK) >> KDBG_CSC_OFFSET)) +#define KDBG_EXTRACT_CODE(Debugid) \ + ((uint16_t)(((Debugid) & KDBG_CODE_MASK) >> KDBG_CODE_OFFSET)) + +/* function qualifiers */ +#define DBG_FUNC_START 1 +#define DBG_FUNC_END 2 +#define DBG_FUNC_NONE 0 + +/* + * Definitions to support IOP tracing. + */ + +#ifdef KERNEL_PRIVATE + +typedef enum { + /* Trace is now enabled; no arguments. */ + KD_CALLBACK_KDEBUG_ENABLED, + /* Trace is now disabled; no arguments. */ + KD_CALLBACK_KDEBUG_DISABLED, + /* + * Request the latest entries from the IOP and block until complete; no + * arguments. + */ + KD_CALLBACK_SYNC_FLUSH, + /* + * The typefilter is enabled; a read-only pointer to the typefilter is + * provided, valid only while in the callback. + */ + KD_CALLBACK_TYPEFILTER_CHANGED, } kd_callback_type; typedef void (*kd_callback_fn) (void* context, kd_callback_type reason, void* arg); struct kd_callback { - kd_callback_fn func; - void* context; - char iop_name[8]; // null-terminated string with name of core. + kd_callback_fn func; + void *context; + /* name of IOP, NUL-terminated */ + char iop_name[8]; }; typedef struct kd_callback kd_callback_t; /* - * Registers an IOP for participation in tracing. - * - * The registered callback function will be called with the - * supplied context as the first argument, followed by a - * kd_callback_type and an associated void* argument. - * - * The return value is a nonzero coreid that shall be used in - * kernel_debug_enter() to refer to your IOP. If the allocation - * failed, then 0 will be returned. - * - * - * Caveats: - * Note that not all callback calls will indicate a change in - * state (e.g. disabling trace twice would send two disable - * notifications). - * + * Registers an IOP for participation in tracing. + * + * The registered callback function will be called with the + * supplied context as the first argument, followed by a + * kd_callback_type and an associated void* argument. + * + * The return value is a nonzero coreid that shall be used in + * kernel_debug_enter() to refer to your IOP. If the allocation + * failed, then 0 will be returned. + * + * Caveats: + * Note that not all callback calls will indicate a change in + * state (e.g. disabling trace twice would send two disable + * notifications). */ extern int kernel_debug_register_callback(kd_callback_t callback); extern void kernel_debug_enter( - uint32_t coreid, - uint32_t debugid, - uint64_t timestamp, - uintptr_t arg1, - uintptr_t arg2, - uintptr_t arg3, - uintptr_t arg4, - uintptr_t threadid + uint32_t coreid, + uint32_t debugid, + uint64_t timestamp, + uintptr_t arg1, + uintptr_t arg2, + uintptr_t arg3, + uintptr_t arg4, + uintptr_t threadid ); +#endif /* KERNEL_PRIVATE */ + +/* The Kernel Debug Classes */ +#define DBG_MACH 1 +#define DBG_NETWORK 2 +#define DBG_FSYSTEM 3 +#define DBG_BSD 4 +#define DBG_IOKIT 5 +#define DBG_DRIVERS 6 +#define DBG_TRACE 7 +#define DBG_DLIL 8 +#define DBG_WORKQUEUE 9 +#define DBG_CORESTORAGE 10 +#define DBG_CG 11 +#define DBG_MISC 20 +#define DBG_SECURITY 30 +#define DBG_DYLD 31 +#define DBG_QT 32 +#define DBG_APPS 33 +#define DBG_LAUNCHD 34 +#define DBG_PERF 37 +#define DBG_IMPORTANCE 38 +#define DBG_BANK 40 +#define DBG_XPC 41 +#define DBG_ATM 42 +#define DBG_ARIADNE 43 +#define DBG_DAEMON 44 +#define DBG_ENERGYTRACE 45 +#define DBG_DISPATCH 46 +#define DBG_IMG 49 +#define DBG_UMALLOC 51 + + +#define DBG_MIG 255 + +#ifdef PRIVATE /* - * state bits for hfs_update event + * Private kdebug userspace API */ -#define DBG_HFS_UPDATE_ACCTIME 0x01 -#define DBG_HFS_UPDATE_MODTIME 0x02 -#define DBG_HFS_UPDATE_CHGTIME 0x04 -#define DBG_HFS_UPDATE_MODIFIED 0x08 -#define DBG_HFS_UPDATE_FORCE 0x10 -#define DBG_HFS_UPDATE_DATEADDED 0x20 - +#ifndef KERNEL +#include /* - * types of faults that vm_fault handles - * and creates trace entries for + * OS components can use the full precision of the "code" field + * (Class, SubClass, Code) to inject events using kdebug_trace() by + * using: + * + * kdebug_trace(KDBG_CODE(DBG_XPC, 15, 1) | DBG_FUNC_NONE, 1, 2, 3, 4); + * + * These trace points can be included in production code, since they + * use reserved, non-overlapping ranges. The performance impact when + * kernel tracing is not enabled is minimal. Classes can be reserved + * by filing a Radar in xnu|all. + * + * 64-bit arguments may be truncated if the system is using a 32-bit + * kernel. + * + * On error, -1 will be returned and errno will indicate the error. */ -#define DBG_ZERO_FILL_FAULT 1 -#define DBG_PAGEIN_FAULT 2 -#define DBG_COW_FAULT 3 -#define DBG_CACHE_HIT_FAULT 4 -#define DBG_NZF_PAGE_FAULT 5 -#define DBG_GUARD_FAULT 6 -#define DBG_PAGEINV_FAULT 7 -#define DBG_PAGEIND_FAULT 8 -#define DBG_COMPRESSOR_FAULT 9 -#define DBG_COMPRESSOR_SWAPIN_FAULT 10 - - -/* The debug code consists of the following -* -* ---------------------------------------------------------------------- -*| | | |Func | -*| Class (8) | SubClass (8) | Code (14) |Qual(2)| -* ---------------------------------------------------------------------- -* The class specifies the higher level -*/ - -/* The Function qualifiers */ -#define DBG_FUNC_START 1 -#define DBG_FUNC_END 2 -#define DBG_FUNC_NONE 0 +extern int kdebug_trace( + uint32_t code, + uint64_t arg1, + uint64_t arg2, + uint64_t arg3, + uint64_t arg4) + __OSX_AVAILABLE(10.10.2) __IOS_AVAILABLE(8.2); + +/*! + * @function kdebug_trace_string + * + * @discussion + * This function emits strings to kdebug trace along with an ID and allows + * for previously-traced strings to be overwritten and invalidated. + * + * To start tracing a string and generate an ID to use to refer to it: + * + * string_id = kdebug_trace_string(debugid, 0, "string"); + * + * To replace a string previously traced: + * + * string_id = kdebug_trace_string(debugid, string_id, "new string"); + * + * To invalidate a string ID: + * + * string_id = kdebug_trace_string(debugid, string_id, NULL); + * + * To check for errors: + * + * if ((int64_t)string_id == -1) { perror("string error") } + * + * @param debugid + * The `debugid` to check if its enabled before tracing and include as + * an argument in the event containing the string. + * + * Some classes or subclasses are reserved for specific uses and are not + * allowed to be used with this function. No function qualifiers are + * allowed on `debugid`. + * + * @param str_id + * When 0, a new ID will be generated and returned if tracing is + * enabled. + * + * Otherwise `str_id` must contain an ID that was previously generated + * with this function. Clents should pass NULL in `str` if `str_id` + * is no longer in use. Otherwise, the string previously mapped to + * `str_id` will be overwritten with the contents of `str`. + * + * @param str + * A NUL-terminated 'C' string containing the characters that should be + * traced alongside `str_id`. + * + * If necessary, the string will be truncated at an + * implementation-defined length. The string must not be the empty + * string, but can be NULL if a valid `str_id` is provided. + * + * @return + * 0 if tracing is disabled or `debugid` is being filtered out of trace. + * It can also return (int64_t)-1 if an error occured. Otherwise, + * it returns the ID to use to refer to the string in future + * kdebug_trace(2) calls. + * + * The errors that can occur are: + * + * EINVAL + * There are function qualifiers on `debugid`, `str` is empty, or + * `str_id` was not generated by this function. + * EPERM + * The `debugid`'s class or subclass is reserved for internal use. + * EFAULT + * `str` is an invalid address or NULL when `str_id` is 0. + */ +extern uint64_t kdebug_trace_string(uint32_t debugid, uint64_t str_id, + const char *str) + __OSX_AVAILABLE(10.11) __IOS_AVAILABLE(9.0); +/* + * Although the performance impact of kdebug_trace() when kernel + * tracing is not enabled is minimal, it may require the caller to + * perform an expensive calculation/summarization. This cost can be + * skipped by checking the kdebug_is_enabled() predicate: + * + * if (kdebug_is_enabled(KDBG_CODE(DBG_XPC, 15, 1))) { + * uint64_t arg1 = ...; + * uint64_t arg2 = ...; + * kdebug_trace(KDBG_CODE(DBG_XPC, 15, 1) | DBG_FUNC_NONE, arg1, arg2, 0, 0); + * } + * + * If tracing is enabled for the code at the time of the check, 1 + * will be returned. Otherwise, 0 will be returned. + */ +extern bool kdebug_is_enabled(uint32_t code) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0); -/* The Kernel Debug Classes */ -#define DBG_MACH 1 -#define DBG_NETWORK 2 -#define DBG_FSYSTEM 3 -#define DBG_BSD 4 -#define DBG_IOKIT 5 -#define DBG_DRIVERS 6 -#define DBG_TRACE 7 -#define DBG_DLIL 8 -#define DBG_WORKQUEUE 9 -#define DBG_CORESTORAGE 10 -#define DBG_CG 11 -#define DBG_MISC 20 -#define DBG_SECURITY 30 -#define DBG_DYLD 31 -#define DBG_QT 32 -#define DBG_APPS 33 -#define DBG_LAUNCHD 34 -#define DBG_PERF 37 -#define DBG_IMPORTANCE 38 -#define DBG_BANK 40 -#define DBG_XPC 41 -#define DBG_ATM 42 - -#define DBG_MIG 255 +/* + * Returns a pointer to the userspace typefilter, if one is available. + * May return NULL. + */ +extern void *kdebug_typefilter(void) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0); + +#endif /* !KERNEL (Private kdebug userspace API) */ +#endif /* PRIVATE */ + +#ifdef XNU_KERNEL_PRIVATE +/* Used in early boot to log strings spanning only a single tracepoint. */ +extern void kernel_debug_string_early(const char *message); +/* Used to trace strings within kdebug tracepoints on arbitrary eventids. */ +extern void kernel_debug_string_simple(uint32_t eventid, const char *str); +/* Only used by ktrace to reset kdebug. ktrace_lock must be held. */ +extern void kdebug_reset(void); +#endif /* XNU_KERNEL_PRIVATE */ /* **** The Kernel Debug Sub Classes for Mach (DBG_MACH) **** */ #define DBG_MACH_EXCP_KTRAP_x86 0x02 /* Kernel Traps on x86 */ @@ -174,26 +362,31 @@ extern void kernel_debug_enter( #define DBG_MACH_EXCP_UTRAP_x86 0x07 /* User Traps on x86 */ #define DBG_MACH_EXCP_FP 0x08 /* FP Unavail */ #define DBG_MACH_EXCP_DECI 0x09 /* Decrementer Interrupt */ -#define DBG_MACH_CHUD 0x0A /* CHUD */ +#define DBG_MACH_CHUD 0x0A /* deprecated name */ +#define DBG_MACH_SIGNPOST 0x0A /* kernel signposts */ #define DBG_MACH_EXCP_SC 0x0C /* System Calls */ #define DBG_MACH_EXCP_TRACE 0x0D /* Trace exception */ #define DBG_MACH_EXCP_EMUL 0x0E /* Instruction emulated */ #define DBG_MACH_IHDLR 0x10 /* Interrupt Handlers */ #define DBG_MACH_IPC 0x20 /* Inter Process Comm */ -#define DBG_MACH_VM 0x30 /* Virtual Memory */ -#define DBG_MACH_LEAKS 0x31 /* alloc/free */ -#define DBG_MACH_SCHED 0x40 /* Scheduler */ -#define DBG_MACH_MSGID_INVALID 0x50 /* Messages - invalid */ +#define DBG_MACH_RESOURCE 0x25 /* tracing limits, etc */ +#define DBG_MACH_VM 0x30 /* Virtual Memory */ +#define DBG_MACH_LEAKS 0x31 /* alloc/free */ +#define DBG_MACH_WORKINGSET 0x32 /* private subclass for working set related debugging */ +#define DBG_MACH_SCHED 0x40 /* Scheduler */ +#define DBG_MACH_MSGID_INVALID 0x50 /* Messages - invalid */ #define DBG_MACH_LOCKS 0x60 /* new lock APIs */ #define DBG_MACH_PMAP 0x70 /* pmap */ -/* #define unused 0x80 */ +#define DBG_MACH_CLOCK 0x80 /* clock */ #define DBG_MACH_MP 0x90 /* MP related */ #define DBG_MACH_VM_PRESSURE 0xA0 /* Memory Pressure Events */ -#define DBG_MACH_STACKSHOT 0xA1 /* Stackshot/Microstackshot subsystem */ -#define DBG_MACH_SFI 0xA2 /* Selective Forced Idle (SFI) */ +#define DBG_MACH_STACKSHOT 0xA1 /* Stackshot/Microstackshot subsystem */ +#define DBG_MACH_SFI 0xA2 /* Selective Forced Idle (SFI) */ #define DBG_MACH_ENERGY_PERF 0xA3 /* Energy/performance resource stats */ +#define DBG_MACH_SYSDIAGNOSE 0xA4 /* sysdiagnose keychord */ +#define DBG_MACH_ZALLOC 0xA5 /* Zone allocator */ -/* Codes for Scheduler (DBG_MACH_SCHED) */ +/* Codes for Scheduler (DBG_MACH_SCHED) */ #define MACH_SCHED 0x0 /* Scheduler */ #define MACH_STACK_ATTACH 0x1 /* stack_attach() */ #define MACH_STACK_HANDOFF 0x2 /* stack_handoff() */ @@ -206,8 +399,8 @@ extern void kernel_debug_enter( #define MACH_IDLE 0x9 /* processor idling */ #define MACH_STACK_DEPTH 0xa /* stack depth at switch */ #define MACH_MOVED 0xb /* did not use original scheduling decision */ -#define MACH_FAIRSHARE_ENTER 0xc /* move to fairshare band */ -#define MACH_FAIRSHARE_EXIT 0xd /* exit fairshare band */ +/* unused 0xc */ +/* unused 0xd */ #define MACH_FAILSAFE 0xe /* tripped fixed-pri/RT failsafe */ #define MACH_BLOCK 0xf /* thread block */ #define MACH_WAIT 0x10 /* thread wait assertion */ @@ -217,10 +410,9 @@ extern void kernel_debug_enter( */ #define MACH_REDISPATCH 0x16 /* "next thread" thread redispatched */ #define MACH_REMOTE_AST 0x17 /* AST signal issued to remote processor */ - #define MACH_SCHED_CHOOSE_PROCESSOR 0x18 /* Result of choose_processor */ #define MACH_DEEP_IDLE 0x19 /* deep idle on master processor */ -#define MACH_SCHED_DECAY_PRIORITY 0x1a /* timeshare thread priority decayed/restored */ +/* unused 0x1a was MACH_SCHED_DECAY_PRIORITY */ #define MACH_CPU_THROTTLE_DISABLE 0x1b /* Global CPU Throttle Disable */ #define MACH_RW_PROMOTE 0x1c /* promoted due to RW lock promotion */ #define MACH_RW_DEMOTE 0x1d /* promotion due to RW lock undone */ @@ -230,12 +422,35 @@ extern void kernel_debug_enter( #define MACH_MULTIQ_DEQUEUE 0x22 /* Result of multiq dequeue */ #define MACH_SCHED_THREAD_SWITCH 0x23 /* attempt direct context switch to hinted thread */ #define MACH_SCHED_SMT_BALANCE 0x24 /* SMT load balancing ASTs */ +#define MACH_REMOTE_DEFERRED_AST 0x25 /* Deferred AST started against remote processor */ +#define MACH_REMOTE_CANCEL_AST 0x26 /* Canceled deferred AST for remote processor */ +#define MACH_SCHED_CHANGE_PRIORITY 0x27 /* thread sched priority changed */ +#define MACH_SCHED_UPDATE_REC_CORES 0x28 /* Change to recommended processor bitmask */ +#define MACH_STACK_WAIT 0x29 /* Thread could not be switched-to because of kernel stack shortage */ +#define MACH_THREAD_BIND 0x2a /* Thread was bound (or unbound) to a processor */ +#define MACH_WAITQ_PROMOTE 0x2b /* Thread promoted by waitq boost */ +#define MACH_WAITQ_DEMOTE 0x2c /* Thread demoted from waitq boost */ +#define MACH_SCHED_LOAD 0x2d /* load update */ +#define MACH_REC_CORES_FAILSAFE 0x2e /* recommended processor failsafe kicked in */ +#define MACH_SCHED_QUANTUM_EXPIRED 0x2f /* thread quantum expired */ /* Variants for MACH_MULTIQ_DEQUEUE */ #define MACH_MULTIQ_BOUND 1 #define MACH_MULTIQ_GROUP 2 #define MACH_MULTIQ_GLOBAL 3 +/* Arguments for vm_fault (DBG_MACH_VM) */ +#define DBG_ZERO_FILL_FAULT 1 +#define DBG_PAGEIN_FAULT 2 +#define DBG_COW_FAULT 3 +#define DBG_CACHE_HIT_FAULT 4 +#define DBG_NZF_PAGE_FAULT 5 +#define DBG_GUARD_FAULT 6 +#define DBG_PAGEINV_FAULT 7 +#define DBG_PAGEIND_FAULT 8 +#define DBG_COMPRESSOR_FAULT 9 +#define DBG_COMPRESSOR_SWAPIN_FAULT 10 + /* Codes for IPC (DBG_MACH_IPC) */ #define MACH_TASK_SUSPEND 0x0 /* Suspended a task */ #define MACH_TASK_RESUME 0x1 /* Resumed a task */ @@ -247,8 +462,10 @@ extern void kernel_debug_enter( #define MACH_IPC_VOUCHER_CREATE 0x7 /* Voucher added to global voucher hashtable */ #define MACH_IPC_VOUCHER_CREATE_ATTR_DATA 0x8 /* Attr data for newly created voucher */ #define MACH_IPC_VOUCHER_DESTROY 0x9 /* Voucher removed from global voucher hashtable */ +#define MACH_IPC_KMSG_INFO 0xa /* Send/Receive info for a kmsg */ +#define MACH_IPC_KMSG_LINK 0xb /* link a kernel kmsg pointer to user mach_msg_header_t */ -/* Codes for pmap (DBG_MACH_PMAP) */ +/* Codes for pmap (DBG_MACH_PMAP) */ #define PMAP__CREATE 0x0 #define PMAP__DESTROY 0x1 #define PMAP__PROTECT 0x2 @@ -265,22 +482,57 @@ extern void kernel_debug_enter( #define PMAP__FLUSH_KERN_TLBS 0xd #define PMAP__FLUSH_DELAYED_TLBS 0xe #define PMAP__FLUSH_TLBS_TO 0xf +#define PMAP__FLUSH_EPT 0x10 + +/* Codes for clock (DBG_MACH_CLOCK) */ +#define MACH_EPOCH_CHANGE 0x0 /* wake epoch change */ + /* Codes for Stackshot/Microstackshot (DBG_MACH_STACKSHOT) */ #define MICROSTACKSHOT_RECORD 0x0 #define MICROSTACKSHOT_GATHER 0x1 +/* Codes for sysdiagnose */ +#define SYSDIAGNOSE_NOTIFY_USER 0x0 + /* Codes for Selective Forced Idle (DBG_MACH_SFI) */ #define SFI_SET_WINDOW 0x0 #define SFI_CANCEL_WINDOW 0x1 -#define SFI_SET_CLASS_OFFTIME 0x2 +#define SFI_SET_CLASS_OFFTIME 0x2 #define SFI_CANCEL_CLASS_OFFTIME 0x3 #define SFI_THREAD_DEFER 0x4 #define SFI_OFF_TIMER 0x5 #define SFI_ON_TIMER 0x6 #define SFI_WAIT_CANCELED 0x7 #define SFI_PID_SET_MANAGED 0x8 -#define SFI_PID_CLEAR_MANAGED 0x9 +#define SFI_PID_CLEAR_MANAGED 0x9 +#define SFI_GLOBAL_DEFER 0xa + +/* Codes for Zone Allocator (DBG_MACH_ZALLOC) */ +#define ZALLOC_ZCRAM 0x0 + +/* Codes for Mach resource management (DBG_MACH_RESOURCE) */ +/* _K32A/B codes start at double the low nibble */ +#define RMON_ENABLE_CPUUSAGE_MONITOR 0x001 +#define RMON_CPUUSAGE_VIOLATED 0x002 +#define RMON_CPUUSAGE_SUSPENDED 0x003 +#define RMON_CPUUSAGE_VIOLATED_K32A 0x004 +#define RMON_CPUUSAGE_VIOLATED_K32B 0x005 +#define RMON_CPUUSAGE_RESUMED 0x006 +#define RMON_DISABLE_CPUUSAGE_MONITOR 0x00f + +#define RMON_ENABLE_CPUWAKES_MONITOR 0x011 +#define RMON_CPUWAKES_VIOLATED 0x012 +#define RMON_CPUWAKES_VIOLATED_K32A 0x014 +#define RMON_CPUWAKES_VIOLATED_K32B 0x015 +#define RMON_DISABLE_CPUWAKES_MONITOR 0x01f + +#define RMON_ENABLE_IO_MONITOR 0x021 +#define RMON_LOGWRITES_VIOLATED 0x022 +#define RMON_PHYSWRITES_VIOLATED 0x023 +#define RMON_LOGWRITES_VIOLATED_K32A 0x024 +#define RMON_LOGWRITES_VIOLATED_K32B 0x025 +#define RMON_DISABLE_IO_MONITOR 0x02f /* **** The Kernel Debug Sub Classes for Network (DBG_NETWORK) **** */ #define DBG_NETIP 1 /* Internet Protocol */ @@ -312,14 +564,15 @@ extern void kernel_debug_enter( /* **** The Kernel Debug Sub Classes for IOKIT (DBG_IOKIT) **** */ #define DBG_IOINTC 0 /* Interrupt controller */ -#define DBG_IOWORKLOOP 1 /* Work from work loop */ +#define DBG_IOWORKLOOP 1 /* Work from work loop */ #define DBG_IOINTES 2 /* Interrupt event source */ #define DBG_IOCLKES 3 /* Clock event source */ #define DBG_IOCMDQ 4 /* Command queue latencies */ #define DBG_IOMCURS 5 /* Memory Cursor */ #define DBG_IOMDESC 6 /* Memory Descriptors */ #define DBG_IOPOWER 7 /* Power Managerment */ -#define DBG_IOSERVICE 8 /* Matching etc. */ +#define DBG_IOSERVICE 8 /* Matching etc. */ +#define DBG_IOREGISTRY 9 /* Registry */ /* **** 9-32 reserved for internal IOKit usage **** */ @@ -354,28 +607,29 @@ extern void kernel_debug_enter( #define DBG_DRVSTORAGE 1 /* Storage layers */ #define DBG_DRVNETWORK 2 /* Network layers */ #define DBG_DRVKEYBOARD 3 /* Keyboard */ -#define DBG_DRVHID 4 /* HID Devices */ +#define DBG_DRVHID 4 /* HID Devices */ #define DBG_DRVAUDIO 5 /* Audio */ #define DBG_DRVSERIAL 7 /* Serial */ -#define DBG_DRVSAM 8 /* SCSI Architecture Model layers */ -#define DBG_DRVPARALLELATA 9 /* Parallel ATA */ +#define DBG_DRVSAM 8 /* SCSI Architecture Model layers */ +#define DBG_DRVPARALLELATA 9 /* Parallel ATA */ #define DBG_DRVPARALLELSCSI 10 /* Parallel SCSI */ -#define DBG_DRVSATA 11 /* Serial ATA */ -#define DBG_DRVSAS 12 /* SAS */ +#define DBG_DRVSATA 11 /* Serial ATA */ +#define DBG_DRVSAS 12 /* SAS */ #define DBG_DRVFIBRECHANNEL 13 /* FiberChannel */ -#define DBG_DRVUSB 14 /* USB */ +#define DBG_DRVUSB 14 /* USB */ #define DBG_DRVBLUETOOTH 15 /* Bluetooth */ #define DBG_DRVFIREWIRE 16 /* FireWire */ #define DBG_DRVINFINIBAND 17 /* Infiniband */ -#define DBG_DRVGRAPHICS 18 /* Graphics */ +#define DBG_DRVGRAPHICS 18 /* Graphics */ #define DBG_DRVSD 19 /* Secure Digital */ #define DBG_DRVNAND 20 /* NAND drivers and layers */ #define DBG_SSD 21 /* SSD */ #define DBG_DRVSPI 22 /* SPI */ +#define DBG_DRVWLAN_802_11 23 /* WLAN 802.11 */ /* Backwards compatibility */ -#define DBG_DRVPOINTING DBG_DRVHID /* OBSOLETE: Use DBG_DRVHID instead */ -#define DBG_DRVDISK DBG_DRVSTORAGE /* OBSOLETE: Use DBG_DRVSTORAGE instead */ +#define DBG_DRVPOINTING DBG_DRVHID /* OBSOLETE: Use DBG_DRVHID instead */ +#define DBG_DRVDISK DBG_DRVSTORAGE /* OBSOLETE: Use DBG_DRVSTORAGE instead */ /* **** The Kernel Debug Sub Classes for the DLIL Layer (DBG_DLIL) **** */ #define DBG_DLIL_STATIC 1 /* Static DLIL code */ @@ -385,32 +639,50 @@ extern void kernel_debug_enter( #define DBG_DLIL_IF_FLT 5 /* DLIL Interface FIlter */ /* The Kernel Debug Sub Classes for File System (DBG_FSYSTEM) */ -#define DBG_FSRW 1 /* reads and writes to the filesystem */ -#define DBG_DKRW 2 /* reads and writes to the disk */ -#define DBG_FSVN 3 /* vnode operations (inc. locking/unlocking) */ -#define DBG_FSLOOOKUP 4 /* namei and other lookup-related operations */ -#define DBG_JOURNAL 5 /* journaling operations */ -#define DBG_IOCTL 6 /* ioctl to the disk */ -#define DBG_BOOTCACHE 7 /* bootcache operations */ -#define DBG_HFS 8 /* HFS-specific events; see bsd/hfs/hfs_kdebug.h */ +#define DBG_FSRW 0x1 /* reads and writes to the filesystem */ +#define DBG_DKRW 0x2 /* reads and writes to the disk */ +#define DBG_FSVN 0x3 /* vnode operations (inc. locking/unlocking) */ +#define DBG_FSLOOOKUP 0x4 /* namei and other lookup-related operations */ +#define DBG_JOURNAL 0x5 /* journaling operations */ +#define DBG_IOCTL 0x6 /* ioctl to the disk */ +#define DBG_BOOTCACHE 0x7 /* bootcache operations */ +#define DBG_HFS 0x8 /* HFS-specific events; see the hfs project */ +#define DBG_APFS 0x9 /* APFS-specific events; see the apfs project */ +#define DBG_SMB 0xA /* SMB-specific events; see the smb project */ #define DBG_EXFAT 0xE /* ExFAT-specific events; see the exfat project */ #define DBG_MSDOS 0xF /* FAT-specific events; see the msdosfs project */ #define DBG_ACFS 0x10 /* Xsan-specific events; see the XsanFS project */ -#define DBG_THROTTLE 0x11 /* I/O Throttling events */ +#define DBG_THROTTLE 0x11 /* I/O Throttling events */ #define DBG_CONTENT_PROT 0xCF /* Content Protection Events: see bsd/sys/cprotect.h */ +/* + * For Kernel Debug Sub Class DBG_HFS, state bits for hfs_update event + */ +#define DBG_HFS_UPDATE_ACCTIME 0x01 +#define DBG_HFS_UPDATE_MODTIME 0x02 +#define DBG_HFS_UPDATE_CHGTIME 0x04 +#define DBG_HFS_UPDATE_MODIFIED 0x08 +#define DBG_HFS_UPDATE_FORCE 0x10 +#define DBG_HFS_UPDATE_DATEADDED 0x20 +#define DBG_HFS_UPDATE_MINOR 0x40 +#define DBG_HFS_UPDATE_SKIPPED 0x80 + /* The Kernel Debug Sub Classes for BSD */ -#define DBG_BSD_PROC 0x01 /* process/signals related */ -#define DBG_BSD_MEMSTAT 0x02 /* memorystatus / jetsam operations */ -#define DBG_BSD_EXCP_SC 0x0C /* System Calls */ -#define DBG_BSD_AIO 0x0D /* aio (POSIX async IO) */ -#define DBG_BSD_SC_EXTENDED_INFO 0x0E /* System Calls, extended info */ -#define DBG_BSD_SC_EXTENDED_INFO2 0x0F /* System Calls, extended info */ +#define DBG_BSD_PROC 0x01 /* process/signals related */ +#define DBG_BSD_MEMSTAT 0x02 /* memorystatus / jetsam operations */ +#define DBG_BSD_EXCP_SC 0x0C /* System Calls */ +#define DBG_BSD_AIO 0x0D /* aio (POSIX async IO) */ +#define DBG_BSD_SC_EXTENDED_INFO 0x0E /* System Calls, extended info */ +#define DBG_BSD_SC_EXTENDED_INFO2 0x0F /* System Calls, extended info */ +#define DBG_BSD_KDEBUG_TEST 0xFF /* for testing kdebug */ /* The Codes for BSD subcode class DBG_BSD_PROC */ -#define BSD_PROC_EXIT 1 /* process exit */ -#define BSD_PROC_FRCEXIT 2 /* Kernel force termination */ +#define BSD_PROC_EXIT 1 /* process exit */ +#define BSD_PROC_FRCEXIT 2 /* Kernel force termination */ +#define BSD_PROC_EXEC 3 /* process spawn / exec */ +#define BSD_PROC_EXITREASON_CREATE 4 /* exit reason creation */ +#define BSD_PROC_EXITREASON_COMMIT 5 /* exit reason commited to a proc */ /* Codes for BSD subcode class DBG_BSD_MEMSTAT */ #define BSD_MEMSTAT_SCAN 1 /* memorystatus thread awake */ @@ -418,23 +690,38 @@ extern void kernel_debug_enter( #define BSD_MEMSTAT_JETSAM_HIWAT 3 /* highwater jetsam */ #define BSD_MEMSTAT_FREEZE 4 /* freeze process */ #define BSD_MEMSTAT_LATENCY_COALESCE 5 /* delay imposed to coalesce jetsam reports */ -#define BSD_MEMSTAT_UPDATE 6 /* priority update */ +#define BSD_MEMSTAT_UPDATE 6 /* priority update */ #define BSD_MEMSTAT_IDLE_DEMOTE 7 /* idle demotion fired */ #define BSD_MEMSTAT_CLEAR_ERRORS 8 /* reset termination error state */ #define BSD_MEMSTAT_DIRTY_TRACK 9 /* track the process state */ #define BSD_MEMSTAT_DIRTY_SET 10 /* set the process state */ #define BSD_MEMSTAT_DIRTY_CLEAR 11 /* clear the process state */ +#ifdef PRIVATE +#define BSD_MEMSTAT_GRP_SET_PROP 12 /* set group properties */ +#define BSD_MEMSTAT_DO_KILL 13 /* memorystatus kills */ +#endif /* PRIVATE */ /* The Kernel Debug Sub Classes for DBG_TRACE */ #define DBG_TRACE_DATA 0 #define DBG_TRACE_STRING 1 #define DBG_TRACE_INFO 2 -/* - * TRACE_DATA_NEWTHREAD 0x1 - * TRACE_DATA_EXEC 0x2 - */ -#define TRACE_DATA_THREAD_TERMINATE 0x3 /* thread has been queued for deallocation and can no longer run */ +/* The Kernel Debug events: */ +#define TRACE_DATA_NEWTHREAD (TRACEDBG_CODE(DBG_TRACE_DATA, 1)) +#define TRACE_DATA_EXEC (TRACEDBG_CODE(DBG_TRACE_DATA, 2)) +#define TRACE_DATA_THREAD_TERMINATE (TRACEDBG_CODE(DBG_TRACE_DATA, 3)) +#define TRACE_DATA_THREAD_TERMINATE_PID (TRACEDBG_CODE(DBG_TRACE_DATA, 4)) +#define TRACE_STRING_GLOBAL (TRACEDBG_CODE(DBG_TRACE_STRING, 0)) +#define TRACE_STRING_NEWTHREAD (TRACEDBG_CODE(DBG_TRACE_STRING, 1)) +#define TRACE_STRING_EXEC (TRACEDBG_CODE(DBG_TRACE_STRING, 2)) +#define TRACE_STRING_PROC_EXIT (TRACEDBG_CODE(DBG_TRACE_STRING, 3)) +#define TRACE_STRING_THREADNAME (TRACEDBG_CODE(DBG_TRACE_STRING, 4)) +#define TRACE_STRING_THREADNAME_PREV (TRACEDBG_CODE(DBG_TRACE_STRING, 5)) +#define TRACE_PANIC (TRACEDBG_CODE(DBG_TRACE_INFO, 0)) +#define TRACE_TIMESTAMPS (TRACEDBG_CODE(DBG_TRACE_INFO, 1)) +#define TRACE_LOST_EVENTS (TRACEDBG_CODE(DBG_TRACE_INFO, 2)) +#define TRACE_WRITING_EVENTS (TRACEDBG_CODE(DBG_TRACE_INFO, 3)) +#define TRACE_INFO_STRING (TRACEDBG_CODE(DBG_TRACE_INFO, 4)) /* The Kernel Debug Sub Classes for DBG_CORESTORAGE */ #define DBG_CS_IO 0 @@ -449,7 +736,24 @@ extern void kernel_debug_enter( #define DBG_BUFFER 0x20 /* The Kernel Debug Sub Classes for DBG_DYLD */ -#define DBG_DYLD_STRING 5 +#define DBG_DYLD_UUID (5) + +/* Kernel Debug codes for the DBG_DYLD_UUID subclass */ +#define DBG_DYLD_UUID_MAP_A (0) +#define DBG_DYLD_UUID_MAP_B (1) +#define DBG_DYLD_UUID_MAP_32_A (2) +#define DBG_DYLD_UUID_MAP_32_B (3) +#define DBG_DYLD_UUID_MAP_32_C (4) +#define DBG_DYLD_UUID_UNMAP_A (5) +#define DBG_DYLD_UUID_UNMAP_B (6) +#define DBG_DYLD_UUID_UNMAP_32_A (7) +#define DBG_DYLD_UUID_UNMAP_32_B (8) +#define DBG_DYLD_UUID_UNMAP_32_C (9) +#define DBG_DYLD_UUID_SHARED_CACHE_A (10) +#define DBG_DYLD_UUID_SHARED_CACHE_B (11) +#define DBG_DYLD_UUID_SHARED_CACHE_32_A (12) +#define DBG_DYLD_UUID_SHARED_CACHE_32_B (13) +#define DBG_DYLD_UUID_SHARED_CACHE_32_C (14) /* The Kernel Debug modifiers for the DBG_DKRW sub class */ #define DKIO_DONE 0x01 @@ -466,11 +770,16 @@ extern void kernel_debug_enter( /* Kernel Debug Sub Classes for Applications (DBG_APPS) */ #define DBG_APP_LOGINWINDOW 0x03 #define DBG_APP_AUDIO 0x04 +#define DBG_APP_SYSTEMUI 0x05 +#define DBG_APP_SIGNPOST 0x0A +#define DBG_APP_APPKIT 0x0C +#define DBG_APP_DFR 0x0E #define DBG_APP_SAMBA 0x80 +#define DBG_APP_EOSSUPPORT 0x81 /* Kernel Debug codes for Throttling (DBG_THROTTLE) */ #define OPEN_THROTTLE_WINDOW 0x1 -#define PROCESS_THROTTLED 0x2 +#define PROCESS_THROTTLED 0x2 #define IO_THROTTLE_DISABLE 0x3 @@ -517,16 +826,17 @@ extern void kernel_debug_enter( #define BANK_TASK_INFO 0x11 /* Trace points related to bank task struct */ /* Subclasses for MACH ATM Voucher Attribute Manager (ATM) */ -#define ATM_SUBAID_INFO 0x10 -#define ATM_GETVALUE_INFO 0x20 -#define ATM_UNREGISTER_INFO 0x30 +#define ATM_SUBAID_INFO 0x10 +#define ATM_GETVALUE_INFO 0x20 +#define ATM_UNREGISTER_INFO 0x30 /* Codes for BANK_ACCOUNT_INFO */ #define BANK_SETTLE_CPU_TIME 0x1 /* Bank ledger(chit) rolled up to tasks. */ +#define BANK_SECURE_ORIGINATOR_CHANGED 0x2 /* Secure Originator changed. */ /* Codes for ATM_SUBAID_INFO */ #define ATM_MIN_CALLED 0x1 -#define ATM_MIN_LINK_LIST 0x2 +#define ATM_LINK_LIST_TRIM 0x2 /* Codes for ATM_GETVALUE_INFO */ #define ATM_VALUE_REPLACED 0x1 @@ -536,11 +846,16 @@ extern void kernel_debug_enter( #define ATM_VALUE_UNREGISTERED 0x1 #define ATM_VALUE_DIFF_MAILBOX 0x2 -/**********************************************************************/ +/* Kernel Debug Sub Classes for daemons (DBG_DAEMON) */ +#define DBG_DAEMON_COREDUET 0x1 -#define KDBG_CODE(Class, SubClass, code) (((Class & 0xff) << 24) | ((SubClass & 0xff) << 16) | ((code & 0x3fff) << 2)) +/* Subclasses for the user space allocator */ +#define DBG_UMALLOC_EXTERNAL 0x1 +#define DBG_UMALLOC_INTERNAL 0x2 +/**********************************************************************/ -#define KDBG_MIGCODE(msgid) ((DBG_MIG << 24) | (((msgid) & 0x3fffff) << 2)) +#define KDBG_MIGCODE(msgid) ((DBG_MIG << KDBG_CLASS_OFFSET) | \ + (((msgid) & 0x3fffff) << KDBG_CODE_OFFSET)) #define MACHDBG_CODE(SubClass, code) KDBG_CODE(DBG_MACH, SubClass, code) #define NETDBG_CODE(SubClass, code) KDBG_CODE(DBG_NETWORK, SubClass, code) @@ -555,6 +870,8 @@ extern void kernel_debug_enter( #define DYLDDBG_CODE(SubClass,code) KDBG_CODE(DBG_DYLD, SubClass, code) #define QTDBG_CODE(SubClass,code) KDBG_CODE(DBG_QT, SubClass, code) #define APPSDBG_CODE(SubClass,code) KDBG_CODE(DBG_APPS, SubClass, code) +#define ARIADNEDBG_CODE(SubClass, code) KDBG_CODE(DBG_ARIADNE, SubClass, code) +#define DAEMONDBG_CODE(SubClass, code) KDBG_CODE(DBG_DAEMON, SubClass, code) #define CPUPM_CODE(code) IOKDBG_CODE(DBG_IOCPUPM, code) #define KMEM_ALLOC_CODE MACHDBG_CODE(DBG_MACH_LEAKS, 0) @@ -573,43 +890,98 @@ extern void kernel_debug_enter( #define BANK_CODE(SubClass, code) KDBG_CODE(DBG_BANK, (SubClass), (code)) #define ATM_CODE(SubClass, code) KDBG_CODE(DBG_ATM, (SubClass), (code)) -/* Usage: -* kernel_debug((KDBG_CODE(DBG_NETWORK, DNET_PROTOCOL, 51) | DBG_FUNC_START), -* offset, 0, 0, 0,0) -* -* For ex, -* -* #include -* -* #define DBG_NETIPINIT NETDBG_CODE(DBG_NETIP,1) -* -* -* void -* ip_init() -* { -* register struct protosw *pr; -* register int i; -* -* KERNEL_DEBUG(DBG_NETIPINIT | DBG_FUNC_START, 0,0,0,0,0) -* -------- -* KERNEL_DEBUG(DBG_NETIPINIT, 0,0,0,0,0) -* -------- -* KERNEL_DEBUG(DBG_NETIPINIT | DBG_FUNC_END, 0,0,0,0,0) -* } -* +/* Kernel Debug Macros for specific daemons */ +#define COREDUETDBG_CODE(code) DAEMONDBG_CODE(DBG_DAEMON_COREDUET, code) -*/ +/* + * To use kdebug in the kernel: + * + * #include + * + * #define DBG_NETIPINIT NETDBG_CODE(DBG_NETIP, 1) + * + * void + * ip_init(void) + * { + * KDBG(DBG_NETIPINIT | DBG_FUNC_START, 1, 2, 3, 4); + * ... + * KDBG(DBG_NETIPINIT); + * ... + * KDBG(DBG_NETIPINIT | DBG_FUNC_END); + * } + */ + +#ifdef KERNEL_PRIVATE + +/* + * The KDBG{,_DEBUG,_RELEASE,_FILTERED} macros are the preferred method of + * making tracepoints. + * + * Kernel pointers must be unslid or permuted using VM_KERNEL_UNSLIDE_OR_PERM. + * Do not trace any sensitive data. + */ + +/* + * Traced on debug and development (and release OS X) kernels. + */ +#define KDBG(x, ...) KDBG_(, x, ## __VA_ARGS__, 4, 3, 2, 1, 0) + +/* + * Traced on debug and development (and release OS X) kernels if explicitly + * requested. Omitted from tracing without a typefilter. + */ +#define KDBG_FILTERED(x, ...) KDBG_(_FILTERED, x, ## __VA_ARGS__, 4, 3, 2, 1, 0) + +/* + * Traced on debug, development, and release kernels. + * + * Only use this tracepoint if the events are required for a shipping trace + * tool. + */ +#define KDBG_RELEASE(x, ...) KDBG_(_RELEASE, x, ## __VA_ARGS__, 4, 3, 2, 1, 0) + +/* + * Traced only on debug kernels. + */ +#define KDBG_DEBUG(x, ...) KDBG_(_DEBUG, x, ## __VA_ARGS__, 4, 3, 2, 1, 0) + +#define KDBG_(f, x, a, b, c, d, n, ...) KDBG##n(f, x, a, b, c, d) +#define KDBG0(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, 0, 0, 0, 0, 0) +#define KDBG1(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, a, 0, 0, 0, 0) +#define KDBG2(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, a, b, 0, 0, 0) +#define KDBG3(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, a, b, c, 0, 0) +#define KDBG4(f, x, a, b, c, d) KERNEL_DEBUG_CONSTANT##f(x, a, b, c, d, 0) + +#endif /* defined(KERNEL_PRIVATE) */ extern unsigned int kdebug_enable; -#define KDEBUG_ENABLE_TRACE 0x1 -#define KDEBUG_ENABLE_ENTROPY 0x2 /* Obsolescent */ -#define KDEBUG_ENABLE_CHUD 0x4 -#define KDEBUG_ENABLE_PPT 0x8 /* - * Infer the supported kernel debug event level from config option. - * Use (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) as a guard to protect - * unaudited debug code. + * Bits used by kdebug_enable. These control which events are traced at + * runtime. + */ +#define KDEBUG_ENABLE_TRACE (1U << 0) +#define KDEBUG_ENABLE_ENTROPY (1U << 1) /* obsolete */ +#define KDEBUG_ENABLE_CHUD (1U << 2) /* obsolete */ +#define KDEBUG_ENABLE_PPT (1U << 3) +#define KDEBUG_ENABLE_SERIAL (1U << 4) + +#define KDEBUG_TRACE (KDEBUG_ENABLE_TRACE) + +/* + * Specify KDEBUG_PPT to indicate that the event belongs to the limited PPT set. + * PPT is deprecated -- use a typefilter and the PPTDBG class instead. + */ +#define KDEBUG_PPT (KDEBUG_ENABLE_PPT) +#define KDEBUG_COMMON (KDEBUG_ENABLE_TRACE | KDEBUG_ENABLE_PPT) + +/* + * The kernel debug configuration level. These values control which events are + * compiled in under different build configurations. + * + * Infer the supported kernel debug event level from config option. Use + * (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) as a guard to protect unaudited debug + * code. */ #define KDEBUG_LEVEL_NONE 0 #define KDEBUG_LEVEL_IST 1 @@ -617,68 +989,140 @@ extern unsigned int kdebug_enable; #define KDEBUG_LEVEL_FULL 3 #if NO_KDEBUG -#define KDEBUG_LEVEL KDEBUG_LEVEL_NONE +#define KDEBUG_LEVEL KDEBUG_LEVEL_NONE #elif IST_KDEBUG #define KDEBUG_LEVEL KDEBUG_LEVEL_IST + // currently configured for the iOS release kernel #elif KDEBUG #define KDEBUG_LEVEL KDEBUG_LEVEL_FULL #else #define KDEBUG_LEVEL KDEBUG_LEVEL_STANDARD +/* + * Currently, all other kernel configurations (development, etc) build with + * KDEBUG_LEVEL_STANDARD. As a result, KERNEL_DEBUG_CONSTANT*() are on by + * default but KERNEL_DEBUG*() are not. + */ #endif -#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) -#define KERNEL_DEBUG_CONSTANT(x,a,b,c,d,e) \ -do { \ - if (kdebug_enable & ~KDEBUG_ENABLE_PPT) \ - kernel_debug(x,(uintptr_t)a,(uintptr_t)b,(uintptr_t)c, \ - (uintptr_t)d,(uintptr_t)e); \ -} while(0) - -#define KERNEL_DEBUG_CONSTANT1(x,a,b,c,d,e) \ -do { \ - if (kdebug_enable & ~KDEBUG_ENABLE_PPT) \ - kernel_debug1(x,(uintptr_t)a,(uintptr_t)b,(uintptr_t)c, \ - (uintptr_t)d,(uintptr_t)e); \ -} while(0) +#ifdef XNU_KERNEL_PRIVATE +#define KDBG_IMPROBABLE __improbable +#else +#define KDBG_IMPROBABLE +#endif -#define KERNEL_DEBUG_EARLY(x,a,b,c,d) \ -do { \ - kernel_debug_early((uint32_t)x, (uintptr_t)a, (uintptr_t)b, \ - (uintptr_t)c, (uintptr_t)d); \ -} while(0) +/* + * KERNEL_DEBUG_CONSTANT_FILTERED events are omitted from tracing unless they + * are explicitly requested in the typefilter. They are not emitted when + * tracing without a typefilter. + */ +#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) +#define KERNEL_DEBUG_CONSTANT_FILTERED(x, a, b, c, d, ...) \ + do { \ + if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \ + kernel_debug_filtered((x), (uintptr_t)(a), (uintptr_t)(b), \ + (uintptr_t)(c), (uintptr_t)(d)); \ + } \ + } while (0) #else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) */ -#define KERNEL_DEBUG_CONSTANT(x,a,b,c,d,e) do { } while(0) -#define KERNEL_DEBUG_CONSTANT1(x,a,b,c,d,e) do { } while(0) -#define KERNEL_DEBUG_EARLY(x,a,b,c,d) do { } while(0) +#define KERNEL_DEBUG_CONSTANT_FILTERED(type, x, a, b, c, d, ...) do {} while (0) #endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) */ -/* - * Specify KDEBUG_PPT to indicate that the event belongs to the - * limited PPT set. +#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) +#define KERNEL_DEBUG_CONSTANT(x, a, b, c, d, e) \ + do { \ + if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \ + kernel_debug((x), (uintptr_t)(a), (uintptr_t)(b), (uintptr_t)(c), \ + (uintptr_t)(d),(uintptr_t)(e)); \ + } \ + } while (0) + +/* + * DO NOT USE THIS MACRO -- it breaks fundamental assumptions about ktrace and + * is only meant to be used by the pthread kext and other points in the kernel + * where the thread ID must be provided explicitly. */ -#define KDEBUG_COMMON (KDEBUG_ENABLE_TRACE|KDEBUG_ENABLE_CHUD|KDEBUG_ENABLE_PPT) -#define KDEBUG_TRACE (KDEBUG_ENABLE_TRACE|KDEBUG_ENABLE_CHUD) -#define KDEBUG_PPT (KDEBUG_ENABLE_PPT) +#define KERNEL_DEBUG_CONSTANT1(x, a, b, c, d, e) \ + do { \ + if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \ + kernel_debug1((x), (uintptr_t)(a), (uintptr_t)(b), (uintptr_t)(c), \ + (uintptr_t)(d), (uintptr_t)(e)); \ + } \ + } while (0) + +#define KERNEL_DEBUG_EARLY(x, a, b, c, d) \ + do { \ + kernel_debug_early((uint32_t)(x), (uintptr_t)(a), (uintptr_t)(b), \ + (uintptr_t)(c), (uintptr_t)(d)); \ + } while (0) +#else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) */ +#define KERNEL_DEBUG_CONSTANT(x, a, b, c, d, e) do {} while (0) +#define KERNEL_DEBUG_CONSTANT1(x, a, b, c, d, e) do {} while (0) +#define KERNEL_DEBUG_EARLY(x, a, b, c, d) do {} while (0) +#endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_STANDARD) */ /* - * KERNEL_DEBUG_CONSTANT_IST events provide an audited subset of - * tracepoints for userland system tracing tools. + * KERNEL_DEBUG_CONSTANT_IST (in-system trace) events provide an audited subset + * of tracepoints for userland system tracing tools. This tracing level was + * created by 8857227 to protect fairplayd and other PT_DENY_ATTACH processes. + * It has two effects: only KERNEL_DEBUG_CONSTANT_IST() traces are emitted and + * any PT_DENY_ATTACH processes will only emit basic traces as defined by the + * kernel_debug_filter() routine. */ +#define KERNEL_DEBUG_CONSTANT_RELEASE(x, a, b, c, d, e) \ + KERNEL_DEBUG_CONSTANT_IST(~KDEBUG_ENABLE_PPT, x, a, b, c, d, 0) + #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) -#define KERNEL_DEBUG_CONSTANT_IST(type,x,a,b,c,d,e) \ -do { \ - if (kdebug_enable & type) \ - kernel_debug(x,(uintptr_t)a,(uintptr_t)b,(uintptr_t)c, \ - (uintptr_t)d,(uintptr_t)e); \ -} while(0) +#define KERNEL_DEBUG_CONSTANT_IST(type, x, a, b, c, d, e) \ + do { \ + if (KDBG_IMPROBABLE(kdebug_enable & (type))) { \ + kernel_debug((x), (uintptr_t)(a), (uintptr_t)(b), (uintptr_t)(c), \ + (uintptr_t)(d), (uintptr_t)(e)); \ + } \ + } while (0) #else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */ -#define KERNEL_DEBUG_CONSTANT_IST(type,x,a,b,c,d,e) do { } while(0) +#define KERNEL_DEBUG_CONSTANT_IST(type, x, a, b, c, d, e) do {} while (0) #endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */ #if NO_KDEBUG #define __kdebug_constant_only __unused #endif +/* + * KERNEL_DEBUG events are only traced for DEBUG kernels. + */ +#define KERNEL_DEBUG_CONSTANT_DEBUG(x, a, b, c, d, e) \ + KERNEL_DEBUG(x, a, b, c, d, e) + +#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_FULL) +#define __kdebug_only + +#define KERNEL_DEBUG(x, a, b, c, d, e) \ + do { \ + if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \ + kernel_debug((uint32_t)(x), (uintptr_t)(a), (uintptr_t)(b), \ + (uintptr_t)(c), (uintptr_t)(d), (uintptr_t)(e)); \ + } \ + } while (0) + +/* + * DO NOT USE THIS MACRO -- see warning above for KERNEL_DEBUG_CONSTANT1. + */ +#define KERNEL_DEBUG1(x, a, b, c, d, e) \ + do { \ + if (KDBG_IMPROBABLE(kdebug_enable & ~KDEBUG_ENABLE_PPT)) { \ + kernel_debug1((uint32_t)(x), (uintptr_t)(a), (uintptr_t)(b), \ + (uintptr_t)(c), (uintptr_t)(d), (uintptr_t)(e)); \ + } \ + } while (0) + +#else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_FULL) */ +#define __kdebug_only __unused + +#define KERNEL_DEBUG(x,a,b,c,d,e) do {} while (0) +#define KERNEL_DEBUG1(x,a,b,c,d,e) do {} while (0) +#endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_FULL) */ + + extern void kernel_debug( uint32_t debugid, uintptr_t arg1, @@ -695,6 +1139,13 @@ extern void kernel_debug1( uintptr_t arg4, uintptr_t arg5); +extern void kernel_debug_filtered( + uint32_t debugid, + uintptr_t arg1, + uintptr_t arg2, + uintptr_t arg3, + uintptr_t arg4); + extern void kernel_debug_early( uint32_t debugid, uintptr_t arg1, @@ -702,35 +1153,483 @@ extern void kernel_debug_early( uintptr_t arg3, uintptr_t arg4); -extern void kernel_debug_string( - const char *message); +/* + * EnergyTracing macros. + */ -#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_FULL) -#define KERNEL_DEBUG(x,a,b,c,d,e) \ +#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) +// whether to bother calculating EnergyTracing inputs +// could change in future to see if DBG_ENERGYTRACE is active +#define ENTR_SHOULDTRACE kdebug_enable +// encode logical EnergyTracing into 32/64 KDebug trace +#define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) \ do { \ - if (kdebug_enable & ~KDEBUG_ENABLE_PPT) \ - kernel_debug((uint32_t)x, (uintptr_t)a, (uintptr_t)b, \ - (uintptr_t)c, (uintptr_t)d, (uintptr_t)e); \ + uint32_t kdcode__; \ + uintptr_t highval__, lowval__, mask__ = 0xffffffff; \ + kdcode__ = KDBG_CODE(DBG_ENERGYTRACE,component,opcode)|(lifespan); \ + highval__ = ((value) >> 32) & mask__; \ + lowval__ = (value) & mask__; \ + ENTR_KDTRACEFUNC(kdcode__, id, quality, highval__, lowval__); \ } while(0) -#define KERNEL_DEBUG1(x,a,b,c,d,e) \ +/* + Trace the association of two existing activations. + + An association is traced as a modification to the parent activation. + In order to fit the sub-activation's component, activation code, and + activation ID into a kdebug tracepoint, the arguments that would hold + the value are left separate, and one stores the component and opcode + of the sub-activation, while the other stores the pointer-sized + activation ID. + + arg2 arg3 arg4 + +-----------------+ +~+----+----+--------+ +----------+ + |kEnTrModAssociate| | | | | | | | + +-----------------+ +~+----+----+--------+ +----------+ + 8-bits unused sub-activation ID + 8-bit sub-component + 16-bit sub-opcode + +*/ +#define kEnTrModAssociate (1 << 28) +#define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, \ + sub_comp, sub_opcode, sub_act_id) \ do { \ - if (kdebug_enable & ~KDEBUG_ENABLE_PPT) \ - kernel_debug1((uint32_t)x, (uintptr_t)a, (uintptr_t)b, \ - (uintptr_t)c, (uintptr_t)d, (uintptr_t)e); \ + unsigned sub_compcode = ((unsigned)sub_comp << 16) | sub_opcode; \ + ENTR_KDTRACEFUNC(KDBG_CODE(DBG_ENERGYTRACE,par_comp,par_opcode), \ + par_act_id, kEnTrModAssociate, sub_compcode, \ + sub_act_id); \ } while(0) -#else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_FULL) */ -#define KERNEL_DEBUG(x,a,b,c,d,e) do {} while (0) -#define KERNEL_DEBUG1(x,a,b,c,d,e) do {} while (0) -#define __kdebug_only __unused -#endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_FULL) */ +#else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */ + +#define ENTR_SHOULDTRACE FALSE +#define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) \ + do {} while (0) +#define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, \ + sub_comp, sub_opcode, sub_act_id) \ + do {} while (0) + +#endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */ + +#ifdef KERNEL_PRIVATE +/* + * kernel_debug_string provides the same functionality as the + * kdebug_trace_string syscall as a KPI. str_id is an in/out + * parameter that, if it's pointing to a string ID of 0, will + * receive a generated ID. If it provides a value in str_id, + * then that will be used, instead. + * + * Returns an errno indicating the type of failure. + */ +extern int +kernel_debug_string(uint32_t debugid, uint64_t *str_id, const char *str); + +/* + * kernel_debug_disable disables event logging, but leaves any buffers + * intact. + */ +extern void kernel_debug_disable(void); +#endif + +/* + * Bits set in the comm page for kdebug. + */ +#define KDEBUG_COMMPAGE_ENABLE_TRACE 0x1 +#define KDEBUG_COMMPAGE_ENABLE_TYPEFILTER 0x2 /* Forced to false if ENABLE_TRACE is 0 */ + +// for EnergyTracing user space & clients +#define kEnTrCompKernel 2 + +/* + EnergyTracing opcodes + + Activations use DBG_FUNC_START/END. + Events are DBG_FUNC_NONE. + */ + +/* Socket reads and writes are uniquely identified by the (sanitized) + pointer to the socket struct in question. To associate this address + with the user space file descriptor, we have a socket activation with + the FD as its identifier and the socket struct pointer as its value. +*/ +#define kEnTrActKernSocket 1 +#define kEnTrActKernSockRead 2 +#define kEnTrActKernSockWrite 3 + +#define kEnTrActKernPoll 10 +#define kEnTrActKernSelect 11 +#define kEnTrActKernKQWait 12 + +// events +#define kEnTrEvUnblocked 256 + +// EnergyTracing flags (the low-order 16 bits of 'quality') +#define kEnTrFlagNonBlocking 1 << 0 +#define kEnTrFlagNoWork 1 << 1 + +// and now the internal mechanism +#ifdef KERNEL_PRIVATE +// 20452597 requests that the trace macros not take an argument it throws away +#define KERNEL_DBG_IST_SANE(x, a, b, c, d) \ + KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE, x, a, b, c, d, \ + 0 /*__unused in kernel_debug()*/) +#define ENTR_KDTRACEFUNC KERNEL_DBG_IST_SANE +// value is int64_t, quality is uint32_t +#define KERNEL_ENERGYTRACE(opcode, lifespan, id, quality, value) \ + ENTR_KDTRACE(kEnTrCompKernel, opcode, lifespan, id, \ + quality, value) +#define KERNEL_ENTR_ASSOCIATE(par_opcode, par_act_id, sub_opcode, sub_act_id) \ + ENTR_KDASSOCIATE(kEnTrCompKernel, par_opcode, par_act_id, \ + kEnTrCompKernel, sub_opcode, sub_act_id) +// end EnergyTracing + + +#include + +#define NUMPARMS 23 + +struct proc; + +extern boolean_t kdebug_debugid_enabled(uint32_t debugid); +extern uint32_t kdebug_commpage_state(void); +extern void kdebug_lookup_gen_events(long *dbg_parms, int dbg_namelen, void *dp, boolean_t lookup); +extern void kdbg_trace_data(struct proc *proc, long *arg_pid); + +extern void kdbg_trace_string(struct proc *proc, long *arg1, long *arg2, long *arg3, long *arg4); + +extern void kdbg_dump_trace_to_file(const char *); +void kdebug_boot_trace(unsigned int n_events, char *filterdesc); +void kdebug_trace_start(unsigned int n_events, const char *filterdesc, boolean_t need_map); +struct task; +extern void kdbg_get_task_name(char*, int, struct task *task); +boolean_t disable_wrap(uint32_t *old_slowcheck, uint32_t *old_flags); +void enable_wrap(uint32_t old_slowcheck, boolean_t lostevents); +void release_storage_unit(int cpu, uint32_t storage_unit); +int allocate_storage_unit(int cpu); + +#define KDBG_CLASS_ENCODE(Class, SubClass) KDBG_EVENTID(Class, SubClass, 0) +#define KDBG_CLASS_DECODE(Debugid) (Debugid & KDBG_CSC_MASK) + +#endif /* KERNEL_PRIVATE */ #endif /* __APPLE_API_UNSTABLE */ __END_DECLS +#ifdef PRIVATE +#ifdef __APPLE_API_PRIVATE +/* + * private kernel_debug definitions + */ + +typedef struct { + uint64_t timestamp; + uintptr_t arg1; + uintptr_t arg2; + uintptr_t arg3; + uintptr_t arg4; + uintptr_t arg5; /* the thread ID */ + uint32_t debugid; +#if defined(__LP64__) + uint32_t cpuid; + uintptr_t unused; +#endif +} kd_buf; + +#if !defined(__LP64__) +#define KDBG_TIMESTAMP_MASK 0x00ffffffffffffffULL +#define KDBG_CPU_MASK 0xff00000000000000ULL +#define KDBG_CPU_SHIFT 56 +static inline void +kdbg_set_cpu(kd_buf *kp, int cpu) +{ + kp->timestamp = (kp->timestamp & KDBG_TIMESTAMP_MASK) | + (((uint64_t) cpu) << KDBG_CPU_SHIFT); +} +static inline int +kdbg_get_cpu(kd_buf *kp) +{ + return (int) (((kp)->timestamp & KDBG_CPU_MASK) >> KDBG_CPU_SHIFT); +} +static inline void +kdbg_set_timestamp(kd_buf *kp, uint64_t thetime) +{ + kp->timestamp = thetime & KDBG_TIMESTAMP_MASK; +} +static inline uint64_t +kdbg_get_timestamp(kd_buf *kp) +{ + return kp->timestamp & KDBG_TIMESTAMP_MASK; +} +static inline void +kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu) +{ + kp->timestamp = (thetime & KDBG_TIMESTAMP_MASK) | + (((uint64_t) cpu) << KDBG_CPU_SHIFT); +} +#else +#define KDBG_TIMESTAMP_MASK 0xffffffffffffffffULL +static inline void +kdbg_set_cpu(kd_buf *kp, int cpu) +{ + kp->cpuid = cpu; +} +static inline int +kdbg_get_cpu(kd_buf *kp) +{ + return kp->cpuid; +} +static inline void +kdbg_set_timestamp(kd_buf *kp, uint64_t thetime) +{ + kp->timestamp = thetime; +} +static inline uint64_t +kdbg_get_timestamp(kd_buf *kp) +{ + return kp->timestamp; +} +static inline void +kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu) +{ + kdbg_set_timestamp(kp, thetime); + kdbg_set_cpu(kp, cpu); +} +#endif + +/* + * 2^16 bits (8 kilobytes), one for each possible class/subclass combination + */ +#define KDBG_TYPEFILTER_BITMAP_SIZE ((256 * 256) / 8) + +/* + * Bits for kd_ctrl_page.flags, KERN_KD{D,E}FLAGS. + */ +#define KDBG_INIT (1U << 0) /* obsolete */ +/* disable tracing when buffers are full */ +#define KDBG_NOWRAP (1U << 1) +#define KDBG_FREERUN (1U << 2) /* obsolete */ +/* buffer has wrapped */ +#define KDBG_WRAPPED (1U << 3) +/* flags that are allowed to be set by user space */ +#define KDBG_USERFLAGS (KDBG_FREERUN | KDBG_NOWRAP | KDBG_INIT) +/* only include processes with kdebug bit set in proc */ +#define KDBG_PIDCHECK (1U << 4) +/* thread map is initialized */ +#define KDBG_MAPINIT (1U << 5) +/* exclude processes based on kdebug bit in proc */ +#define KDBG_PIDEXCLUDE (1U << 6) +/* whether the kdebug locks are intialized */ +#define KDBG_LOCKINIT (1U << 7) +/* word size of the kernel */ +#define KDBG_LP64 (1U << 8) + +/* bits for kd_ctrl_page.flags and kbufinfo_t.flags */ + +/* only trace events within a range */ +#define KDBG_RANGECHECK 0x00100000U +/* only trace at most 4 types of events, at the code granularity */ +#define KDBG_VALCHECK 0x00200000U +/* check class and subclass against the typefilter */ +#define KDBG_TYPEFILTER_CHECK 0x00400000U +/* kdebug trace buffers are initialized */ +#define KDBG_BUFINIT 0x80000000U + +/* bits for the type field of kd_regtype */ +#define KDBG_CLASSTYPE 0x10000 +#define KDBG_SUBCLSTYPE 0x20000 +#define KDBG_RANGETYPE 0x40000 +#define KDBG_TYPENONE 0x80000 +#define KDBG_CKTYPES 0xF0000 + +typedef struct { + unsigned int type; + unsigned int value1; + unsigned int value2; + unsigned int value3; + unsigned int value4; +} kd_regtype; + +typedef struct { + /* number of events that can fit in the buffers */ + int nkdbufs; + /* set if trace is disabled */ + int nolog; + /* kd_ctrl_page.flags */ + unsigned int flags; + /* number of threads in thread map */ + int nkdthreads; + /* the owning pid */ + int bufid; +} kbufinfo_t; + +typedef struct { + /* the thread ID */ + uintptr_t thread; + /* 0 for invalid, otherwise the PID (or 1 for kernel_task) */ + int valid; + /* the name of the process owning the thread */ + char command[20]; +} kd_threadmap; + +typedef struct { + uint32_t version_no; + uint32_t cpu_count; +} kd_cpumap_header; + +/* cpumap flags */ +#define KDBG_CPUMAP_IS_IOP 0x1 + +typedef struct { + uint32_t cpu_id; + uint32_t flags; + char name[8]; +} kd_cpumap; + +/* + * TRACE file formats... + * + * RAW_VERSION0 + * + * uint32_t #threadmaps + * kd_threadmap[] + * kd_buf[] + * + * RAW_VERSION1 + * + * RAW_header, with version_no set to RAW_VERSION1 + * kd_threadmap[] + * Empty space to pad alignment to the nearest page boundary. + * kd_buf[] + * + * RAW_VERSION1+ + * + * RAW_header, with version_no set to RAW_VERSION1 + * kd_threadmap[] + * kd_cpumap_header, with version_no set to RAW_VERSION1 + * kd_cpumap[] + * Empty space to pad alignment to the nearest page boundary. + * kd_buf[] + * + * V1+ implementation details... + * + * It would have been nice to add the cpumap data "correctly", but there were + * several obstacles. Existing code attempts to parse both V1 and V0 files. + * Due to the fact that V0 has no versioning or header, the test looks like + * this: + * + * // Read header + * if (header.version_no != RAW_VERSION1) { // Assume V0 } + * + * If we add a VERSION2 file format, all existing code is going to treat that + * as a VERSION0 file when reading it, and crash terribly when trying to read + * RAW_VERSION2 threadmap entries. + * + * To differentiate between a V1 and V1+ file, read as V1 until you reach + * the padding bytes. Then: + * + * boolean_t is_v1plus = FALSE; + * if (padding_bytes >= sizeof(kd_cpumap_header)) { + * kd_cpumap_header header = // read header; + * if (header.version_no == RAW_VERSION1) { + * is_v1plus = TRUE; + * } + * } + * + */ + +typedef struct { + int version_no; + int thread_count; + uint64_t TOD_secs; + uint32_t TOD_usecs; +} RAW_header; + +// Version 3 header +// The header chunk has the tag 0x00001000 which also serves as a magic word +// that identifies the file as a version 3 trace file. The header payload is +// a set of fixed fields followed by a variable number of sub-chunks: +/* + ____________________________________________________________________________ + | Offset | Size | Field | + ---------------------------------------------------------------------------- + | 0 | 4 | Tag (0x00001000) | + | 4 | 4 | Sub-tag. Represents the version of the header. | + | 8 | 8 | Length of header payload (40+8x) | + | 16 | 8 | Time base info. Two 32-bit numbers, numer/denom, | + | | | for converting timestamps to nanoseconds. | + | 24 | 8 | Timestamp of trace start. | + | 32 | 8 | Wall time seconds since Unix epoch. | + | | | As returned by gettimeofday(). | + | 40 | 4 | Wall time microseconds. As returned by gettimeofday(). | + | 44 | 4 | Local time zone offset in minutes. ( " ) | + | 48 | 4 | Type of daylight savings time correction to apply. ( " ) | + | 52 | 4 | Flags. 1 = 64-bit. Remaining bits should be written | + | | | as 0 and ignored when reading. | + | 56 | 8x | Variable number of sub-chunks. None are required. | + | | | Ignore unknown chunks. | + ---------------------------------------------------------------------------- +*/ +// NOTE: The header sub-chunks are considered part of the header chunk, +// so they must be included in the header chunk’s length field. +// The CPU map is an optional sub-chunk of the header chunk. It provides +// information about the CPUs that are referenced from the trace events. +typedef struct { + uint32_t tag; + uint32_t sub_tag; + uint64_t length; + uint32_t timebase_numer; + uint32_t timebase_denom; + uint64_t timestamp; + uint64_t walltime_secs; + uint32_t walltime_usecs; + uint32_t timezone_minuteswest; + uint32_t timezone_dst; + uint32_t flags; +} __attribute__((packed)) kd_header_v3; + +typedef struct { + uint32_t tag; + uint32_t sub_tag; + uint64_t length; +} __attribute__((packed)) kd_chunk_header_v3; + +#define RAW_VERSION0 0x55aa0000 +#define RAW_VERSION1 0x55aa0101 +#define RAW_VERSION2 0x55aa0200 /* Only used by kperf and Instruments */ +#define RAW_VERSION3 0x00001000 + +#define V3_CONFIG 0x00001b00 +#define V3_CPU_MAP 0x00001c00 +#define V3_THREAD_MAP 0x00001d00 +#define V3_RAW_EVENTS 0x00001e00 +#define V3_NULL_CHUNK 0x00002000 + +// The current version of all kernel managed chunks is 1. The +// V3_CURRENT_CHUNK_VERSION is added to ease the simple case +// when most/all the kernel managed chunks have the same version. + +#define V3_CURRENT_CHUNK_VERSION 1 +#define V3_HEADER_VERSION V3_CURRENT_CHUNK_VERSION +#define V3_CPUMAP_VERSION V3_CURRENT_CHUNK_VERSION +#define V3_THRMAP_VERSION V3_CURRENT_CHUNK_VERSION +#define V3_EVENT_DATA_VERSION V3_CURRENT_CHUNK_VERSION + +// Apis to support writing v3 chunks in the kernel +int kdbg_write_v3_chunk_header_to_buffer(void *buffer, uint32_t tag, uint32_t sub_tag, uint64_t length); +int kdbg_write_v3_chunk_to_fd(uint32_t tag, uint32_t sub_tag, uint64_t length, void *payload, uint64_t payload_size, int fd); + +/* VFS lookup events for serial traces */ +#define VFS_LOOKUP (FSDBG_CODE(DBG_FSRW,36)) +#define VFS_LOOKUP_DONE (FSDBG_CODE(DBG_FSRW,39)) + +#if defined(XNU_KERNEL_PRIVATE) && (DEVELOPMENT || DEBUG) +#define KDEBUG_MOJO_TRACE 1 +#endif +#endif /* __APPLE_API_PRIVATE */ +#endif /* PRIVATE */ #endif /* !BSD_SYS_KDEBUG_H */ diff --git a/platform-include/sys/kdebug_signpost.h b/platform-include/sys/kdebug_signpost.h new file mode 100644 index 000000000..e4332be3b --- /dev/null +++ b/platform-include/sys/kdebug_signpost.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef BSD_SYS_KDEBUG_SIGNPOST_H +#define BSD_SYS_KDEBUG_SIGNPOST_H + +#include +#include +#include + +__BEGIN_DECLS + +#ifndef KERNEL + +/* + * In previous versions of the operating system, applications could use: + * + * syscall(SYS_kdebug_trace, APPSDBG_CODE(DBG_MACH_CHUD, ) | DBG_FUNC_, arg1, arg2, arg3, arg4); + * + * to record events that would be displayed by Instruments. + * + * syscall(2) is now deprecated and this interface replaces the above call as follows: + * + * The code argument is . Only the low 14-bits of the code are + * preserved. + */ + +/* + * When is NONE, use kdebug_signpost. + */ +int kdebug_signpost(uint32_t code, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0); + +/* + * When is START, use kdebug_signpost_start. + */ +int kdebug_signpost_start(uint32_t code, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0); + +/* + * When is END, use kdebug_signpost_end. + */ +int kdebug_signpost_end(uint32_t code, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0); + +#endif /* !KERNEL */ + +__END_DECLS + +#endif /* !BSD_SYS_KDEBUG_SIGNPOST_H */ diff --git a/platform-include/sys/persona.h b/platform-include/sys/persona.h new file mode 100644 index 000000000..d0912055f --- /dev/null +++ b/platform-include/sys/persona.h @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifndef _SYS_PERSONA_H_ +#define _SYS_PERSONA_H_ + +#ifdef PRIVATE +#include + +enum { + PERSONA_INVALID = 0, + PERSONA_GUEST = 1, + PERSONA_MANAGED = 2, + PERSONA_PRIV = 3, + PERSONA_SYSTEM = 4, + + PERSONA_TYPE_MAX = PERSONA_SYSTEM, +}; + +#define PERSONA_ID_NONE ((uid_t)-1) + +struct kpersona_info { + uint32_t persona_info_version; + + uid_t persona_id; /* overlaps with UID */ + int persona_type; + gid_t persona_gid; + uint32_t persona_ngroups; + gid_t persona_groups[NGROUPS]; + uid_t persona_gmuid; + char persona_name[MAXLOGNAME+1]; + + /* TODO: MAC policies?! */ +}; + +#define PERSONA_INFO_V1 1 +#define PERSONA_INFO_V1_SIZE (sizeof(struct kpersona_info)) + + +#define PERSONA_OP_ALLOC 1 +#define PERSONA_OP_DEALLOC 2 +#define PERSONA_OP_GET 3 +#define PERSONA_OP_INFO 4 +#define PERSONA_OP_PIDINFO 5 +#define PERSONA_OP_FIND 6 + +#ifndef KERNEL +/* + * user space persona interface + */ + +/* + * kpersona_alloc: Allocate a new in-kernel persona + * + * Parameters: + * info: Pointer to persona info structure describing the + * attributes of the persona to create / allocate. + * + * id: output: set to the ID of the created persona + * + * Note: + * The 'persona_id' field of the 'info' parameter is ignored. + * + * Return: + * != 0: ERROR + * == 0: Success + */ +int kpersona_alloc(struct kpersona_info *info, uid_t *id); + +/* + * kpersona_dealloc: delete / destroy an in-kernel persona + * + * Parameters: + * id: the ID of the persona to destroy + * + * Return: + * < 0: ERROR + * 0: Success + */ +int kpersona_dealloc(uid_t id); + + +/* + * kpersona_get: retrieve the persona with which the current thread is running + * + * Parameters: + * id: output: will be filled with current thread's persona + * (or current processes persona) on success. + * + * Return: + * < 0: Thread is not running under any persona + * 0: Success (uuid is filled with running persona UUID) + */ +int kpersona_get(uid_t *id); + + +/* + * kpersona_info: gather info about the given persona + * + * Parameters: + * id: ID of the persona to investigate + * + * info: output: filled in with persona attributes on success. + * + * Return: + * < 0: ERROR + * 0: Success + */ +int kpersona_info(uid_t id, struct kpersona_info *info); + + +/* + * kpersona_pidinfo: gather persona info about the given PID + * + * Parameters: + * pid: PID of the process whose persona info we're to return + * + * info: output: filled in with persona attributes on success. + * + * Return: + * < 0: ERROR + * 0: Success + */ +int kpersona_pidinfo(pid_t pid, struct kpersona_info *info); + + +/* + * kpersona_find: lookup the kernel's UUID of a persona + * + * Parameters: + * name: Local login name of the persona. + * Set this to NULL to find personas by 'uid'. + * + * uid: UID of the persona. + * Set this to -1 to find personas by 'name' + * + * id: output: the ID(s) matching the input parameters + * idlen: input - size of 'id' buffer (in number of IDs) + * output - the total required size of the 'id' buffer + * (in number of IDs) - may be larger than input size + * Note: + * At least one of 'name' or 'uid' must be set. + * + * Return: + * < 0: ERROR + * >= 0: The number of IDs found to match the input parameters + */ +int kpersona_find(const char *name, uid_t uid, uid_t *id, size_t *idlen); +#endif /* !KERNEL */ + +#ifdef KERNEL_PRIVATE +/* XNU + kext private interface */ +#include +#include +#include + +#ifdef PERSONA_DEBUG +#define persona_dbg(fmt, ...) \ + printf("[%4d] %s: " fmt "\n", \ + current_proc() ? current_proc()->p_pid : -1, \ + __func__, ## __VA_ARGS__) +#else +#define persona_dbg(fmt, ...) do { } while (0) +#endif + +/* + * Persona + */ +#ifdef XNU_KERNEL_PRIVATE +/* only XNU proper needs to see the persona structure */ +struct persona { + int32_t pna_refcount; + int32_t pna_valid; + + uid_t pna_id; + int pna_type; + char pna_login[MAXLOGNAME+1]; + + kauth_cred_t pna_cred; + uid_t pna_pgid; + + int pna_cred_locked; /* set upon first adoption */ + + LIST_ENTRY(persona) pna_list; + + /* this could go away if we used a coalition */ + LIST_HEAD(, proc) pna_members; + + lck_mtx_t pna_lock; + + /* + * We can add things here such as PID maps, UID maps, etc. + */ +#ifdef PERSONA_DEBUG + char pna_desc[128]; +#endif +}; + +#define persona_lock(persona) lck_mtx_lock(&(persona)->pna_lock) +#define persona_unlock(persona) lck_mtx_unlock(&(persona)->pna_lock) +#define persona_try_lock(persona) lck_mtx_try_lock(&(persona)->pna_lock) + +#define persona_lock_assert_held(persona) \ + lck_mtx_assert(&(persona)->pna_lock, LCK_MTX_ASSERT_OWNED) + +#ifdef PERSONA_DEBUG +static inline const char *persona_desc(struct persona *persona, int locked) +{ + if (!persona) + return ""; + + if (persona->pna_desc[0] != 0) + return persona->pna_desc; + + if (!locked) + persona_lock(persona); + if (persona->pna_desc[0] != 0) + goto out_unlock; + + char *p = &persona->pna_desc[0]; + char *end = p + sizeof(persona->pna_desc) - 1; + + *end = 0; + p += snprintf(p, end - p, "%s/%d:%d", + persona->pna_login, + kauth_cred_getuid(persona->pna_cred), + kauth_cred_getgid(persona->pna_cred)); + + if (p <= end) + *p = 0; +out_unlock: + if (!locked) + persona_unlock(persona); + + return persona->pna_desc; +} +#else /* !PERSONA_DEBUG */ +static inline const char *persona_desc(struct persona *persona, int locked) +{ + (void)persona; + (void)locked; + return ""; +} +#endif + +#else /* !XNU_KERNEL_PRIVATE */ +/* kexts should only see an opaque persona structure */ +struct persona; +#endif + +__BEGIN_DECLS + +#ifndef _KAUTH_CRED_T +#define _KAUTH_CRED_T +typedef struct ucred *kauth_cred_t; +#endif /* !_KAUTH_CRED_T */ + +/* returns the persona ID for the given pesona structure */ +uid_t persona_get_id(struct persona *persona); + +/* returns the type of the persona (see enum above: PERSONA_GUEST, etc.) */ +int persona_get_type(struct persona *persona); + +/* returns ref on kauth_cred_t that must be dropped via kauth_cred_unref() */ +kauth_cred_t persona_get_cred(struct persona *persona); + +/* returns a reference that must be released with persona_put() */ +struct persona *persona_lookup(uid_t id); + +/* + * returns non-zero on error, on success returns 0 and updates 'plen' to + * total found (could be more than original value of 'plen') + */ +int persona_find(const char *login, uid_t uid, + struct persona **persona, size_t *plen); + +/* returns a reference to the persona tied to the current thread */ +struct persona *current_persona_get(void); + +/* get a reference to a persona structure */ +struct persona *persona_get(struct persona *persona); + +/* release a reference to a persona structure */ +void persona_put(struct persona *persona); + +#ifdef XNU_KERNEL_PRIVATE + +#if CONFIG_PERSONAS +#include + +/* + * In-kernel persona API + */ +extern uint32_t g_max_personas; +extern struct persona *g_system_persona; + +void personas_bootstrap(void); + +struct persona *persona_alloc(uid_t id, const char *login, + int type, int *error); +int persona_invalidate(struct persona *persona); + +static inline int proc_has_persona(proc_t p) +{ + if (p && p->p_persona) + return 1; + return 0; +} + +static inline uid_t persona_id_from_proc(proc_t p) +{ + if (p && p->p_persona) + return p->p_persona->pna_id; + return PERSONA_ID_NONE; +} + +int persona_proc_inherit(proc_t child, proc_t parent); + +int persona_proc_adopt_id(proc_t p, uid_t id, + kauth_cred_t auth_override); +int persona_proc_adopt(proc_t p, struct persona *persona, + kauth_cred_t auth_override); +int persona_proc_drop(proc_t p); + +int persona_set_cred(struct persona *persona, kauth_cred_t cred); +int persona_set_cred_from_proc(struct persona *persona, proc_t proc); + +uid_t persona_get_uid(struct persona *persona); + +int persona_set_gid(struct persona *persona, gid_t gid); +gid_t persona_get_gid(struct persona *persona); + +int persona_set_groups(struct persona *persona, gid_t *groups, int ngroups, uid_t gmuid); +int persona_get_groups(struct persona *persona, int *ngroups, gid_t *groups, int groups_sz); + +uid_t persona_get_gmuid(struct persona *persona); + +int persona_get_login(struct persona *persona, char login[MAXLOGNAME+1]); + +/* returns a reference that must be released with persona_put() */ +struct persona *persona_proc_get(pid_t pid); + +#else /* !CONFIG_PERSONAS */ + +static inline int proc_has_persona(__unused proc_t p) +{ + return 0; +} + +static inline uid_t persona_id_from_proc(__unused proc_t p) +{ + return PERSONA_ID_NONE; +} + +#endif /* CONFIG_PERSONAS */ +#endif /* XNU_KERNEL_PRIVATE */ +__END_DECLS + +#endif /* KERNEL_PRIVATE */ + +#endif /* PRIVATE */ +#endif /* _SYS_PERSONA_H_ */ diff --git a/platform-include/sys/proc_info.h b/platform-include/sys/proc_info.h index e8ca29c4f..8f22d8007 100644 --- a/platform-include/sys/proc_info.h +++ b/platform-include/sys/proc_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005-2016 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -37,11 +37,17 @@ #include #include #include +#include #include #include #include #include #include +#include + +#ifdef PRIVATE +#include /* COALITION_NUM_TYPES */ +#endif __BEGIN_DECLS @@ -118,12 +124,20 @@ struct proc_archinfo { }; struct proc_pidcoalitioninfo { - uint64_t coalition_id; + uint64_t coalition_id[COALITION_NUM_TYPES]; uint64_t reserved1; uint64_t reserved2; uint64_t reserved3; }; +struct proc_originatorinfo { + uuid_t originator_uuid; /* UUID of the originator process */ + pid_t originator_pid; /* pid of the originator process */ + uint64_t p_reserve2; + uint64_t p_reserve3; + uint64_t p_reserve4; +}; + #endif @@ -270,9 +284,9 @@ struct proc_workqueueinfo { /* * workqueue state (pwq_state field) */ -#define WQ_EXCEEDED_CONSTRAINED_THREAD_LIMIT 0x1 -#define WQ_EXCEEDED_TOTAL_THREAD_LIMIT 0x2 - +#define WQ_EXCEEDED_CONSTRAINED_THREAD_LIMIT 0x1 +#define WQ_EXCEEDED_TOTAL_THREAD_LIMIT 0x2 +#define WQ_FLAGS_AVAILABLE 0x4 struct proc_fileinfo { uint32_t fi_openflags; @@ -286,12 +300,28 @@ struct proc_fileinfo { #define PROC_FP_SHARED 1 /* shared by more than one fd */ #define PROC_FP_CLEXEC 2 /* close on exec */ #define PROC_FP_GUARDED 4 /* guarded fd */ +#define PROC_FP_CLFORK 8 /* close on fork */ #define PROC_FI_GUARD_CLOSE (1u << 0) #define PROC_FI_GUARD_DUP (1u << 1) #define PROC_FI_GUARD_SOCKET_IPC (1u << 2) #define PROC_FI_GUARD_FILEPORT (1u << 3) +struct proc_exitreasonbasicinfo { + uint32_t beri_namespace; + uint64_t beri_code; + uint64_t beri_flags; + uint32_t beri_reason_buf_size; +} __attribute__((packed)); + +struct proc_exitreasoninfo { + uint32_t eri_namespace; + uint64_t eri_code; + uint64_t eri_flags; + uint32_t eri_reason_buf_size; + uint64_t eri_kcd_buf; +} __attribute__((packed)); + /* * A copy of stat64 with static sized fields. */ @@ -605,8 +635,23 @@ struct kqueue_info { uint32_t kq_state; uint32_t rfu_1; /* reserved */ }; -#define PROC_KQUEUE_SELECT 1 -#define PROC_KQUEUE_SLEEP 2 + +/* keep in sync with KQ_* in sys/eventvar.h */ +#define PROC_KQUEUE_SELECT 0x01 +#define PROC_KQUEUE_SLEEP 0x02 +#define PROC_KQUEUE_32 0x08 +#define PROC_KQUEUE_64 0x10 +#define PROC_KQUEUE_QOS 0x20 + +#ifdef PRIVATE +struct kevent_extinfo { + struct kevent_qos_s kqext_kev; + uint64_t kqext_sdata; + int kqext_status; + int kqext_sfflags; + uint64_t kqext_reserved[2]; +}; +#endif /* PRIVATE */ struct kqueue_fdinfo { struct proc_fileinfo pfi; @@ -633,6 +678,7 @@ struct appletalk_fdinfo { #define PROX_FDTYPE_KQUEUE 5 #define PROX_FDTYPE_PIPE 6 #define PROX_FDTYPE_FSEVENTS 7 +#define PROX_FDTYPE_NETPOLICY 9 struct proc_fdinfo { int32_t proc_fd; @@ -644,6 +690,7 @@ struct proc_fileportinfo { uint32_t proc_fdtype; }; + /* Flavors for proc_pidinfo() */ #define PROC_PIDLISTFDS 1 #define PROC_PIDLISTFD_SIZE (sizeof(struct proc_fdinfo)) @@ -720,6 +767,12 @@ struct proc_fileportinfo { #define PROC_PIDREGIONPATHINFO3 23 #define PROC_PIDREGIONPATHINFO3_SIZE (sizeof(struct proc_regionwithpathinfo)) +#define PROC_PIDEXITREASONINFO 24 +#define PROC_PIDEXITREASONINFO_SIZE (sizeof(struct proc_exitreasoninfo)) + +#define PROC_PIDEXITREASONBASICINFO 25 +#define PROC_PIDEXITREASONBASICINFOSIZE (sizeof(struct proc_exitreasonbasicinfo)) + #endif /* Flavors for proc_pidfdinfo */ @@ -748,6 +801,13 @@ struct proc_fileportinfo { #define PROC_PIDFDATALKINFO 8 #define PROC_PIDFDATALKINFO_SIZE (sizeof(struct appletalk_fdinfo)) +#ifdef PRIVATE +#define PROC_PIDFDKQUEUE_EXTINFO 9 +#define PROC_PIDFDKQUEUE_EXTINFO_SIZE (sizeof(struct kevent_extinfo)) +#define PROC_PIDFDKQUEUE_KNOTES_MAX (1024 * 128) +#endif /* PRIVATE */ + + /* Flavors for proc_pidfileportinfo */ #define PROC_PIDFILEPORTVNODEPATHINFO 2 /* out: vnode_fdinfowithpath */ @@ -800,6 +860,29 @@ struct proc_fileportinfo { #define PROC_PIDORIGINATOR_BGSTATE 0x2 #define PROC_PIDORIGINATOR_BGSTATE_SIZE (sizeof(uint32_t)) +#define PROC_PIDORIGINATOR_PID_UUID 0x3 +#define PROC_PIDORIGINATOR_PID_UUID_SIZE (sizeof(struct proc_originatorinfo)) + +/* Flavors for proc_listcoalitions */ +#define LISTCOALITIONS_ALL_COALS 1 +#define LISTCOALITIONS_ALL_COALS_SIZE (sizeof(struct procinfo_coalinfo)) + +#define LISTCOALITIONS_SINGLE_TYPE 2 +#define LISTCOALITIONS_SINGLE_TYPE_SIZE (sizeof(struct procinfo_coalinfo)) + +/* reasons for proc_can_use_foreground_hw */ +#define PROC_FGHW_OK 0 /* pid may use foreground HW */ +#define PROC_FGHW_DAEMON_OK 1 +#define PROC_FGHW_DAEMON_LEADER 10 /* pid is in a daemon coalition */ +#define PROC_FGHW_LEADER_NONUI 11 /* coalition leader is in a non-focal state */ +#define PROC_FGHW_LEADER_BACKGROUND 12 /* coalition leader is in a background state */ +#define PROC_FGHW_DAEMON_NO_VOUCHER 13 /* pid is a daemon with no adopted voucher */ +#define PROC_FGHW_NO_VOUCHER_ATTR 14 /* pid has adopted a voucher with no bank/originator attribute */ +#define PROC_FGHW_NO_ORIGINATOR 15 /* pid has adopted a voucher for a process that's gone away */ +#define PROC_FGHW_ORIGINATOR_BACKGROUND 16 /* pid has adopted a voucher for an app that's in the background */ +#define PROC_FGHW_VOUCHER_ERROR 98 /* error in voucher / originator callout */ +#define PROC_FGHW_ERROR 99 /* syscall parameter/permissions error */ + /* __proc_info() call numbers */ #define PROC_INFO_CALL_LISTPIDS 0x1 #define PROC_INFO_CALL_PIDINFO 0x2 @@ -811,6 +894,8 @@ struct proc_fileportinfo { #define PROC_INFO_CALL_DIRTYCONTROL 0x8 #define PROC_INFO_CALL_PIDRUSAGE 0x9 #define PROC_INFO_CALL_PIDORIGINATORINFO 0xa +#define PROC_INFO_CALL_LISTCOALITIONS 0xb +#define PROC_INFO_CALL_CANUSEFGHW 0xc #endif /* PRIVATE */ @@ -832,7 +917,15 @@ extern int fill_pshminfo(struct pshmnode * pshm, struct pshm_info * pinfo); extern int fill_pseminfo(struct psemnode * psem, struct psem_info * pinfo); extern int fill_pipeinfo(struct pipe * cpipe, struct pipe_info * pinfo); extern int fill_kqueueinfo(struct kqueue * kq, struct kqueue_info * kinfo); +extern int pid_kqueue_extinfo(proc_t, struct kqueue * kq, user_addr_t buffer, + uint32_t buffersize, int32_t * retval); +extern int pid_kqueue_udatainfo(proc_t p, struct kqueue *kq, uint64_t *buf, + uint32_t bufsize); extern int fill_procworkqueue(proc_t, struct proc_workqueueinfo *); +extern boolean_t workqueue_get_pwq_exceeded(void *v, boolean_t *exceeded_total, + boolean_t *exceeded_constrained); +extern uint32_t workqueue_get_pwq_state_kdp(void *proc); + #endif /* XNU_KERNEL_PRIVATE */ __END_DECLS diff --git a/platform-include/sys/reason.h b/platform-include/sys/reason.h new file mode 100644 index 000000000..13a49e3e6 --- /dev/null +++ b/platform-include/sys/reason.h @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _REASON_H_ +#define _REASON_H_ + +#include + +__BEGIN_DECLS + +#ifdef KERNEL + +#include + +#ifdef XNU_KERNEL_PRIVATE +#include + +typedef struct os_reason { + decl_lck_mtx_data(, osr_lock) + int osr_refcount; + uint32_t osr_namespace; + uint64_t osr_code; + uint64_t osr_flags; + uint32_t osr_bufsize; + struct kcdata_descriptor osr_kcd_descriptor; + char *osr_kcd_buf; +} *os_reason_t; + +#define OS_REASON_NULL ((os_reason_t) 0) + +/* We only include 800 bytes of the exit reason description to not blow through the panic buffer */ +#define LAUNCHD_PANIC_REASON_STRING_MAXLEN "800" + +void os_reason_init(void); + +os_reason_t build_userspace_exit_reason(uint32_t reason_namespace, uint64_t reason_code, user_addr_t payload, uint32_t payload_size, + user_addr_t reason_string, uint64_t reason_flags); +char *launchd_exit_reason_get_string_desc(os_reason_t exit_reason); + +#else /* XNU_KERNEL_PRIVATE */ + +typedef void * os_reason_t; + +#endif /* XNU_KERNEL_PRIVATE */ + +os_reason_t os_reason_create(uint32_t osr_namespace, uint64_t osr_code); +int os_reason_alloc_buffer(os_reason_t cur_reason, uint32_t osr_bufsize); +struct kcdata_descriptor * os_reason_get_kcdata_descriptor(os_reason_t cur_reason); +void os_reason_ref(os_reason_t cur_reason); +void os_reason_free(os_reason_t cur_reason); + +#endif /* KERNEL */ + +/* + * Reason namespaces. + */ +#define OS_REASON_INVALID 0 +#define OS_REASON_JETSAM 1 +#define OS_REASON_SIGNAL 2 +#define OS_REASON_CODESIGNING 3 +#define OS_REASON_HANGTRACER 4 +#define OS_REASON_TEST 5 +#define OS_REASON_DYLD 6 +#define OS_REASON_LIBXPC 7 +#define OS_REASON_OBJC 8 +#define OS_REASON_EXEC 9 +#define OS_REASON_SPRINGBOARD 10 +#define OS_REASON_TCC 11 +#define OS_REASON_REPORTCRASH 12 +#define OS_REASON_COREANIMATION 13 +#define OS_REASON_AGGREGATED 14 + +/* + * Update whenever new OS_REASON namespaces are added. + */ +#define OS_REASON_MAX_VALID_NAMESPACE OS_REASON_AGGREGATED + +#define OS_REASON_BUFFER_MAX_SIZE 5120 + +#define OS_REASON_FLAG_NO_CRASH_REPORT 0x1 /* Don't create a crash report */ +#define OS_REASON_FLAG_GENERATE_CRASH_REPORT 0x2 /* Create a crash report - the default for userspace requests */ +#define OS_REASON_FLAG_FROM_USERSPACE 0x4 /* Reason created from a userspace syscall */ +#define OS_REASON_FLAG_FAILED_DATA_COPYIN 0x8 /* We failed to copyin data from userspace */ +#define OS_REASON_FLAG_PAYLOAD_TRUNCATED 0x10 /* The payload was truncated because it was longer than allowed */ +#define OS_REASON_FLAG_BAD_PARAMS 0x20 /* Invalid parameters were passed involved with creating this reason */ +#define OS_REASON_FLAG_CONSISTENT_FAILURE 0x40 /* Whatever caused this reason to be created will happen again */ +#define OS_REASON_FLAG_ONE_TIME_FAILURE 0x80 /* Whatever caused this reason to be created was a one time issue */ + +/* + * Set of flags that are allowed to be passed from userspace + */ +#define OS_REASON_FLAG_MASK_ALLOWED_FROM_USER (OS_REASON_FLAG_CONSISTENT_FAILURE | OS_REASON_FLAG_ONE_TIME_FAILURE | OS_REASON_FLAG_NO_CRASH_REPORT) + +/* + * Macros to encode the exit reason namespace and first 32 bits of code in exception code + * which is used by Report Crash as a hint. It should be only used as a hint since it + * looses higher 32 bits of exit reason code. + */ +#define ENCODE_OSR_NAMESPACE_TO_MACH_EXCEPTION_CODE(code, osr_namespace) \ + (code) = (code) | (((osr_namespace) & ((uint64_t)UINT32_MAX)) << 32) +#define ENCODE_OSR_CODE_TO_MACH_EXCEPTION_CODE(code, osr_code) \ + (code) = (code) | ((osr_code) & ((uint64_t)UINT32_MAX)) + +#ifndef KERNEL +/* + * abort_with_reason: Used to exit the current process and pass along + * specific information about why it is being terminated. + * + * Inputs: args->reason_namespace - OS_REASON namespace specified for the reason + * args->reason_code - code in the specified namespace for the reason + * args->reason_string - additional string formatted information about the request + * args->reason_flags - options requested for how the process should be terminated (see OS_REASON_FLAG_* above). + * + * Outputs: Does not return. + */ +void abort_with_reason(uint32_t reason_namespace, uint64_t reason_code, const char *reason_string, uint64_t reason_flags) __attribute__((noreturn)); + +/* + * abort_with_payload: Used to exit the current process and pass along + * specific information about why it is being terminated. The payload pointer + * should point to structured data that can be interpreted by the consumer of + * exit reason information. + * + * Inputs: args->reason_namespace - OS_REASON namespace specified for the reason + * args->reason_code - code in the specified namespace for the reason + * args->payload - pointer to payload structure in user space + * args->payload_size - length of payload buffer (this will be truncated to EXIT_REASON_PAYLOAD_MAX_LEN) + * args->reason_string - additional string formatted information about the request + * args->reason_flags - options requested for how the process should be terminated (see OS_REASON_FLAG_* above). + * + * Outputs: Does not return. + */ +void abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, void *payload, uint32_t payload_size, const char *reason_string, + uint64_t reason_flags) __attribute__((noreturn)); + +/* + * terminate_with_reason: Used to terminate a specific process and pass along + * specific information about why it is being terminated. + * + * Inputs: args->pid - the PID of the process to be terminated + * args->reason_namespace - OS_REASON namespace specified for the reason + * args->reason_code - code in the specified namespace for the reason + * args->reason_string - additional string formatted information about the request + * args->reason_flags - options requested for how the process should be terminated (see OS_REASON_FLAG_* above) + * + * Outputs: EINVAL if the PID requested is the same as that of the calling process, invalid or the namespace provided is invalid. + * ESRCH if we couldn't find a live process with the requested PID + * EPERM if the caller is not privileged enough to kill the process with the requested PID + * returns 0 otherwise + */ +int terminate_with_reason(int pid, uint32_t reason_namespace, uint64_t reason_code, const char *reason_string, uint64_t reason_flags); + +/* + * terminate_with_payload: Used to terminate a specific process and pass along + * specific information about why it is being terminated. The payload pointer + * should point to structured data that can be interpreted by the consumer of + * exit reason information. + * + * Inputs: args->pid - the PID of the process to be terminated. + * args->reason_namespace - OS_REASON namespace specified for the reason + * args->reason_code - code in the specified namespace for the reason + * args->payload - pointer to payload structure in user space + * args->payload_size - length of payload buffer (this will be truncated to EXIT_REASON_PAYLOAD_MAX_LEN) + * args->reason_string - additional string formatted information about the request + * args->reason_flags - options requested for how the process should be terminated (see OS_REASON_FLAG_* above) + * + * Outputs: EINVAL if the PID requested is the same as that of the calling process, is invalid or the namespace provided is invalid. + * ESRCH if we couldn't find a live process with the requested PID + * EPERM if the caller is not privileged enough to kill the process with the requested PID + * returns 0 otherwise + */ +int terminate_with_payload(int pid, uint32_t reason_namespace, uint64_t reason_code, void *payload, uint32_t payload_size, + const char *reason_string, uint64_t reason_flags); +#endif /* KERNEL */ + +/* + * codesigning exit reasons + */ +#define CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG 1 +#define CODESIGNING_EXIT_REASON_INVALID_PAGE 2 +#define CODESIGNING_EXIT_REASON_TASK_ACCESS_PORT 3 + +/* + * exec path specific exit reasons + */ +#define EXEC_EXIT_REASON_BAD_MACHO 1 +#define EXEC_EXIT_REASON_SUGID_FAILURE 2 +#define EXEC_EXIT_REASON_ACTV_THREADSTATE 3 +#define EXEC_EXIT_REASON_STACK_ALLOC 4 +#define EXEC_EXIT_REASON_APPLE_STRING_INIT 5 +#define EXEC_EXIT_REASON_COPYOUT_STRINGS 6 +#define EXEC_EXIT_REASON_COPYOUT_DYNLINKER 7 +#define EXEC_EXIT_REASON_SECURITY_POLICY 8 +#define EXEC_EXIT_REASON_TASKGATED_OTHER 9 +#define EXEC_EXIT_REASON_FAIRPLAY_DECRYPT 10 +#define EXEC_EXIT_REASON_DECRYPT 11 +#define EXEC_EXIT_REASON_UPX 12 + +__END_DECLS + +#endif /* _REASON_H_ */ diff --git a/platform-include/sys/sfi.h b/platform-include/sys/sfi.h new file mode 100644 index 000000000..bd3d22aea --- /dev/null +++ b/platform-include/sys/sfi.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_SFI_H_ +#define _SYS_SFI_H_ + +#include +#include +#include +/* + * Selective Forced Idle (SFI) is a mechanism for doing + * phase-aligned modulation of runnable tasks + */ + +/* Flags for use with sfi_process_set_flags() */ +#define SFI_PROCESS_SET_MANAGED 0x00000001 +#define SFI_PROCESS_SET_UNMANAGED 0x00000002 + +#define SFI_PROCESS_SET_MANAGED_MASK 0x00000003 + +#ifndef KERNEL +/* + * The system_set_sfi_window() call can be used to set "Selective + * Forced Idle" window for the system. sfi_window_usec is the + * interval in microseconds and when the "Selective Forced Idle" is + * active its "off phase" starts every sfi_window_usec. A nonzero + * value lower than MIN_SFI_WINDOW_USEC will be automatically changed + * to MIN_SFI_WINDOW_USEC. The actual window size used is + * implementation dependent and may be longer. + * + * system_get_sfi_window() can be used to determine the actual value. + * + * A value of 0 for sfi_window_usec can be used to disable "Selective + * Forced Idle". + */ +int system_set_sfi_window(uint64_t sfi_window_usec); + +int system_get_sfi_window(uint64_t *sfi_window_usec); + +/* + * sfi_set_class_offtime() can be used to set the "off time" interval + * for all threads placed in a "Selective Forced Idle" class class_id. + * A thread placed in class_id will not execute for offtime_usec + * microseconds at the beginning of each "Selective Forced Idle" + * window. A nonzero value lower than MIN_OFFTIME_USEC will be + * automatically changed to MIN_OFFTIME_USEC. The actual "off time" + * used is implementation dependent and may be + * longer. sfi_get_class_offtime() can be used to determine the actual + * value. + * + * A value of 0 for offtime_usec can be used to disable "Selective + * Forced Idle" for all the threads placed in class_id. + * + * A value of offtime_usec greater than the value of system wide + * "Selective Forced Idle" window will cause failure. + */ +int sfi_set_class_offtime(sfi_class_id_t class_id, uint64_t offtime_usec); + +int sfi_get_class_offtime(sfi_class_id_t class_id, uint64_t *offtime_usec); + +/* + * The sfi_process_set_class() can be used to place all the threads in + * a process ID pid in the "Selective Forced Idle" managed class, or clear + * the managed state. + */ + +int sfi_process_set_flags(pid_t pid, uint32_t flags); + +int sfi_process_get_flags(pid_t pid, uint32_t *flags); + +#endif /* !KERNEL */ + +#if PRIVATE + +/* This is the private system call interface between Libsyscall and xnu */ +#define SFI_CTL_OPERATION_SFI_SET_WINDOW 0x00000001 +#define SFI_CTL_OPERATION_SFI_GET_WINDOW 0x00000002 +#define SFI_CTL_OPERATION_SET_CLASS_OFFTIME 0x00000003 +#define SFI_CTL_OPERATION_GET_CLASS_OFFTIME 0x00000004 + +#define SFI_PIDCTL_OPERATION_PID_SET_FLAGS 0x00000001 +#define SFI_PIDCTL_OPERATION_PID_GET_FLAGS 0x00000002 + +int __sfi_ctl(uint32_t operation, uint32_t sfi_class, uint64_t time, uint64_t *out_time); +int __sfi_pidctl(uint32_t operation, pid_t pid, uint32_t sfi_flags, uint32_t *out_sfi_flags); + +#endif /* PRIVATE */ + +#endif /* _SYS_SFI_H_ */ diff --git a/platform-include/sys/snapshot.h b/platform-include/sys/snapshot.h new file mode 100644 index 000000000..c18cd8510 --- /dev/null +++ b/platform-include/sys/snapshot.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_SNAPSHOT_H_ +#define _SYS_SNAPSHOT_H_ + +#ifndef KERNEL + +#include +#include +#include +#include <_types/_uint32_t.h> +#include +#include + +__BEGIN_DECLS + +int fs_snapshot_create(int, const char *, uint32_t) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +int fs_snapshot_list(int, struct attrlist *, void *, size_t, uint32_t) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +int fs_snapshot_delete(int, const char *, uint32_t) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +int fs_snapshot_rename(int, const char *, const char *, uint32_t) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +int fs_snapshot_mount(int, const char *, const char *, uint32_t) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +int fs_snapshot_revert(int, const char *, uint32_t) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +__END_DECLS + +#endif /* !KERNEL */ + +#ifdef PRIVATE + +#define SNAPSHOT_OP_CREATE 0x01 +#define SNAPSHOT_OP_DELETE 0x02 +#define SNAPSHOT_OP_RENAME 0x03 +#define SNAPSHOT_OP_MOUNT 0x04 +#define SNAPSHOT_OP_REVERT 0x05 + +#endif + +#endif /* !_SYS_SNAPSHOT_H_ */ diff --git a/platform-include/sys/stackshot.h b/platform-include/sys/stackshot.h new file mode 100644 index 000000000..dcd24eada --- /dev/null +++ b/platform-include/sys/stackshot.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_STACKSHOT_H +#define _SYS_STACKSHOT_H + +#include + +#define STACKSHOT_CONFIG_TYPE 1 + +typedef struct stackshot_config { + /* Input options */ + int sc_pid; /* PID to trace, or -1 for the entire system */ + uint32_t sc_flags; /* Stackshot flags */ + uint64_t sc_delta_timestamp; /* Retrieve a delta stackshot of system state that has changed since this time */ + + /* Stackshot results */ + uint64_t sc_buffer; /* Pointer to stackshot buffer */ + uint32_t sc_size; /* Length of the stackshot buffer */ + + /* Internals */ + uint64_t sc_out_buffer_addr; /* Location where the kernel should copy the address of the newly mapped buffer in user space */ + uint64_t sc_out_size_addr; /* Location where the kernel should copy the size of the stackshot buffer */ +} stackshot_config_t; + +#ifndef KERNEL + +stackshot_config_t * stackshot_config_create(void); +int stackshot_config_set_pid(stackshot_config_t * stackshot_config, int pid); +int stackshot_config_set_flags(stackshot_config_t * stackshot_config, uint32_t flags); +int stackshot_capture_with_config(stackshot_config_t * stackshot_config); +void * stackshot_config_get_stackshot_buffer(stackshot_config_t * stackshot_config); +uint32_t stackshot_config_get_stackshot_size(stackshot_config_t * stackshot_config); +int stackshot_config_set_size_hint(stackshot_config_t * stackshot_config, uint32_t suggested_size); +int stackshot_config_set_delta_timestamp(stackshot_config_t * stackshot_config, uint64_t delta_timestamp); +int stackshot_config_dealloc_buffer(stackshot_config_t * stackshot_config); +int stackshot_config_dealloc(stackshot_config_t * stackshot_config); + +#endif /* KERNEL */ + +#endif /* _SYS_STACKSHOT_H */ diff --git a/platform-include/sys/stat.h b/platform-include/sys/stat.h index f92414226..d1eb9f59e 100644 --- a/platform-include/sys/stat.h +++ b/platform-include/sys/stat.h @@ -339,7 +339,7 @@ struct stat64 __DARWIN_STRUCT_STAT64; * The following two bits are reserved for FreeBSD. They are not * implemented in Mac OS X. */ -/* #define SF_NOUNLINK 0x00100000 */ /* file may not be removed or renamed */ +#define SF_NOUNLINK 0x00100000 /* file may not be removed or renamed */ /* #define SF_SNAPSHOT 0x00200000 */ /* snapshot inode */ /* NOTE: There is no SF_HIDDEN bit. */ diff --git a/platform-include/sys/syscall.h b/platform-include/sys/syscall.h index 665988edc..1c4d545db 100644 --- a/platform-include/sys/syscall.h +++ b/platform-include/sys/syscall.h @@ -29,7 +29,7 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * created from /Library/Caches/com.apple.xbs/Sources/xnu/xnu-3248.40.184/bsd/kern/syscalls.master + * created from /home/lubos/Projects/darling/src/kernel/libsyscall/xcodescripts/syscalls.master */ #ifndef _SYS_SYSCALL_H_ @@ -100,7 +100,7 @@ #define SYS_umask 60 #define SYS_chroot 61 /* 62 old fstat */ - /* 63 used internally , reserved */ + /* 63 used internally and reserved */ /* 64 old getpagesize */ #define SYS_msync 65 #define SYS_vfork 66 @@ -214,7 +214,7 @@ /* 174 old getdents */ /* 175 old gc_control */ /* 176 old add_profil */ - /* 177 */ +#define SYS_kdebug_typefilter 177 #define SYS_kdebug_trace_string 178 #define SYS_kdebug_trace64 179 #define SYS_kdebug_trace 180 @@ -222,7 +222,7 @@ #define SYS_setegid 182 #define SYS_seteuid 183 #define SYS_sigreturn 184 -#define SYS_chud 185 + /* 185 old chud */ /* 186 */ #define SYS_fdatasync 187 #define SYS_stat 188 @@ -230,12 +230,12 @@ #define SYS_lstat 190 #define SYS_pathconf 191 #define SYS_fpathconf 192 - /* 193 */ + /* 193 old getfsstat */ #define SYS_getrlimit 194 #define SYS_setrlimit 195 #define SYS_getdirentries 196 #define SYS_mmap 197 - /* 198 __syscall */ + /* 198 old __syscall */ #define SYS_lseek 199 #define SYS_truncate 200 #define SYS_ftruncate 201 @@ -254,14 +254,14 @@ /* 214 */ /* 215 */ #define SYS_open_dprotected_np 216 - /* 217 */ - /* 218 */ - /* 219 */ + /* 217 old statv */ + /* 218 old lstatv */ + /* 219 old fstatv */ #define SYS_getattrlist 220 #define SYS_setattrlist 221 #define SYS_getdirentriesattr 222 #define SYS_exchangedata 223 - /* 224 old checkuseraccess / fsgetpath ( which moved to 427 ) */ + /* 224 old checkuseraccess or fsgetpath */ #define SYS_searchfs 225 #define SYS_delete 226 #define SYS_copyfile 227 @@ -294,7 +294,7 @@ #define SYS_semctl 254 #define SYS_semget 255 #define SYS_semop 256 - /* 257 */ + /* 257 old semconfig */ #define SYS_msgctl 258 #define SYS_msgget 259 #define SYS_msgsnd 260 @@ -402,7 +402,7 @@ #define SYS_kqueue 362 #define SYS_kevent 363 #define SYS_lchown 364 -#define SYS_stack_snapshot 365 + /* 365 old stack_snapshot */ #define SYS_bsdthread_register 366 #define SYS_workq_open 367 #define SYS_workq_kernreturn 368 @@ -472,8 +472,8 @@ #define SYS_audit_session_port 432 #define SYS_pid_suspend 433 #define SYS_pid_resume 434 -#define SYS_pid_hibernate 435 -#define SYS_pid_shutdown_sockets 436 + /* 435 */ + /* 436 */ /* 437 old shared_region_slide_np */ #define SYS_shared_region_map_and_slide_np 438 #define SYS_kas_info 439 @@ -499,7 +499,7 @@ #define SYS_coalition_info 459 #define SYS_necp_match_policy 460 #define SYS_getattrlistbulk 461 - /* 462 */ +#define SYS_clonefileat 462 #define SYS_openat 463 #define SYS_openat_nocancel 464 #define SYS_renameat 465 @@ -525,7 +525,7 @@ #define SYS_guarded_write_np 485 #define SYS_guarded_pwrite_np 486 #define SYS_guarded_writev_np 487 -#define SYS_rename_ext 488 +#define SYS_renameatx_np 488 #define SYS_mremap_encrypted 489 #define SYS_netagent_trigger 490 #define SYS_stack_snapshot_with_config 491 @@ -537,7 +537,30 @@ /* 497 */ /* 498 */ #define SYS_work_interval_ctl 499 -#define SYS_MAXSYSCALL 500 +#define SYS_getentropy 500 +#define SYS_necp_open 501 +#define SYS_necp_client_action 502 + /* 503 */ + /* 504 */ + /* 505 */ + /* 506 */ + /* 507 */ + /* 508 */ + /* 509 */ + /* 510 */ + /* 511 */ + /* 512 */ + /* 513 */ + /* 514 */ +#define SYS_ulock_wait 515 +#define SYS_ulock_wake 516 +#define SYS_fclonefileat 517 +#define SYS_fs_snapshot 518 + /* 519 */ +#define SYS_terminate_with_payload 520 +#define SYS_abort_with_payload 521 +#define SYS_MAXSYSCALL 522 +#define SYS_invalid 63 #endif /* __APPLE_API_PRIVATE */ #endif /* !_SYS_SYSCALL_H_ */ diff --git a/platform-include/sys/ulock.h b/platform-include/sys/ulock.h new file mode 100644 index 000000000..de799d8f1 --- /dev/null +++ b/platform-include/sys/ulock.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_ULOCK_H +#define _SYS_ULOCK_H + +__BEGIN_DECLS + +#if PRIVATE + +#ifdef XNU_KERNEL_PRIVATE +extern mach_port_name_t ipc_entry_name_mask(mach_port_name_t name); + +static __inline mach_port_name_t +ulock_owner_value_to_port_name(uint32_t uval) +{ + /* + * userland uses the least significant bits for flags as these are + * never used in the mach port name, and are generally always set by + * the ipc_entry code in the kernel. Here we reconstruct a mach port + * name that we can use in the kernel. + */ + return ipc_entry_name_mask((mach_port_name_t)uval); +} +#else +static __inline mach_port_name_t +ulock_owner_value_to_port_name(uint32_t uval) +{ + return uval | 0x3; +} +#endif + +#ifndef KERNEL + +extern int __ulock_wait(uint32_t operation, void *addr, uint64_t value, + uint32_t timeout); /* timeout is specified in microseconds */ +extern int __ulock_wake(uint32_t operation, void *addr, uint64_t wake_value); + +#endif /* !KERNEL */ + +/* + * operation bits [7, 0] contain the operation code + */ +#define UL_COMPARE_AND_WAIT 1 +#define UL_UNFAIR_LOCK 2 +/* obsolete names */ +#define UL_OSSPINLOCK UL_COMPARE_AND_WAIT +#define UL_HANDOFFLOCK UL_UNFAIR_LOCK +/* These operation code are only implemented in (DEVELOPMENT || DEBUG) kernels */ +#define UL_DEBUG_SIMULATE_COPYIN_FAULT 253 +#define UL_DEBUG_HASH_DUMP_ALL 254 +#define UL_DEBUG_HASH_DUMP_PID 255 + +/* + * operation bits [15, 8] contain the flags for __ulock_wake + */ +#define ULF_WAKE_ALL 0x00000100 +#define ULF_WAKE_THREAD 0x00000200 + +/* + * operation bits [23, 16] contain the flags for __ulock_wait + */ +/* The waiter is contending on this lock for synchronization around global data. + * This causes the workqueue subsystem to not create new threads to offset for + * waiters on this lock. + */ +#define ULF_WAIT_WORKQ_DATA_CONTENTION 0x00010000 + +/* + * operation bits [31, 24] contain the generic flags + */ +#define ULF_NO_ERRNO 0x01000000 + +/* + * masks + */ +#define UL_OPCODE_MASK 0x000000FF +#define UL_FLAGS_MASK 0xFFFFFF00 +#define ULF_GENERIC_MASK 0xFFFF0000 + +#define ULF_WAIT_MASK (ULF_NO_ERRNO | \ + ULF_WAIT_WORKQ_DATA_CONTENTION) + +#define ULF_WAKE_MASK (ULF_WAKE_ALL | \ + ULF_WAKE_THREAD | \ + ULF_NO_ERRNO) + +#endif /* PRIVATE */ + +__END_DECLS + +#endif diff --git a/platform-include/sys/work_interval.h b/platform-include/sys/work_interval.h new file mode 100644 index 000000000..cc9ba9fb7 --- /dev/null +++ b/platform-include/sys/work_interval.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _SYS_WORK_INTERVAL_H +#define _SYS_WORK_INTERVAL_H + +#include +#include +#include + +__BEGIN_DECLS + +/* + * Trusted clients with deadline-sensitive work may report information + * about the execution of their work using the work interval facility. + * This is intended to be a higher-level semantic than realtime scheduling, + * which operates at the level of thread block/unblock. A high level + * operation may have many blocking points, including IPC to other tasks, + * and this this metric will capture the overall time to complete a unit of + * work. + * + * A work interval is defined by several timestamps, namely (S)tart, + * (F)inish, (D)eadline, and (N)ext start. + * + * ... ----+==================+--------+--+==== ... + * | | | | + * S F D N + * + * \__________________/ + * Active + * \___________________________/ + * Work Interval + * + * \_________/ + * | + * report information here ---------+ + * + * Definitions: + * + * Start: Absolute time when the current deadline-oriented work began. Due + * to scheduling latency, preemption, and blocking points, the + * thread controlling the work interval may actually begin + * executing after this ideal time (which may be the previous work + * interval's "next start") + * Finish: Absolute time when the current deadline-oriented work finished. + * This will typically be a timestamp taken before reporting using + * the work interval interface. + * Deadline: Absolute time by which the current work was expected to finish. + * In cases where the amount of computation (or preemption, or time + * spent blocked) causes the active period to take longer than + * expected, F may be greater than D. + * Next start: Absolute time when the next deadline-oriented work is + * expected to begin. This is typically the same as Deadline. + * Active: The fraction of the work interval spent completing the work. In + * cases where the Finish time exceeded the Deadline, this fraction + * will be >1.0. + * + * Basic Use: + * + * Clients should report information for a work interval after finishing + * work for the current interval but before the next work interval begins. + * + * If Finish far exceeds the previously expected Deadline, the + * caller may adjust Next Start to align to a multiple of the period + * (and skip over several work intervals that could not be + * executed). + * + * Caution (!): + * + * Because the information supplied via this facility directly influences power + * management decisions, clients should strive to be as accurate as possible. + * Failure to do so will adversely impact system power and performance. + * + */ +#ifndef KERNEL + +typedef struct work_interval *work_interval_t; + +/* Create a new work interval handle (currently for the current thread only). Flags is unused */ +int work_interval_create(work_interval_t *interval_handle, uint32_t flags); + +/* Notify the power management subsystem that the work for a current interval has completed */ +int work_interval_notify(work_interval_t interval_handle, uint64_t start, uint64_t finish, uint64_t deadline, uint64_t next_start, uint32_t flags); + +/* Notify, with "finish" implicitly set to the current time */ +int work_interval_notify_simple(work_interval_t interval_handle, uint64_t start, uint64_t deadline, uint64_t next_start); + +/* Deallocate work interval (currently for the current thread only) */ +int work_interval_destroy(work_interval_t interval_handle); + +#endif /* KERNEL */ + +#if PRIVATE + +/* Private interface between Libsyscall and xnu */ +#define WORK_INTERVAL_OPERATION_CREATE 0x00000001 /* arg is a uint64_t * that accepts work interval ID as an OUT param */ +#define WORK_INTERVAL_OPERATION_DESTROY 0x00000002 +#define WORK_INTERVAL_OPERATION_NOTIFY 0x00000003 /* arg is a work_interval_notification_t */ + +struct work_interval_notification { + uint64_t start; + uint64_t finish; + uint64_t deadline; + uint64_t next_start; + uint32_t flags; + uint32_t unused1; +}; +typedef struct work_interval_notification *work_interval_notification_t; + +int __work_interval_ctl(uint32_t operation, uint64_t work_interval_id, void *arg, size_t len); + +#endif /* PRIVATE */ + +__END_DECLS + +#endif /* _SYS_WORK_INTERVAL_H */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c9be163bc..a49872233 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,7 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}") add_subdirectory(bootstrap_cmds) add_subdirectory(external/cctools-port/cctools/ld64/src) add_subdirectory(external/cctools-port/cctools/ar) +#add_subdirectory(external/cctools-port/cctools/as) add_subdirectory(external/cctools-port/cctools/misc) #add_subdirectory(util) #add_subdirectory(libmach-o) @@ -51,9 +52,13 @@ include_directories("${DARLING_TOP_DIRECTORY}/platform-include/pthread") include_directories("${DARLING_TOP_DIRECTORY}/kernel-include") include_directories("${DARLING_TOP_DIRECTORY}/compiler-include") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/duct/include") +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/external/libplatform/include") +add_subdirectory(external/libplatform) add_subdirectory(kernel) add_subdirectory(libc) + +add_definitions(-D_LIBC_NO_FEATURE_VERIFICATION) add_subdirectory(libm) add_subdirectory(libmacho) add_subdirectory(libgcc) diff --git a/src/duct/src/CMakeLists.txt b/src/duct/src/CMakeLists.txt index 8da99a14b..b4e1b0b3f 100644 --- a/src/duct/src/CMakeLists.txt +++ b/src/duct/src/CMakeLists.txt @@ -17,6 +17,7 @@ SET(duct_sources set(DYLIB_INSTALL_NAME "/usr/lib/system/libsystem_duct.dylib") add_darling_library(system_duct SHARED ${duct_sources}) +make_fat(system_duct) set(CMAKE_AR "${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/ar/x86_64-apple-darwin11-ar") set(CMAKE_RANLIB "${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/misc/ranlib") diff --git a/src/dyld-apple/CMakeLists.txt b/src/dyld-apple/CMakeLists.txt index b6d929253..421f161b6 100644 --- a/src/dyld-apple/CMakeLists.txt +++ b/src/dyld-apple/CMakeLists.txt @@ -20,6 +20,11 @@ add_definitions(-D__APPLE__ -D__DYNAMIC__) include_directories(${CMAKE_SOURCE_DIR}/src/launchd/liblaunch) include_directories(${CMAKE_SOURCE_DIR}/src/libc/darwin) include_directories(${CMAKE_SOURCE_DIR}/src/libc/gen) +include_directories(${CMAKE_SOURCE_DIR}/src/libc/locale) +include_directories(${CMAKE_SOURCE_DIR}/src/libc/locale/FreeBSD) +include_directories(${CMAKE_SOURCE_DIR}/src/libc/stdtime/FreeBSD) +include_directories(${CMAKE_SOURCE_DIR}/src/libmalloc/include) +include_directories(${CMAKE_SOURCE_DIR}/src/kernel/emulation/linux/misc) include_directories(${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/sandbox) include_directories(${CMAKE_SOURCE_DIR}/src/external/libcxx/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/launch-cache) diff --git a/src/external/libplatform/.gitignore b/src/external/libplatform/.gitignore new file mode 100644 index 000000000..b45520f6b --- /dev/null +++ b/src/external/libplatform/.gitignore @@ -0,0 +1,2 @@ +/libplatform.xcodeproj/project.xcworkspace/ +/libplatform.xcodeproj/xcuserdata/ diff --git a/src/external/libplatform/CMakeLists.txt b/src/external/libplatform/CMakeLists.txt new file mode 100644 index 000000000..64f4e4588 --- /dev/null +++ b/src/external/libplatform/CMakeLists.txt @@ -0,0 +1,95 @@ +project(libplatform) + +cmake_minimum_required(VERSION 2.4.0) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc") + +add_definitions(-DTARGET_OS_MAC=1) +add_definitions(-DHAVE_STDINT_H=1) +add_definitions(-D__APPLE__ -D__DYNAMIC__ -DPRIVATE) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/private + ${CMAKE_CURRENT_SOURCE_DIR}/internal + ${CMAKE_SOURCE_DIR}/src/libc/derived + ${CMAKE_SOURCE_DIR}/src/libc/darwin + ${CMAKE_SOURCE_DIR}/src/kernel/libsyscall + ${CMAKE_SOURCE_DIR}/src/kernel/libsyscall/wrappers) + +set(platform_x86_64_sources + src/setjmp/x86_64/_setjmp.S + src/setjmp/x86_64/setjmp.S + src/setjmp/x86_64/_sigtramp.S + src/ucontext/x86_64/_ctx_start.S + src/ucontext/x86_64/getcontext.S + src/ucontext/x86_64/_setcontext.S + src/cachecontrol/x86_64/cache.S + src/atomics/x86_64/pfz.S + src/atomics/x86_64/OSAtomic.S +) +add_library(platform_x86_64 OBJECT ${platform_x86_64_sources}) +set_target_properties(platform_x86_64 PROPERTIES COMPILE_FLAGS "-arch x86_64") + +set(platform_i386_sources + src/setjmp/i386/_setjmp.S + src/setjmp/i386/setjmp.S + src/setjmp/i386/_sigtramp.S + src/ucontext/i386/_ctx_start.S + src/ucontext/i386/getcontext.S + src/ucontext/i386/_setcontext.S + src/atomics/i386/pfz.S + src/atomics/i386/OSAtomic.S + src/cachecontrol/i386/cache.S +) +add_library(platform_i386 OBJECT ${platform_i386_sources}) +set_target_properties(platform_i386 PROPERTIES COMPILE_FLAGS "-arch i386") + +set(platform_sources + src/setjmp/generic/sigtramp.c + src/setjmp/generic/setjmperr.c + src/os/semaphore.c + src/os/atomic_up.c + src/os/lock.c + src/os/lock_wfe.c + src/os/lock_up.c + src/os/resolver.c + src/os/alloc_once.c + src/os/atomic.c + src/ucontext/generic/getmcontext.c + src/ucontext/generic/makecontext.c + src/ucontext/generic/swapcontext.c + src/ucontext/generic/setcontext.c + src/force_libplatform_to_build.c + src/init.c + src/cachecontrol/generic/cache.c + src/string/generic/memccpy.c + src/string/generic/memmove.c + src/string/generic/strcmp.c + src/string/generic/flsll.c + src/string/generic/memcmp.c + src/string/generic/strchr.c + src/string/generic/ffsll.c + src/string/generic/strncmp.c + src/string/generic/bzero.c + src/string/generic/memset_pattern.c + src/string/generic/memchr.c + src/atomics/common/MKGetTimeBaseInfo.c + src/atomics/init.c + src/simple/string_io.c + src/simple/asl.c + src/simple/getenv.c + #src/introspection/introspection.c +) + +set(DYLIB_INSTALL_NAME "/usr/lib/system/libplatform.dylib") +add_darling_library(platform SHARED ${platform_sources} $ $) +make_fat(platform) + +target_link_libraries(platform PRIVATE system_kernel system_dyld compiler_rt) + +#set(CMAKE_AR "${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/ar/x86_64-apple-darwin11-ar") +#set(CMAKE_RANLIB "${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/misc/ranlib") +#add_library(platform_static STATIC ${platform_sources}) +#add_dependencies(platform_static ranlib x86_64-apple-darwin11-ar) + +install(TARGETS platform DESTINATION libexec/darling/usr/lib/system) diff --git a/src/external/libplatform/LICENSE b/src/external/libplatform/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/src/external/libplatform/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/libc/gen/_simple.h b/src/external/libplatform/include/_simple.h similarity index 80% rename from src/libc/gen/_simple.h rename to src/external/libplatform/include/_simple.h index 7f2d49a9c..b3bd92461 100644 --- a/src/libc/gen/_simple.h +++ b/src/external/libplatform/include/_simple.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010 Apple Inc. All rights reserved. + * Copyright (c) 2006, 2010, 2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,9 +20,14 @@ * * @APPLE_LICENSE_HEADER_END@ */ + +#ifndef _SYSTEM_SIMPLE_H_ +#define _SYSTEM_SIMPLE_H_ + #include #include -#include + +#include typedef void *_SIMPLE_STRING; typedef const char *_esc_func(unsigned char); @@ -54,16 +59,16 @@ _SIMPLE_STRING _simple_salloc(void); /* * The format string is interpreted with arguments from the va_list, and the * results are appended to the string maintained by the opaque structure, as - * returned by a previous call to _simple_salloc(). Non-zero is returned on - * out-of-memory error. + * returned by a previous call to _simple_salloc(). + * Always returns 0 on OS X >= 10.12 and iOS >= 10.0 */ int _simple_vsprintf(_SIMPLE_STRING __b, const char *__fmt, va_list __ap); /* * The format string is interpreted with arguments from the variable argument * list, and the results are appended to the string maintained by the opaque - * structure, as returned by a previous call to _simple_salloc(). Non-zero is - * returned on out-of-memory error. + * structure, as returned by a previous call to _simple_salloc(). + * Always returns 0 on OS X >= 10.12 and iOS >= 10.0 */ int _simple_sprintf(_SIMPLE_STRING __b, const char *__fmt, ...); @@ -95,7 +100,7 @@ void _simple_sresize(_SIMPLE_STRING __b); /* * Append the null-terminated string to the string associated with the opaque - * structure. Non-zero is returned on out-of-memory error. + * structure. Always returns 0 on OS X >= 10.12 and iOS >= 10.0 */ int _simple_sappend(_SIMPLE_STRING __b, const char *__str); @@ -126,6 +131,32 @@ void _simple_sfree(_SIMPLE_STRING __b); * Simplified ASL log interface; does not use malloc. Unfortunately, this * requires knowledge of the format used by ASL. */ +#ifndef ASL_LEVEL_DEBUG +#define ASL_LEVEL_EMERG 0 +#define ASL_LEVEL_ALERT 1 +#define ASL_LEVEL_CRIT 2 +#define ASL_LEVEL_ERR 3 +#define ASL_LEVEL_WARNING 4 +#define ASL_LEVEL_NOTICE 5 +#define ASL_LEVEL_INFO 6 +#define ASL_LEVEL_DEBUG 7 +#endif + void _simple_asl_log(int __level, const char *__facility, const char *__message); void _simple_asl_log_prog(int level, const char *facility, const char *message, const char *progname); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +_SIMPLE_STRING _simple_asl_msg_new(void); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void _simple_asl_msg_set(_SIMPLE_STRING __b, const char *__key, const char *__val); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void _simple_asl_send(_SIMPLE_STRING __b); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +const char *_simple_getenv(const char *envp[], const char *var); + __END_DECLS + +#endif /* _SYSTEM_SIMPLE_H_ */ diff --git a/src/external/libplatform/include/libkern/OSAtomic.h b/src/external/libplatform/include/libkern/OSAtomic.h new file mode 100644 index 000000000..ac38f9440 --- /dev/null +++ b/src/external/libplatform/include/libkern/OSAtomic.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OSATOMIC_H_ +#define _OSATOMIC_H_ + +/*! @header + * These are deprecated legacy interfaces for atomic and synchronization + * operations. + * + * Define OSATOMIC_USE_INLINED=1 to get inline implementations of the + * OSAtomic interfaces in terms of the primitives. + * + * Define OSSPINLOCK_USE_INLINED=1 to get inline implementations of the + * OSSpinLock interfaces in terms of the primitives. + * + * These are intended as a transition convenience, direct use of those + * primitives should be preferred. + */ + +#include + +#include "OSAtomicDeprecated.h" +#include "OSSpinLockDeprecated.h" +#include "OSAtomicQueue.h" + +#endif /* _OSATOMIC_H_ */ diff --git a/src/external/libplatform/include/libkern/OSAtomicDeprecated.h b/src/external/libplatform/include/libkern/OSAtomicDeprecated.h new file mode 100644 index 000000000..278e04ef5 --- /dev/null +++ b/src/external/libplatform/include/libkern/OSAtomicDeprecated.h @@ -0,0 +1,1177 @@ +/* + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OSATOMIC_DEPRECATED_H_ +#define _OSATOMIC_DEPRECATED_H_ + +/*! @header + * These are deprecated legacy interfaces for atomic operations. + * The C11 interfaces in resp. C++11 interfaces in + * should be used instead. + * + * Define OSATOMIC_USE_INLINED=1 to get inline implementations of these + * interfaces in terms of the resp. primitives. + * This is intended as a transition convenience, direct use of those primitives + * is preferred. + */ + +#if !(defined(OSATOMIC_USE_INLINED) && OSATOMIC_USE_INLINED) + +#include +#include +#include +#include +#include + +#ifndef OSATOMIC_DEPRECATED +#define OSATOMIC_DEPRECATED 1 +#ifndef __cplusplus +#define OSATOMIC_BARRIER_DEPRECATED_MSG(_r) \ + "Use " #_r "() from instead" +#define OSATOMIC_DEPRECATED_MSG(_r) \ + "Use " #_r "_explicit(memory_order_relaxed) from instead" +#else +#define OSATOMIC_BARRIER_DEPRECATED_MSG(_r) \ + "Use std::" #_r "() from instead" +#define OSATOMIC_DEPRECATED_MSG(_r) \ + "Use std::" #_r "_explicit(std::memory_order_relaxed) from instead" +#endif +#define OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(_r) \ + __OS_AVAILABILITY_MSG(macosx, deprecated=10.12, OSATOMIC_BARRIER_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(ios, deprecated=10.0, OSATOMIC_BARRIER_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(tvos, deprecated=10.0, OSATOMIC_BARRIER_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(watchos, deprecated=3.0, OSATOMIC_BARRIER_DEPRECATED_MSG(_r)) +#define OSATOMIC_DEPRECATED_REPLACE_WITH(_r) \ + __OS_AVAILABILITY_MSG(macosx, deprecated=10.12, OSATOMIC_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(ios, deprecated=10.0, OSATOMIC_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(tvos, deprecated=10.0, OSATOMIC_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(watchos, deprecated=3.0, OSATOMIC_DEPRECATED_MSG(_r)) +#else +#undef OSATOMIC_DEPRECATED +#define OSATOMIC_DEPRECATED 0 +#define OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(_r) +#define OSATOMIC_DEPRECATED_REPLACE_WITH(_r) +#endif + +/* + * WARNING: all addresses passed to these functions must be "naturally aligned", + * i.e. int32_t pointers must be 32-bit aligned (low 2 bits of + * address are zeroes), and int64_t pointers must be 64-bit + * aligned (low 3 bits of address are zeroes.). + * Note that this is not the default alignment of the int64_t type + * in the iOS ARMv7 ABI, see + * {@link //apple_ref/doc/uid/TP40009021-SW8 iPhoneOSABIReference} + * + * Note that some versions of the atomic functions incorporate memory barriers + * and some do not. Barriers strictly order memory access on weakly-ordered + * architectures such as ARM. All loads and stores that appear (in sequential + * program order) before the barrier are guaranteed to complete before any + * load or store that appears after the barrier. + * + * The barrier operation is typically a no-op on uniprocessor systems and + * fully enabled on multiprocessor systems. On some platforms, such as ARM, + * the barrier can be quite expensive. + * + * Most code should use the barrier functions to ensure that memory shared + * between threads is properly synchronized. For example, if you want to + * initialize a shared data structure and then atomically increment a variable + * to indicate that the initialization is complete, you must use + * {@link OSAtomicIncrement32Barrier} to ensure that the stores to your data + * structure complete before the atomic increment. + * + * Likewise, the consumer of that data structure must use + * {@link OSAtomicDecrement32Barrier}, + * in order to ensure that their loads of the structure are not executed before + * the atomic decrement. On the other hand, if you are simply incrementing a + * global counter, then it is safe and potentially faster to use + * {@link OSAtomicIncrement32}. + * + * If you are unsure which version to use, prefer the barrier variants as they + * are safer. + * + * For the kernel-space version of this header, see + * {@link //apple_ref/doc/header/OSAtomic.h OSAtomic.h (Kernel Framework)} + * + * @apiuid //apple_ref/doc/header/user_space_OSAtomic.h + */ + +__BEGIN_DECLS + +/*! @typedef OSAtomic_int64_aligned64_t + * 64-bit aligned int64_t type. + * Use for variables whose addresses are passed to OSAtomic*64() functions to + * get the compiler to generate the required alignment. + */ + +#if __has_attribute(aligned) +typedef int64_t __attribute__((__aligned__((sizeof(int64_t))))) + OSAtomic_int64_aligned64_t; +#else +typedef int64_t OSAtomic_int64_aligned64_t; +#endif + +/*! @group Arithmetic functions + All functions in this group return the new value. + */ + +/*! @abstract Atomically adds two 32-bit values. + @discussion + This function adds the value given by __theAmount to the + value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the new value. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +int32_t OSAtomicAdd32( int32_t __theAmount, volatile int32_t *__theValue ); + + +/*! @abstract Atomically adds two 32-bit values. + @discussion + This function adds the value given by __theAmount to the + value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicAdd32} + except that it also introduces a barrier. + @result Returns the new value. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +int32_t OSAtomicAdd32Barrier( int32_t __theAmount, volatile int32_t *__theValue ); + + +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10 || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_1 + +/*! @abstract Atomically increments a 32-bit value. + @result Returns the new value. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add) +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) +int32_t OSAtomicIncrement32( volatile int32_t *__theValue ); + + +/*! @abstract Atomically increments a 32-bit value with a barrier. + @discussion + This function is equivalent to {@link OSAtomicIncrement32} + except that it also introduces a barrier. + @result Returns the new value. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add) +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) +int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue ); + + +/*! @abstract Atomically decrements a 32-bit value. + @result Returns the new value. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_sub) +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) +int32_t OSAtomicDecrement32( volatile int32_t *__theValue ); + + +/*! @abstract Atomically decrements a 32-bit value with a barrier. + @discussion + This function is equivalent to {@link OSAtomicDecrement32} + except that it also introduces a barrier. + @result Returns the new value. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_sub) +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) +int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue ); + +#else +__inline static +int32_t OSAtomicIncrement32( volatile int32_t *__theValue ) + { return OSAtomicAdd32( 1, __theValue); } + +__inline static +int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue ) + { return OSAtomicAdd32Barrier( 1, __theValue); } + +__inline static +int32_t OSAtomicDecrement32( volatile int32_t *__theValue ) + { return OSAtomicAdd32( -1, __theValue); } + +__inline static +int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue ) + { return OSAtomicAdd32Barrier( -1, __theValue); } +#endif + + +/*! @abstract Atomically adds two 64-bit values. + @discussion + This function adds the value given by __theAmount to the + value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the new value. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +int64_t OSAtomicAdd64( int64_t __theAmount, + volatile OSAtomic_int64_aligned64_t *__theValue ); + + +/*! @abstract Atomically adds two 64-bit values with a barrier. + @discussion + This function adds the value given by __theAmount to the + value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicAdd64} + except that it also introduces a barrier. + @result Returns the new value. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2) +int64_t OSAtomicAdd64Barrier( int64_t __theAmount, + volatile OSAtomic_int64_aligned64_t *__theValue ); + + +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10 || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_1 + +/*! @abstract Atomically increments a 64-bit value. + @result Returns the new value. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_add) +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) +int64_t OSAtomicIncrement64( volatile OSAtomic_int64_aligned64_t *__theValue ); + + +/*! @abstract Atomically increments a 64-bit value with a barrier. + @discussion + This function is equivalent to {@link OSAtomicIncrement64} + except that it also introduces a barrier. + @result Returns the new value. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_add) +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) +int64_t OSAtomicIncrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue ); + + +/*! @abstract Atomically decrements a 64-bit value. + @result Returns the new value. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_sub) +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) +int64_t OSAtomicDecrement64( volatile OSAtomic_int64_aligned64_t *__theValue ); + + +/*! @abstract Atomically decrements a 64-bit value with a barrier. + @discussion + This function is equivalent to {@link OSAtomicDecrement64} + except that it also introduces a barrier. + @result Returns the new value. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_sub) +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_1) +int64_t OSAtomicDecrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue ); + +#else +__inline static +int64_t OSAtomicIncrement64( volatile OSAtomic_int64_aligned64_t *__theValue ) + { return OSAtomicAdd64( 1, __theValue); } + +__inline static +int64_t OSAtomicIncrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue ) + { return OSAtomicAdd64Barrier( 1, __theValue); } + +__inline static +int64_t OSAtomicDecrement64( volatile OSAtomic_int64_aligned64_t *__theValue ) + { return OSAtomicAdd64( -1, __theValue); } + +__inline static +int64_t OSAtomicDecrement64Barrier( volatile OSAtomic_int64_aligned64_t *__theValue ) + { return OSAtomicAdd64Barrier( -1, __theValue); } +#endif + + +/*! @group Boolean functions (AND, OR, XOR) + * + * @discussion Functions in this group come in four variants for each operation: + * with and without barriers, and functions that return the original value or + * the result value of the operation. + * + * The "Orig" versions return the original value, (before the operation); the non-Orig + * versions return the value after the operation. All are layered on top of + * {@link OSAtomicCompareAndSwap32} and similar. + */ + +/*! @abstract Atomic bitwise OR of two 32-bit values. + @discussion + This function performs the bitwise OR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the new value. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +int32_t OSAtomicOr32( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise OR of two 32-bit values with barrier. + @discussion + This function performs the bitwise OR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicOr32} + except that it also introduces a barrier. + @result Returns the new value. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +int32_t OSAtomicOr32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise OR of two 32-bit values returning original. + @discussion + This function performs the bitwise OR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the original value referenced by __theValue. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) +int32_t OSAtomicOr32Orig( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise OR of two 32-bit values returning original with barrier. + @discussion + This function performs the bitwise OR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicOr32Orig} + except that it also introduces a barrier. + @result Returns the original value referenced by __theValue. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) +int32_t OSAtomicOr32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ); + + + + +/*! @abstract Atomic bitwise AND of two 32-bit values. + @discussion + This function performs the bitwise AND of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the new value. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +int32_t OSAtomicAnd32( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise AND of two 32-bit values with barrier. + @discussion + This function performs the bitwise AND of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicAnd32} + except that it also introduces a barrier. + @result Returns the new value. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +int32_t OSAtomicAnd32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise AND of two 32-bit values returning original. + @discussion + This function performs the bitwise AND of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the original value referenced by __theValue. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) +int32_t OSAtomicAnd32Orig( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise AND of two 32-bit values returning original with barrier. + @discussion + This function performs the bitwise AND of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicAnd32Orig} + except that it also introduces a barrier. + @result Returns the original value referenced by __theValue. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) +int32_t OSAtomicAnd32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ); + + + + +/*! @abstract Atomic bitwise XOR of two 32-bit values. + @discussion + This function performs the bitwise XOR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the new value. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_xor) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +int32_t OSAtomicXor32( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise XOR of two 32-bit values with barrier. + @discussion + This function performs the bitwise XOR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicXor32} + except that it also introduces a barrier. + @result Returns the new value. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_xor) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +int32_t OSAtomicXor32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise XOR of two 32-bit values returning original. + @discussion + This function performs the bitwise XOR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + @result Returns the original value referenced by __theValue. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_xor) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) +int32_t OSAtomicXor32Orig( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @abstract Atomic bitwise XOR of two 32-bit values returning original with barrier. + @discussion + This function performs the bitwise XOR of the value given by __theMask + with the value in the memory location referenced by __theValue, + storing the result back to that memory location atomically. + + This function is equivalent to {@link OSAtomicXor32Orig} + except that it also introduces a barrier. + @result Returns the original value referenced by __theValue. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_xor) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2) +int32_t OSAtomicXor32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ); + + +/*! @group Compare and swap + * Functions in this group return true if the swap occured. There are several versions, + * depending on data type and on whether or not a barrier is used. + */ + + +/*! @abstract Compare and swap for 32-bit values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +bool OSAtomicCompareAndSwap32( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); + + +/*! @abstract Compare and swap for 32-bit values with barrier. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwap32} + except that it also introduces a barrier. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); + + +/*! @abstract Compare and swap pointers. + @discussion + This function compares the pointer stored in __oldValue to the pointer + in the memory location referenced by __theValue. If the pointers + match, this function stores the pointer from __newValue into + that memory location atomically. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) +bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ); + + +/*! @abstract Compare and swap pointers with barrier. + @discussion + This function compares the pointer stored in __oldValue to the pointer + in the memory location referenced by __theValue. If the pointers + match, this function stores the pointer from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwapPtr} + except that it also introduces a barrier. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) +bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue ); + + +/*! @abstract Compare and swap for int values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwap32}. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) +bool OSAtomicCompareAndSwapInt( int __oldValue, int __newValue, volatile int *__theValue ); + + +/*! @abstract Compare and swap for int values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwapInt} + except that it also introduces a barrier. + + This function is equivalent to {@link OSAtomicCompareAndSwap32Barrier}. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) +bool OSAtomicCompareAndSwapIntBarrier( int __oldValue, int __newValue, volatile int *__theValue ); + + +/*! @abstract Compare and swap for long values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures, + or {@link OSAtomicCompareAndSwap64} on 64-bit architectures. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) +bool OSAtomicCompareAndSwapLong( long __oldValue, long __newValue, volatile long *__theValue ); + + +/*! @abstract Compare and swap for long values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwapLong} + except that it also introduces a barrier. + + This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures, + or {@link OSAtomicCompareAndSwap64} on 64-bit architectures. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0) +bool OSAtomicCompareAndSwapLongBarrier( long __oldValue, long __newValue, volatile long *__theValue ); + + +/*! @abstract Compare and swap for uint64_t values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +bool OSAtomicCompareAndSwap64( int64_t __oldValue, int64_t __newValue, + volatile OSAtomic_int64_aligned64_t *__theValue ); + + +/*! @abstract Compare and swap for uint64_t values. + @discussion + This function compares the value in __oldValue to the value + in the memory location referenced by __theValue. If the values + match, this function stores the value from __newValue into + that memory location atomically. + + This function is equivalent to {@link OSAtomicCompareAndSwap64} + except that it also introduces a barrier. + @result Returns TRUE on a match, FALSE otherwise. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_compare_exchange_strong) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2) +bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, + volatile OSAtomic_int64_aligned64_t *__theValue ); + + +/* Test and set. + * They return the original value of the bit, and operate on bit (0x80>>(n&7)) + * in byte ((char*)theAddress + (n>>3)). + */ +/*! @abstract Atomic test and set + @discussion + This function tests a bit in the value referenced by + __theAddress and if it is not set, sets it. + + The bit is chosen by the value of __n such that the + operation will be performed on bit (0x80 >> (__n & 7)) + of byte ((char *)__theAddress + (n >> 3)). + + For example, if __theAddress points to a 64-bit value, + to compare the value of the most significant bit, you would specify + 56 for __n. + @result + Returns the original value of the bit being tested. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_or) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +bool OSAtomicTestAndSet( uint32_t __n, volatile void *__theAddress ); + + +/*! @abstract Atomic test and set with barrier + @discussion + This function tests a bit in the value referenced by __theAddress + and if it is not set, sets it. + + The bit is chosen by the value of __n such that the + operation will be performed on bit (0x80 >> (__n & 7)) + of byte ((char *)__theAddress + (n >> 3)). + + For example, if __theAddress points to a 64-bit value, + to compare the value of the most significant bit, you would specify + 56 for __n. + + This function is equivalent to {@link OSAtomicTestAndSet} + except that it also introduces a barrier. + @result + Returns the original value of the bit being tested. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_or) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +bool OSAtomicTestAndSetBarrier( uint32_t __n, volatile void *__theAddress ); + + + +/*! @abstract Atomic test and clear + @discussion + This function tests a bit in the value referenced by __theAddress + and if it is not cleared, clears it. + + The bit is chosen by the value of __n such that the + operation will be performed on bit (0x80 >> (__n & 7)) + of byte ((char *)__theAddress + (n >> 3)). + + For example, if __theAddress points to a 64-bit value, + to compare the value of the most significant bit, you would specify + 56 for __n. + + @result + Returns the original value of the bit being tested. + */ +OSATOMIC_DEPRECATED_REPLACE_WITH(atomic_fetch_and) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +bool OSAtomicTestAndClear( uint32_t __n, volatile void *__theAddress ); + + +/*! @abstract Atomic test and clear + @discussion + This function tests a bit in the value referenced by __theAddress + and if it is not cleared, clears it. + + The bit is chosen by the value of __n such that the + operation will be performed on bit (0x80 >> (__n & 7)) + of byte ((char *)__theAddress + (n >> 3)). + + For example, if __theAddress points to a 64-bit value, + to compare the value of the most significant bit, you would specify + 56 for __n. + + This function is equivalent to {@link OSAtomicTestAndSet} + except that it also introduces a barrier. + @result + Returns the original value of the bit being tested. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_fetch_and) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +bool OSAtomicTestAndClearBarrier( uint32_t __n, volatile void *__theAddress ); + + +/*! @group Memory barriers */ + +/*! @abstract Memory barrier. + @discussion + This function serves as both a read and write barrier. + */ +OSATOMIC_BARRIER_DEPRECATED_REPLACE_WITH(atomic_thread_fence) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +void OSMemoryBarrier( void ); + +__END_DECLS + +#else // defined(OSATOMIC_USE_INLINED) && OSATOMIC_USE_INLINED + +/* + * Inline implementations of the legacy OSAtomic interfaces in terms of + * C11 resp. C++11 primitives. + * Direct use of those primitives is preferred. + */ + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C++" { +#if !(__has_include() && __has_feature(cxx_atomic)) +#error Cannot use inlined OSAtomic without and C++11 atomics +#endif +#include +typedef std::atomic _OSAtomic_uint8_t; +typedef std::atomic _OSAtomic_int32_t; +typedef std::atomic _OSAtomic_uint32_t; +typedef std::atomic _OSAtomic_int64_t; +typedef std::atomic _OSAtomic_void_ptr_t; +#define OSATOMIC_STD(_a) std::_a +__BEGIN_DECLS +#else +#if !(__has_include() && __has_extension(c_atomic)) +#error Cannot use inlined OSAtomic without and C11 atomics +#endif +#include +typedef _Atomic(uint8_t) _OSAtomic_uint8_t; +typedef _Atomic(int32_t) _OSAtomic_int32_t; +typedef _Atomic(uint32_t) _OSAtomic_uint32_t; +typedef _Atomic(int64_t) _OSAtomic_int64_t; +typedef _Atomic(void*) _OSAtomic_void_ptr_t; +#define OSATOMIC_STD(_a) _a +#endif + +#if __has_extension(c_alignof) && __has_attribute(aligned) +typedef int64_t __attribute__((__aligned__(_Alignof(_OSAtomic_int64_t)))) + OSAtomic_int64_aligned64_t; +#elif __has_attribute(aligned) +typedef int64_t __attribute__((__aligned__((sizeof(_OSAtomic_int64_t))))) + OSAtomic_int64_aligned64_t; +#else +typedef int64_t OSAtomic_int64_aligned64_t; +#endif + +#if __has_attribute(always_inline) +#define OSATOMIC_INLINE static __inline +#else +#define OSATOMIC_INLINE static __inline __attribute__((__always_inline__)) +#endif + +OSATOMIC_INLINE +int32_t +OSAtomicAdd32(int32_t __theAmount, volatile int32_t *__theValue) +{ + return (OSATOMIC_STD(atomic_fetch_add_explicit)( + (volatile _OSAtomic_int32_t*) __theValue, __theAmount, + OSATOMIC_STD(memory_order_relaxed)) + __theAmount); +} + +OSATOMIC_INLINE +int32_t +OSAtomicAdd32Barrier(int32_t __theAmount, volatile int32_t *__theValue) +{ + return (OSATOMIC_STD(atomic_fetch_add_explicit)( + (volatile _OSAtomic_int32_t*) __theValue, __theAmount, + OSATOMIC_STD(memory_order_seq_cst)) + __theAmount); +} + +OSATOMIC_INLINE +int32_t +OSAtomicIncrement32(volatile int32_t *__theValue) +{ + return OSAtomicAdd32(1, __theValue); +} + +OSATOMIC_INLINE +int32_t +OSAtomicIncrement32Barrier(volatile int32_t *__theValue) +{ + return OSAtomicAdd32Barrier(1, __theValue); +} + +OSATOMIC_INLINE +int32_t +OSAtomicDecrement32(volatile int32_t *__theValue) +{ + return OSAtomicAdd32(-1, __theValue); +} + +OSATOMIC_INLINE +int32_t +OSAtomicDecrement32Barrier(volatile int32_t *__theValue) +{ + return OSAtomicAdd32Barrier(-1, __theValue); +} + +OSATOMIC_INLINE +int64_t +OSAtomicAdd64(int64_t __theAmount, + volatile OSAtomic_int64_aligned64_t *__theValue) +{ + return (OSATOMIC_STD(atomic_fetch_add_explicit)( + (volatile _OSAtomic_int64_t*) __theValue, __theAmount, + OSATOMIC_STD(memory_order_relaxed)) + __theAmount); +} + +OSATOMIC_INLINE +int64_t +OSAtomicAdd64Barrier(int64_t __theAmount, + volatile OSAtomic_int64_aligned64_t *__theValue) +{ + return (OSATOMIC_STD(atomic_fetch_add_explicit)( + (volatile _OSAtomic_int64_t*) __theValue, __theAmount, + OSATOMIC_STD(memory_order_seq_cst)) + __theAmount); +} + +OSATOMIC_INLINE +int64_t +OSAtomicIncrement64(volatile OSAtomic_int64_aligned64_t *__theValue) +{ + return OSAtomicAdd64(1, __theValue); +} + +OSATOMIC_INLINE +int64_t +OSAtomicIncrement64Barrier(volatile OSAtomic_int64_aligned64_t *__theValue) +{ + return OSAtomicAdd64Barrier(1, __theValue); +} + +OSATOMIC_INLINE +int64_t +OSAtomicDecrement64(volatile OSAtomic_int64_aligned64_t *__theValue) +{ + return OSAtomicAdd64(-1, __theValue); +} + +OSATOMIC_INLINE +int64_t +OSAtomicDecrement64Barrier(volatile OSAtomic_int64_aligned64_t *__theValue) +{ + return OSAtomicAdd64Barrier(-1, __theValue); +} + +OSATOMIC_INLINE +int32_t +OSAtomicOr32(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_or_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_relaxed)) | __theMask); +} + +OSATOMIC_INLINE +int32_t +OSAtomicOr32Barrier(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_or_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_seq_cst)) | __theMask); +} + +OSATOMIC_INLINE +int32_t +OSAtomicOr32Orig(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_or_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +int32_t +OSAtomicOr32OrigBarrier(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_or_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_seq_cst))); +} + +OSATOMIC_INLINE +int32_t +OSAtomicAnd32(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_and_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_relaxed)) & __theMask); +} + +OSATOMIC_INLINE +int32_t +OSAtomicAnd32Barrier(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_and_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_seq_cst)) & __theMask); +} + +OSATOMIC_INLINE +int32_t +OSAtomicAnd32Orig(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_and_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +int32_t +OSAtomicAnd32OrigBarrier(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_and_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_seq_cst))); +} + +OSATOMIC_INLINE +int32_t +OSAtomicXor32(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_xor_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_relaxed)) ^ __theMask); +} + +OSATOMIC_INLINE +int32_t +OSAtomicXor32Barrier(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_xor_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_seq_cst)) ^ __theMask); +} + +OSATOMIC_INLINE +int32_t +OSAtomicXor32Orig(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_xor_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +int32_t +OSAtomicXor32OrigBarrier(uint32_t __theMask, volatile uint32_t *__theValue) +{ + return (int32_t)(OSATOMIC_STD(atomic_fetch_xor_explicit)( + (volatile _OSAtomic_uint32_t*)__theValue, __theMask, + OSATOMIC_STD(memory_order_seq_cst))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwap32(int32_t __oldValue, int32_t __newValue, + volatile int32_t *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile _OSAtomic_int32_t*)__theValue, &__oldValue, __newValue, + OSATOMIC_STD(memory_order_relaxed), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwap32Barrier(int32_t __oldValue, int32_t __newValue, + volatile int32_t *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile _OSAtomic_int32_t*)__theValue, &__oldValue, __newValue, + OSATOMIC_STD(memory_order_seq_cst), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwapPtr(void *__oldValue, void *__newValue, + void * volatile *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile _OSAtomic_void_ptr_t*)__theValue, &__oldValue, __newValue, + OSATOMIC_STD(memory_order_relaxed), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, + void * volatile *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile _OSAtomic_void_ptr_t*)__theValue, &__oldValue, __newValue, + OSATOMIC_STD(memory_order_seq_cst), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwapInt(int __oldValue, int __newValue, + volatile int *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile OSATOMIC_STD(atomic_int)*)__theValue, &__oldValue, + __newValue, OSATOMIC_STD(memory_order_relaxed), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwapIntBarrier(int __oldValue, int __newValue, + volatile int *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile OSATOMIC_STD(atomic_int)*)__theValue, &__oldValue, + __newValue, OSATOMIC_STD(memory_order_seq_cst), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwapLong(long __oldValue, long __newValue, + volatile long *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile OSATOMIC_STD(atomic_long)*)__theValue, &__oldValue, + __newValue, OSATOMIC_STD(memory_order_relaxed), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwapLongBarrier(long __oldValue, long __newValue, + volatile long *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile OSATOMIC_STD(atomic_long)*)__theValue, &__oldValue, + __newValue, OSATOMIC_STD(memory_order_seq_cst), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwap64(int64_t __oldValue, int64_t __newValue, + volatile OSAtomic_int64_aligned64_t *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile _OSAtomic_int64_t*)__theValue, &__oldValue, __newValue, + OSATOMIC_STD(memory_order_relaxed), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicCompareAndSwap64Barrier(int64_t __oldValue, int64_t __newValue, + volatile OSAtomic_int64_aligned64_t *__theValue) +{ + return (OSATOMIC_STD(atomic_compare_exchange_strong_explicit)( + (volatile _OSAtomic_int64_t*)__theValue, &__oldValue, __newValue, + OSATOMIC_STD(memory_order_seq_cst), + OSATOMIC_STD(memory_order_relaxed))); +} + +OSATOMIC_INLINE +bool +OSAtomicTestAndSet(uint32_t __n, volatile void *__theAddress) +{ + uintptr_t a = (uintptr_t)__theAddress + (__n >> 3); + uint8_t v = (0x80u >> (__n & 7)); + return (OSATOMIC_STD(atomic_fetch_or_explicit)((_OSAtomic_uint8_t*)a, v, + OSATOMIC_STD(memory_order_relaxed)) & v); +} + +OSATOMIC_INLINE +bool +OSAtomicTestAndSetBarrier(uint32_t __n, volatile void *__theAddress) +{ + uintptr_t a = (uintptr_t)__theAddress + (__n >> 3); + uint8_t v = (0x80u >> (__n & 7)); + return (OSATOMIC_STD(atomic_fetch_or_explicit)((_OSAtomic_uint8_t*)a, v, + OSATOMIC_STD(memory_order_seq_cst)) & v); +} + +OSATOMIC_INLINE +bool +OSAtomicTestAndClear(uint32_t __n, volatile void *__theAddress) +{ + uintptr_t a = (uintptr_t)__theAddress + (__n >> 3); + uint8_t v = (0x80u >> (__n & 7)); + return (OSATOMIC_STD(atomic_fetch_and_explicit)((_OSAtomic_uint8_t*)a, + (uint8_t)~v, OSATOMIC_STD(memory_order_relaxed)) & v); +} + +OSATOMIC_INLINE +bool +OSAtomicTestAndClearBarrier(uint32_t __n, volatile void *__theAddress) +{ + uintptr_t a = (uintptr_t)__theAddress + (__n >> 3); + uint8_t v = (0x80u >> (__n & 7)); + return (OSATOMIC_STD(atomic_fetch_and_explicit)((_OSAtomic_uint8_t*)a, + (uint8_t)~v, OSATOMIC_STD(memory_order_seq_cst)) & v); +} + +OSATOMIC_INLINE +void +OSMemoryBarrier(void) +{ + OSATOMIC_STD(atomic_thread_fence)(OSATOMIC_STD(memory_order_seq_cst)); +} + +#undef OSATOMIC_INLINE +#undef OSATOMIC_STD +#ifdef __cplusplus +__END_DECLS +} // extern "C++" +#endif + +#endif // defined(OSATOMIC_USE_INLINED) && OSATOMIC_USE_INLINED + +#endif /* _OSATOMIC_DEPRECATED_H_ */ diff --git a/src/external/libplatform/include/libkern/OSAtomicQueue.h b/src/external/libplatform/include/libkern/OSAtomicQueue.h new file mode 100644 index 000000000..8ffa4be84 --- /dev/null +++ b/src/external/libplatform/include/libkern/OSAtomicQueue.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OSATOMICQUEUE_H_ +#define _OSATOMICQUEUE_H_ + +#include +#include +#include +#include + +#include + +/*! @header Lockless atomic enqueue and dequeue + * These routines manipulate singly-linked LIFO lists. + */ + +__BEGIN_DECLS + +/*! @abstract The data structure for a queue head. + @discussion + You should always initialize a queue head structure with the + initialization vector {@link OS_ATOMIC_QUEUE_INIT} before use. + */ +#if defined(__x86_64__) + +typedef volatile struct { + void *opaque1; + long opaque2; +} __attribute__ ((aligned (16))) OSQueueHead; + +#else + +typedef volatile struct { + void *opaque1; + long opaque2; +} OSQueueHead; + +#endif + +/*! @abstract The initialization vector for a queue head. */ +#define OS_ATOMIC_QUEUE_INIT { NULL, 0 } + +/*! @abstract Enqueue an element onto a list. + @discussion + Memory barriers are incorporated as needed to permit thread-safe access + to the queue element. + @param __list + The list on which you want to enqueue the element. + @param __new + The element to add. + @param __offset + The "offset" parameter is the offset (in bytes) of the link field + from the beginning of the data structure being queued (__new). + The link field should be a pointer type. + The __offset value needs to be same for all enqueuing and + dequeuing operations on the same list, even if different structure types + are enqueued on that list. The use of offsetset(), defined in + stddef.h is the common way to specify the __offset + value. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0) +void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset); + + +/*! @abstract Dequeue an element from a list. + @discussion + Memory barriers are incorporated as needed to permit thread-safe access + to the queue element. + @param __list + The list from which you want to dequeue an element. + @param __offset + The "offset" parameter is the offset (in bytes) of the link field + from the beginning of the data structure being dequeued (__new). + The link field should be a pointer type. + The __offset value needs to be same for all enqueuing and + dequeuing operations on the same list, even if different structure types + are enqueued on that list. The use of offsetset(), defined in + stddef.h is the common way to specify the __offset + value. + IMPORTANT: the memory backing the link field of a queue element must not be + unmapped after OSAtomicDequeue() returns until all concurrent calls to + OSAtomicDequeue() for the same list on other threads have also returned, + as they may still be accessing that memory location. + @result + Returns the most recently enqueued element, or NULL if the + list is empty. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0) +void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset); + +#if defined(__x86_64__) || defined(__i386__) + +/*! @group Lockless atomic fifo enqueue and dequeue + * These routines manipulate singly-linked FIFO lists. + */ + +/*! @abstract The data structure for a fifo queue head. + @discussion + You should always initialize a fifo queue head structure with the + initialization vector {@link OS_ATOMIC_FIFO_QUEUE_INIT} before use. + */ +#if defined(__x86_64__) + +typedef volatile struct { + void *opaque1; + void *opaque2; + int opaque3; +} __attribute__ ((aligned (16))) OSFifoQueueHead; + +#else + +typedef volatile struct { + void *opaque1; + void *opaque2; + int opaque3; +} OSFifoQueueHead; + +#endif + +/*! @abstract The initialization vector for a fifo queue head. */ +#define OS_ATOMIC_FIFO_QUEUE_INIT { NULL, NULL, 0 } + +/*! @abstract Enqueue an element onto a list. + @discussion + Memory barriers are incorporated as needed to permit thread-safe access + to the queue element. + @param __list + The list on which you want to enqueue the element. + @param __new + The element to add. + @param __offset + The "offset" parameter is the offset (in bytes) of the link field + from the beginning of the data structure being queued (__new). + The link field should be a pointer type. + The __offset value needs to be same for all enqueuing and + dequeuing operations on the same list, even if different structure types + are enqueued on that list. The use of offsetset(), defined in + stddef.h is the common way to specify the __offset + value. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) +void OSAtomicFifoEnqueue( OSFifoQueueHead *__list, void *__new, size_t __offset); + +/*! @abstract Dequeue an element from a list. + @discussion + Memory barriers are incorporated as needed to permit thread-safe access + to the queue element. + @param __list + The list from which you want to dequeue an element. + @param __offset + The "offset" parameter is the offset (in bytes) of the link field + from the beginning of the data structure being dequeued (__new). + The link field should be a pointer type. + The __offset value needs to be same for all enqueuing and + dequeuing operations on the same list, even if different structure types + are enqueued on that list. The use of offsetset(), defined in + stddef.h is the common way to specify the __offset + value. + @result + Returns the oldest enqueued element, or NULL if the + list is empty. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) +void* OSAtomicFifoDequeue( OSFifoQueueHead *__list, size_t __offset); + +#endif /* __i386__ || __x86_64__ */ + +__END_DECLS + +#endif /* _OSATOMICQUEUE_H_ */ diff --git a/src/libc/include/libkern/OSCacheControl.h b/src/external/libplatform/include/libkern/OSCacheControl.h similarity index 90% rename from src/libc/include/libkern/OSCacheControl.h rename to src/external/libplatform/include/libkern/OSCacheControl.h index ca8df013c..44644770d 100644 --- a/src/libc/include/libkern/OSCacheControl.h +++ b/src/external/libplatform/include/libkern/OSCacheControl.h @@ -52,10 +52,10 @@ __BEGIN_DECLS /* perform one of the above cache functions: */ -int sys_cache_control( int function, void *start, size_t len); +int sys_cache_control( int function, void *start, size_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); /* equivalent to sys_cache_control(kCacheFunctionPrepareForExecution): */ -void sys_icache_invalidate( void *start, size_t len); +void sys_icache_invalidate( void *start, size_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); /* equivalent to sys_cache_control(kCacheFunctionFlushDcache): */ void sys_dcache_flush( void *start, size_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); diff --git a/src/external/libplatform/include/libkern/OSSpinLockDeprecated.h b/src/external/libplatform/include/libkern/OSSpinLockDeprecated.h new file mode 100644 index 000000000..68b64cdc2 --- /dev/null +++ b/src/external/libplatform/include/libkern/OSSpinLockDeprecated.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OSSPINLOCK_DEPRECATED_H_ +#define _OSSPINLOCK_DEPRECATED_H_ + +/*! @header + * These are deprecated legacy interfaces for userspace spinlocks. + * + * These interfaces should no longer be used, particularily in situations where + * threads of differing priorities may contend on the same spinlock. + * + * The interfaces in should be used instead in cases where a very + * low-level lock primitive is required. In general however, using higher level + * synchronization primitives such as those provided by the pthread or dispatch + * subsystems should be preferred. + * + * Define OSSPINLOCK_USE_INLINED=1 to get inline implementations of these + * interfaces in terms of the primitives. This is intended as a + * transition convenience, direct use of those primitives is preferred. + */ + +#ifndef OSSPINLOCK_DEPRECATED +#define OSSPINLOCK_DEPRECATED 1 +#define OSSPINLOCK_DEPRECATED_MSG(_r) "Use " #_r "() from instead" +#define OSSPINLOCK_DEPRECATED_REPLACE_WITH(_r) \ + __OS_AVAILABILITY_MSG(macosx, deprecated=10.12, OSSPINLOCK_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(ios, deprecated=10.0, OSSPINLOCK_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(tvos, deprecated=10.0, OSSPINLOCK_DEPRECATED_MSG(_r)) \ + __OS_AVAILABILITY_MSG(watchos, deprecated=3.0, OSSPINLOCK_DEPRECATED_MSG(_r)) +#else +#undef OSSPINLOCK_DEPRECATED +#define OSSPINLOCK_DEPRECATED 0 +#define OSSPINLOCK_DEPRECATED_REPLACE_WITH(_r) +#endif + +#if !(defined(OSSPINLOCK_USE_INLINED) && OSSPINLOCK_USE_INLINED) + +#include +#include +#include +#include +#include + +__BEGIN_DECLS + +/*! @abstract The default value for an OSSpinLock. + @discussion + The convention is that unlocked is zero, locked is nonzero. + */ +#define OS_SPINLOCK_INIT 0 + + +/*! @abstract Data type for a spinlock. + @discussion + You should always initialize a spinlock to {@link OS_SPINLOCK_INIT} before + using it. + */ +typedef int32_t OSSpinLock OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock); + + +/*! @abstract Locks a spinlock if it would not block + @result + Returns false if the lock was already held by another thread, + true if it took the lock successfully. + */ +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_trylock) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +bool OSSpinLockTry( volatile OSSpinLock *__lock ); + + +/*! @abstract Locks a spinlock + @discussion + Although the lock operation spins, it employs various strategies to back + off if the lock is held. + */ +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_lock) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +void OSSpinLockLock( volatile OSSpinLock *__lock ); + + +/*! @abstract Unlocks a spinlock */ +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_unlock) +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +void OSSpinLockUnlock( volatile OSSpinLock *__lock ); + +__END_DECLS + +#else /* OSSPINLOCK_USE_INLINED */ + +/* + * Inline implementations of the legacy OSSpinLock interfaces in terms of the + * of the primitives. Direct use of those primitives is preferred. + * + * NOTE: the locked value of os_unfair_lock is implementation defined and + * subject to change, code that relies on the specific locked value used by the + * legacy OSSpinLock interface WILL break when using these inline + * implementations in terms of os_unfair_lock. + */ + +#if !OSSPINLOCK_USE_INLINED_TRANSPARENT + +#include + +__BEGIN_DECLS + +#if __has_attribute(always_inline) +#define OSSPINLOCK_INLINE static __inline +#else +#define OSSPINLOCK_INLINE static __inline __attribute__((__always_inline__)) +#endif + +#define OS_SPINLOCK_INIT 0 +typedef int32_t OSSpinLock; + +#if __has_extension(c_static_assert) +_Static_assert(sizeof(OSSpinLock) == sizeof(os_unfair_lock), + "Incompatible os_unfair_lock type"); +#endif + +OSSPINLOCK_INLINE +void +OSSpinLockLock(volatile OSSpinLock *__lock) +{ + os_unfair_lock_t lock = (os_unfair_lock_t)__lock; + return os_unfair_lock_lock(lock); +} + +OSSPINLOCK_INLINE +bool +OSSpinLockTry(volatile OSSpinLock *__lock) +{ + os_unfair_lock_t lock = (os_unfair_lock_t)__lock; + return os_unfair_lock_trylock(lock); +} + +OSSPINLOCK_INLINE +void +OSSpinLockUnlock(volatile OSSpinLock *__lock) +{ + os_unfair_lock_t lock = (os_unfair_lock_t)__lock; + return os_unfair_lock_unlock(lock); +} + +#undef OSSPINLOCK_INLINE + +__END_DECLS + +#else /* OSSPINLOCK_USE_INLINED_TRANSPARENT */ + +#include +#include +#include +#include +#include + +#define OS_NOSPIN_LOCK_AVAILABILITY \ + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) \ + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) + +__BEGIN_DECLS + +#define OS_SPINLOCK_INIT 0 +typedef int32_t OSSpinLock OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock); +typedef volatile OSSpinLock *_os_nospin_lock_t; + +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_lock) +OS_NOSPIN_LOCK_AVAILABILITY +void _os_nospin_lock_lock(_os_nospin_lock_t lock); +#undef OSSpinLockLock +#define OSSpinLockLock(lock) _os_nospin_lock_lock(lock) + +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_trylock) +OS_NOSPIN_LOCK_AVAILABILITY +bool _os_nospin_lock_trylock(_os_nospin_lock_t lock); +#undef OSSpinLockTry +#define OSSpinLockTry(lock) _os_nospin_lock_trylock(lock) + +OSSPINLOCK_DEPRECATED_REPLACE_WITH(os_unfair_lock_unlock) +OS_NOSPIN_LOCK_AVAILABILITY +void _os_nospin_lock_unlock(_os_nospin_lock_t lock); +#undef OSSpinLockUnlock +#define OSSpinLockUnlock(lock) _os_nospin_lock_unlock(lock) + +__END_DECLS + +#endif /* OSSPINLOCK_USE_INLINED_TRANSPARENT */ + +#endif /* OSSPINLOCK_USE_INLINED */ + +#endif /* _OSSPINLOCK_DEPRECATED_H_ */ diff --git a/src/external/libplatform/include/os/alloc_once_impl.h b/src/external/libplatform/include/os/alloc_once_impl.h new file mode 100644 index 000000000..d821e1890 --- /dev/null +++ b/src/external/libplatform/include/os/alloc_once_impl.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2012-2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_ALLOC_ONCE_IMPL__ +#define __OS_ALLOC_ONCE_IMPL__ + +#ifndef __OS_ALLOC_INDIRECT__ +#error "Please include instead of this file directly." +#endif + +#include +#include +#include +#include + +__BEGIN_DECLS + +#define OS_ALLOC_SPI_VERSION 20120430 + +#define OS_ALLOC_ONCE_KEY_MAX 100 + +typedef os_once_t os_alloc_token_t; +struct _os_alloc_once_s { + os_alloc_token_t once; + void *ptr; +}; + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +extern struct _os_alloc_once_s _os_alloc_once_table[]; + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) +OS_EXPORT OS_NONNULL1 +void* +_os_alloc_once(struct _os_alloc_once_s *slot, size_t sz, os_function_t init); + +/* + * The region allocated by os_alloc_once is 0-filled when initially + * returned (or handed off to the initializer). + */ +OS_WARN_RESULT OS_NOTHROW OS_CONST +__header_always_inline void* +os_alloc_once(os_alloc_token_t token, size_t sz, os_function_t init) +{ + struct _os_alloc_once_s *slot = &_os_alloc_once_table[token]; + if (OS_EXPECT(slot->once, ~0l) != ~0l) { + void *ptr = _os_alloc_once(slot, sz, init); + OS_COMPILER_CAN_ASSUME(slot->once == ~0l); + return ptr; + } + return slot->ptr; +} + +__END_DECLS + +#endif // __OS_ALLOC_ONCE_IMPL__ diff --git a/src/libc/os/base.h b/src/external/libplatform/include/os/base.h similarity index 100% rename from src/libc/os/base.h rename to src/external/libplatform/include/os/base.h diff --git a/src/external/libplatform/include/os/base_private.h b/src/external/libplatform/include/os/base_private.h new file mode 100644 index 000000000..2d3826615 --- /dev/null +++ b/src/external/libplatform/include/os/base_private.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_BASE_PRIVATE__ +#define __OS_BASE_PRIVATE__ + +#include + +#ifndef os_fastpath +#define os_fastpath(x) ((__typeof__(x))OS_EXPECT((long)(x), ~0l)) +#endif +#ifndef os_slowpath +#define os_slowpath(x) ((__typeof__(x))OS_EXPECT((long)(x), 0l)) +#endif +#ifndef os_likely +#define os_likely(x) OS_EXPECT(!!(x), 1) +#endif +#ifndef os_unlikely +#define os_unlikely(x) OS_EXPECT(!!(x), 0) +#endif + +#endif // __OS_BASE_PRIVATE__ diff --git a/src/external/libplatform/include/os/internal/atomic.h b/src/external/libplatform/include/os/internal/atomic.h new file mode 100644 index 000000000..f2af82bae --- /dev/null +++ b/src/external/libplatform/include/os/internal/atomic.h @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_INTERNAL_ATOMIC__ +#define __OS_INTERNAL_ATOMIC__ + +#ifndef __OS_EXPOSE_INTERNALS_INDIRECT__ +/* + * Use c11 or c++11 std::atomic from instead + * + * XXX /!\ WARNING /!\ XXX + * + * This header file describes INTERNAL interfaces to libplatform used by other + * libsystem targets, which are subject to change in future releases of OS X + * and iOS. Any applications relying on these interfaces WILL break. + * + * If you are not a libsystem target, you should NOT EVER use these headers. + * Not even a little. + * + * XXX /!\ WARNING /!\ XXX + */ +#error "Please #include instead of this file directly." +#else + +// generate error during codegen +#define _os_atomic_unimplemented() \ + ({ __asm__(".err unimplemented"); }) + +#pragma mark - +#pragma mark memory_order + +typedef enum _os_atomic_memory_order +{ + _os_atomic_memory_order_relaxed, + _os_atomic_memory_order_consume, + _os_atomic_memory_order_acquire, + _os_atomic_memory_order_release, + _os_atomic_memory_order_acq_rel, + _os_atomic_memory_order_seq_cst, + _os_atomic_memory_order_ordered, +} _os_atomic_memory_order; + +#if !OS_ATOMIC_UP + +#define os_atomic_memory_order_relaxed \ + _os_atomic_memory_order_relaxed +#define os_atomic_memory_order_acquire \ + _os_atomic_memory_order_acquire +#define os_atomic_memory_order_release \ + _os_atomic_memory_order_release +#define os_atomic_memory_order_acq_rel \ + _os_atomic_memory_order_acq_rel +#define os_atomic_memory_order_seq_cst \ + _os_atomic_memory_order_seq_cst +#define os_atomic_memory_order_ordered \ + _os_atomic_memory_order_seq_cst + +#else // OS_ATOMIC_UP + +#define os_atomic_memory_order_relaxed \ + _os_atomic_memory_order_relaxed +#define os_atomic_memory_order_acquire \ + _os_atomic_memory_order_relaxed +#define os_atomic_memory_order_release \ + _os_atomic_memory_order_relaxed +#define os_atomic_memory_order_acq_rel \ + _os_atomic_memory_order_relaxed +#define os_atomic_memory_order_seq_cst \ + _os_atomic_memory_order_relaxed +#define os_atomic_memory_order_ordered \ + _os_atomic_memory_order_relaxed + +#endif // OS_ATOMIC_UP + +#if __has_extension(c_generic_selections) +#define _os_atomic_basetypeof(p) \ + typeof(*_Generic((p), \ + char*: (char*)(p), \ + volatile char*: (char*)(p), \ + signed char*: (signed char*)(p), \ + volatile signed char*: (signed char*)(p), \ + unsigned char*: (unsigned char*)(p), \ + volatile unsigned char*: (unsigned char*)(p), \ + short*: (short*)(p), \ + volatile short*: (short*)(p), \ + unsigned short*: (unsigned short*)(p), \ + volatile unsigned short*: (unsigned short*)(p), \ + int*: (int*)(p), \ + volatile int*: (int*)(p), \ + unsigned int*: (unsigned int*)(p), \ + volatile unsigned int*: (unsigned int*)(p), \ + long*: (long*)(p), \ + volatile long*: (long*)(p), \ + unsigned long*: (unsigned long*)(p), \ + volatile unsigned long*: (unsigned long*)(p), \ + long long*: (long long*)(p), \ + volatile long long*: (long long*)(p), \ + unsigned long long*: (unsigned long long*)(p), \ + volatile unsigned long long*: (unsigned long long*)(p), \ + const void**: (const void**)(p), \ + const void*volatile*: (const void**)(p), \ + default: (void**)(p))) +#endif + +#if __has_extension(c_atomic) && __has_extension(c_generic_selections) +#pragma mark - +#pragma mark c11 + +#define _os_atomic_c11_atomic(p) \ + _Generic((p), \ + char*: (_Atomic(char)*)(p), \ + volatile char*: (volatile _Atomic(char)*)(p), \ + signed char*: (_Atomic(signed char)*)(p), \ + volatile signed char*: (volatile _Atomic(signed char)*)(p), \ + unsigned char*: (_Atomic(unsigned char)*)(p), \ + volatile unsigned char*: (volatile _Atomic(unsigned char)*)(p), \ + short*: (_Atomic(short)*)(p), \ + volatile short*: (volatile _Atomic(short)*)(p), \ + unsigned short*: (_Atomic(unsigned short)*)(p), \ + volatile unsigned short*: (volatile _Atomic(unsigned short)*)(p), \ + int*: (_Atomic(int)*)(p), \ + volatile int*: (volatile _Atomic(int)*)(p), \ + unsigned int*: (_Atomic(unsigned int)*)(p), \ + volatile unsigned int*: (volatile _Atomic(unsigned int)*)(p), \ + long*: (_Atomic(long)*)(p), \ + volatile long*: (volatile _Atomic(long)*)(p), \ + unsigned long*: (_Atomic(unsigned long)*)(p), \ + volatile unsigned long*: (volatile _Atomic(unsigned long)*)(p), \ + long long*: (_Atomic(long long)*)(p), \ + volatile long long*: (volatile _Atomic(long long)*)(p), \ + unsigned long long*: (_Atomic(unsigned long long)*)(p), \ + volatile unsigned long long*: \ + (volatile _Atomic(unsigned long long)*)(p), \ + const void**: (_Atomic(const void*)*)(p), \ + const void*volatile*: (volatile _Atomic(const void*)*)(p), \ + default: (volatile _Atomic(void*)*)(p)) + +#define _os_atomic_barrier(m) \ + ({ __c11_atomic_thread_fence(os_atomic_memory_order_##m); }) +#define os_atomic_load(p, m) \ + ({ _os_atomic_basetypeof(p) _r = \ + __c11_atomic_load(_os_atomic_c11_atomic(p), \ + os_atomic_memory_order_##m); (typeof(*(p)))_r; }) +#define os_atomic_store(p, v, m) \ + ({ _os_atomic_basetypeof(p) _v = (v); \ + __c11_atomic_store(_os_atomic_c11_atomic(p), _v, \ + os_atomic_memory_order_##m); }) +#define os_atomic_xchg(p, v, m) \ + ({ _os_atomic_basetypeof(p) _v = (v), _r = \ + __c11_atomic_exchange(_os_atomic_c11_atomic(p), _v, \ + os_atomic_memory_order_##m); (typeof(*(p)))_r; }) +#define os_atomic_cmpxchg(p, e, v, m) \ + ({ _os_atomic_basetypeof(p) _v = (v), _r = (e); \ + __c11_atomic_compare_exchange_strong(_os_atomic_c11_atomic(p), \ + &_r, _v, os_atomic_memory_order_##m, os_atomic_memory_order_relaxed); }) +#define os_atomic_cmpxchgv(p, e, v, g, m) \ + ({ _os_atomic_basetypeof(p) _v = (v), _r = (e); _Bool _b = \ + __c11_atomic_compare_exchange_strong(_os_atomic_c11_atomic(p), \ + &_r, _v, os_atomic_memory_order_##m, os_atomic_memory_order_relaxed); \ + *(g) = (typeof(*(p)))_r; _b; }) +#define os_atomic_cmpxchgvw(p, e, v, g, m) \ + ({ _os_atomic_basetypeof(p) _v = (v), _r = (e); _Bool _b = \ + __c11_atomic_compare_exchange_weak(_os_atomic_c11_atomic(p), \ + &_r, _v, os_atomic_memory_order_##m, os_atomic_memory_order_relaxed); \ + *(g) = (typeof(*(p)))_r; _b; }) +#define _os_atomic_c11_op(p, v, m, o, op) \ + ({ _os_atomic_basetypeof(p) _v = (v), _r = \ + __c11_atomic_fetch_##o(_os_atomic_c11_atomic(p), _v, \ + os_atomic_memory_order_##m); (typeof(*(p)))(_r op _v); }) +#define _os_atomic_c11_op_orig(p, v, m, o, op) \ + ({ _os_atomic_basetypeof(p) _v = (v), _r = \ + __c11_atomic_fetch_##o(_os_atomic_c11_atomic(p), _v, \ + os_atomic_memory_order_##m); (typeof(*(p)))_r; }) + +#define os_atomic_add(p, v, m) \ + _os_atomic_c11_op((p), (v), m, add, +) +#define os_atomic_add_orig(p, v, m) \ + _os_atomic_c11_op_orig((p), (v), m, add, +) +#define os_atomic_sub(p, v, m) \ + _os_atomic_c11_op((p), (v), m, sub, -) +#define os_atomic_sub_orig(p, v, m) \ + _os_atomic_c11_op_orig((p), (v), m, sub, -) +#define os_atomic_and(p, v, m) \ + _os_atomic_c11_op((p), (v), m, and, &) +#define os_atomic_and_orig(p, v, m) \ + _os_atomic_c11_op_orig((p), (v), m, and, &) +#define os_atomic_or(p, v, m) \ + _os_atomic_c11_op((p), (v), m, or, |) +#define os_atomic_or_orig(p, v, m) \ + _os_atomic_c11_op_orig((p), (v), m, or, |) +#define os_atomic_xor(p, v, m) \ + _os_atomic_c11_op((p), (v), m, xor, ^) +#define os_atomic_xor_orig(p, v, m) \ + _os_atomic_c11_op_orig((p), (v), m, xor, ^) + +#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) +#pragma mark - +#pragma mark gnu99 + +#define _os_atomic_full_barrier() \ + __sync_synchronize() +#define _os_atomic_barrier(m) \ + ({ switch(os_atomic_memory_order_##m) { \ + case _os_atomic_memory_order_relaxed: \ + break; \ + default: \ + _os_atomic_full_barrier(); break; \ + } }) +#define os_atomic_load(p, m) \ + ({ typeof(*(p)) _r = *(p); \ + switch(os_atomic_memory_order_##m) { \ + case _os_atomic_memory_order_relaxed: \ + case _os_atomic_memory_order_acquire: \ + case _os_atomic_memory_order_seq_cst: \ + _os_atomic_barrier(m); \ + break; \ + default: \ + _os_atomic_unimplemented(); break; \ + } _r; }) +#define os_atomic_store(p, v, m) \ + ({ switch(os_atomic_memory_order_##m) { \ + case _os_atomic_memory_order_relaxed: \ + case _os_atomic_memory_order_release: \ + case _os_atomic_memory_order_seq_cst: \ + _os_atomic_barrier(m); \ + *(p) = (v); break; \ + default: \ + _os_atomic_unimplemented(); break; \ + } switch(os_atomic_memory_order_##m) { \ + case _os_atomic_memory_order_seq_cst: \ + _os_atomic_barrier(m); break; \ + default: \ + break; \ + } }) +#if __has_builtin(__sync_swap) +#define os_atomic_xchg(p, v, m) \ + ((typeof(*(p)))__sync_swap((p), (v))) +#else +#define os_atomic_xchg(p, v, m) \ + ((typeof(*(p)))__sync_lock_test_and_set((p), (v))) +#endif +#define os_atomic_cmpxchg(p, e, v, m) \ + __sync_bool_compare_and_swap((p), (e), (v)) +#define os_atomic_cmpxchgv(p, e, v, g, m) \ + ({ typeof(*(g)) _e = (e), _r = \ + __sync_val_compare_and_swap((p), _e, (v)); \ + bool _b = (_e == _r); *(g) = _r; _b; }) +#define os_atomic_cmpxchgvw(p, e, v, g, m) \ + os_atomic_cmpxchgv((p), (e), (v), (g), m) + +#define os_atomic_add(p, v, m) \ + __sync_add_and_fetch((p), (v)) +#define os_atomic_add_orig(p, v, m) \ + __sync_fetch_and_add((p), (v)) +#define os_atomic_sub(p, v, m) \ + __sync_sub_and_fetch((p), (v)) +#define os_atomic_sub_orig(p, v, m) \ + __sync_fetch_and_sub((p), (v)) +#define os_atomic_and(p, v, m) \ + __sync_and_and_fetch((p), (v)) +#define os_atomic_and_orig(p, v, m) \ + __sync_fetch_and_and((p), (v)) +#define os_atomic_or(p, v, m) \ + __sync_or_and_fetch((p), (v)) +#define os_atomic_or_orig(p, v, m) \ + __sync_fetch_and_or((p), (v)) +#define os_atomic_xor(p, v, m) \ + __sync_xor_and_fetch((p), (v)) +#define os_atomic_xor_orig(p, v, m) \ + __sync_fetch_and_xor((p), (v)) + +#if defined(__x86_64__) || defined(__i386__) +// GCC emits nothing for __sync_synchronize() on x86_64 & i386 +#undef _os_atomic_full_barrier +#define _os_atomic_full_barrier() \ + ({ __asm__ __volatile__( \ + "mfence" \ + : : : "memory"); }) +#undef os_atomic_load +#define os_atomic_load(p, m) \ + ({ switch(os_atomic_memory_order_##m) { \ + case _os_atomic_memory_order_relaxed: \ + case _os_atomic_memory_order_acquire: \ + case _os_atomic_memory_order_seq_cst: \ + break; \ + default: \ + _os_atomic_unimplemented(); break; \ + } *(p); }) +// xchg is faster than store + mfence +#undef os_atomic_store +#define os_atomic_store(p, v, m) \ + ({ switch(os_atomic_memory_order_##m) { \ + case _os_atomic_memory_order_relaxed: \ + case _os_atomic_memory_order_release: \ + *(p) = (v); break; \ + case _os_atomic_memory_order_seq_cst: \ + (void)os_atomic_xchg((p), (v), m); break; \ + default:\ + _os_atomic_unimplemented(); break; \ + } }) +#endif + +#else +#error "Please upgrade to GCC 4.2 or newer." +#endif + +#pragma mark - +#pragma mark generic + +#define os_atomic_thread_fence(m) _os_atomic_barrier(m) +// see comment in os_once.c +#define os_atomic_maximally_synchronizing_barrier() \ + _os_atomic_barrier(seq_cst) + +#define os_atomic_load2o(p, f, m) \ + os_atomic_load(&(p)->f, m) +#define os_atomic_store2o(p, f, v, m) \ + os_atomic_store(&(p)->f, (v), m) +#define os_atomic_xchg2o(p, f, v, m) \ + os_atomic_xchg(&(p)->f, (v), m) +#define os_atomic_cmpxchg2o(p, f, e, v, m) \ + os_atomic_cmpxchg(&(p)->f, (e), (v), m) +#define os_atomic_cmpxchgv2o(p, f, e, v, g, m) \ + os_atomic_cmpxchgv(&(p)->f, (e), (v), (g), m) +#define os_atomic_cmpxchgvw2o(p, f, e, v, g, m) \ + os_atomic_cmpxchgvw(&(p)->f, (e), (v), (g), m) +#define os_atomic_add2o(p, f, v, m) \ + os_atomic_add(&(p)->f, (v), m) +#define os_atomic_add_orig2o(p, f, v, m) \ + os_atomic_add_orig(&(p)->f, (v), m) +#define os_atomic_sub2o(p, f, v, m) \ + os_atomic_sub(&(p)->f, (v), m) +#define os_atomic_sub_orig2o(p, f, v, m) \ + os_atomic_sub_orig(&(p)->f, (v), m) +#define os_atomic_and2o(p, f, v, m) \ + os_atomic_and(&(p)->f, (v), m) +#define os_atomic_and_orig2o(p, f, v, m) \ + os_atomic_and_orig(&(p)->f, (v), m) +#define os_atomic_or2o(p, f, v, m) \ + os_atomic_or(&(p)->f, (v), m) +#define os_atomic_or_orig2o(p, f, v, m) \ + os_atomic_or_orig(&(p)->f, (v), m) +#define os_atomic_xor2o(p, f, v, m) \ + os_atomic_xor(&(p)->f, (v), m) +#define os_atomic_xor_orig2o(p, f, v, m) \ + os_atomic_xor_orig(&(p)->f, (v), m) + +#define os_atomic_inc(p, m) \ + os_atomic_add((p), 1, m) +#define os_atomic_inc_orig(p, m) \ + os_atomic_add_orig((p), 1, m) +#define os_atomic_inc2o(p, f, m) \ + os_atomic_add2o(p, f, 1, m) +#define os_atomic_inc_orig2o(p, f, m) \ + os_atomic_add_orig2o(p, f, 1, m) +#define os_atomic_dec(p, m) \ + os_atomic_sub((p), 1, m) +#define os_atomic_dec_orig(p, m) \ + os_atomic_sub_orig((p), 1, m) +#define os_atomic_dec2o(p, f, m) \ + os_atomic_sub2o(p, f, 1, m) +#define os_atomic_dec_orig2o(p, f, m) \ + os_atomic_sub_orig2o(p, f, 1, m) + +#define os_atomic_rmw_loop(p, ov, nv, m, ...) ({ \ + bool _result = false; \ + typeof(p) _p = (p); \ + ov = os_atomic_load(_p, relaxed); \ + do { \ + __VA_ARGS__; \ + _result = os_atomic_cmpxchgvw(_p, ov, nv, &ov, m); \ + } while (os_unlikely(!_result)); \ + _result; \ + }) +#define os_atomic_rmw_loop2o(p, f, ov, nv, m, ...) \ + os_atomic_rmw_loop(&(p)->f, ov, nv, m, __VA_ARGS__) +#define os_atomic_rmw_loop_give_up_with_fence(m, expr) \ + ({ os_atomic_thread_fence(m); expr; __builtin_unreachable(); }) +#define os_atomic_rmw_loop_give_up(expr) \ + os_atomic_rmw_loop_give_up_with_fence(relaxed, expr) + +#define os_atomic_tsx_xacq_cmpxchgv(p, e, v, g) \ + os_atomic_cmpxchgv((p), (e), (v), (g), acquire) +#define os_atomic_tsx_xrel_store(p, v) \ + os_atomic_store(p, v, release) +#define os_atomic_tsx_xacq_cmpxchgv2o(p, f, e, v, g) \ + os_atomic_tsx_xacq_cmpxchgv(&(p)->f, (e), (v), (g)) +#define os_atomic_tsx_xrel_store2o(p, f, v) \ + os_atomic_tsx_xrel_store(&(p)->f, (v)) + +#if defined(__x86_64__) || defined(__i386__) +#pragma mark - +#pragma mark x86 + +#undef os_atomic_maximally_synchronizing_barrier +#ifdef __LP64__ +#define os_atomic_maximally_synchronizing_barrier() \ + ({ unsigned long _clbr; __asm__ __volatile__( \ + "cpuid" \ + : "=a" (_clbr) : "0" (0) : "rbx", "rcx", "rdx", "cc", "memory"); }) +#else +#ifdef __llvm__ +#define os_atomic_maximally_synchronizing_barrier() \ + ({ unsigned long _clbr; __asm__ __volatile__( \ + "cpuid" \ + : "=a" (_clbr) : "0" (0) : "ebx", "ecx", "edx", "cc", "memory"); }) +#else // gcc does not allow inline i386 asm to clobber ebx +#define os_atomic_maximally_synchronizing_barrier() \ + ({ unsigned long _clbr; __asm__ __volatile__( \ + "pushl %%ebx\n\t" \ + "cpuid\n\t" \ + "popl %%ebx" \ + : "=a" (_clbr) : "0" (0) : "ecx", "edx", "cc", "memory"); }) +#endif +#endif + + +#endif + + +#endif // __OS_EXPOSE_INTERNALS_INDIRECT__ + +#endif // __OS_ATOMIC__ diff --git a/src/external/libplatform/include/os/internal/crashlog.h b/src/external/libplatform/include/os/internal/crashlog.h new file mode 100644 index 000000000..41417ab1e --- /dev/null +++ b/src/external/libplatform/include/os/internal/crashlog.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_INTERNAL_CRASHLOG__ +#define __OS_INTERNAL_CRASHLOG__ + +#ifndef __OS_EXPOSE_INTERNALS_INDIRECT__ +/* + * XXX /!\ WARNING /!\ XXX + * + * This header file describes INTERNAL interfaces to libplatform used by other + * libsystem targets, which are subject to change in future releases of OS X + * and iOS. Any applications relying on these interfaces WILL break. + * + * If you are not a libsystem target, you should NOT EVER use these headers. + * Not even a little. + * + * XXX /!\ WARNING /!\ XXX + */ +#error "Please #include instead of this file directly." +#else + + +#define _os_set_crash_log_cause_and_message(ac, msg) ((void)(ac), (void)(msg)) +#define _os_set_crash_log_message(msg) ((void)(msg)) +#define _os_set_crash_log_message_dynamic(msg) ((void)(msg)) + + +#endif // __OS_EXPOSE_INTERNALS_INDIRECT__ + +#endif // __OS_INTERNAL_CRASHLOG__ diff --git a/src/external/libplatform/include/os/internal/internal_shared.h b/src/external/libplatform/include/os/internal/internal_shared.h new file mode 100644 index 000000000..732c42097 --- /dev/null +++ b/src/external/libplatform/include/os/internal/internal_shared.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_INTERNAL_SHARED__ +#define __OS_INTERNAL_SHARED__ + +#ifndef __OS_EXPOSE_INTERNALS__ +/* + * XXX /!\ WARNING /!\ XXX + * + * This header file describes INTERNAL interfaces to libplatform used by other + * libsystem targets, which are subject to change in future releases of Mac + * OS X and iOS. Any applications relying on these interfaces WILL break. + * + * If you are not a libsystem target, you should NOT EVER use these headers. + * Not even a little. + * + * XXX /!\ WARNING /!\ XXX + */ +#error "these internals are not for general use outside of libsystem" +#else + +#ifndef __OS_EXPOSE_INTERNALS_INDIRECT__ +#define __OS_EXPOSE_INTERNALS_INDIRECT__ +#endif + +#include +#include +#include +#if defined(__arm__) || defined(__arm64__) +#include +#endif + +#include +#include +#include +#include + +#endif // __OS_EXPOSE_INTERNALS__ + +#endif // __OS_INTERNAL_SHARED__ diff --git a/src/external/libplatform/include/os/lock.h b/src/external/libplatform/include/os/lock.h new file mode 100644 index 000000000..4af8449fd --- /dev/null +++ b/src/external/libplatform/include/os/lock.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_LOCK__ +#define __OS_LOCK__ + +#include +#include +#include +#include +#include +#include + +OS_ASSUME_NONNULL_BEGIN + +/*! @header + * Low-level lock API. + */ + +#define OS_LOCK_API_VERSION 20160309 + +__BEGIN_DECLS + +#define OS_UNFAIR_LOCK_AVAILABILITY \ + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) \ + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) + +/*! + * @typedef os_unfair_lock + * + * @abstract + * Low-level lock that allows waiters to block efficiently on contention. + * + * In general, higher level synchronization primitives such as those provided by + * the pthread or dispatch subsystems should be preferred. + * + * The values stored in the lock should be considered opaque and implementation + * defined, they contain thread ownership information that the system may use + * to attempt to resolve priority inversions. + * + * This lock must be unlocked from the same thread that locked it, attemps to + * unlock from a different thread will cause an assertion aborting the process. + * + * This lock must not be accessed from multiple processes or threads via shared + * or multiply-mapped memory, the lock implementation relies on the address of + * the lock value and owning process. + * + * Must be initialized with OS_UNFAIR_LOCK_INIT + * + * @discussion + * Replacement for the deprecated OSSpinLock. Does not spin on contention but + * waits in the kernel to be woken up by an unlock. + * + * As with OSSpinLock there is no attempt at fairness or lock ordering, e.g. an + * unlocker can potentially immediately reacquire the lock before a woken up + * waiter gets an opportunity to attempt to acquire the lock. This may be + * advantageous for performance reasons, but also makes starvation of waiters a + * possibility. + */ +OS_UNFAIR_LOCK_AVAILABILITY +typedef struct os_unfair_lock_s { + uint32_t _os_unfair_lock_opaque; +} os_unfair_lock, *os_unfair_lock_t; + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define OS_UNFAIR_LOCK_INIT ((os_unfair_lock){0}) +#elif defined(__cplusplus) && __cplusplus >= 201103L +#define OS_UNFAIR_LOCK_INIT (os_unfair_lock{}) +#elif defined(__cplusplus) +#define OS_UNFAIR_LOCK_INIT (os_unfair_lock()) +#else +#define OS_UNFAIR_LOCK_INIT {0} +#endif + +/*! + * @function os_unfair_lock_lock + * + * @abstract + * Locks an os_unfair_lock. + * + * @param lock + * Pointer to an os_unfair_lock. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_unfair_lock_lock(os_unfair_lock_t lock); + +/*! + * @function os_unfair_lock_trylock + * + * @abstract + * Locks an os_unfair_lock if it is not already locked. + * + * @discussion + * It is invalid to surround this function with a retry loop, if this function + * returns false, the program must be able to proceed without having acquired + * the lock, or it must call os_unfair_lock_lock() directly (a retry loop around + * os_unfair_lock_trylock() amounts to an inefficient implementation of + * os_unfair_lock_lock() that hides the lock waiter from the system and prevents + * resolution of priority inversions). + * + * @param lock + * Pointer to an os_unfair_lock. + * + * @result + * Returns true if the lock was succesfully locked and false if the lock was + * already locked. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_WARN_RESULT OS_NONNULL_ALL +bool os_unfair_lock_trylock(os_unfair_lock_t lock); + +/*! + * @function os_unfair_lock_unlock + * + * @abstract + * Unlocks an os_unfair_lock. + * + * @param lock + * Pointer to an os_unfair_lock. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_unfair_lock_unlock(os_unfair_lock_t lock); + +__END_DECLS + +OS_ASSUME_NONNULL_END + +#endif // __OS_LOCK__ diff --git a/src/external/libplatform/include/os/lock_private.h b/src/external/libplatform/include/os/lock_private.h new file mode 100644 index 000000000..f1daee2d6 --- /dev/null +++ b/src/external/libplatform/include/os/lock_private.h @@ -0,0 +1,650 @@ +/* + * Copyright (c) 2013-2016 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_LOCK_PRIVATE__ +#define __OS_LOCK_PRIVATE__ + +#include +#include +#include +#include +#include +#include +#include +#include + +OS_ASSUME_NONNULL_BEGIN + +/*! @header + * Low-level lock SPI + */ + +#define OS_LOCK_SPI_VERSION 20160406 + +/*! + * @typedef os_lock_t + * + * @abstract + * Pointer to one of the os_lock variants. + */ + +#define OS_LOCK_TYPE_STRUCT(type) const struct _os_lock_type_##type##_s +#define OS_LOCK_TYPE_REF(type) _os_lock_type_##type +#define OS_LOCK_TYPE_DECL(type) OS_LOCK_TYPE_STRUCT(type) OS_LOCK_TYPE_REF(type) + +#define OS_LOCK(type) os_lock_##type##_s +#define OS_LOCK_STRUCT(type) struct OS_LOCK(type) + +#if defined(__cplusplus) && __cplusplus >= 201103L + +#define OS_LOCK_DECL(type, size) \ + typedef OS_LOCK_STRUCT(type) : public OS_LOCK(base) { \ + private: \ + OS_LOCK_TYPE_STRUCT(type) * const osl_type OS_UNUSED; \ + uintptr_t _osl_##type##_opaque[size-1] OS_UNUSED; \ + public: \ + constexpr OS_LOCK(type)() : \ + osl_type(&OS_LOCK_TYPE_REF(type)), _osl_##type##_opaque() {} \ + } OS_LOCK(type) +#define OS_LOCK_INIT(type) {} + +typedef OS_LOCK_STRUCT(base) { + protected: + constexpr OS_LOCK(base)() {} +} *os_lock_t; + +#else + +#define OS_LOCK_DECL(type, size) \ + typedef OS_LOCK_STRUCT(type) { \ + OS_LOCK_TYPE_STRUCT(type) * const osl_type; \ + uintptr_t _osl_##type##_opaque[size-1]; \ + } OS_LOCK(type) + +#define OS_LOCK_INIT(type) { .osl_type = &OS_LOCK_TYPE_REF(type), } + +#ifndef OS_LOCK_T_MEMBER +#define OS_LOCK_T_MEMBER(type) OS_LOCK_STRUCT(type) *_osl_##type +#endif + +typedef OS_TRANSPARENT_UNION union { + OS_LOCK_T_MEMBER(base); + OS_LOCK_T_MEMBER(unfair); + OS_LOCK_T_MEMBER(nospin); + OS_LOCK_T_MEMBER(spin); + OS_LOCK_T_MEMBER(handoff); + OS_LOCK_T_MEMBER(eliding); + OS_LOCK_T_MEMBER(transactional); +} os_lock_t; + +#endif + +/*! + * @typedef os_lock_unfair_s + * + * @abstract + * os_lock variant equivalent to os_unfair_lock. Does not spin on contention but + * waits in the kernel to be woken up by an unlock. The lock value contains + * ownership information that the system may use to attempt to resolve priority + * inversions. + * + * @discussion + * Intended as a replacement for os_lock_spin_s or OSSpinLock. Like with + * OSSpinLock there is no attempt at fairness or lock ordering, e.g. an unlocker + * can potentially immediately reacquire the lock before a woken up waiter gets + * an opportunity to attempt to acquire the lock, so starvation is possibile. + * + * Must be initialized with OS_LOCK_UNFAIR_INIT + */ +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) +__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +OS_EXPORT OS_LOCK_TYPE_DECL(unfair); +OS_LOCK_DECL(unfair, 2); +#define OS_LOCK_UNFAIR_INIT OS_LOCK_INIT(unfair) + +/*! + * @typedef os_lock_nospin_s + * + * @abstract + * os_lock variant that does not spin on contention but waits in the kernel to + * be woken up by an unlock. No attempt to resolve priority inversions is made + * so os_unfair_lock or os_lock_unfair_s should generally be preferred. + * + * @discussion + * Intended as a replacement for os_lock_spin_s or OSSpinLock. Like with + * OSSpinLock there is no attempt at fairness or lock ordering, e.g. an unlocker + * can potentially immediately reacquire the lock before a woken up waiter gets + * an opportunity to attempt to acquire the lock, so starvation is possibile. + * + * Must be initialized with OS_LOCK_NOSPIN_INIT + */ +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) +__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +OS_EXPORT OS_LOCK_TYPE_DECL(nospin); +OS_LOCK_DECL(nospin, 2); +#define OS_LOCK_NOSPIN_INIT OS_LOCK_INIT(nospin) + +/*! + * @typedef os_lock_spin_s + * + * @abstract + * Deprecated os_lock variant that on contention starts by spinning trying to + * acquire the lock, then depressing the priority of the current thread and + * finally blocking the thread waiting for the lock to become available. + * Equivalent to OSSpinLock and equally not recommended, see discussion in + * libkern/OSAtomic.h headerdoc. + * + * @discussion + * Spinlocks are intended to be held only for very brief periods of time. The + * critical section must not make syscalls and should avoid touching areas of + * memory that may trigger a page fault, in particular if the critical section + * may be executing on threads of widely differing priorities or on a mix of + * IO-throttled and unthrottled threads. + * + * Must be initialized with OS_LOCK_SPIN_INIT + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_LOCK_TYPE_DECL(spin); +OS_LOCK_DECL(spin, 2); +#define OS_LOCK_SPIN_INIT OS_LOCK_INIT(spin) + +/*! + * @typedef os_lock_handoff_s + * + * @abstract + * os_lock variant that on contention hands off the current kernel thread to the + * lock-owning userspace thread (if it is not running), temporarily overriding + * its priority and IO throttle if necessary. + * + * @discussion + * Intended for use in limited circumstances where the critical section might + * be executing on threads of widely differing priorities or on a mix of + * IO-throttled and unthrottled threads where the ordinary os_lock_spin_s would + * be likely to encounter a priority inversion. + * + * IMPORTANT: This lock variant is NOT intended as a general replacement for all + * uses of os_lock_spin_s or OSSpinLock. + * + * Must be initialized with OS_LOCK_HANDOFF_INIT + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_LOCK_TYPE_DECL(handoff); +OS_LOCK_DECL(handoff, 2); +#define OS_LOCK_HANDOFF_INIT OS_LOCK_INIT(handoff) + + +#if !TARGET_OS_IPHONE +/*! + * @typedef os_lock_eliding_s + * + * @abstract + * os_lock variant that uses hardware lock elision support if available to allow + * multiple processors to concurrently execute a critical section as long as + * they don't perform conflicting operations on each other's data. In case of + * conflict, the lock reverts to exclusive operation and os_lock_spin_s behavior + * on contention (at potential extra cost for the aborted attempt at lock-elided + * concurrent execution). If hardware HLE support is not present, this lock + * variant behaves like os_lock_spin_s. + * + * @discussion + * IMPORTANT: Use of this lock variant MUST be extensively tested on hardware + * with HLE support to ensure the data access pattern and length of the critical + * section allows lock-elided execution to succeed frequently enough to offset + * the cost of any aborted concurrent execution. + * + * Must be initialized with OS_LOCK_ELIDING_INIT + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_NA) +OS_EXPORT OS_LOCK_TYPE_DECL(eliding); +OS_LOCK_DECL(eliding, 8) OS_ALIGNED(64); +#define OS_LOCK_ELIDING_INIT OS_LOCK_INIT(eliding) + +/*! + * @typedef os_lock_transactional_s + * + * @abstract + * os_lock variant that uses hardware restricted transactional memory support if + * available to allow multiple processors to concurrently execute the critical + * section as a transactional region. If transactional execution aborts, the + * lock reverts to exclusive operation and os_lock_spin_s behavior on contention + * (at potential extra cost for the aborted attempt at transactional concurrent + * execution). If hardware RTM support is not present, this lock variant behaves + * like os_lock_eliding_s. + * + * @discussion + * IMPORTANT: Use of this lock variant MUST be extensively tested on hardware + * with RTM support to ensure the data access pattern and length of the critical + * section allows transactional execution to succeed frequently enough to offset + * the cost of any aborted transactions. + * + * Must be initialized with OS_LOCK_TRANSACTIONAL_INIT + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_NA) +OS_EXPORT OS_LOCK_TYPE_DECL(transactional); +OS_LOCK_DECL(transactional, 8) OS_ALIGNED(64); +#define OS_LOCK_TRANSACTIONAL_INIT OS_LOCK_INIT(transactional) +#endif + +__BEGIN_DECLS + +/*! + * @function os_lock_lock + * + * @abstract + * Locks an os_lock variant. + * + * @param lock + * Pointer to one of the os_lock variants. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_lock_lock(os_lock_t lock); + +/*! + * @function os_lock_trylock + * + * @abstract + * Locks an os_lock variant if it is not already locked. + * + * @param lock + * Pointer to one of the os_lock variants. + * + * @result + * Returns true if the lock was succesfully locked and false if the lock was + * already locked. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +bool os_lock_trylock(os_lock_t lock); + +/*! + * @function os_lock_unlock + * + * @abstract + * Unlocks an os_lock variant. + * + * @param lock + * Pointer to one of the os_lock variants. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_lock_unlock(os_lock_t lock); + +/*! @group os_unfair_lock SPI + * + * @abstract + * Replacement for the deprecated OSSpinLock. Does not spin on contention but + * waits in the kernel to be woken up by an unlock. The opaque lock value + * contains thread ownership information that the system may use to attempt to + * resolve priority inversions. + * + * This lock must be unlocked from the same thread that locked it, attemps to + * unlock from a different thread will cause an assertion aborting the process. + * + * This lock must not be accessed from multiple processes or threads via shared + * or multiply-mapped memory, the lock implementation relies on the address of + * the lock value and owning process. + * + * @discussion + * As with OSSpinLock there is no attempt at fairness or lock ordering, e.g. an + * unlocker can potentially immediately reacquire the lock before a woken up + * waiter gets an opportunity to attempt to acquire the lock. This may be + * advantageous for performance reasons, but also makes starvation of waiters a + * possibility. + * + * Must be initialized with OS_UNFAIR_LOCK_INIT + */ + +/*! + * @typedef os_unfair_lock_options_t + * + * @const OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION + * This flag informs the runtime that the specified lock is used for data + * synchronization and that the lock owner is always able to make progress + * toward releasing the lock without the help of another thread in the same + * process. This hint will cause the workqueue subsystem to not create new + * threads to offset for threads waiting for the lock. + * + * When this flag is used, the code running under the critical section should + * be well known and under your control (Generally it should not call into + * framework code). + */ +OS_ENUM(os_unfair_lock_options, uint32_t, + OS_UNFAIR_LOCK_NONE + OS_UNFAIR_LOCK_AVAILABILITY = 0x00000000, + OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION + OS_UNFAIR_LOCK_AVAILABILITY = 0x00010000, +); + +/*! + * @function os_unfair_lock_lock_with_options + * + * @abstract + * Locks an os_unfair_lock. + * + * @param lock + * Pointer to an os_unfair_lock. + * + * @param options + * Options to alter the behavior of the lock. See os_unfair_lock_options_t. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_unfair_lock_lock_with_options(os_unfair_lock_t lock, + os_unfair_lock_options_t options); + +/*! + * @function os_unfair_lock_assert_owner + * + * @abstract + * Asserts that the calling thread is the current owner of the specified + * unfair lock. + * + * @discussion + * If the lock is currently owned by the calling thread, this function returns. + * + * If the lock is unlocked or owned by a different thread, this function + * asserts and terminates the process. + * + * @param lock + * Pointer to an os_unfair_lock. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_unfair_lock_assert_owner(os_unfair_lock_t lock); + +/*! + * @function os_unfair_lock_assert_not_owner + * + * @abstract + * Asserts that the calling thread is not the current owner of the specified + * unfair lock. + * + * @discussion + * If the lock is unlocked or owned by a different thread, this function + * returns. + * + * If the lock is currently owned by the current thread, this function asserts + * and terminates the process. + * + * @param lock + * Pointer to an os_unfair_lock. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_unfair_lock_assert_not_owner(os_unfair_lock_t lock); + +/*! @group os_unfair_lock variant for consumption by Libc + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_unfair_lock_lock_with_options_4Libc(os_unfair_lock_t lock, + os_unfair_lock_options_t options); + +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_unfair_lock_unlock_4Libc(os_unfair_lock_t lock); + +__END_DECLS + +OS_ASSUME_NONNULL_END + +/*! @group Inline os_unfair_lock interfaces + * + * Inline versions of the os_unfair_lock fastpath. + * + * Intended exclusively for special highly performance-sensitive cases where the + * function calls to the os_unfair_lock API entrypoints add measurable overhead. + * + * Do not use in frameworks to implement synchronization API primitives that are + * exposed to developers, that would lead to false primitives for that API from + * tools such as ThreadSanitizer. + * + * !!!!!!!!!!!!!!!!!!!!! WARNING WARNING WARNING WARNING !!!!!!!!!!!!!!!!!!!!! + * DO NOT USE IN CODE THAT IS NOT PART OF THE OPERATING SYSTEM OR THAT IS NOT + * REBUILT AS PART OF AN OS WORLDBUILD. YOU HAVE BEEN WARNED! + * !!!!!!!!!!!!!!!!!!!!! WARNING WARNING WARNING WARNING !!!!!!!!!!!!!!!!!!!!! + * + * Define OS_UNFAIR_LOCK_INLINE=1 to indicate that you have read the warning + * above and still wish to use these interfaces. + */ + +#if defined(OS_UNFAIR_LOCK_INLINE) && OS_UNFAIR_LOCK_INLINE + +#include + +#ifdef __cplusplus +extern "C++" { +#if !(__has_include() && __has_feature(cxx_atomic)) +#error Cannot use inline os_unfair_lock without and C++11 atomics +#endif +#include +typedef std::atomic _os_atomic_unfair_lock; +#define OSLOCK_STD(_a) std::_a +__BEGIN_DECLS +#else +#if !(__has_include() && __has_extension(c_atomic)) +#error Cannot use inline os_unfair_lock without and C11 atomics +#endif +#include +typedef _Atomic(os_unfair_lock) _os_atomic_unfair_lock; +#define OSLOCK_STD(_a) _a +#endif + +OS_ASSUME_NONNULL_BEGIN + +/*! + * @function os_unfair_lock_lock_inline + * + * @abstract + * Locks an os_unfair_lock. + * + * @param lock + * Pointer to an os_unfair_lock. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_INLINE OS_ALWAYS_INLINE OS_NONNULL_ALL +void +os_unfair_lock_lock_inline(os_unfair_lock_t lock) +{ + if (!_pthread_has_direct_tsd()) return os_unfair_lock_lock(lock); + uintptr_t mts = (uintptr_t)_pthread_getspecific_direct( + _PTHREAD_TSD_SLOT_MACH_THREAD_SELF); + os_unfair_lock unlocked = OS_UNFAIR_LOCK_INIT, locked = { mts }; + if (!OSLOCK_STD(atomic_compare_exchange_strong_explicit)( + (_os_atomic_unfair_lock*)lock, &unlocked, locked, + OSLOCK_STD(memory_order_acquire), + OSLOCK_STD(memory_order_relaxed))) { + return os_unfair_lock_lock(lock); + } +} + +/*! + * @function os_unfair_lock_lock_with_options_inline + * + * @abstract + * Locks an os_unfair_lock. + * + * @param lock + * Pointer to an os_unfair_lock. + * + * @param options + * Options to alter the behavior of the lock. See os_unfair_lock_options_t. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_INLINE OS_ALWAYS_INLINE OS_NONNULL_ALL +void +os_unfair_lock_lock_with_options_inline(os_unfair_lock_t lock, + os_unfair_lock_options_t options) +{ + if (!_pthread_has_direct_tsd()) { + return os_unfair_lock_lock_with_options(lock, options); + } + uintptr_t mts = (uintptr_t)_pthread_getspecific_direct( + _PTHREAD_TSD_SLOT_MACH_THREAD_SELF); + os_unfair_lock unlocked = OS_UNFAIR_LOCK_INIT, locked = { mts }; + if (!OSLOCK_STD(atomic_compare_exchange_strong_explicit)( + (_os_atomic_unfair_lock*)lock, &unlocked, locked, + OSLOCK_STD(memory_order_acquire), + OSLOCK_STD(memory_order_relaxed))) { + return os_unfair_lock_lock_with_options(lock, options); + } +} + +/*! + * @function os_unfair_lock_trylock_inline + * + * @abstract + * Locks an os_unfair_lock if it is not already locked. + * + * @discussion + * It is invalid to surround this function with a retry loop, if this function + * returns false, the program must be able to proceed without having acquired + * the lock, or it must call os_unfair_lock_lock_inline() instead. + * + * @param lock + * Pointer to an os_unfair_lock. + * + * @result + * Returns true if the lock was succesfully locked and false if the lock was + * already locked. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_INLINE OS_ALWAYS_INLINE OS_WARN_RESULT OS_NONNULL_ALL +bool +os_unfair_lock_trylock_inline(os_unfair_lock_t lock) +{ + if (!_pthread_has_direct_tsd()) return os_unfair_lock_trylock(lock); + uintptr_t mts = (uintptr_t)_pthread_getspecific_direct( + _PTHREAD_TSD_SLOT_MACH_THREAD_SELF); + os_unfair_lock unlocked = OS_UNFAIR_LOCK_INIT, locked = { mts }; + return OSLOCK_STD(atomic_compare_exchange_strong_explicit)( + (_os_atomic_unfair_lock*)lock, &unlocked, locked, + OSLOCK_STD(memory_order_acquire), OSLOCK_STD(memory_order_relaxed)); +} + +/*! + * @function os_unfair_lock_unlock_inline + * + * @abstract + * Unlocks an os_unfair_lock. + * + * @param lock + * Pointer to an os_unfair_lock. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_INLINE OS_ALWAYS_INLINE OS_NONNULL_ALL +void +os_unfair_lock_unlock_inline(os_unfair_lock_t lock) +{ + if (!_pthread_has_direct_tsd()) return os_unfair_lock_unlock(lock); + uintptr_t mts = (uintptr_t)_pthread_getspecific_direct( + _PTHREAD_TSD_SLOT_MACH_THREAD_SELF); + os_unfair_lock unlocked = OS_UNFAIR_LOCK_INIT, locked = { mts }; + if (!OSLOCK_STD(atomic_compare_exchange_strong_explicit)( + (_os_atomic_unfair_lock*)lock, &locked, unlocked, + OSLOCK_STD(memory_order_release), + OSLOCK_STD(memory_order_relaxed))) { + return os_unfair_lock_unlock(lock); + } +} + +/*! @group os_unfair_lock no-TSD interfaces + * + * Like the above, but don't require being on a thread with valid TSD, so they + * can be called from injected mach-threads. The normal routines use the TSD + * value for mach_thread_self(), these routines use MACH_PORT_DEAD for the + * locked value instead. As a result, they will be unable to resolve priority + * inversions. + * + * This should only be used by libpthread. + * + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_unfair_lock_lock_no_tsd_4libpthread(os_unfair_lock_t lock); + +OS_UNFAIR_LOCK_AVAILABILITY +OS_EXPORT OS_NOTHROW OS_NONNULL_ALL +void os_unfair_lock_unlock_no_tsd_4libpthread(os_unfair_lock_t lock); + +/*! + * @function os_unfair_lock_lock_inline_no_tsd_4libpthread + * + * @abstract + * Locks an os_unfair_lock, without requiring valid TSD. + * + * This should only be used by libpthread. + * + * @param lock + * Pointer to an os_unfair_lock. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_INLINE OS_ALWAYS_INLINE OS_NONNULL_ALL +void +os_unfair_lock_lock_inline_no_tsd_4libpthread(os_unfair_lock_t lock) +{ + uintptr_t mts = (uintptr_t)MACH_PORT_DEAD; + os_unfair_lock unlocked = OS_UNFAIR_LOCK_INIT, locked = { mts }; + if (!OSLOCK_STD(atomic_compare_exchange_strong_explicit)( + (_os_atomic_unfair_lock*)lock, &unlocked, locked, + OSLOCK_STD(memory_order_acquire), + OSLOCK_STD(memory_order_relaxed))) { + return os_unfair_lock_lock_no_tsd_4libpthread(lock); + } +} + +/*! + * @function os_unfair_lock_unlock_inline_no_tsd_4libpthread + * + * @abstract + * Unlocks an os_unfair_lock, without requiring valid TSD. + * + * This should only be used by libpthread. + * + * @param lock + * Pointer to an os_unfair_lock. + */ +OS_UNFAIR_LOCK_AVAILABILITY +OS_INLINE OS_ALWAYS_INLINE OS_NONNULL_ALL +void +os_unfair_lock_unlock_inline_no_tsd_4libpthread(os_unfair_lock_t lock) +{ + uintptr_t mts = (uintptr_t)MACH_PORT_DEAD; + os_unfair_lock unlocked = OS_UNFAIR_LOCK_INIT, locked = { mts }; + if (!OSLOCK_STD(atomic_compare_exchange_strong_explicit)( + (_os_atomic_unfair_lock*)lock, &locked, unlocked, + OSLOCK_STD(memory_order_release), + OSLOCK_STD(memory_order_relaxed))) { + return os_unfair_lock_unlock_no_tsd_4libpthread(lock); + } +} + +OS_ASSUME_NONNULL_END + +#undef OSLOCK_STD +#ifdef __cplusplus +__END_DECLS +} // extern "C++" +#endif + +#endif // OS_UNFAIR_LOCK_INLINE + +#endif // __OS_LOCK_PRIVATE__ diff --git a/src/external/libplatform/include/os/once_private.h b/src/external/libplatform/include/os/once_private.h new file mode 100644 index 000000000..c93cc14fb --- /dev/null +++ b/src/external/libplatform/include/os/once_private.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_ONCE_PRIVATE__ +#define __OS_ONCE_PRIVATE__ + +#include +#include + +OS_ASSUME_NONNULL_BEGIN + +__BEGIN_DECLS + +#define OS_ONCE_SPI_VERSION 20130313 + +OS_SWIFT_UNAVAILABLE("Swift has lazy init") +typedef long os_once_t; + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_NONNULL1 OS_NONNULL3 OS_NOTHROW +OS_SWIFT_UNAVAILABLE("Swift has lazy init") +void +_os_once(os_once_t *predicate, void *_Nullable context, os_function_t function); + +OS_NONNULL1 OS_NONNULL3 OS_NOTHROW +__header_always_inline void +os_once(os_once_t *predicate, void *_Nullable context, os_function_t function) +{ + if (OS_EXPECT(*predicate, ~0l) != ~0l) { + _os_once(predicate, context, function); + OS_COMPILER_CAN_ASSUME(*predicate == ~0l); + } else { + os_compiler_barrier(); + } +} + +/* This SPI is *strictly* for the use of pthread_once only. This is not + * safe in general use of os_once. + */ +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) +OS_EXPORT OS_NONNULL1 OS_NOTHROW +OS_SWIFT_UNAVAILABLE("Swift has lazy init") +void +__os_once_reset(os_once_t *val); + +__END_DECLS + +OS_ASSUME_NONNULL_END + +#endif // __OS_ONCE_PRIVATE__ diff --git a/src/external/libplatform/include/os/semaphore_private.h b/src/external/libplatform/include/os/semaphore_private.h new file mode 100644 index 000000000..d6bd7284d --- /dev/null +++ b/src/external/libplatform/include/os/semaphore_private.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_SEMAPHORE_PRIVATE__ +#define __OS_SEMAPHORE_PRIVATE__ + +#include +#include +#include +#include + +OS_ASSUME_NONNULL_BEGIN + +__BEGIN_DECLS + +#define OS_SEMAPHORE_SPI_VERSION 20130313 + +typedef uintptr_t os_semaphore_t; + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_WARN_RESULT OS_NOTHROW +os_semaphore_t _os_semaphore_create(void); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_NOTHROW +void _os_semaphore_dispose(os_semaphore_t); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_NOTHROW +void _os_semaphore_wait(os_semaphore_t); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +OS_EXPORT OS_NOTHROW +void _os_semaphore_signal(os_semaphore_t); + +OS_WARN_RESULT OS_NOTHROW +__header_always_inline os_semaphore_t +os_get_cached_semaphore(void) +{ + os_semaphore_t sema; + sema = (os_semaphore_t)_os_tsd_get_direct(__TSD_SEMAPHORE_CACHE); + if (os_unlikely(!sema)) { + return _os_semaphore_create(); + } + _os_tsd_set_direct(__TSD_SEMAPHORE_CACHE, 0); + return sema; +} + +OS_NOTHROW +__header_always_inline void +os_put_cached_semaphore(os_semaphore_t sema) +{ + os_semaphore_t old_sema; + old_sema = (os_semaphore_t)_os_tsd_get_direct(__TSD_SEMAPHORE_CACHE); + _os_tsd_set_direct(__TSD_SEMAPHORE_CACHE, (void*)sema); + if (os_unlikely(old_sema)) { + return _os_semaphore_dispose(old_sema); + } +} + +OS_NOTHROW +__header_always_inline void +os_semaphore_wait(os_semaphore_t sema) +{ + return _os_semaphore_wait(sema); +} + +OS_NOTHROW +__header_always_inline void +os_semaphore_signal(os_semaphore_t sema) +{ + return _os_semaphore_signal(sema); +} + +__END_DECLS + +OS_ASSUME_NONNULL_END + +#endif // __OS_SEMAPHORE_PRIVATE__ diff --git a/src/external/libplatform/include/platform/compat.h b/src/external/libplatform/include/platform/compat.h new file mode 100644 index 000000000..a9f59fd14 --- /dev/null +++ b/src/external/libplatform/include/platform/compat.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _PLATFORM_COMPAT_H_ +#define _PLATFORM_COMPAT_H_ + +#include + +__BEGIN_DECLS + +/* Helpers for other common non-primitive routines */ + +__header_always_inline +size_t +_platform_strlen(const char *s) { + const char *t = _platform_memchr(s, '\0', SIZE_MAX); + return (uintptr_t)t - (uintptr_t)s; +} + +__header_always_inline +size_t +_platform_strlcpy(char * restrict dst, const char * restrict src, size_t maxlen) { + const size_t srclen = _platform_strlen(src); + if (srclen < maxlen) { + _platform_memmove(dst, src, srclen+1); + } else if (maxlen != 0) { + _platform_memmove(dst, src, maxlen-1); + dst[maxlen-1] = '\0'; + } + return srclen; +} + +__END_DECLS + +/* Compat macros for primitives */ +#define bzero _platform_bzero +#define memchr _platform_memchr +#define memcmp _platform_memcmp +#define memmove _platform_memmove +#define memccpy _platform_memccpy +#define memset _platform_memset +#define memset_pattern4 _platform_memset_pattern4 +#define memset_pattern8 _platform_memset_pattern8 +#define memset_pattern16 _platform_memset_pattern16 +#define strchr _platform_strchr +#define strcmp _platform_strcmp +#define strncmp _platform_strncmp + +/* Compat macros for non-primitive helpers */ +#define strlcpy _platform_strlcpy +#define strlen _platform_strlen + +#endif /* _PLATFORM_COMPAT_H_ */ diff --git a/src/external/libplatform/include/platform/introspection_private.h b/src/external/libplatform/include/platform/introspection_private.h new file mode 100644 index 000000000..f09ee5802 --- /dev/null +++ b/src/external/libplatform/include/platform/introspection_private.h @@ -0,0 +1,447 @@ +#ifndef __PLATFORM_INTROSPECTION_H__ +#define __PLATFORM_INTROSPECTION_H__ + +#include +#include +#include + +#include + +#include + +typedef struct platform_task_s *platform_task_t; +typedef struct platform_thread_s *platform_thread_t; + +/*! + * @typedef platform_thread_id_t + * + * @discussion + * The type of the 64-bit system-wide unique thread ID. + */ +typedef uint64_t platform_thread_id_t; + +/*! @functiongroup Tasks */ + +/*! + * @function platform_task_attach + * + * @discussion + * Attach to a process (specified by its mach task port) for debugging. This + * function creates a new task handle which must be disposed by a call to + * platform_task_detach(). + * + * @param task + * On output, a newly created task handle. + * + * @param target + * The mach task port of the target process. + * + * @return + * KERN_SUCCESS if the process was successfully attached, otherwise a mach + * error code. + */ +kern_return_t +platform_task_attach(platform_task_t *task, task_t target); + +/*! + * @function platform_task_detach + * + * @discussion + * Detaches from the target task and deallocates all memory associated with + * the task handle. + * + * @param task + * The task handle to detach. + * + * @return + * KERN_SUCCESS if the process was successfully detached, otherwise a mach + * error code. + */ +kern_return_t +platform_task_detach(platform_task_t task); + +/*! + * @function platform_task_is_64_bit + * + * @discussion + * Returns true if the target task is LP64. + * + * @param task + * A handle to the target task. + * + * @return + * true if the target task is LP64, otherwise false. + */ +bool +platform_task_is_64_bit(platform_task_t task); + +/*! + * @function platform_task_suspend_threads + * + * @discussion + * Suspends all the threads in the target task. This differs from task_suspend + * in that the task itself is not suspended, only the individual threads. While + * this suspension is in effect, any newly created threads will be created in + * a suspended state. The debuger may resume an individual thread for execution + * using platform_thread_resume() or evaluate an expression in the context of + * the task or a specific thread using platform_task_perform() and + * platform_thread_perform(), respectively. All threads in the task may be + * resumed with platform_task_resume_threads(). + * + * @param task + * A handle to the target task. + * + * @return + * KERN_SUCCESS if the threads were successfully suspended, otherwise a mach + * error code. + */ +kern_return_t +platform_task_suspend_threads(platform_task_t task); + +/*! + * @function platform_task_resume_threads + * + * @discussion + * Resumes the threads in the target task. See platform_task_suspend_threads(). + * + * @param task + * A handle to the target task. + */ +kern_return_t +platform_task_resume_threads(platform_task_t task); + +/*! + * @function platform_task_perform + * + * @discussion + * Performs the specified function on a newly created thread in the target task. + * This newly created thread will execute even if the threads in the task are + * suspended as the result of a call to platform_task_suspend_threads(). + * + * The function and context addresses are in the virtual address space of the + * target task. It is the responsiblity of the debugger to have previously + * mapped executable text and data at these addresses in the target task. + * + * @param task + * A handle to the target task. + * + * @param func_addr + * The address (in the virtual address space of the target task) of the + * function to perform. The function should be of type (void (*)(void *)) + * and will be passed the value of the data_addr parameter. + * + * @param data_addr + * The address (in the virtual address space of the target task) of the + * data to pass as a parameter to the function to perform. + * + * @return + * KERN_SUCCESS if the function was successfully performed, otherwise a mach + * error code. + */ +kern_return_t +platform_task_perform(platform_task_t task, + mach_vm_address_t func_addr, + mach_vm_address_t data_addr); + +/*! + * @function platform_task_update_threads + * + * @discussion + * Updates an internal representation of all threads in the target task. The + * list of threads may then be iterated using platform_task_copy_next_thread(). + * + * Calling this function resets any iteration currently in progress and a + * subsequent call to platform_task_copy_next_thread() will return the first + * thread in the list. + * + * @param task + * A handle to the target task. + * + * @return + * KERN_SUCCESS if the threads were successfully updated, otherwise a mach + * error code. + */ +kern_return_t +platform_task_update_threads(platform_task_t task); + +/*! + * @function platform_task_copy_next_thread + * + * @discussion + * Iterates the list of threads in the task. Returns a copied thread handle + * which must subsequently be released using platform_thread_release(). + * + * The platform_task_update_threads() function must be called before this + * function will return any thread handles. A NULL pointer is returned to + * signify the end of the list + * + * @param task + * A handle to the target task. + * + * @return + * A thread handle which must be released using platform_thread_release(), + * or NULL, signifying the end of the list. + */ +platform_thread_t +platform_task_copy_next_thread(platform_task_t task); + +/*! @functiongroup Threads */ + +/*! + * @function platform_thread_get_unique_id + * + * @discussion + * Returns the 64-bit system-wide unique ID of the target thread. + * + * @param thread + * A handle to the target thread. + * + * @return + * The unique ID of the thread. + */ +platform_thread_id_t +platform_thread_get_unique_id(platform_thread_t thread); + +/*! + * @function platform_thread_release + * + * @discussion + * Releases a thread handle obtained by platform_task_copy_next_thread(). + * + * @param thread + * The thread handle to release. + */ +void +platform_thread_release(platform_thread_t thread); + +/*! + * @function platform_thread_abort_safely + * + * @discussion + * Similar to thread_abort_safely(). + * + * @param thread + * A handle to the thread to signal. + * + * @return + * KERN_SUCCESS if the thread was successfully signaled, otherwise a mach + * error code. + */ +kern_return_t +platform_thread_abort_safely(platform_thread_t thread); + +/*! + * @function platform_thread_suspend + * + * @discussion + * Suspends execution of a thread similar to thread_suspend(). See also + * platform_task_suspend_threads(). + * + * @param thread + * A handle to the thread to suspend. + * + * @return + * KERN_SUCCESS if the thread was successfully suspended, otherwise a mach + * error code. + */ +kern_return_t +platform_thread_suspend(platform_thread_t thread); + +/*! + * @function platform_thread_resume + * + * @discussion + * Suspends execution of a thread similar to thread_suspend(). See also + * platform_task_suspend_threads() and platform_task_resume_threads(). + * + * @param thread + * A handle to the thread to resume. + * + * @return + * KERN_SUCCESS if the thread was successfully resumed, otherwise a mach + * error code. +*/ +kern_return_t +platform_thread_resume(platform_thread_t thread); + +/*! + * @function platform_thread_info + * + * @discussion + * Similar to thread_info. Supported flavor structures: + * - THREAD_BASIC_INFO: struct thread_basic_info + * - THREAD_IDENTIFIER_INFO: struct thread_identifier_info + * + * @param thread + * A handle to the target thread. + * + * @param flavor + * The desired thread info structure. + * + * @param info + * A pointer to storage where the thread info structure should be written. + * + * @param size + * On input, the size in bytes of the storage where the thread info structure + * is to be written. On output, the size of the thread info structure in bytes. + * + * @return + * KERN_SUCCESS if the function was successfully performed, otherwise a mach + * error code. + */ +kern_return_t +platform_thread_info(platform_thread_t thread, + thread_flavor_t flavor, + void *info, + size_t *size); + +/*! + * @function platform_thread_get_state + * + * @discussion + * Similar to thread_get_state. Supported flavor structures: + * - x86_THREAD_STATE32: struct ... + * - x86_FLOAT_STATE32: struct ... + * - x86_EXCEPTION_STATE32: struct ... + * - x86_DEBUG_STATE32: struct ... + * - x86_AVX_STATE32: struct ... + * - x86_THREAD_STATE64: struct ... + * - x86_FLOAT_STATE64: struct ... + * - x86_EXCEPTION_STATE64: struct ... + * - x86_DEBUG_STATE64: struct ... + * - x86_AVX_STATE64: struct ... + * - ARM_THREAD_STATE32: struct ... + * - ARM_FLOAT_STATE32: struct ... + * - ARM_EXCEPTION_STATE32: struct ... + * - ARM_DEBUG_STATE32: struct ... + * - ARM_THREAD_STATE64: struct ... + * - ARM_FLOAT_STATE64: struct ... + * - ARM_EXCEPTION_STATE64: struct ... + * - ARM_DEBUG_STATE64: struct ... + * - ... + * + * @param thread + * A handle to the target thread. + * + * @param flavor + * The desired thread state structure. + * + * @param state + * A pointer to storage where the thread state structure should be written. + * + * @param size + * On input, the size in bytes of the storage where the thread state structure + * is to be written. On output, the size of the thread state structure in bytes. + * + * @return + * KERN_SUCCESS if the function was successfully performed, otherwise a mach + * error code. + */ +kern_return_t +platform_thread_get_state(platform_thread_t thread, + thread_state_flavor_t flavor, + void *state, + size_t *size); + +/*! + * @function platform_thread_set_state + * + * @discussion + * Similar to thread_set_state. Supported flavor structures: + * - x86_THREAD_STATE32: struct ... + * - x86_FLOAT_STATE32: struct ... + * - x86_EXCEPTION_STATE32: struct ... + * - x86_DEBUG_STATE32: struct ... + * - x86_AVX_STATE32: struct ... + * - x86_THREAD_STATE64: struct ... + * - x86_FLOAT_STATE64: struct ... + * - x86_EXCEPTION_STATE64: struct ... + * - x86_DEBUG_STATE64: struct ... + * - x86_AVX_STATE64: struct ... + * - ARM_THREAD_STATE32: struct ... + * - ARM_FLOAT_STATE32: struct ... + * - ARM_EXCEPTION_STATE32: struct ... + * - ARM_DEBUG_STATE32: struct ... + * - ARM_THREAD_STATE64: struct ... + * - ARM_FLOAT_STATE64: struct ... + * - ARM_EXCEPTION_STATE64: struct ... + * - ARM_DEBUG_STATE64: struct ... + * - ... + * + * @param thread + * A handle to the target thread. + * + * @param flavor + * The desired thread state structure. + * + * @param state + * A pointer to storage where the thread state structure should be written. + * + * @param size + * The size of the thread state structure in bytes. + * + * @return + * KERN_SUCCESS if the function was successfully performed, otherwise a mach + * error code. + */ +kern_return_t +platform_thread_set_state(platform_thread_t thread, + thread_state_flavor_t flavor, + const void *state, + size_t size); + +/*! + * @function platform_thread_perform + * + * @discussion + * Performs the specified function within the context of the specified thread + * in the target task. The function will execute in the style of an + * asynchronous signal handler even if the thread is suspended as the result + * of a call to platform_task_suspend_threads() or platform_thread_suspend(). + * The original state of the thread will be restored when the function returns. + * + * The function and context addresses are in the virtual address space of the + * target task. It is the responsiblity of the debugger to have previously + * mapped executable text and data at these addresses in the target task. + * + * See also platform_task_perform(). + * + * @param thread + * A handle to the target thread. + * + * @param func_addr + * The address (in the virtual address space of the target task) of the + * function to perform. The function should be of type (void (*)(void *)) + * and will be passed the value of the data_addr parameter. + * + * @param data_addr + * The address (in the virtual address space of the target task) of the + * data to pass as a parameter to the function to perform. + * + * @return + * KERN_SUCCESS if the function was successfully performed, otherwise a mach + * error code. + */ +kern_return_t +platform_thread_perform(platform_thread_t thread, + mach_vm_address_t func_addr, + mach_vm_address_t data_addr); + +/*! + * @function platform_thread_get_pthread + * + * @discussion + * Returns a pointer to mapped memory which represents the pthread_t of the + * target process. Any embedded pointers will need to be mapped into the current + * process space on a case-by-case basis. + * + * @param thread + * A handle to the target thread. + * + * @return + * A valid pointer. + */ +const void * +platform_thread_get_pthread(platform_thread_t thread); + +#endif // __PLATFORM_INTROSPECTION_H__ diff --git a/src/external/libplatform/include/platform/string.h b/src/external/libplatform/include/platform/string.h new file mode 100644 index 000000000..c4d1c3f8f --- /dev/null +++ b/src/external/libplatform/include/platform/string.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _PLATFORM_STRING_H_ +#define _PLATFORM_STRING_H_ + +#include +#include +#include + +#include +#include + +#define _PLATFORM_OPTIMIZED_BZERO 0 +#define _PLATFORM_OPTIMIZED_MEMCCPY 0 +#define _PLATFORM_OPTIMIZED_MEMCHR 0 +#define _PLATFORM_OPTIMIZED_MEMCMP 0 +#define _PLATFORM_OPTIMIZED_MEMMOVE 0 +#define _PLATFORM_OPTIMIZED_MEMSET 0 +#define _PLATFORM_OPTIMIZED_MEMSET_PATTERN4 0 +#define _PLATFORM_OPTIMIZED_MEMSET_PATTERN8 0 +#define _PLATFORM_OPTIMIZED_MEMSET_PATTERN16 0 +#define _PLATFORM_OPTIMIZED_STRCHR 0 +#define _PLATFORM_OPTIMIZED_STRCMP 0 +#define _PLATFORM_OPTIMIZED_STRNCMP 0 + +/* Primitives used to implement C memory and string routines */ + +__BEGIN_DECLS + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void +_platform_bzero(void *s, size_t n); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void * +_platform_memchr(const void *s, int c, size_t n); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +int +_platform_memcmp(const void *s1, const void *s2, size_t n); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void * +_platform_memmove(void *dst, const void *src, size_t n); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void * +_platform_memccpy(void *restrict dst, const void *restrict src, int c, size_t n); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void * +_platform_memset(void *b, int c, size_t len); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void +_platform_memset_pattern4(void *b, const void *pattern4, size_t len); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void +_platform_memset_pattern8(void *b, const void *pattern8, size_t len); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +void +_platform_memset_pattern16(void *b, const void *pattern16, size_t len); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +char * +_platform_strchr(const char *s, int c); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +int +_platform_strcmp(const char *s1, const char *s2); + +__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) +int +_platform_strncmp(const char *s1, const char *s2, size_t n); + +__END_DECLS + +#endif /* _PLATFORM_STRING_H_ */ diff --git a/src/libc/include/setjmp.h b/src/external/libplatform/include/setjmp.h similarity index 82% rename from src/libc/include/setjmp.h rename to src/external/libplatform/include/setjmp.h index 8e6b4a864..f54ddefa5 100644 --- a/src/libc/include/setjmp.h +++ b/src/external/libplatform/include/setjmp.h @@ -24,6 +24,7 @@ #define _BSD_SETJMP_H #include +#include #if defined(__x86_64__) /* @@ -49,7 +50,7 @@ typedef int sigjmp_buf[_JBLEN + 1]; typedef int jmp_buf[_JBLEN]; typedef int sigjmp_buf[_JBLEN + 1]; -#elif defined(__arm__) +#elif defined(__arm__) && !defined(__ARM_ARCH_7K__) #include @@ -65,6 +66,19 @@ typedef int sigjmp_buf[_JBLEN + 1]; typedef int jmp_buf[_JBLEN]; typedef int sigjmp_buf[_JBLEN + 1]; +#elif defined(__arm64__) || defined(__ARM_ARCH_7K__) +/* + * _JBLEN is the number of ints required to save the following: + * r21-r29, sp, fp, lr == 12 registers, 8 bytes each. d8-d15 + * are another 8 registers, each 8 bytes long. (aapcs64 specifies + * that only 64-bit versions of FP registers need to be saved). + * Finally, two 8-byte fields for signal handling purposes. + */ +#define _JBLEN ((14 + 8 + 2) * 2) + +typedef int jmp_buf[_JBLEN]; +typedef int sigjmp_buf[_JBLEN + 1]; + #else # error Undefined platform for setjmp #endif diff --git a/src/libc/include/ucontext.h b/src/external/libplatform/include/ucontext.h similarity index 77% rename from src/libc/include/ucontext.h rename to src/external/libplatform/include/ucontext.h index b99a6c770..db570b21d 100644 --- a/src/libc/include/ucontext.h +++ b/src/external/libplatform/include/ucontext.h @@ -29,32 +29,18 @@ #include -//Begin-Libc -#ifdef __LIBC__ -#include -__BEGIN_DECLS -int getcontext(ucontext_t *); -void makecontext(ucontext_t *, void (*)(), int, ...); -int setcontext(const ucontext_t *); -int swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict); -__END_DECLS -#else /* !__LIBC__ */ -//End-Libc #ifdef _XOPEN_SOURCE #include #include __BEGIN_DECLS -int getcontext(ucontext_t *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0); -void makecontext(ucontext_t *, void (*)(), int, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0); -int setcontext(const ucontext_t *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0); -int swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0); +int getcontext(ucontext_t *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +void makecontext(ucontext_t *, void (*)(), int, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int setcontext(const ucontext_t *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; __END_DECLS #else /* !_XOPEN_SOURCE */ #error The deprecated ucontext routines require _XOPEN_SOURCE to be defined #endif /* _XOPEN_SOURCE */ -//Begin-Libc -#endif /* __LIBC__ */ -//End-Libc #endif /* _UCONTEXT_H_ */ diff --git a/src/external/libplatform/internal/os/internal.h b/src/external/libplatform/internal/os/internal.h new file mode 100644 index 000000000..4d7a083ed --- /dev/null +++ b/src/external/libplatform/internal/os/internal.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_INTERNAL_H__ +#define __OS_INTERNAL_H__ + +#define __OS_ALLOC_INDIRECT__ + +#include +#include + +#include "os/base_private.h" +#include "os/semaphore_private.h" + +#include +#include +#include +#include +#if defined(__arm__) +#include +#endif +#include + +#define likely(x) os_likely(x) +#define unlikely(x) os_unlikely(x) + +#define __OS_CRASH__(rc, msg) ({ \ + _os_set_crash_log_cause_and_message(rc, msg); \ + os_prevent_tail_call_optimization(); \ + __builtin_trap(); \ + }) + +#define __LIBPLATFORM_CLIENT_CRASH__(rc, msg) \ + __OS_CRASH__(rc, "BUG IN CLIENT OF LIBPLATFORM: " msg) +#define __LIBPLATFORM_INTERNAL_CRASH__(rc, msg) \ + __OS_CRASH__(rc, "BUG IN LIBPLATFORM: " msg) + + +#define __OS_EXPOSE_INTERNALS__ 1 +#include "os/internal/internal_shared.h" +#include "yield.h" + +#if !VARIANT_NO_RESOLVERS +#if defined(_ARM_ARCH_7) && !defined(__ARM_ARCH_7S__) +#if OS_ATOMIC_UP +#define OS_VARIANT_SELECTOR up +#else +#define OS_VARIANT_SELECTOR mp +#endif +#endif +#if !defined(OS_VARIANT_SELECTOR) && defined(VARIANT_NO_RESOLVERS) +// forced up variant for no-barrier OSAtomics +#define OS_ATOMIC_NO_BARRIER_ONLY 1 +#define OS_VARIANT_SELECTOR up +#endif +#if (defined(_ARM_ARCH_7) || defined(__arm64__)) && \ + (!defined(OS_ATOMIC_WFE) && !OS_ATOMIC_UP) +#define OS_ATOMIC_WFE 0 +#endif +#ifdef OS_ATOMIC_WFE +#if OS_ATOMIC_WFE +#define OS_LOCK_VARIANT_SELECTOR wfe +#else +#define OS_LOCK_VARIANT_SELECTOR mp +#endif +#endif +#endif // !VARIANT_NO_RESOLVERS + +#define OS_VARIANT(f, v) OS_CONCAT(f, OS_CONCAT($VARIANT$, v)) + +#ifdef OS_VARIANT_SELECTOR +#define _OS_ATOMIC_ALIAS_PRIVATE_EXTERN(n) \ + ".private_extern _" OS_STRINGIFY(n) "\n\t" +#define OS_ATOMIC_EXPORT +#else +#define _OS_ATOMIC_ALIAS_PRIVATE_EXTERN(n) +#define OS_ATOMIC_EXPORT OS_EXPORT +#endif +#define _OS_ATOMIC_ALIAS_GLOBL(n) \ + ".globl _" OS_STRINGIFY(n) "\n\t" +#ifdef __thumb__ +#define _OS_ATOMIC_ALIAS_THUMB(n) \ + ".thumb_func _" OS_STRINGIFY(n) "\n\t" +#else +#define _OS_ATOMIC_ALIAS_THUMB(n) +#endif +#define _OS_ATOMIC_ALIAS_SET(n, o) \ + ".set _" OS_STRINGIFY(n) ", _" OS_STRINGIFY(o) + +#define OS_ATOMIC_ALIAS(n, o) __asm__( \ + _OS_ATOMIC_ALIAS_PRIVATE_EXTERN(n) \ + _OS_ATOMIC_ALIAS_GLOBL(n) \ + _OS_ATOMIC_ALIAS_THUMB(n) \ + _OS_ATOMIC_ALIAS_SET(n, o)) + +#define OS_ATOMIC_EXPORT_ALIAS(n, o) __asm__( \ + _OS_ATOMIC_ALIAS_GLOBL(n) \ + _OS_ATOMIC_ALIAS_THUMB(n) \ + _OS_ATOMIC_ALIAS_SET(n, o)) + +#define _OS_VARIANT_RESOLVER(s, v, ...) \ + __attribute__((visibility(OS_STRINGIFY(v)))) extern void* s(void); \ + void* s(void) { \ + __asm__(".symbol_resolver _" OS_STRINGIFY(s)); \ + __VA_ARGS__ \ + } + +#define _OS_VARIANT_UPMP_RESOLVER(s, v) \ + _OS_VARIANT_RESOLVER(s, v, \ + uint32_t *_c = (void*)(uintptr_t)_COMM_PAGE_CPU_CAPABILITIES; \ + if (*_c & kUP) { \ + extern void OS_VARIANT(s, up)(void); \ + return &OS_VARIANT(s, up); \ + } else { \ + extern void OS_VARIANT(s, mp)(void); \ + return &OS_VARIANT(s, mp); \ + }) + +#define OS_VARIANT_UPMP_RESOLVER(s) \ + _OS_VARIANT_UPMP_RESOLVER(s, default) + +#define OS_VARIANT_UPMP_RESOLVER_INTERNAL(s) \ + _OS_VARIANT_UPMP_RESOLVER(s, hidden) + +#endif // __OS_INTERNAL_H__ diff --git a/src/external/libplatform/internal/os/internal_asm.h b/src/external/libplatform/internal/os/internal_asm.h new file mode 100644 index 000000000..4504cf13a --- /dev/null +++ b/src/external/libplatform/internal/os/internal_asm.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef __INTERNAL_ASM_H__ +#define __INTERNAL_ASM_H__ + +#include + +#define OS_STRINGIFY1(s) #s +#define OS_STRINGIFY(s) OS_STRINGIFY1(s) +#define OS_CONCAT1(x, y) x##y +#define OS_CONCAT(x, y) OS_CONCAT1(x,y) + +#ifdef __ASSEMBLER__ +#define OS_VARIANT(f, v) OS_CONCAT(_,OS_CONCAT(f,OS_CONCAT($VARIANT$,v))) +#else +#define OS_VARIANT(f, v) OS_CONCAT(f,OS_CONCAT($VARIANT$,v)) +#endif + +#if defined(__ASSEMBLER__) + +#if defined(__i386__) || defined(__x86_64__) + +#define OS_VARIANT_FUNCTION_START(name, variant, alignment) \ + .text ; \ + .align alignment, 0x90 ; \ + .private_extern OS_VARIANT(name,variant) ; \ + OS_VARIANT(name,variant) ## : + +// GENERIC indicates that this function will be chosen as the generic +// implementation (at compile time) when building targets which do not +// support dyld variant resolves. +#if defined(VARIANT_NO_RESOLVERS) || defined(VARIANT_DYLD) +#define OS_VARIANT_FUNCTION_START_GENERIC(name, variant, alignment) \ + OS_VARIANT_FUNCTION_START(name,variant,alignment) \ + .globl _ ## name ; \ + _ ## name ## : +#else +#define OS_VARIANT_FUNCTION_START_GENERIC OS_VARIANT_FUNCTION_START +#endif + +#define OS_ATOMIC_FUNCTION_START(name, alignment) \ + .text ; \ + .align alignment, 0x90 ; \ + .globl _ ## name ; \ + _ ## name ## : + +#endif // defined(__i386__) || defined(__x86_64__) + +#endif // defined(__ASSEMBLER__) + +#endif // __INTERNAL_ASM_H__ diff --git a/src/external/libplatform/internal/os/yield.h b/src/external/libplatform/internal/os/yield.h new file mode 100644 index 000000000..a094b2d86 --- /dev/null +++ b/src/external/libplatform/internal/os/yield.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +/* + * IMPORTANT: This header file describes INTERNAL interfaces to libplatform + * which are subject to change in future releases of Mac OS X. Any applications + * relying on these interfaces WILL break. + */ + +#ifndef __OS_YIELD__ +#define __OS_YIELD__ + +#include + +#pragma mark - +#pragma mark _os_wait_until + +#if OS_ATOMIC_UP +#define _os_wait_until(c) do { \ + int _spins = 0; \ + while (unlikely(!(c))) { \ + _spins++; \ + _os_preemption_yield(_spins); \ + } } while (0) +#elif TARGET_OS_EMBEDDED +// +#ifndef OS_WAIT_SPINS +#define OS_WAIT_SPINS 1024 +#endif +#define _os_wait_until(c) do { \ + int _spins = -(OS_WAIT_SPINS); \ + while (unlikely(!(c))) { \ + if (unlikely(_spins++ >= 0)) { \ + _os_preemption_yield(_spins); \ + } else { \ + os_hardware_pause(); \ + } \ + } } while (0) +#else +#define _os_wait_until(c) do { \ + while (!(c)) { \ + os_hardware_pause(); \ + } } while (0) +#endif + +#pragma mark - +#pragma mark os_hardware_pause + +#if defined(__x86_64__) || defined(__i386__) +#define os_hardware_pause() __asm__("pause") +#elif (defined(__arm__) && defined(_ARM_ARCH_7) && defined(__thumb__)) || \ + defined(__arm64__) +#define os_hardware_pause() __asm__("yield") +#define os_hardware_wfe() __asm__("wfe") +#else +#define os_hardware_pause() __asm__("") +#endif + +#pragma mark - +#pragma mark _os_preemption_yield + +#if defined(SWITCH_OPTION_OSLOCK_DEPRESS) && !(TARGET_IPHONE_SIMULATOR && \ + IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090) +#define OS_YIELD_THREAD_SWITCH_OPTION SWITCH_OPTION_OSLOCK_DEPRESS +#else +#define OS_YIELD_THREAD_SWITCH_OPTION SWITCH_OPTION_DEPRESS +#endif +#define _os_preemption_yield(n) thread_switch(MACH_PORT_NULL, \ + OS_YIELD_THREAD_SWITCH_OPTION, (mach_msg_timeout_t)(n)) + +#endif // __OS_YIELD__ diff --git a/src/external/libplatform/man/atomic.3 b/src/external/libplatform/man/atomic.3 new file mode 100644 index 000000000..eee6e43fe --- /dev/null +++ b/src/external/libplatform/man/atomic.3 @@ -0,0 +1,62 @@ +.Dd May 26, 2004 +.Dt ATOMIC 3 +.Os Darwin +.Sh NAME +.Nm OSAtomicEnqueue , +.Nm OSAtomicDequeue +.Nd atomic lockless queues +.Sh SYNOPSIS +.In libkern/OSAtomic.h +.Ft void +.Fn OSAtomicEnqueue "OSQueueHead *list" "void *new" "size_t offset" +.Ft void* +.Fn OSAtomicDequeue "OSQueueHead *list" "size_t offset" +.Sh DESCRIPTION +The routines +.Fn OSAtomicEnqueue +and +.Fn OSAtomicDequeue +operate on singly linked LIFO queues. Ie, a dequeue operation will return the +most recently enqueued element, or NULL if the list is empty. The operations +are lockless, and barriers are used as necessary to permit thread-safe access to +the queue element. +.Fa offset +is the offset in bytes to the link field in the queue element. +.Pp +.Bf -symbolic +Important: the memory backing the link field of a queue element must not be +unmapped after +.Fn OSAtomicDequeue +returns until all concurrent calls to +.Fn OSAtomicDequeue +for the same list on other threads have also returned, as they may still be +accessing that memory location. +.Ef +.Sh EXAMPLES +.Bd -literal -offset indent + typedef struct elem { + long data1; + struct elem *link; + int data2; + } elem_t; + + elem_t fred, mary, *p; + + OSQueueHead q = OS_ATOMIC_QUEUE_INIT; + + OSAtomicEnqueue( &q, &fred, offsetof(elem_t,link) ); + OSAtomicEnqueue( &q, &mary, offsetof(elem_t,link) ); + + p = OSAtomicDequeue( &q, offsetof(elem_t,link) ); + +.Ed +In this example, the call of +.Fn OSAtomicDequeue +will return a ptr to mary. +.Sh RETURN VALUES +The dequeue operation returns the most recently enqueued element, or NULL if the list in empty. +.Sh SEE ALSO +.Xr atomic_deprecated 3 , +.Xr spinlock_deprecated 3 +.Sh HISTORY +These functions first appeared in Mac OS 10.5 (Leopard). diff --git a/src/external/libplatform/man/atomic_deprecated.3 b/src/external/libplatform/man/atomic_deprecated.3 new file mode 100644 index 000000000..8db9557fa --- /dev/null +++ b/src/external/libplatform/man/atomic_deprecated.3 @@ -0,0 +1,232 @@ +.Dd May 26, 2004 +.Dt ATOMIC_DEPRECATED 3 +.Os Darwin +.Sh NAME +.Nm OSAtomicAdd32 , +.Nm OSAtomicAdd32Barrier , +.Nm OSAtomicIncrement32 , +.Nm OSAtomicIncrement32Barrier , +.Nm OSAtomicDecrement32 , +.Nm OSAtomicDecrement32Barrier , +.Nm OSAtomicOr32 , +.Nm OSAtomicOr32Barrier , +.Nm OSAtomicOr32Orig , +.Nm OSAtomicOr32OrigBarrier , +.Nm OSAtomicAnd32 , +.Nm OSAtomicAnd32Barrier , +.Nm OSAtomicAnd32Orig , +.Nm OSAtomicAnd32OrigBarrier , +.Nm OSAtomicXor32 , +.Nm OSAtomicXor32Barrier , +.Nm OSAtomicXor32Orig , +.Nm OSAtomicXor32OrigBarrier , +.Nm OSAtomicAdd64 , +.Nm OSAtomicAdd64Barrier , +.Nm OSAtomicIncrement64 , +.Nm OSAtomicIncrement64Barrier , +.Nm OSAtomicDecrement64 , +.Nm OSAtomicDecrement64Barrier , +.Nm OSAtomicCompareAndSwapInt , +.Nm OSAtomicCompareAndSwapIntBarrier , +.Nm OSAtomicCompareAndSwapLong , +.Nm OSAtomicCompareAndSwapLongBarrier , +.Nm OSAtomicCompareAndSwapPtr , +.Nm OSAtomicCompareAndSwapPtrBarrier , +.Nm OSAtomicCompareAndSwap32 , +.Nm OSAtomicCompareAndSwap32Barrier , +.Nm OSAtomicCompareAndSwap64 , +.Nm OSAtomicCompareAndSwap64Barrier , +.Nm OSAtomicTestAndSet , +.Nm OSAtomicTestAndSetBarrier , +.Nm OSAtomicTestAndClear , +.Nm OSAtomicTestAndClearBarrier , +.Nm OSMemoryBarrier +.Nd deprecated atomic add, increment, decrement, or, and, xor, compare and swap, test and set, test and clear, and memory barrier +.Sh SYNOPSIS +.In libkern/OSAtomic.h +.Ft int32_t +.Fn OSAtomicAdd32 "int32_t theAmount" "volatile int32_t *theValue" +.Ft int32_t +.Fn OSAtomicAdd32Barrier "int32_t theAmount" "volatile int32_t *theValue" +.Ft int32_t +.Fn OSAtomicIncrement32 "volatile int32_t *theValue" +.Ft int32_t +.Fn OSAtomicIncrement32Barrier "volatile int32_t *theValue" +.Ft int32_t +.Fn OSAtomicDecrement32 "volatile int32_t *theValue" +.Ft int32_t +.Fn OSAtomicDecrement32Barrier "volatile int32_t *theValue" +.Ft int32_t +.Fn OSAtomicOr32 "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicOr32Barrier "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicAnd32 "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicAnd32Barrier "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicXor32 "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicXor32Barrier "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicOr32Orig "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicOr32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicAnd32Orig "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicAnd32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicXor32Orig "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int32_t +.Fn OSAtomicXor32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" +.Ft int64_t +.Fn OSAtomicAdd64 "int64_t theAmount" "volatile OSAtomic_int64_aligned64_t *theValue" +.Ft int64_t +.Fn OSAtomicAdd64Barrier "int64_t theAmount" "volatile OSAtomic_int64_aligned64_t *theValue" +.Ft int64_t +.Fn OSAtomicIncrement64 "volatile OSAtomic_int64_aligned64_t *theValue" +.Ft int64_t +.Fn OSAtomicIncrement64Barrier "volatile OSAtomic_int64_aligned64_t *theValue" +.Ft int64_t +.Fn OSAtomicDecrement64 "volatile OSAtomic_int64_aligned64_t *theValue" +.Ft int64_t +.Fn OSAtomicDecrement64Barrier "volatile OSAtomic_int64_aligned64_t *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwapInt "int oldValue" "int newValue" "volatile int *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwapIntBarrier "int oldValue" "int newValue" "volatile int *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwapLong "long oldValue" "long newValue" "volatile long *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwapLongBarrier "long oldValue" "long newValue" "volatile long *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwapPtr "void* oldValue" "void* newValue" "void* volatile *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwapPtrBarrier "void* oldValue" "void* newValue" "void* volatile *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "volatile OSAtomic_int64_aligned64_t *theValue" +.Ft bool +.Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "volatile OSAtomic_int64_aligned64_t *theValue" +.Ft bool +.Fn OSAtomicTestAndSet "uint32_t n" "volatile void *theAddress" +.Ft bool +.Fn OSAtomicTestAndSetBarrier "uint32_t n" "volatile void *theAddress" +.Ft bool +.Fn OSAtomicTestAndClear "uint32_t n" "volatile void *theAddress" +.Ft bool +.Fn OSAtomicTestAndClearBarrier "uint32_t n" "volatile void *theAddress" +.Ft bool +.Fn OSAtomicEnqueue "OSQueueHead *list" "void *new" "size_t offset" +.Ft void* +.Fn OSAtomicDequeue "OSQueueHead *list" "size_t offset" +.Ft void +.Fn OSMemoryBarrier "void" +.Sh DESCRIPTION +.Bf -symbolic +These are deprecated interfaces for atomic and synchronization +operations, provided for compatibility with legacy code. New code should use +the C11 +.In stdatomic.h +interfaces. +.Ef +.Pp +These functions are thread and multiprocessor safe. For each function, there +is a version which incorporates a memory barrier and another version which does +not. +Barriers strictly order memory access on a weakly-ordered architecture such as +ARM. All loads and stores executed in sequential program +order before the barrier will complete before any load or store executed after +the barrier. +On some platforms, such as ARM, the barrier operation can be quite expensive. +.Pp +Most code will want to use the barrier functions to ensure that memory shared +between threads is properly synchronized. For example, if you want to +initialize a shared data structure and then atomically increment a variable to +indicate that the initialization is complete, then you must use +.Fn OSAtomicIncrement32Barrier +to ensure that the stores to your data structure complete before the atomic add. +Likewise, the consumer of that data structure must use +.Fn OSAtomicDecrement32Barrier , +in order to ensure that their loads of the structure are not executed before +the atomic decrement. On the other hand, if you are simply incrementing a +global counter, then it is safe and potentially much faster to use +.Fn OSAtomicIncrement32 . +If you are unsure which version to use, prefer the barrier variants as they are +safer. +.Pp +The logical (and, or, xor) and bit test operations are layered on top of the +.Fn OSAtomicCompareAndSwap +primitives. There are four versions of each logical operation, depending on +whether or not there is a barrier, and whether the return value is the result +of the operation (eg, +.Fn OSAtomicOr32 +) or the original value before the operation (eg, +.Fn OSAtomicOr32Orig +). +.Pp +The memory address +.Fa theValue +must be "naturally aligned", i.e. 32-bit aligned for 32-bit operations and +64-bit aligned for 64-bit operations. Note that this is not the default alignment +of the +.Vt int64_t +in the iOS ARMv7 ABI, the +.Vt OSAtomic_int64_aligned64_t +type can be used to declare variables with the required alignment. +.Pp +The +.Fn OSAtomicCompareAndSwap +operations compare +.Fa oldValue +to +.Fa *theValue , +and set +.Fa *theValue +to +.Fa newValue +if the comparison is equal. The comparison and assignment +occur as one atomic operation. +.Pp +.Fn OSAtomicTestAndSet +and +.Fn OSAtomicTestAndClear +operate on bit (0x80 >> ( +.Fa n +& 7)) of byte ((char*) +.Fa theAddress ++ ( +.Fa n +>> 3)). They set the named bit to either 1 or 0, respectively. +.Fa theAddress +need not be aligned. +.Pp +The +.Fn OSMemoryBarrier +function strictly orders memory accesses in a weakly ordered memory model such +as with ARM, by creating a barrier. +All loads and stores executed in sequential program order before the barrier +will complete with respect to the memory coherence mechanism, before any load +or store executed after the barrier. Used with an atomic operation, the barrier +can be used to create custom synchronization protocols as an alternative to the +spinlock or queue/dequeue operations. Note that this barrier does not order +uncached loads and stores. On a uniprocessor, the barrier operation is +typically optimized into a no-op. +.Sh RETURN VALUES +The arithmetic operations return the new value, after the operation has been +performed. The boolean operations come in two styles, one of which returns the +new value, and one of which (the "Orig" versions) returns the old. +The compare-and-swap operations return true if the comparison was equal, ie if +the swap occured. The bit test and set/clear operations return the original +value of the bit. +.Sh SEE ALSO +.Xr atomic 3 , +.Xr spinlock_deprecated 3 +.Sh HISTORY +Most of these functions first appeared in Mac OS 10.4 (Tiger). The "Orig" +forms of the boolean operations, the "int", "long" and "ptr" forms of +compare-and-swap first appeared in Mac OS 10.5 (Leopard). diff --git a/src/libc/sys/cache.3 b/src/external/libplatform/man/cache.3 similarity index 100% rename from src/libc/sys/cache.3 rename to src/external/libplatform/man/cache.3 diff --git a/src/libc/string/FreeBSD/ffs.3 b/src/external/libplatform/man/ffs.3 similarity index 81% rename from src/libc/string/FreeBSD/ffs.3 rename to src/external/libplatform/man/ffs.3 index d019b6d3e..df37a3d31 100644 --- a/src/libc/string/FreeBSD/ffs.3 +++ b/src/external/libplatform/man/ffs.3 @@ -28,49 +28,56 @@ .\" SUCH DAMAGE. .\" .\" @(#)ffs.3 8.2 (Berkeley) 4/19/94 -.\" $FreeBSD: src/lib/libc/string/ffs.3,v 1.13 2009/01/13 13:19:42 kib Exp $ +.\" $FreeBSD: src/lib/libc/string/ffs.3,v 1.15 2012/09/30 03:25:04 eadler Exp $ .\" -.Dd October 26, 2008 +.Dd September 29, 2012 .Dt FFS 3 .Os .Sh NAME .Nm ffs , .Nm ffsl , +.Nm ffsll , .Nm fls , -.Nm flsl +.Nm flsl , +.Nm flsll .Nd find first or last bit set in a bit string .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In strings.h .Ft int -.Fn ffs "int i" +.Fn ffs "int value" .Ft int -.Fn ffsl "long i" +.Fn ffsl "long value" .Ft int -.Fn fls "int i" +.Fn ffsll "long long value" .Ft int -.Fn flsl "long i" +.Fn fls "int value" +.Ft int +.Fn flsl "long value" +.Ft int +.Fn flsll "long long value" .Sh DESCRIPTION The -.Fn ffs -and +.Fn ffs , .Fn ffsl -functions find the first bit set -(beginning with the least significant bit) +and +.Fn ffsll +functions find the first (least significant) bit set in -.Fa i +.Fa value and return the index of that bit. .Pp The -.Fn fls -and +.Fn fls , .Fn flsl -functions find the last bit set in -.Fa i +and +.Fn flsll +functions find the last (most significant) bit set in +.Fa value and return the index of that bit. .Pp -Bits are numbered starting at 1 (the least significant bit). +Bits are numbered starting at 1, the least significant bit. A return value of zero from any of these functions means that the argument was zero. .Sh SEE ALSO @@ -90,8 +97,14 @@ compliance. .Pp The .Fn ffsl , -.Fn fls , +.Fn fls and .Fn flsl functions appeared in .Fx 5.3 . +The +.Fn ffsll +and +.Fn flsll +functions appeared in +.Fx 7.1 . diff --git a/src/libc/gen/FreeBSD/getcontext.3 b/src/external/libplatform/man/getcontext.3 similarity index 100% rename from src/libc/gen/FreeBSD/getcontext.3 rename to src/external/libplatform/man/getcontext.3 diff --git a/src/libc/gen/FreeBSD/makecontext.3 b/src/external/libplatform/man/makecontext.3 similarity index 100% rename from src/libc/gen/FreeBSD/makecontext.3 rename to src/external/libplatform/man/makecontext.3 diff --git a/src/external/libplatform/man/manpages.lst b/src/external/libplatform/man/manpages.lst new file mode 100644 index 000000000..898750d18 --- /dev/null +++ b/src/external/libplatform/man/manpages.lst @@ -0,0 +1,13 @@ +# manpage tables +# [ ...] + +# man3 +atomic.3 atomic.3 OSAtomicDequeue.3 OSAtomicEnqueue.3 +atomic_deprecated.3 atomic_deprecated.3 OSAtomicAdd32.3 OSAtomicAdd32Barrier.3 OSAtomicAdd64.3 OSAtomicAdd64Barrier.3 OSAtomicAnd32.3 OSAtomicAnd32Barrier.3 OSAtomicAnd32Orig.3 OSAtomicAnd32OrigBarrier.3 OSAtomicCompareAndSwap32.3 OSAtomicCompareAndSwap32Barrier.3 OSAtomicCompareAndSwap64.3 OSAtomicCompareAndSwap64Barrier.3 OSAtomicCompareAndSwapInt.3 OSAtomicCompareAndSwapIntBarrier.3 OSAtomicCompareAndSwapLong.3 OSAtomicCompareAndSwapLongBarrier.3 OSAtomicCompareAndSwapPtr.3 OSAtomicCompareAndSwapPtrBarrier.3 OSAtomicDecrement32.3 OSAtomicDecrement32Barrier.3 OSAtomicDecrement64.3 OSAtomicDecrement64Barrier.3 OSAtomicIncrement32.3 OSAtomicIncrement32Barrier.3 OSAtomicIncrement64.3 OSAtomicIncrement64Barrier.3 OSAtomicOr32.3 OSAtomicOr32Barrier.3 OSAtomicOr32Orig.3 OSAtomicOr32OrigBarrier.3 OSAtomicTestAndClear.3 OSAtomicTestAndClearBarrier.3 OSAtomicTestAndSet.3 OSAtomicTestAndSetBarrier.3 OSAtomicXor32.3 OSAtomicXor32Barrier.3 OSAtomicXor32Orig.3 OSAtomicXor32OrigBarrier.3 OSMemoryBarrier.3 +cache.3 cache.3 sys_cache_control.3 sys_icache_invalidate.3 sys_dcache_flush.3 +ffs.3 ffs.3 ffsl.3 ffsll.3 fls.3 flsl.3 flsll.3 +getcontext.3 getcontext.3 setcontext.3 +makecontext.3 makecontext.3 swapcontext.3 +setjmp.3 setjmp.3 _longjmp.3 _setjmp.3 longjmp.3 longjmperr.3 longjmperror.3 siglongjmp.3 sigsetjmp.3 +spinlock_deprecated.3 spinlock_deprecated.3 OSSpinLockLock.3 OSSpinLockTry.3 OSSpinLockUnlock.3 +ucontext.3 ucontext.3 diff --git a/src/libc/gen/setjmp.3 b/src/external/libplatform/man/setjmp.3 similarity index 100% rename from src/libc/gen/setjmp.3 rename to src/external/libplatform/man/setjmp.3 diff --git a/src/external/libplatform/man/spinlock_deprecated.3 b/src/external/libplatform/man/spinlock_deprecated.3 new file mode 100644 index 000000000..3305c3268 --- /dev/null +++ b/src/external/libplatform/man/spinlock_deprecated.3 @@ -0,0 +1,54 @@ +.Dd May 26, 2004 +.Dt SPINLOCK_DEPRECATED 3 +.Os Darwin +.Sh NAME +.Nm OSSpinLockTry , +.Nm OSSpinLockLock , +.Nm OSSpinLockUnlock +.Nd deprecated atomic spin lock synchronization primitives +.Sh SYNOPSIS +.In libkern/OSAtomic.h +.Ft bool +.Fn OSSpinLockTry "OSSpinLock *lock" +.Ft void +.Fn OSSpinLockLock "OSSpinLock *lock" +.Ft void +.Fn OSSpinLockUnlock "OSSpinLock *lock" +.Sh DESCRIPTION +.Bf -symbolic +These are deprecated interfaces for userspace spinlocks, provided for +compatibility with legacy code. These interfaces should no longer be used, +particularily in situations where threads of differing priorities may contend +on the same spinlock. +.Pp +The interfaces in +.In os/lock.h +should be used instead in cases where a very low-level lock primitive is +required. In general however, using higher level synchronization primitives +such as those provided by the pthread or dispatch subsystems are preferred. +.Ef +.Pp +The OSSpinLock operations use memory barriers to synchronize access to shared +memory protected by the lock. Preemption is possible while the lock is held. +.Pp +.Ft OSSpinLock +is an integer type. The convention is that unlocked is zero, and locked is nonzero. +Locks must be naturally aligned and cannot be in cache-inhibited memory. +.Pp +.Fn OSSpinLockLock +will spin if the lock is already held, but employs various strategies to back +off. Because it can spin, it will generally be less cpu and power efficient than +other synchronization primitives. +.Pp +.Fn OSSpinLockTry +immediately returns false if the lock was held, true if it took the lock. +It does not spin. +.Pp +.Fn OSSpinLockUnlock +unconditionally unlocks the lock by zeroing it. +.Sh RETURN VALUES +.Fn OSSpinLockTry +returns true if it took the lock, false if the lock was already held. +.Sh SEE ALSO +.Xr atomic 3 , +.Xr atomic_deprecated 3 diff --git a/src/libc/gen/FreeBSD/ucontext.3 b/src/external/libplatform/man/ucontext.3 similarity index 100% rename from src/libc/gen/FreeBSD/ucontext.3 rename to src/external/libplatform/man/ucontext.3 diff --git a/src/external/libplatform/private/libkern/OSAtomic.h b/src/external/libplatform/private/libkern/OSAtomic.h new file mode 100644 index 000000000..7b3f296e3 --- /dev/null +++ b/src/external/libplatform/private/libkern/OSAtomic.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2004-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _OSATOMIC_PRIVATE_H_ +#define _OSATOMIC_PRIVATE_H_ + +#include + +#if __has_include() && \ + __has_include() && \ + __has_include() + + +#include +#include +#include + +#else + +#include_next + +#endif + +#endif // _OSATOMIC_PRIVATE_H_ diff --git a/src/external/libplatform/private/libkern/module.modulemap b/src/external/libplatform/private/libkern/module.modulemap new file mode 100644 index 000000000..72b650c4b --- /dev/null +++ b/src/external/libplatform/private/libkern/module.modulemap @@ -0,0 +1,6 @@ +module libkernPrivate [system] [extern_c] { + module OSAtomic { + header "OSAtomic.h" + export Darwin.libkern.OSAtomic + } +} diff --git a/src/libc/darwin/MKGetTimeBaseInfo.c b/src/external/libplatform/src/atomics/common/MKGetTimeBaseInfo.c similarity index 97% rename from src/libc/darwin/MKGetTimeBaseInfo.c rename to src/external/libplatform/src/atomics/common/MKGetTimeBaseInfo.c index 6b2af3697..21393649c 100644 --- a/src/libc/darwin/MKGetTimeBaseInfo.c +++ b/src/external/libplatform/src/atomics/common/MKGetTimeBaseInfo.c @@ -21,6 +21,8 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if defined(i386) || defined(__arm__) + #include #include #include @@ -60,3 +62,5 @@ MKGetTimeBaseInfo( *theProcessorToAbsoluteTimeDenominator = 1; return KERN_SUCCESS; } + +#endif diff --git a/src/external/libplatform/src/atomics/i386/OSAtomic.S b/src/external/libplatform/src/atomics/i386/OSAtomic.S new file mode 100644 index 000000000..5cef29f75 --- /dev/null +++ b/src/external/libplatform/src/atomics/i386/OSAtomic.S @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include "os/internal_asm.h" + +#define ATOMIC_RET_ORIG 0 +#define ATOMIC_RET_NEW 1 + +// compare and exchange 32-bit +// xchg32 +.macro xchg32 + lock + cmpxchgl $0, ($1) +.endm + +// compare and exchange 64-bit +// xchg64 +.macro xchg64 + lock + cmpxchg8b ($0) +.endm + + +// int32_t OSAtomicAdd32(int32_t theAmount, volatile int32_t *theValue); +#define ATOMIC_ARITHMETIC(instr, orig) \ + movl 8(%esp), %ecx /* load 2nd arg ptr into ecx */ ;\ + movl (%ecx), %eax /* load contents of ecx into eax */ ;\ +1: movl 4(%esp), %edx /* load 1st arg into edx */ ;\ + instr %eax, %edx /* do the operation */ ;\ + xchg32 %edx, %ecx /* old in %eax, new in %edx, exchange into %ecx */ ;\ + jnz 1b /* go back if we failed to exchange */ ;\ + .if orig == ATOMIC_RET_NEW ;\ + movl %edx, %eax /* return new value */ ;\ + .endif + +// bool OSAtomicTestAndSet(uint32_t n, volatile void *theAddress); +#define ATOMIC_BIT_OP(instr) \ + movl 4(%esp), %eax ;\ + movl 8(%esp), %edx ;\ + shldl $3,%edx,%ecx /* save top 3 bits of address in %ecx */ ;\ + shll $3,%edx ;\ + xorl $7,%eax /* bit position is numbered big endian so convert to little endian */ ;\ + addl %eax,%edx /* generate bit address */ ;\ + adcl $0,%ecx /* handle carry out of lower half of address */ ;\ + movl %edx,%eax /* copy lower half of bit address */ ;\ + andl $31,%eax /* keep bit offset in range 0..31 */ ;\ + xorl %eax,%edx /* 4-byte align address */ ;\ + shrdl $3,%ecx,%edx /* restore 32-bit byte address in %edx */ ;\ + lock ;\ + instr %eax, (%edx) ;\ + setc %al ;\ + movzbl %al,%eax // widen in case caller assumes we return an int + +// int64_t OSAtomicAdd64(int64_t theAmount, volatile int64_t *theValue); +#define ATOMIC_ADD64() \ + pushl %ebx ;\ + pushl %esi ;\ + movl 20(%esp), %esi ;\ + movl 0(%esi), %eax ;\ + movl 4(%esi), %edx ;\ +1: movl 12(%esp), %ebx ;\ + movl 16(%esp), %ecx ;\ + addl %eax, %ebx ;\ + adcl %edx, %ecx ;\ + xchg64 %esi ;\ + jnz 1b ;\ + movl %ebx, %eax ;\ + movl %ecx, %edx ;\ + popl %esi ;\ + popl %ebx + +// int64_t OSAtomicIncrement64(volatile int64_t *theValue); +#define ATOMIC_INC64() \ + pushl %ebx ;\ + pushl %esi ;\ + movl 12(%esp), %esi ;\ + movl 0(%esi), %eax ;\ + movl 4(%esi), %edx ;\ +1: movl $1, %ebx ;\ + xorl %ecx, %ecx ;\ + addl %eax, %ebx ;\ + adcl %edx, %ecx ;\ + xchg64 %esi ;\ + jnz 1b ;\ + movl %ebx, %eax ;\ + movl %ecx, %edx ;\ + popl %esi ;\ + popl %ebx + +// int64_t OSAtomicDecrement64(volatile int64_t *theValue); +#define ATOMIC_DEC64() \ + pushl %ebx ;\ + pushl %esi ;\ + movl 12(%esp), %esi ;\ + movl 0(%esi), %eax ;\ + movl 4(%esi), %edx ;\ +1: movl $-1, %ebx ;\ + movl $-1, %ecx ;\ + addl %eax, %ebx ;\ + adcl %edx, %ecx ;\ + xchg64 %esi ;\ + jnz 1b ;\ + movl %ebx, %eax ;\ + movl %ecx, %edx ;\ + popl %esi ;\ + popl %ebx + + .text + +OS_ATOMIC_FUNCTION_START(OSAtomicAnd32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicAnd32Barrier, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW) + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicOr32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicOr32Barrier, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW) + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicXor32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicXor32Barrier, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW) + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicAnd32Orig, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicAnd32OrigBarrier, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG) + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicOr32Orig, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicOr32OrigBarrier, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG) + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicXor32Orig, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicXor32OrigBarrier, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG) + ret + +// bool OSAtomicCompareAndSwapInt(int oldValue, int newValue, volatile int *theValue); +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapPtr, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapPtrBarrier, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapInt, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapIntBarrier, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapLong, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapLongBarrier, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwap32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwap32Barrier, 2) + movl 4(%esp), %eax + movl 8(%esp), %edx + movl 12(%esp), %ecx + xchg32 %edx, %ecx + sete %al + movzbl %al,%eax // widen in case caller assumes we return an int + ret + +// bool OSAtomicCompareAndSwap64(int64_t oldValue, int64_t newValue, volatile int64_t *theValue); +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwap64, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwap64Barrier, 2) + pushl %ebx // push out spare stuff for space + pushl %esi + movl 12(%esp), %eax // load in 1st 64-bit parameter + movl 16(%esp), %edx + movl 20(%esp), %ebx // load in 2nd 64-bit parameter + movl 24(%esp), %ecx + movl 28(%esp), %esi // laod in destination address + xchg64 %esi // compare and swap 64-bit + sete %al + movzbl %al,%eax // widen in case caller assumes we return an int + popl %esi + popl %ebx + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicAdd32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicAdd32Barrier, 2) + movl 4(%esp), %eax + movl 8(%esp), %edx + movl %eax, %ecx + lock + xaddl %eax, (%edx) + addl %ecx, %eax + ret + +OS_VARIANT_FUNCTION_START(OSAtomicIncrement32, up, 2) +OS_VARIANT_FUNCTION_START(OSAtomicIncrement32Barrier, up, 2) + movl 4(%esp), %ecx + movl $1, %eax + xaddl %eax, (%ecx) + incl %eax + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicIncrement32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicIncrement32Barrier, 2) + movl 4(%esp), %ecx + movl $1, %eax + lock + xaddl %eax, (%ecx) + incl %eax + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicDecrement32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicDecrement32Barrier, 2) + movl 4(%esp), %ecx + movl $-1, %eax + lock + xaddl %eax, (%ecx) + decl %eax + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicAdd64, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicAdd64Barrier, 2) + ATOMIC_ADD64() + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicIncrement64, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicIncrement64Barrier, 2) + ATOMIC_INC64() + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicDecrement64, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicDecrement64Barrier, 2) + ATOMIC_DEC64() + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicTestAndSet, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicTestAndSetBarrier, 2) + ATOMIC_BIT_OP(btsl) + ret + +OS_ATOMIC_FUNCTION_START(OSAtomicTestAndClear, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicTestAndClearBarrier, 2) + ATOMIC_BIT_OP(btrl) + ret + +// OSMemoryBarrier() +// These are used both in 32 and 64-bit mode. We use a fence even on UP +// machines, so this function can be used with nontemporal stores. + +OS_ATOMIC_FUNCTION_START(OSMemoryBarrier, 4) + mfence + ret + + /* + * typedef volatile struct { + * void *opaque1; <-- ptr to 1st queue element or null + * long opaque2; <-- generation count + * } OSQueueHead; + * + * void OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset); + */ +OS_ATOMIC_FUNCTION_START(OSAtomicEnqueue, 2) + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%edi // %edi == ptr to list head + movl 20(%esp),%ebx // %ebx == new + movl 24(%esp),%esi // %esi == offset + movl (%edi),%eax // %eax == ptr to 1st element in Q + movl 4(%edi),%edx // %edx == current generation count +1: movl %eax,(%ebx,%esi)// link to old list head from new element + movl %edx,%ecx + incl %ecx // increment generation count + xchg64 %edi // ...push on new element + jnz 1b + popl %ebx + popl %esi + popl %edi + ret + +/* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ +OS_ATOMIC_FUNCTION_START(OSAtomicDequeue, 2) + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%edi // %edi == ptr to list head + movl 20(%esp),%esi // %esi == offset + movl (%edi),%eax // %eax == ptr to 1st element in Q + movl 4(%edi),%edx // %edx == current generation count +1: testl %eax,%eax // list empty? + jz 2f // yes + movl (%eax,%esi),%ebx // point to 2nd in Q + movl %edx,%ecx + incl %ecx // increment generation count + xchg64 %edi // ...pop off 1st element + jnz 1b +2: popl %ebx + popl %esi + popl %edi + ret // ptr to 1st element in Q still in %eax + +/* + * typedef volatile struct { + * void *opaque1; <-- ptr to first queue element or null + * void *opaque2; <-- ptr to last queue element or null + * int opaque3; <-- spinlock + * } OSFifoQueueHead; + * + * void OSAtomicFifoEnqueue( OSFifoQueueHead *list, void *new, size_t offset); + */ +OS_ATOMIC_FUNCTION_START(OSAtomicFifoEnqueue, 2) + pushl %edi + pushl %esi + pushl %ebx + xorl %ebx,%ebx // clear "preemption pending" flag + movl 16(%esp),%edi // %edi == ptr to list head + movl 20(%esp),%esi // %esi == new + EXTERN_TO_REG(_commpage_pfz_base,%ecx) + movl (%ecx), %ecx + addl $(_COMM_TEXT_PFZ_ENQUEUE_OFFSET), %ecx + movl 24(%esp),%edx // %edx == offset + call *%ecx + testl %ebx,%ebx // pending preemption? + jz 1f + call _preempt +1: popl %ebx + popl %esi + popl %edi + ret + +/* void* OSAtomicFifoDequeue( OSFifoQueueHead *list, size_t offset); */ +OS_ATOMIC_FUNCTION_START(OSAtomicFifoDequeue, 2) + pushl %edi + pushl %esi + pushl %ebx + xorl %ebx,%ebx // clear "preemption pending" flag + movl 16(%esp),%edi // %edi == ptr to list head + PICIFY(_commpage_pfz_base) + movl (%edx),%ecx + movl 20(%esp),%edx // %edx == offset + addl $(_COMM_TEXT_PFZ_DEQUEUE_OFFSET), %ecx + call *%ecx + testl %ebx,%ebx // pending preemption? + jz 1f + pushl %eax // save return value across sysenter + call _preempt + popl %eax +1: popl %ebx + popl %esi + popl %edi + ret // ptr to 1st element in Q still in %eax + +// Local Variables: +// tab-width: 8 +// End: diff --git a/src/external/libplatform/src/atomics/i386/pfz.S b/src/external/libplatform/src/atomics/i386/pfz.S new file mode 100644 index 000000000..ca6940b2b --- /dev/null +++ b/src/external/libplatform/src/atomics/i386/pfz.S @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2006-2013 Apple, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + + .text + +/* Subroutine to make a preempt syscall. Called when we notice %ebx is + * nonzero after returning from a PFZ subroutine. + * When we enter kernel: + * %edx = return address + * %ecx = stack ptr + * Destroys %eax, %ecx, and %edx. + */ + .align 4 + .private_extern _preempt + .globl _preempt +_preempt: + popl %edx // get return address + movl %esp,%ecx // save stack ptr here + movl $(-58),%eax /* 58 = pfz_exit */ + xorl %ebx,%ebx // clear "preemption pending" flag + sysenter + +/* Subroutine to back off if we cannot get the spinlock. Called + * after a few attempts inline in the PFZ subroutines. This code is + * not in the PFZ. + * %edi = ptr to queue head structure + * %ebx = preemption flag (nonzero if preemption pending) + * Destroys %eax. + */ + + .align 4 + .private_extern _backoff + .globl _backoff +_backoff: + testl %ebx,%ebx // does kernel want to preempt us? + jz 1f // no + xorl %ebx,%ebx // yes, clear flag + pushl %edx // preserve regs used by preempt syscall + pushl %ecx + call _preempt + popl %ecx + popl %edx +1: + pause // SMT-friendly backoff + cmpl $0,8(%edi) // sniff the lockword + jnz 1b // loop if still taken + ret // lockword is free, so reenter PFZ diff --git a/src/external/libplatform/src/atomics/init.c b/src/external/libplatform/src/atomics/init.c new file mode 100644 index 000000000..58e9ed517 --- /dev/null +++ b/src/external/libplatform/src/atomics/init.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include + +#include <_simple.h> + +#include +#include + +__attribute__ ((visibility ("hidden"))) +uintptr_t commpage_pfz_base=0; + +__attribute__ ((visibility ("hidden"))) +void +__pfz_setup(const char *apple[]) +{ + const char *p = _simple_getenv(apple, "pfz"); + if (p != NULL) { + const char *q; + + /* We are given hex starting with 0x */ + if (p[0] != '0' || p[1] != 'x') { + goto __pfz_setup_clear; + } + + for (q = p + 2; *q; q++) { + commpage_pfz_base <<= 4; // *= 16 + + if ('0' <= *q && *q <= '9') { + commpage_pfz_base += *q - '0'; + } else if ('a' <= *q && *q <= 'f') { + commpage_pfz_base += *q - 'a' + 10; + } else if ('A' <= *q && *q <= 'F') { + commpage_pfz_base += *q - 'A' + 10; + } else { + commpage_pfz_base=0; + goto __pfz_setup_clear; + } + } + +__pfz_setup_clear: + bzero((void *)((uintptr_t)p - 4), strlen(p) + 4); + } + + if (commpage_pfz_base == 0) { + commpage_pfz_base = _COMM_PAGE_TEXT_START; + } +} diff --git a/src/external/libplatform/src/atomics/x86_64/OSAtomic.S b/src/external/libplatform/src/atomics/x86_64/OSAtomic.S new file mode 100644 index 000000000..0da885fa4 --- /dev/null +++ b/src/external/libplatform/src/atomics/x86_64/OSAtomic.S @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include "os/internal_asm.h" + +.text + +#define ATOMIC_RET_ORIG 0 +#define ATOMIC_RET_NEW 1 + +// compare and exchange 32-bit +// xchg32 +.macro xchg32 + lock + cmpxchgl $0, ($1) +.endm + +// xchg64 +.macro xchg64 + lock + cmpxchg $0, ($1) +.endm + +#define ATOMIC_ARITHMETIC(instr, orig) \ + movl (%rsi), %eax /* get 2nd arg -> eax */ ;\ +1: movl %eax, %edx /* copy value to new reg */ ;\ + instr %edi, %edx /* apply instr to %edx with arg2 */ ;\ + xchg32 %edx, %rsi /* do the compare swap (see macro above) */ ;\ + jnz 1b /* jump if failed */ ;\ + .if orig == 1 /* to return the new value, overwrite eax */ ;\ + movl %edx, %eax /* return the new value */ ;\ + .endif + +// Used in OSAtomicTestAndSet( uint32_t n, void *value ), assumes ABI parameter loctions +// Manpage says bit to test/set is (0x80 >> (n & 7)) of byte (addr + (n >> 3)) +#define ATOMIC_BIT_OP(instr) \ + xorl $7, %edi /* bit position is numbered big endian so convert to little endian */ ;\ + shlq $3, %rsi ;\ + addq %rdi, %rsi /* generate bit address */ ;\ + movq %rsi, %rdi ;\ + andq $31, %rdi /* keep bit offset in range 0..31 */ ;\ + xorq %rdi, %rsi /* 4-byte align address */ ;\ + shrq $3, %rsi /* get 4-byte aligned address */ ;\ + lock /* lock the bit test */ ;\ + instr %edi, (%rsi) /* do the bit test, supplied into the macro */ ;\ + setc %al ;\ + movzbl %al,%eax /* widen in case caller assumes we return an int */ + +// uint32_t OSAtomicAnd32( uint32_t mask, uint32_t *value); +OS_ATOMIC_FUNCTION_START(OSAtomicAnd32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicAnd32Barrier, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW) + ret + +// uint32_t OSAtomicOr32( uint32_t mask, uint32_t *value); +OS_ATOMIC_FUNCTION_START(OSAtomicOr32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicOr32Barrier, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW) + ret + +// uint32_t OSAtomicXor32( uint32_t mask, uint32_t *value); +OS_ATOMIC_FUNCTION_START(OSAtomicXor32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicXor32Barrier, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW) + ret + +// uint32_t OSAtomicAnd32Orig( uint32_t mask, uint32_t *value); +OS_ATOMIC_FUNCTION_START(OSAtomicAnd32Orig, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicAnd32OrigBarrier, 2) + ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG) + ret + +// uint32_t OSAtomicOr32Orig( uint32_t mask, uint32_t *value); +OS_ATOMIC_FUNCTION_START(OSAtomicOr32Orig, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicOr32OrigBarrier, 2) + ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG) + ret + +// uint32_t OSAtomicXor32Orig( uint32_t mask, uint32_t *value); +OS_ATOMIC_FUNCTION_START(OSAtomicXor32Orig, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicXor32OrigBarrier, 2) + ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG) + ret + +// bool OSAtomicCompareAndSwap32( int32_t old, int32_t new, int32_t *value); +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapInt, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapIntBarrier, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwap32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwap32Barrier, 2) + movl %edi, %eax + xchg32 %esi, %rdx + sete %al + movzbl %al,%eax // widen in case caller assumes we return an int + ret + +// bool OSAtomicCompareAndSwap64( int64_t old, int64_t new, int64_t *value); +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapPtr, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapPtrBarrier, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapLong, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwapLongBarrier, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwap64, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicCompareAndSwap64Barrier, 2) + mov %rdi, %rax + xchg64 %rsi, %rdx + sete %al + movzbl %al,%eax // widen in case caller assumes we return an int + ret + +// int32_t OSAtomicAdd32( int32_t amt, int32_t *value ); +OS_ATOMIC_FUNCTION_START(OSAtomicAdd32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicAdd32Barrier, 2) + movl %edi, %eax // save amt to add + lock // lock prefix breaks tabs ;) + xaddl %edi, (%rsi) // swap and add value, returns old value in %edi + addl %edi, %eax // add old value to amt as return value + ret + +// int32_t OSAtomicIncrement32(int32_t *value ); +OS_ATOMIC_FUNCTION_START(OSAtomicIncrement32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicIncrement32Barrier, 2) + movl $1, %eax // load increment + lock // lock prefix breaks tabs ;) + xaddl %eax, (%rdi) // swap and add value, returns old value in %eax + incl %eax // increment old value as return value + ret + +// int32_t OSAtomicDecrement32(int32_t *value ); +OS_ATOMIC_FUNCTION_START(OSAtomicDecrement32, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicDecrement32Barrier, 2) + movl $-1, %eax // load decrement + lock // lock prefix breaks tabs ;) + xaddl %eax, (%rdi) // swap and add value, returns old value in %eax + decl %eax // decrement old value as return value + ret + +// int64_t OSAtomicAdd64( int64_t amt, int64_t *value ); +OS_ATOMIC_FUNCTION_START(OSAtomicAdd64, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicAdd64Barrier, 2) + movq %rdi, %rax // save amt to add + lock + xaddq %rdi, (%rsi) // swap and add value, returns old value in %rsi + addq %rdi, %rax // add old value to amt as return value + ret + +// int64_t OSAtomicIncrement64(int64_t *value ); +OS_ATOMIC_FUNCTION_START(OSAtomicIncrement64, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicIncrement64Barrier, 2) + movq $1, %rax // load increment + lock // lock prefix breaks tabs ;) + xaddq %rax, (%rdi) // swap and add value, returns old value in %eax + incq %rax // increment old value as return value + ret + +// int64_t OSAtomicDecrement64(int64_t *value ); +OS_ATOMIC_FUNCTION_START(OSAtomicDecrement64, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicDecrement64Barrier, 2) + movq $-1, %rax // load decrement + lock // lock prefix breaks tabs ;) + xaddq %rax, (%rdi) // swap and add value, returns old value in %eax + decq %rax // decrement old value as return value + ret + +// bool OSAtomicTestAndSet( uint32_t n, void *value ); +OS_ATOMIC_FUNCTION_START(OSAtomicTestAndSet, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicTestAndSetBarrier, 2) + ATOMIC_BIT_OP(btsl) + ret + +// bool OSAtomicTestAndClear( uint32_t n, void *value ); +OS_ATOMIC_FUNCTION_START(OSAtomicTestAndClear, 2) +OS_ATOMIC_FUNCTION_START(OSAtomicTestAndClearBarrier, 2) + ATOMIC_BIT_OP(btrl) + ret + +// void OSMemoryBarrier( void ); +OS_ATOMIC_FUNCTION_START(OSMemoryBarrier, 2) + mfence + ret + +/* + * typedef volatile struct { + * void *opaque1; <-- ptr to 1st queue element or null + * long opaque2; <-- generation count + * } OSQueueHead; + * + * void OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset); + */ +OS_ATOMIC_FUNCTION_START(OSAtomicEnqueue, 2) + pushq %rbx // %rdi == list head, %rsi == new, %rdx == offset + movq %rsi,%rbx // %rbx == new + movq %rdx,%rsi // %rsi == offset + movq (%rdi),%rax // %rax == ptr to 1st element in Q + movq 8(%rdi),%rdx // %rdx == current generation count +1: + movq %rax,(%rbx,%rsi)// link to old list head from new element + movq %rdx,%rcx + incq %rcx // increment generation count + lock // always lock for now... + cmpxchg16b (%rdi) // ...push on new element + jnz 1b + popq %rbx + ret + + + /* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ +OS_ATOMIC_FUNCTION_START(OSAtomicDequeue, 2) + pushq %rbx // %rdi == list head, %rsi == offset + movq (%rdi),%rax // %rax == ptr to 1st element in Q + movq 8(%rdi),%rdx // %rdx == current generation count +1: + testq %rax,%rax // list empty? + jz 2f // yes + movq (%rax,%rsi),%rbx // point to 2nd in Q + movq %rdx,%rcx + incq %rcx // increment generation count + lock // always lock for now... + cmpxchg16b (%rdi) // ...pop off 1st element + jnz 1b +2: + popq %rbx + ret // ptr to 1st element in Q still in %rax + +/* + * typedef volatile struct { + * void *opaque1; <-- ptr to first queue element or null + * void *opaque2; <-- ptr to last queue element or null + * int opaque3; <-- spinlock + * } OSFifoQueueHead; + * + * void OSAtomicFifoEnqueue( OSFifoQueueHead *list, void *new, size_t offset); + */ +OS_ATOMIC_FUNCTION_START(OSAtomicFifoEnqueue, 2) +#if 0 // Linux has not preemption free zone (PFZ), this needs to be rewritten + pushq %rbx + xorl %ebx,%ebx // clear "preemption pending" flag + movq _commpage_pfz_base(%rip),%rcx + addq $(_COMM_TEXT_PFZ_ENQUEUE_OFFSET), %rcx + call *%rcx + testl %ebx,%ebx // pending preemption? + jz 1f + call _preempt // call into the kernel to pfz_exit +1: + popq %rbx +#endif + ret + + +/* void* OSAtomicFifoDequeue( OSFifoQueueHead *list, size_t offset); */ +OS_ATOMIC_FUNCTION_START(OSAtomicFifoDequeue, 2) +#if 0 + pushq %rbx + xorl %ebx,%ebx // clear "preemption pending" flag + movq _commpage_pfz_base(%rip), %rcx + movq %rsi,%rdx // move offset to %rdx to be like the Enqueue case + addq $(_COMM_TEXT_PFZ_DEQUEUE_OFFSET), %rcx + call *%rcx + testl %ebx,%ebx // pending preemption? + jz 1f + call _preempt // call into the kernel to pfz_exit +1: + popq %rbx +#endif + ret // ptr to 1st element in Q in %rax + +// Local Variables: +// tab-width: 8 +// End: diff --git a/src/external/libplatform/src/atomics/x86_64/pfz.S b/src/external/libplatform/src/atomics/x86_64/pfz.S new file mode 100644 index 000000000..9647b1907 --- /dev/null +++ b/src/external/libplatform/src/atomics/x86_64/pfz.S @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2006-2013 Apple, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include + + .text + +/* Subroutine to make a preempt syscall. Called when we notice %ebx is + * nonzero after returning from a PFZ subroutine. Not in PFZ. + * + * All registers preserved (but does clear the %ebx preemption flag). + */ + .align 2 + .private_extern _preempt + .globl _preempt +_preempt: + pushq %rax + pushq %rcx + pushq %r11 + movl $(SYSCALL_CONSTRUCT_MACH(58)),%eax /* 58 = pfz_exit */ + xorl %ebx,%ebx + syscall + popq %r11 + popq %rcx + popq %rax + ret + +/* Subroutine to back off if we cannot get the spinlock. Called + * after a few attempts inline in the PFZ subroutines. This code is + * not in the PFZ. + * %rdi = ptr to queue head structure + * %ebx = preemption flag (nonzero if preemption pending) + * Uses: %rax. + */ + .align 2 + .private_extern _backoff + .globl _backoff +_backoff: + testl %ebx,%ebx // does kernel want to preempt us? + jz 1f // no + call _preempt +1: + pause // SMT-friendly backoff + cmpl $0,16(%rdi) // sniff the lockword + jnz 1b // loop if still taken + ret // lockword is free, so reenter PFZ diff --git a/src/libc/arm/gen/icacheinval.s b/src/external/libplatform/src/cachecontrol/arm/cache.S similarity index 100% rename from src/libc/arm/gen/icacheinval.s rename to src/external/libplatform/src/cachecontrol/arm/cache.S diff --git a/src/external/libplatform/src/cachecontrol/arm64/cache.S b/src/external/libplatform/src/cachecontrol/arm64/cache.S new file mode 100644 index 000000000..d59afdd65 --- /dev/null +++ b/src/external/libplatform/src/cachecontrol/arm64/cache.S @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +/* void sys_icache_invalidate(addr_t start, int length) */ +.globl _sys_icache_invalidate +_sys_icache_invalidate: + /* fast trap for icache_invalidate */ + mov x3, #0 + mov x16, #0x80000000 + svc #SWI_SYSCALL + ret + +/* void sys_dcache_flush(addr_t start, int length) */ +.globl _sys_dcache_flush +_sys_dcache_flush: + /* fast trap for dcache_flush */ + mov x3, #1 + mov x16, #0x80000000 + svc #SWI_SYSCALL + ret + diff --git a/src/libc/gen/cache.c b/src/external/libplatform/src/cachecontrol/generic/cache.c similarity index 98% rename from src/libc/gen/cache.c rename to src/external/libplatform/src/cachecontrol/generic/cache.c index c47d48142..1fc465aab 100644 --- a/src/libc/gen/cache.c +++ b/src/external/libplatform/src/cachecontrol/generic/cache.c @@ -22,13 +22,11 @@ */ /* cache control */ -#include #include #include #include #include - int sys_cache_control(int function, void *start, size_t len) { diff --git a/src/external/libplatform/src/cachecontrol/i386/cache.S b/src/external/libplatform/src/cachecontrol/i386/cache.S new file mode 100644 index 000000000..ca4b95880 --- /dev/null +++ b/src/external/libplatform/src/cachecontrol/i386/cache.S @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + + #include + + + .text + .align 4, 0x00 + +/* void sys_icache_invalidate(addr_t start, int length) */ + + .globl _sys_icache_invalidate +_sys_icache_invalidate: + // This is a NOP on intel processors, since the intent of the API + // is to make data executable, and Intel L1Is are coherent with L1D. + ret + + +/* void sys_dcache_flush(addr_t start, int length) */ + + .globl _sys_dcache_flush +_sys_dcache_flush: + movl 8(%esp),%ecx // get length + movl 4(%esp),%edx // get ptr + testl %ecx,%ecx // length 0? + jz 2f // yes + mfence // ensure previous stores make it to memory + clflush -1(%edx,%ecx) // make sure last line is flushed +1: + clflush (%edx) // flush a line + addl $64,%edx + subl $64,%ecx + ja 1b + mfence // make sure memory is updated before we return +2: + ret diff --git a/src/external/libplatform/src/cachecontrol/x86_64/cache.S b/src/external/libplatform/src/cachecontrol/x86_64/cache.S new file mode 100644 index 000000000..f7a364807 --- /dev/null +++ b/src/external/libplatform/src/cachecontrol/x86_64/cache.S @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + + #include + + + .text + .align 4, 0x00 + +/* void sys_icache_invalidate(addr_t start, int length) */ + + .globl _sys_icache_invalidate +_sys_icache_invalidate: + // This is a NOP on intel processors, since the intent of the API + // is to make data executable, and Intel L1Is are coherent with L1D. + ret + + +/* void sys_dcache_flush(addr_t start, int length) */ + + .globl _sys_dcache_flush +_sys_dcache_flush: + testq %rsi,%rsi // length 0? + jz 2f // yes + mfence // ensure previous stores make it to memory + clflush -1(%rdi,%rsi) // make sure last line is flushed +1: + clflush (%rdi) // flush a line + addq $64,%rdi + subq $64,%rsi + ja 1b + mfence // make sure memory is updated before we return +2: + ret diff --git a/src/external/libplatform/src/force_libplatform_to_build.c b/src/external/libplatform/src/force_libplatform_to_build.c new file mode 100644 index 000000000..9b0b97c8a --- /dev/null +++ b/src/external/libplatform/src/force_libplatform_to_build.c @@ -0,0 +1,6 @@ +// XCode will not build a library unless it contains at least one module. +// Absent this requirement, libm.dylib would be composed entirely by linking +// the component static libraries together, but to satisfy it, we must have +// a C file. + +typedef int theCStandardDoesNotAllowAnEmptyModule; diff --git a/src/external/libplatform/src/init.c b/src/external/libplatform/src/init.c new file mode 100644 index 000000000..7e8bc6ae0 --- /dev/null +++ b/src/external/libplatform/src/init.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +struct ProgramVars; /* forward reference */ + +extern void _simple_asl_init(const char *envp[], const struct ProgramVars *vars); +extern void __pfz_setup(const char *apple[]); + + +void __libplatform_init(void *future_use __unused, const char *envp[], const char *apple[], const struct ProgramVars *vars) { + + /* In the Simulator, we just provide _simple for dyld */ +#if !TARGET_IPHONE_SIMULATOR + __pfz_setup(apple); +#endif + _simple_asl_init(envp, vars); + +} diff --git a/src/external/libplatform/src/introspection/introspection.c b/src/external/libplatform/src/introspection/introspection.c new file mode 100644 index 000000000..c4d451ba7 --- /dev/null +++ b/src/external/libplatform/src/introspection/introspection.c @@ -0,0 +1,524 @@ +#include "os/internal.h" +#include "platform/introspection_private.h" +#include "introspection_internal.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include "libkern/OSAtomic.h" + +// Returns the number of thread entries that can be stored in a task page. +static unsigned int +_platform_threads_per_page(void) +{ + // Subtract out the header storage. + return (int)(vm_page_size / sizeof(struct platform_thread_s)) - 1; +} + +// Returns the page-aligned base address for a given pthread structure address. +static mach_vm_size_t +_platform_pthread_addr(mach_vm_address_t addr) { + return trunc_page(addr); // XXX approximation +} + +// Returns the page-aligned size for a given pthread structure address. +static mach_vm_size_t +_platform_pthread_size(mach_vm_address_t addr) { + return vm_page_size; // XXX approximation +} + +static kern_return_t +_platform_thread_deallocate(platform_thread_t thread) +{ + kern_return_t ret; + if (MACH_PORT_VALID(thread->act)) { + mach_port_deallocate(mach_task_self(), thread->act); + thread->act = MACH_PORT_NULL; + } + + if (thread->pthread_addr != 0) { + ret = mach_vm_deallocate(mach_task_self(), + _platform_pthread_addr(thread->pthread_addr), + _platform_pthread_size(thread->pthread_addr)); + thread->pthread_addr = 0; + } + return ret; +} + +static kern_return_t +_platform_task_deallocate(platform_task_t task) +{ + kern_return_t ret; + + if (!task) { + return KERN_INVALID_TASK; + } + + task_t port = task->metadata.port; + if (port != MACH_PORT_NULL) { + mach_port_deallocate(mach_task_self(), port); + } + + platform_task_t ptr = task; + do { + mach_vm_address_t addr = (mach_vm_address_t)ptr; + + // Deallocate threads. + int i, start = (ptr == task) ? 1 : 0; // Skip over meta data. + for (i = start; i < _platform_threads_per_page() - start; ++i) { + _platform_thread_deallocate(&ptr->threads[i]); + } + + ptr = ptr->header.next; + ret = mach_vm_deallocate(mach_task_self(), addr, vm_page_size); + } while (ptr); + + return ret; +} + +extern int __sysctl(int *, unsigned int, void *, size_t *, void *, size_t); + +static kern_return_t +_platform_task_query_64_bit(platform_task_t task) +{ + task_flags_info_data_t task_flags_info; + mach_msg_type_number_t count = TASK_FLAGS_INFO_COUNT; + + kern_return_t ret = task_info(task->metadata.port, TASK_FLAGS_INFO, (task_info_t) &task_flags_info, &count); + if (ret == KERN_SUCCESS) { + task->metadata.is_64_bit = (task_flags_info.flags & TF_LP64) ? true : false; + } else if (ret == KERN_INVALID_ARGUMENT) { + pid_t pid; + kern_return_t ret = pid_for_task(task->metadata.port, &pid); + if (ret != KERN_SUCCESS) return ret; + + struct kinfo_proc info; + size_t size = sizeof(info); + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; + unsigned int len = sizeof(mib) / sizeof(*mib); + int res = __sysctl(mib, len, &info, &size, NULL, 0); + if (res == 0 && size >= sizeof(info)) { + task->metadata.is_64_bit = (info.kp_proc.p_flag & P_LP64) != 0; + } + } + + return ret; +} + +kern_return_t +platform_task_attach(platform_task_t *out_task, task_t port) +{ + kern_return_t ret; + + // Test some invariants. + _Static_assert(sizeof(struct platform_task_header_s) == 32, ""); + _Static_assert(sizeof(struct platform_task_metadata_s) == 32, ""); + _Static_assert(sizeof(struct platform_thread_s) == 32, ""); + + // Allocate storage for the returned task handle. + mach_vm_address_t addr = 0; + mach_vm_size_t size = vm_page_size; + ret = mach_vm_allocate(mach_task_self(), &addr, size, VM_FLAGS_ANYWHERE); + if (ret != KERN_SUCCESS) return ret; + + platform_task_t result = (platform_task_t)addr; + + // Keep a reference to the task port. + ret = mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, 1); + if (ret != KERN_SUCCESS) { + _platform_task_deallocate(result); + return ret; + } + + result->header.head = result; + result->metadata.port = port; + + ret = _platform_task_query_64_bit(result); + if (ret != KERN_SUCCESS) { + _platform_task_deallocate(result); + return ret; + } + + *out_task = result; + + return ret; +} + +kern_return_t +platform_task_detach(platform_task_t task) +{ + kern_return_t ret; + ret = _platform_task_deallocate(task); + return ret; +} + +bool +platform_task_is_64_bit(platform_task_t task) +{ + return task->metadata.is_64_bit; +} + +kern_return_t +platform_task_suspend_threads(platform_task_t task) +{ + return KERN_NOT_SUPPORTED; +} + +kern_return_t +platform_task_resume_threads(platform_task_t task) +{ + return KERN_NOT_SUPPORTED; +} + +kern_return_t +platform_task_perform(platform_task_t task, + mach_vm_address_t func_addr, + mach_vm_address_t data_addr) +{ + return KERN_NOT_SUPPORTED; +} + +static platform_task_t +_platform_thread_get_task(platform_thread_t thread) +{ + platform_task_t task = (platform_task_t)trunc_page((uintptr_t)thread); + platform_task_t head = task->header.head; + if (head) { + task = head; + } + return task; +} + +static kern_return_t +_platform_thread_map(platform_task_t task, + platform_thread_t thread, + mach_vm_address_t thread_handle) +{ + kern_return_t ret; + vm_prot_t cur_protection, max_protection; + + vm_offset_t data = 0; + mach_vm_size_t wordsize = task->metadata.is_64_bit ? 8 : 4; + mach_msg_type_number_t size; + ret = mach_vm_read(_platform_thread_get_task(thread)->metadata.port, + thread_handle, // &TSD[0] + wordsize, + &data, + &size); + if (ret != KERN_SUCCESS) return ret; + + mach_vm_address_t pthread_addr = (uintptr_t)*(void **)data; // deref TSD[0] + mach_vm_deallocate(mach_task_self(), data, size); + + mach_vm_address_t src_addr = _platform_pthread_addr(pthread_addr); + mach_vm_offset_t offset = pthread_addr - src_addr; + mach_vm_address_t dst_addr = 0; + ret = mach_vm_remap(mach_task_self(), + &dst_addr, + _platform_pthread_size(pthread_addr), + 0, + VM_FLAGS_ANYWHERE, + _platform_thread_get_task(thread)->metadata.port, + src_addr, + 0, // no copy + &cur_protection, + &max_protection, + VM_INHERIT_NONE); + if (ret == KERN_SUCCESS) { + thread->pthread_addr = dst_addr + offset; + } + + return ret; +} + +// Add a mach thread to the task's thread array. Updates the existing entry +// with the same unique id if one exists, otherwise allocates a new entry. +// Consumes the reference to the thread act mach port. +static kern_return_t +_platform_task_add_mach_thread(platform_task_t task, thread_act_t act) +{ + int i; + kern_return_t ret; + + thread_identifier_info_data_t info; + mach_msg_type_number_t info_count = THREAD_IDENTIFIER_INFO_COUNT; + ret = thread_info(act, + THREAD_IDENTIFIER_INFO, + (thread_info_t)&info, + &info_count); + if (ret != KERN_SUCCESS) return ret; + + // Anything older than the previous generation is a candidate for recycling. + uint32_t gen = task->metadata.gen - 1; + + // Look for an existing slot with this unique ID or the first empty slot. + platform_thread_t empty = NULL; + platform_thread_t found = NULL; + platform_task_t last, ptr = task; + do { + int start = (ptr == task) ? 1 : 0; // Skip over meta data. + for (i = start; i < _platform_threads_per_page() - start; ++i) { + platform_thread_t thread = &ptr->threads[i]; + if (!empty && + thread->refcnt == 0 && + (thread->unique_id == 0 || thread->gen < gen)) { + empty = &ptr->threads[i]; + } else if (task->threads[i].unique_id == info.thread_id) { + found = &ptr->threads[i]; + break; + } + } + last = ptr; + } while (!found && (ptr = ptr->header.next)); + + if (found) { + mach_port_deallocate(mach_task_self(), found->act); + found->act = act; + found->gen = task->metadata.gen; + } else { + if (!empty) { + // Allocate new storage if necessary. + mach_vm_address_t addr = 0; + mach_vm_size_t size = vm_page_size; + ret = mach_vm_allocate(mach_task_self(), + &addr, + size, + VM_FLAGS_ANYWHERE); + if (ret != KERN_SUCCESS) return ret; + + last = last->header.next = (platform_task_t)addr; + last->header.head = task; + + empty = &last->threads[0]; + } else { + _platform_thread_deallocate(empty); + } + + empty->act = act; // transfer ownership + empty->gen = task->metadata.gen; + empty->unique_id = info.thread_id; + ret = _platform_thread_map(task, empty, info.thread_handle); + } + + return ret; +} + +kern_return_t +platform_task_update_threads(platform_task_t task) +{ + kern_return_t ret; + thread_act_array_t array; + mach_msg_type_number_t array_count; + ret = task_threads(task->metadata.port, &array, &array_count); + if (ret != KERN_SUCCESS) return ret; + + ++task->metadata.gen; + task->metadata.cursor = &task->threads[1]; // Reset iteration cursor. + + unsigned int i; + for (i = 0; i < array_count; ++i) { + ret = _platform_task_add_mach_thread(task, array[i]); + } + + mach_vm_size_t array_size = array_count * sizeof(*array); + mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)array, array_size); + + return ret; +} + +platform_thread_t +platform_task_copy_next_thread(platform_task_t task) +{ + int i; + platform_thread_t result = NULL; + platform_thread_t cursor = task->metadata.cursor; + + if (cursor == NULL) { + // End of iteration. + return NULL; + } + + uint32_t gen = task->metadata.gen; + platform_task_t ptr = (platform_task_t)trunc_page((uintptr_t)cursor); + + do { + if (cursor->gen == gen && cursor->unique_id != 0) { + result = cursor; + } + + ++cursor; + + if ((uintptr_t)cursor >= ((uintptr_t)ptr + vm_page_size)) { + ptr = ptr->header.next; + if (ptr) { + cursor = &ptr->threads[0]; + } else { + cursor = NULL; + } + } + } while (!result && cursor); + + task->metadata.cursor = cursor; + + if (result) { + OSAtomicIncrement32(&result->refcnt); + } + + return result; +} + +platform_thread_id_t +platform_thread_get_unique_id(platform_thread_t thread) +{ + return thread->unique_id; +} + +void +platform_thread_release(platform_thread_t thread) +{ + int32_t refcnt = OSAtomicDecrement32(&thread->refcnt); + if (refcnt < 0) { + __LIBPLATFORM_CLIENT_CRASH__(refcnt, "Over-release of platform thread object"); + } +} + +kern_return_t +platform_thread_abort_safely(platform_thread_t thread) +{ + kern_return_t ret; + ret = thread_abort_safely(thread->act); + return ret; +} + +kern_return_t +platform_thread_suspend(platform_thread_t thread) +{ + kern_return_t ret; + ret = thread_suspend(thread->act); + return ret; +} + +kern_return_t +platform_thread_resume(platform_thread_t thread) +{ + kern_return_t ret; + ret = thread_resume(thread->act); + return ret; +} + +kern_return_t +platform_thread_info(platform_thread_t thread, + thread_flavor_t flavor, + void *info, + size_t *size) +{ + kern_return_t ret; + mach_msg_type_number_t count = (int)*size / sizeof(natural_t); + ret = thread_info(thread->act, flavor, info, &count); + *size = count * sizeof(natural_t); + return ret; +} + +kern_return_t +platform_thread_get_state(platform_thread_t thread, + thread_state_flavor_t flavor, + void *state, + size_t *size) +{ + kern_return_t ret; + mach_msg_type_number_t count = (int)*size / (int)sizeof(natural_t); + ret = thread_get_state(thread->act, flavor, state, &count); + *size = count * sizeof(natural_t); + return ret; +} + +kern_return_t +platform_thread_set_state(platform_thread_t thread, + thread_state_flavor_t flavor, + const void *state, + size_t size) +{ + kern_return_t ret; + mach_msg_type_number_t count = (int)size / (int)sizeof(natural_t); + ret = thread_set_state(thread->act, flavor, (thread_state_t)state, count); + return ret; +} + +kern_return_t +platform_thread_perform(platform_thread_t thread, + mach_vm_address_t func_addr, + mach_vm_address_t data_addr) +{ + return KERN_NOT_SUPPORTED; +} + +const void * +platform_thread_get_pthread(platform_thread_t thread) +{ + return (const void *) thread->pthread_addr; +} + +#ifdef MAIN + +// cc -DMAIN -I../../include/platform introspection.c + +#include +#include + +int main(int argc, char *argv[]) { + kern_return_t ret; + + task_t port = MACH_PORT_NULL; + ret = task_for_pid(mach_task_self(), getppid(), &port); + if (ret != KERN_SUCCESS) { + mach_error("task_for_pid", ret); + return 1; + } + + platform_task_t task = NULL; + ret = platform_task_attach(&task, port); + if (ret != KERN_SUCCESS) { + mach_error("platform_task_attach", ret); + return 1; + } + + printf("Task is %s.\n", platform_task_is_64_bit(task) ? "64-bit" : "32-bit"); + + int i; + for (i = 0; i < 3; ++i) { + ret = platform_task_update_threads(task); + if (ret != KERN_SUCCESS) { + mach_error("platform_task_update_threads", ret); + return 1; + } + + platform_thread_t thread; + while ((thread = platform_task_copy_next_thread(task))) { + printf("thread = { .unique_id = 0x%llx, pthread_addr = 0x%llx }\n", + thread->unique_id, + thread->pthread_addr); + printf("pthread = { .sig = %lx, .unique_id = 0x%llx }\n", + *(unsigned long *)thread->pthread_addr, + *(uint64_t *)((uintptr_t)thread->pthread_addr + 32)); + + platform_thread_release(thread); + } + + sleep(3); + } + + ret = platform_task_detach(task); + if (ret != KERN_SUCCESS) { + mach_error("platform_task_detach", ret); + return 1; + } + + return 0; +} +#endif diff --git a/src/external/libplatform/src/introspection/introspection_internal.h b/src/external/libplatform/src/introspection/introspection_internal.h new file mode 100644 index 000000000..c28fe73cd --- /dev/null +++ b/src/external/libplatform/src/introspection/introspection_internal.h @@ -0,0 +1,64 @@ +#ifndef __PLATFORM_INTROSPECTION_INTERNAL_H__ +#define __PLATFORM_INTROSPECTION_INTERNAL_H__ + + +// Task Allocations (with 4K vm_page_size) +// +// Page 1 Page 2 +// +----------------+ <---- Head ----- +----------------+ +// | Header | ----- Next ----> | Header | ----- Next ----> ... +// +----------------+ +----------------+ +// | Meta Data | | Thread[126] | +// +----------------+ +----------------+ +// | Thread[0] | | Thread[127] | +// +----------------+ +----------------+ +// ~ ... ~ ~ ... ~ +// +----------------+ +----------------+ +// | Thread[125] | | Thread[252] | +// +----------------+ +----------------+ +// + +// 32 bytes +struct platform_task_header_s { + // Linkage to other platform task pages. + platform_task_t head; + platform_task_t next; +#ifdef __LP64__ + uint64_t _reserved[2]; +#else + uint32_t _reserved[6]; +#endif +}; + +// 32 bytes +struct platform_task_metadata_s { + platform_thread_t cursor; + task_t port; + uint32_t gen; + uint32_t is_64_bit:1, unused_flags:31; +#ifdef __LP64__ + uint32_t _reserved[3]; +#else + uint32_t _reserved[4]; +#endif +}; + +// 32 bytes +struct platform_thread_s { + int32_t refcnt; + uint32_t gen; + platform_thread_id_t unique_id; + mach_vm_address_t pthread_addr; + thread_act_t act; + uint32_t _reserved; +}; + +struct platform_task_s { + struct platform_task_header_s header; + union { + struct platform_task_metadata_s metadata; + struct platform_thread_s threads[127]; + }; +}; + +#endif // __PLATFORM_INTROSPECTION_INTERNAL_H__ diff --git a/src/external/libplatform/src/os/alloc_once.c b/src/external/libplatform/src/os/alloc_once.c new file mode 100644 index 000000000..a8ff35857 --- /dev/null +++ b/src/external/libplatform/src/os/alloc_once.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2012-2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "os/internal.h" +#include "os/alloc_once_impl.h" +#include +#include +#include + +#pragma mark - +#pragma mark os_alloc + +typedef struct _os_alloc_heap_metadata_s { + size_t allocated_bytes; + void *prev; +} _os_alloc_heap_metadata_s; + +#define allocation_size (2 * vm_page_size) +#define usable (allocation_size-sizeof(_os_alloc_heap_metadata_s)) +static void * volatile _os_alloc_heap; + +/* + * Simple allocator that doesn't have to worry about ever freeing allocations. + * + * The heapptr entry of _os_alloc_once_metadata always points to the newest + * available heap page, or NULL if this is the first allocation. The heap has a + * small header at the top of each heap block, recording the currently + * allocated bytes and the pointer to the previous heap block. + * + * Ignoring the special case where the heapptr is NULL; in which case we always + * make a block. The allocator first atomically increments the allocated_bytes + * counter by sz and calculates the eventual base pointer. If base+sz is + * greater than allocation_size then we begin allocating a new page. Otherwise, + * base is returned. + * + * Page allocation vm_allocates a new page of allocation_size and then attempts + * to atomically cmpxchg that pointer with the current headptr. If successful, + * it links the previous page to the new heap block for debugging purposes and + * then reattempts allocation. If a thread loses the allocation race, it + * vm_deallocates the still-clean region and reattempts the whole allocation. + */ + +static inline void* +_os_alloc_alloc(void *heap, size_t sz) +{ + if (likely(heap)) { + _os_alloc_heap_metadata_s *metadata = (_os_alloc_heap_metadata_s*)heap; + size_t used = os_atomic_add(&metadata->allocated_bytes, sz, relaxed); + if (likely(used <= usable)) { + return ((char*)metadata + sizeof(_os_alloc_heap_metadata_s) + + used - sz); + } + } + /* This fall-through case is heap == NULL, or heap block is exhausted. */ + return NULL; +} + +OS_NOINLINE +static void* +_os_alloc_slow(void *heap, size_t sz) +{ + void *ptr; + do { + /* + * We allocate at PAGE_SIZE or above to ensure + * we don't land in the zero page *if* a binary has opted not to include + * the __PAGEZERO load command. + */ + mach_vm_address_t heapblk = PAGE_SIZE; + kern_return_t kr; + kr = mach_vm_map(mach_task_self(), &heapblk, allocation_size, + 0, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_OS_ALLOC_ONCE), + MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL, + VM_INHERIT_DEFAULT); + if (unlikely(kr)) { + __LIBPLATFORM_INTERNAL_CRASH__(kr, "Failed to allocate in os_alloc_once"); + } + if (os_atomic_cmpxchg(&_os_alloc_heap, heap, (void*)heapblk, relaxed)) { + ((_os_alloc_heap_metadata_s*)heapblk)->prev = heap; + heap = (void*)heapblk; + } else { + mach_vm_deallocate(mach_task_self(), heapblk, allocation_size); + heap = _os_alloc_heap; + } + ptr = _os_alloc_alloc(heap, sz); + } while (unlikely(!ptr)); + return ptr; +} + +static inline void* +_os_alloc2(size_t sz) +{ + void *heap, *ptr; + if (unlikely(!sz || sz > usable)) { + __LIBPLATFORM_CLIENT_CRASH__(sz, "Requested allocation size is invalid"); + } + heap = _os_alloc_heap; + if (likely(ptr = _os_alloc_alloc(heap, sz))) { + return ptr; + } + return _os_alloc_slow(heap, sz); +} + +#pragma mark - +#pragma mark os_alloc_once + +typedef struct _os_alloc_once_ctxt_s { + struct _os_alloc_once_s *slot; + size_t sz; + os_function_t init; +} _os_alloc_once_ctxt_s; + +static void +_os_alloc(void *ctxt) +{ + _os_alloc_once_ctxt_s *c = ctxt; + c->slot->ptr = _os_alloc2((c->sz + 0xf) & ~0xfu); + if (c->init) { + c->init(c->slot->ptr); + } +} + +void* +_os_alloc_once(struct _os_alloc_once_s *slot, size_t sz, os_function_t init) +{ + _os_alloc_once_ctxt_s c = { + .slot = slot, + .sz = sz, + .init = init, + }; + _os_once(&slot->once, &c, _os_alloc); + return slot->ptr; +} diff --git a/src/external/libplatform/src/os/atomic.c b/src/external/libplatform/src/os/atomic.c new file mode 100644 index 000000000..6c846f66a --- /dev/null +++ b/src/external/libplatform/src/os/atomic.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include "os/internal.h" +#include "libkern/OSAtomic.h" +#include "resolver.h" + +#if TARGET_OS_EMBEDDED + +OS_ATOMIC_EXPORT +int32_t OSAtomicAdd32Barrier(int32_t v, volatile int32_t *p); +OS_ATOMIC_EXPORT +int32_t OSAtomicIncrement32Barrier(volatile int32_t *p); +OS_ATOMIC_EXPORT +int32_t OSAtomicDecrement32Barrier(volatile int32_t *p); +OS_ATOMIC_EXPORT +int64_t OSAtomicAdd64Barrier(int64_t v, volatile int64_t *p); +OS_ATOMIC_EXPORT +int64_t OSAtomicIncrement64Barrier(volatile int64_t *p); +OS_ATOMIC_EXPORT +int64_t OSAtomicDecrement64Barrier(volatile int64_t *p); +OS_ATOMIC_EXPORT +int32_t OSAtomicAnd32Barrier(uint32_t v, volatile uint32_t *p); +OS_ATOMIC_EXPORT +int32_t OSAtomicAnd32OrigBarrier(uint32_t v, volatile uint32_t *p); +OS_ATOMIC_EXPORT +int32_t OSAtomicOr32Barrier(uint32_t v, volatile uint32_t *p); +OS_ATOMIC_EXPORT +int32_t OSAtomicOr32OrigBarrier(uint32_t v, volatile uint32_t *p); +OS_ATOMIC_EXPORT +int32_t OSAtomicXor32Barrier(uint32_t v, volatile uint32_t *p); +OS_ATOMIC_EXPORT +int32_t OSAtomicXor32OrigBarrier(uint32_t v, volatile uint32_t *p); +OS_ATOMIC_EXPORT +bool OSAtomicCompareAndSwap32Barrier(int32_t o, int32_t n, volatile int32_t *p); +OS_ATOMIC_EXPORT +bool OSAtomicCompareAndSwap64Barrier(int64_t o, int64_t n, volatile int64_t *p); +OS_ATOMIC_EXPORT +bool OSAtomicTestAndSetBarrier(uint32_t n, volatile void * p); +OS_ATOMIC_EXPORT +bool OSAtomicTestAndClearBarrier(uint32_t n, volatile void * p); +OS_ATOMIC_EXPORT +void OSAtomicEnqueue(OSQueueHead *list, void *new, size_t offset); +OS_ATOMIC_EXPORT +void* OSAtomicDequeue(OSQueueHead *list, size_t offset); +OS_ATOMIC_EXPORT +void OSMemoryBarrier(void); + +#if OS_ATOMIC_UP +#define OS_ATOMIC_ALIAS_NO_BARRIER(n) OS_ATOMIC_EXPORT_ALIAS(n, n##Barrier) +#else +#define OS_ATOMIC_ALIAS_NO_BARRIER(n) +#endif + +int32_t +OSAtomicAdd32Barrier(int32_t v, volatile int32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicAdd32); + int32_t r = os_atomic_add(p, v, acq_rel); + return r; +} + +int32_t +OSAtomicIncrement32Barrier(volatile int32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicIncrement32); + int32_t r = os_atomic_add(p, 1, acq_rel); + return r; +} + +int32_t +OSAtomicDecrement32Barrier(volatile int32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicDecrement32); + int32_t r = os_atomic_add(p, -1, acq_rel); + return r; +} + +int64_t +OSAtomicAdd64Barrier(int64_t v, volatile int64_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicAdd64); + int64_t r = os_atomic_add(p, v, acq_rel); + return r; +} + +int64_t +OSAtomicIncrement64Barrier(volatile int64_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicIncrement64); + int64_t r = os_atomic_add(p, 1, acq_rel); + return r; +} + +int64_t +OSAtomicDecrement64Barrier(volatile int64_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicDecrement64); + int64_t r = os_atomic_add(p, -1, acq_rel); + return r; +} + +int32_t +OSAtomicAnd32Barrier(uint32_t v, volatile uint32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicAnd32); + uint32_t r = os_atomic_and(p, v, acq_rel); + return (int32_t)r; +} + +int32_t +OSAtomicAnd32OrigBarrier(uint32_t v, volatile uint32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicAnd32Orig); + uint32_t r = os_atomic_and_orig(p, v, acq_rel); + return (int32_t)r; +} + +int32_t +OSAtomicOr32Barrier(uint32_t v, volatile uint32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicOr32); + uint32_t r = os_atomic_or(p, v, acq_rel); + return (int32_t)r; +} + +int32_t +OSAtomicOr32OrigBarrier(uint32_t v, volatile uint32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicOr32Orig); + uint32_t r = os_atomic_or_orig(p, v, acq_rel); + return (int32_t)r; +} + +int32_t +OSAtomicXor32Barrier(uint32_t v, volatile uint32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicXor32); + uint32_t r = os_atomic_xor(p, v, acq_rel); + return (int32_t)r; +} + +int32_t +OSAtomicXor32OrigBarrier(uint32_t v, volatile uint32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicXor32Orig); + uint32_t r = os_atomic_xor_orig(p, v, acq_rel); + return (int32_t)r; +} + +bool +OSAtomicCompareAndSwap32Barrier(int32_t o, int32_t n, volatile int32_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwap32); + OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapIntBarrier, + OSAtomicCompareAndSwap32Barrier); + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapInt); +#ifndef __LP64__ + OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapLongBarrier, + OSAtomicCompareAndSwap32Barrier); + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapLong); + OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapPtrBarrier, + OSAtomicCompareAndSwap32Barrier); + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapPtr); +#endif + return os_atomic_cmpxchg(p, o, n, acq_rel); +} + +bool +OSAtomicCompareAndSwap64Barrier(int64_t o, int64_t n, volatile int64_t *p) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwap64); +#ifdef __LP64__ + OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapLongBarrier, + OSAtomicCompareAndSwap64Barrier); + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapLong); + OS_ATOMIC_ALIAS(OSAtomicCompareAndSwapPtrBarrier, + OSAtomicCompareAndSwap64Barrier); + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicCompareAndSwapPtr); +#endif + return os_atomic_cmpxchg(p, o, n, acq_rel); +} + +static inline uint32_t* +_OSAtomicTestPtrVal(uint32_t bit, volatile void *addr, uint32_t *vp) +{ + uintptr_t a = (uintptr_t)addr; + if (a & 3) { + // 32-bit align addr and adjust bit to compensate + bit += (a & 3) * 8; + a &= ~3ull; + } + *vp = (0x80u >> (bit & 7)) << (bit & ~7u & 31); + return (uint32_t*)((char*)a + 4 * (bit / 32)); +} + +bool +OSAtomicTestAndSetBarrier(uint32_t bit, volatile void *addr) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicTestAndSet); + uint32_t v; + volatile uint32_t *p = _OSAtomicTestPtrVal(bit, addr, &v); + uint32_t r = os_atomic_or_orig(p, v, acq_rel); + return (r & v); +} + +bool +OSAtomicTestAndClearBarrier(uint32_t bit, volatile void *addr) +{ + OS_ATOMIC_ALIAS_NO_BARRIER(OSAtomicTestAndClear); + uint32_t v; + volatile uint32_t *p = _OSAtomicTestPtrVal(bit, addr, &v); + uint32_t r = os_atomic_and_orig(p, ~v, acq_rel); + return (r & v); +} + +#if !OS_ATOMIC_NO_BARRIER_ONLY + +typedef volatile struct { + void * volatile item; + long unused; +} _OSQueueHead; + +void +OSAtomicEnqueue(OSQueueHead *list, void *new, size_t offset) +{ + void * volatile *headptr = &(((_OSQueueHead*)list)->item); + void * volatile *nextptr = (void*)((char*)new + offset); + void *head = *headptr; + do { + *nextptr = head; + } while (!os_atomic_cmpxchgvw(headptr, head, new, &head, release)); +} + +void* +OSAtomicDequeue(OSQueueHead *list, size_t offset) +{ + void * volatile *headptr = &(((_OSQueueHead*)list)->item); + void * volatile *nextptr; + void *head, *next; + (void)os_atomic_rmw_loop(headptr, head, next, acquire, { + if (!head) { + os_atomic_rmw_loop_give_up(break); + } + nextptr = (void*)((char*)head + offset); + next = *nextptr; + }); + return head; +} + +void +OSMemoryBarrier(void) +{ + os_atomic_thread_fence(seq_cst); +} + +#endif // !OS_ATOMIC_NO_BARRIER_ONLY +#endif // TARGET_OS_EMBEDDED + +struct _os_empty_files_are_not_c_files; diff --git a/src/external/libplatform/src/os/atomic_up.c b/src/external/libplatform/src/os/atomic_up.c new file mode 100644 index 000000000..901364348 --- /dev/null +++ b/src/external/libplatform/src/os/atomic_up.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +// Force up variant to be generated to get the no-barrier OSAtomics +#undef VARIANT_NO_RESOLVERS +#define VARIANT_NO_RESOLVERS 0 + +#define OS_ATOMIC_UP 1 +#include "os/internal.h" + +#ifdef OS_VARIANT_SELECTOR +#define OS_VARIANT_ONLY 1 +#include "atomic.c" +#endif + +struct _os_empty_files_are_not_c_files; diff --git a/src/external/libplatform/src/os/lock.c b/src/external/libplatform/src/os/lock.c new file mode 100644 index 000000000..8f3f7a936 --- /dev/null +++ b/src/external/libplatform/src/os/lock.c @@ -0,0 +1,1124 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include "lock_internal.h" +#include "libkern/OSAtomic.h" +#include "os/lock.h" +#include "os/lock_private.h" +#include "os/once_private.h" +#include "resolver.h" + +#include +#include +#include +#include + +#pragma mark - +#pragma mark _os_lock_base_t + +#if !OS_VARIANT_ONLY + +OS_LOCK_STRUCT_DECL_INTERNAL(base); +OS_USED static OS_LOCK_TYPE_STRUCT_DECL(base); + +void +os_lock_lock(os_lock_t l) +{ + return l._osl_base->osl_type->osl_lock(l); +} + +bool +os_lock_trylock(os_lock_t l) +{ + return l._osl_base->osl_type->osl_trylock(l); +} + +void +os_lock_unlock(os_lock_t l) +{ + return l._osl_base->osl_type->osl_unlock(l); +} + +#endif //!OS_VARIANT_ONLY + +OS_NOINLINE OS_NORETURN OS_COLD +static void +_os_lock_corruption_abort(void *lock_ptr OS_UNUSED, uintptr_t lock_value) +{ + __LIBPLATFORM_CLIENT_CRASH__(lock_value, "os_lock is corrupt"); +} + +#pragma mark - +#pragma mark OSSpinLock + +#ifdef OS_LOCK_VARIANT_SELECTOR +void _OSSpinLockLockSlow(volatile OSSpinLock *l); +#else +OS_NOINLINE OS_USED static void _OSSpinLockLockSlow(volatile OSSpinLock *l); +#endif // OS_LOCK_VARIANT_SELECTOR + +OS_ATOMIC_EXPORT void OSSpinLockLock(volatile OSSpinLock *l); +OS_ATOMIC_EXPORT bool OSSpinLockTry(volatile OSSpinLock *l); +OS_ATOMIC_EXPORT int spin_lock_try(volatile OSSpinLock *l); +OS_ATOMIC_EXPORT void OSSpinLockUnlock(volatile OSSpinLock *l); + +#if OS_ATOMIC_UP +// Don't spin on UP +#elif OS_ATOMIC_WFE +#define OS_LOCK_SPIN_SPIN_TRIES 100 +#define OS_LOCK_SPIN_PAUSE() os_hardware_wfe() +#else +#define OS_LOCK_SPIN_SPIN_TRIES 1000 +#define OS_LOCK_SPIN_PAUSE() os_hardware_pause() +#endif +#define OS_LOCK_SPIN_YIELD_TRIES 100 + +static const OSSpinLock _OSSpinLockLocked = TARGET_OS_EMBEDDED ? 1 : -1; + +OS_NOINLINE +static void +_OSSpinLockLockYield(volatile OSSpinLock *l) +{ + int option = SWITCH_OPTION_DEPRESS; + mach_msg_timeout_t timeout = 1; + uint32_t tries = OS_LOCK_SPIN_YIELD_TRIES; + OSSpinLock lock; + while (unlikely(lock = *l)) { +_yield: + if (unlikely(lock != _OSSpinLockLocked)) { + _os_lock_corruption_abort((void *)l, (uintptr_t)lock); + } + // Yield until tries first hits zero, then permanently switch to wait + if (unlikely(!tries--)) option = SWITCH_OPTION_WAIT; + thread_switch(MACH_PORT_NULL, option, timeout); + } + bool r = os_atomic_cmpxchgv(l, 0, _OSSpinLockLocked, &lock, acquire); + if (likely(r)) return; + goto _yield; +} + +#if OS_ATOMIC_UP +void +_OSSpinLockLockSlow(volatile OSSpinLock *l) +{ + return _OSSpinLockLockYield(l); // Don't spin on UP +} +#else +void +_OSSpinLockLockSlow(volatile OSSpinLock *l) +{ + uint32_t tries = OS_LOCK_SPIN_SPIN_TRIES; + OSSpinLock lock; + while (unlikely(lock = *l)) { +_spin: + if (unlikely(lock != _OSSpinLockLocked)) { + return _os_lock_corruption_abort((void *)l, (uintptr_t)lock); + } + if (unlikely(!tries--)) return _OSSpinLockLockYield(l); + OS_LOCK_SPIN_PAUSE(); + } + bool r = os_atomic_cmpxchgv(l, 0, _OSSpinLockLocked, &lock, acquire); + if (likely(r)) return; + goto _spin; +} +#endif + +#ifdef OS_LOCK_VARIANT_SELECTOR +#undef _OSSpinLockLockSlow +extern void _OSSpinLockLockSlow(volatile OSSpinLock *l); +#endif + +#if !OS_LOCK_VARIANT_ONLY + +#if OS_LOCK_OSSPINLOCK_IS_NOSPINLOCK && !TARGET_OS_SIMULATOR + +typedef struct _os_nospin_lock_s *_os_nospin_lock_t; +void _os_nospin_lock_lock(_os_nospin_lock_t lock); +bool _os_nospin_lock_trylock(_os_nospin_lock_t lock); +void _os_nospin_lock_unlock(_os_nospin_lock_t lock); + +void +OSSpinLockLock(volatile OSSpinLock *l) +{ + OS_ATOMIC_ALIAS(spin_lock, OSSpinLockLock); + OS_ATOMIC_ALIAS(_spin_lock, OSSpinLockLock); + return _os_nospin_lock_lock((_os_nospin_lock_t)l); +} + +bool +OSSpinLockTry(volatile OSSpinLock *l) +{ + return _os_nospin_lock_trylock((_os_nospin_lock_t)l); +} + +int +spin_lock_try(volatile OSSpinLock *l) +{ + OS_ATOMIC_ALIAS(_spin_lock_try, spin_lock_try); + return _os_nospin_lock_trylock((_os_nospin_lock_t)l); +} + +void +OSSpinLockUnlock(volatile OSSpinLock *l) +{ + OS_ATOMIC_ALIAS(spin_unlock, OSSpinLockUnlock); + OS_ATOMIC_ALIAS(_spin_unlock, OSSpinLockUnlock); + return _os_nospin_lock_unlock((_os_nospin_lock_t)l); +} + +#undef OS_ATOMIC_ALIAS +#define OS_ATOMIC_ALIAS(n, o) +static void _OSSpinLockLock(volatile OSSpinLock *l); +#undef OSSpinLockLock +#define OSSpinLockLock _OSSpinLockLock +static bool _OSSpinLockTry(volatile OSSpinLock *l); +#undef OSSpinLockTry +#define OSSpinLockTry _OSSpinLockTry +static __unused int __spin_lock_try(volatile OSSpinLock *l); +#undef spin_lock_try +#define spin_lock_try __spin_lock_try +static void _OSSpinLockUnlock(volatile OSSpinLock *l); +#undef OSSpinLockUnlock +#define OSSpinLockUnlock _OSSpinLockUnlock + +#endif // OS_LOCK_OSSPINLOCK_IS_NOSPINLOCK + +void +OSSpinLockLock(volatile OSSpinLock *l) +{ + OS_ATOMIC_ALIAS(spin_lock, OSSpinLockLock); + OS_ATOMIC_ALIAS(_spin_lock, OSSpinLockLock); + bool r = os_atomic_cmpxchg(l, 0, _OSSpinLockLocked, acquire); + if (likely(r)) return; + return _OSSpinLockLockSlow(l); +} + +bool +OSSpinLockTry(volatile OSSpinLock *l) +{ + bool r = os_atomic_cmpxchg(l, 0, _OSSpinLockLocked, acquire); + return r; +} + +int +spin_lock_try(volatile OSSpinLock *l) // +{ + OS_ATOMIC_ALIAS(_spin_lock_try, spin_lock_try); + return OSSpinLockTry(l); +} + +void +OSSpinLockUnlock(volatile OSSpinLock *l) +{ + OS_ATOMIC_ALIAS(spin_unlock, OSSpinLockUnlock); + OS_ATOMIC_ALIAS(_spin_unlock, OSSpinLockUnlock); + os_atomic_store(l, 0, release); +} + +#pragma mark - +#pragma mark os_lock_spin_t + +OS_LOCK_STRUCT_DECL_INTERNAL(spin, + OSSpinLock volatile osl_spinlock; +); +#if !OS_VARIANT_ONLY +OS_LOCK_METHODS_DECL(spin); +OS_LOCK_TYPE_INSTANCE(spin); +#endif // !OS_VARIANT_ONLY + +#ifdef OS_VARIANT_SELECTOR +#define _os_lock_spin_lock \ + OS_VARIANT(_os_lock_spin_lock, OS_VARIANT_SELECTOR) +#define _os_lock_spin_trylock \ + OS_VARIANT(_os_lock_spin_trylock, OS_VARIANT_SELECTOR) +#define _os_lock_spin_unlock \ + OS_VARIANT(_os_lock_spin_unlock, OS_VARIANT_SELECTOR) +OS_LOCK_METHODS_DECL(spin); +#endif // OS_VARIANT_SELECTOR + +void +_os_lock_spin_lock(_os_lock_spin_t l) +{ + return OSSpinLockLock(&l->osl_spinlock); +} + +bool +_os_lock_spin_trylock(_os_lock_spin_t l) +{ + return OSSpinLockTry(&l->osl_spinlock); +} + +void +_os_lock_spin_unlock(_os_lock_spin_t l) +{ + return OSSpinLockUnlock(&l->osl_spinlock); +} + +#pragma mark - +#pragma mark os_lock_owner_t + +#ifndef __TSD_MACH_THREAD_SELF +#define __TSD_MACH_THREAD_SELF 3 +#endif + +typedef mach_port_name_t os_lock_owner_t; + +OS_ALWAYS_INLINE +static inline os_lock_owner_t +_os_lock_owner_get_self(void) +{ + os_lock_owner_t self; + self = (os_lock_owner_t)_os_tsd_get_direct(__TSD_MACH_THREAD_SELF); + return self; +} + +#define OS_LOCK_NO_OWNER MACH_PORT_NULL + +#if !OS_LOCK_VARIANT_ONLY + +OS_NOINLINE OS_NORETURN OS_COLD +static void +_os_lock_recursive_abort(os_lock_owner_t owner) +{ + __LIBPLATFORM_CLIENT_CRASH__(owner, "Trying to recursively lock an " + "os_lock"); +} + +#endif //!OS_LOCK_VARIANT_ONLY + +#pragma mark - +#pragma mark os_lock_handoff_t + +OS_LOCK_STRUCT_DECL_INTERNAL(handoff, + os_lock_owner_t volatile osl_owner; +); +#if !OS_VARIANT_ONLY +OS_LOCK_METHODS_DECL(handoff); +OS_LOCK_TYPE_INSTANCE(handoff); +#endif // !OS_VARIANT_ONLY + +#ifdef OS_VARIANT_SELECTOR +#define _os_lock_handoff_lock \ + OS_VARIANT(_os_lock_handoff_lock, OS_VARIANT_SELECTOR) +#define _os_lock_handoff_trylock \ + OS_VARIANT(_os_lock_handoff_trylock, OS_VARIANT_SELECTOR) +#define _os_lock_handoff_unlock \ + OS_VARIANT(_os_lock_handoff_unlock, OS_VARIANT_SELECTOR) +OS_LOCK_METHODS_DECL(handoff); +#endif // OS_VARIANT_SELECTOR + +#define OS_LOCK_HANDOFF_YIELD_TRIES 100 + +OS_NOINLINE +static void +_os_lock_handoff_lock_slow(_os_lock_handoff_t l) +{ + int option = SWITCH_OPTION_OSLOCK_DEPRESS; + mach_msg_timeout_t timeout = 1; + uint32_t tries = OS_LOCK_HANDOFF_YIELD_TRIES; + os_lock_owner_t self = _os_lock_owner_get_self(), owner; + while (unlikely(owner = l->osl_owner)) { +_handoff: + if (unlikely(owner == self)) return _os_lock_recursive_abort(self); + // Yield until tries first hits zero, then permanently switch to wait + if (unlikely(!tries--)) option = SWITCH_OPTION_OSLOCK_WAIT; + thread_switch(owner, option, timeout); + // Redrive the handoff every 1ms until switching to wait + if (option == SWITCH_OPTION_OSLOCK_WAIT) timeout++; + } + bool r = os_atomic_cmpxchgv2o(l, osl_owner, MACH_PORT_NULL, self, &owner, + acquire); + if (likely(r)) return; + goto _handoff; +} + +void +_os_lock_handoff_lock(_os_lock_handoff_t l) +{ + os_lock_owner_t self = _os_lock_owner_get_self(); + bool r = os_atomic_cmpxchg2o(l, osl_owner, MACH_PORT_NULL, self, acquire); + if (likely(r)) return; + return _os_lock_handoff_lock_slow(l); +} + +bool +_os_lock_handoff_trylock(_os_lock_handoff_t l) +{ + os_lock_owner_t self = _os_lock_owner_get_self(); + bool r = os_atomic_cmpxchg2o(l, osl_owner, MACH_PORT_NULL, self, acquire); + return r; +} + +void +_os_lock_handoff_unlock(_os_lock_handoff_t l) +{ + os_atomic_store2o(l, osl_owner, MACH_PORT_NULL, release); +} + +#pragma mark - +#pragma mark os_ulock_value_t + +#include +#include + +typedef os_lock_owner_t os_ulock_value_t; + +// This assumes that all thread mach port values always have the low bit set! +// Clearing this bit is used to communicate the existence of waiters to unlock. +#define OS_ULOCK_NOWAITERS_BIT ((os_ulock_value_t)1u) +#define OS_ULOCK_OWNER(value) ((value) | OS_ULOCK_NOWAITERS_BIT) + +#define OS_ULOCK_ANONYMOUS_OWNER MACH_PORT_DEAD +#define OS_ULOCK_IS_OWNER(value, self) ({ \ + os_lock_owner_t _owner = OS_ULOCK_OWNER(value); \ + (_owner == (self) && _owner != OS_ULOCK_ANONYMOUS_OWNER); }) +#define OS_ULOCK_IS_NOT_OWNER(value, self) ({ \ + os_lock_owner_t _owner = OS_ULOCK_OWNER(value); \ + (_owner != (self) && _owner != OS_ULOCK_ANONYMOUS_OWNER); }) + + +#pragma mark - +#pragma mark os_unfair_lock + +typedef struct _os_unfair_lock_s { + os_ulock_value_t oul_value; +} *_os_unfair_lock_t; + +_Static_assert(sizeof(struct os_unfair_lock_s) == + sizeof(struct _os_unfair_lock_s), "os_unfair_lock size mismatch"); + +OS_ATOMIC_EXPORT void os_unfair_lock_lock(os_unfair_lock_t lock); +OS_ATOMIC_EXPORT void os_unfair_lock_lock_with_options(os_unfair_lock_t lock, + os_unfair_lock_options_t options); +OS_ATOMIC_EXPORT bool os_unfair_lock_trylock(os_unfair_lock_t lock); +OS_ATOMIC_EXPORT void os_unfair_lock_unlock(os_unfair_lock_t lock); + +OS_ATOMIC_EXPORT void os_unfair_lock_lock_no_tsd_4libpthread( + os_unfair_lock_t lock); +OS_ATOMIC_EXPORT void os_unfair_lock_unlock_no_tsd_4libpthread( + os_unfair_lock_t lock); + +_Static_assert(OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION == + ULF_WAIT_WORKQ_DATA_CONTENTION, + "check value for OS_UNFAIR_LOCK_OPTIONS_MASK"); +#define OS_UNFAIR_LOCK_OPTIONS_MASK \ + (os_unfair_lock_options_t)(OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION) + +OS_NOINLINE OS_NORETURN OS_COLD +static void +_os_unfair_lock_recursive_abort(os_lock_owner_t owner) +{ + __LIBPLATFORM_CLIENT_CRASH__(owner, "Trying to recursively lock an " + "os_unfair_lock"); +} + +OS_NOINLINE OS_NORETURN OS_COLD +static void +_os_unfair_lock_unowned_abort(os_lock_owner_t owner) +{ + __LIBPLATFORM_CLIENT_CRASH__(owner, "Unlock of an os_unfair_lock not " + "owned by current thread"); +} + +OS_NOINLINE OS_NORETURN OS_COLD +static void +_os_unfair_lock_corruption_abort(os_ulock_value_t current) +{ + __LIBPLATFORM_CLIENT_CRASH__(current, "os_unfair_lock is corrupt"); +} + +OS_NOINLINE +static void +_os_unfair_lock_lock_slow(_os_unfair_lock_t l, os_lock_owner_t self, + os_unfair_lock_options_t options) +{ + os_ulock_value_t current, new, waiters_mask = 0; + if (unlikely(options & ~OS_UNFAIR_LOCK_OPTIONS_MASK)) { + __LIBPLATFORM_CLIENT_CRASH__(options, "Invalid options"); + } + while (unlikely((current = os_atomic_load2o(l, oul_value, relaxed)) != + OS_LOCK_NO_OWNER)) { +_retry: + if (unlikely(OS_ULOCK_IS_OWNER(current, self))) { + return _os_unfair_lock_recursive_abort(self); + } + new = current & ~OS_ULOCK_NOWAITERS_BIT; + if (current != new) { + // Clear nowaiters bit in lock value before waiting + if (!os_atomic_cmpxchgv2o(l, oul_value, current, new, ¤t, + relaxed)){ + continue; + } + current = new; + } + int ret = __ulock_wait(UL_UNFAIR_LOCK | ULF_NO_ERRNO | options, + l, current, 0); + if (unlikely(ret < 0)) { + switch (-ret) { + case EINTR: + case EFAULT: + continue; + case EOWNERDEAD: + _os_unfair_lock_corruption_abort(current); + break; + default: + __LIBPLATFORM_INTERNAL_CRASH__(-ret, "ulock_wait failure"); + } + } + // If there are more waiters, unset nowaiters bit when acquiring lock + waiters_mask = (ret > 0) ? OS_ULOCK_NOWAITERS_BIT : 0; + } + new = self & ~waiters_mask; + bool r = os_atomic_cmpxchgv2o(l, oul_value, OS_LOCK_NO_OWNER, new, + ¤t, acquire); + if (unlikely(!r)) goto _retry; +} + +OS_NOINLINE +static void +_os_unfair_lock_unlock_slow(_os_unfair_lock_t l, os_ulock_value_t current, + os_lock_owner_t self) +{ + if (unlikely(OS_ULOCK_IS_NOT_OWNER(current, self))) { + return _os_unfair_lock_unowned_abort(OS_ULOCK_OWNER(current)); + } + if (current & OS_ULOCK_NOWAITERS_BIT) { + __LIBPLATFORM_INTERNAL_CRASH__(current, "unlock_slow with no waiters"); + } + for (;;) { + int ret = __ulock_wake(UL_UNFAIR_LOCK | ULF_NO_ERRNO, l, 0); + if (unlikely(ret < 0)) { + switch (-ret) { + case EINTR: + continue; + case ENOENT: + break; + default: + __LIBPLATFORM_INTERNAL_CRASH__(-ret, "ulock_wake failure"); + } + } + break; + } +} + +void +os_unfair_lock_lock(os_unfair_lock_t lock) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = _os_lock_owner_get_self(); + bool r = os_atomic_cmpxchg2o(l, oul_value, OS_LOCK_NO_OWNER, self, acquire); + if (likely(r)) return; + return _os_unfair_lock_lock_slow(l, self, OS_UNFAIR_LOCK_NONE); +} + +void +os_unfair_lock_lock_with_options(os_unfair_lock_t lock, + os_unfair_lock_options_t options) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = _os_lock_owner_get_self(); + bool r = os_atomic_cmpxchg2o(l, oul_value, OS_LOCK_NO_OWNER, self, acquire); + if (likely(r)) return; + return _os_unfair_lock_lock_slow(l, self, options); +} + +bool +os_unfair_lock_trylock(os_unfair_lock_t lock) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = _os_lock_owner_get_self(); + bool r = os_atomic_cmpxchg2o(l, oul_value, OS_LOCK_NO_OWNER, self, acquire); + return r; +} + +void +os_unfair_lock_unlock(os_unfair_lock_t lock) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = _os_lock_owner_get_self(); + os_ulock_value_t current; + current = os_atomic_xchg2o(l, oul_value, OS_LOCK_NO_OWNER, release); + if (likely(current == self)) return; + return _os_unfair_lock_unlock_slow(l, current, self); +} + +void +os_unfair_lock_lock_no_tsd_4libpthread(os_unfair_lock_t lock) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = OS_ULOCK_ANONYMOUS_OWNER; + bool r = os_atomic_cmpxchg2o(l, oul_value, OS_LOCK_NO_OWNER, self, acquire); + if (likely(r)) return; + return _os_unfair_lock_lock_slow(l, self, + OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); +} + +void +os_unfair_lock_unlock_no_tsd_4libpthread(os_unfair_lock_t lock) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = OS_ULOCK_ANONYMOUS_OWNER; + os_ulock_value_t current; + current = os_atomic_xchg2o(l, oul_value, OS_LOCK_NO_OWNER, release); + if (likely(current == self)) return; + return _os_unfair_lock_unlock_slow(l, current, self); +} + +#pragma mark - +#pragma mark _os_lock_unfair_t 4Libc // + +OS_ATOMIC_EXPORT void os_unfair_lock_lock_with_options_4Libc( + os_unfair_lock_t lock, os_unfair_lock_options_t options); +OS_ATOMIC_EXPORT void os_unfair_lock_unlock_4Libc(os_unfair_lock_t lock); + +OS_NOINLINE +static void +_os_unfair_lock_lock_slow_4Libc(_os_unfair_lock_t l, os_lock_owner_t self, + os_unfair_lock_options_t options) +{ + os_ulock_value_t current, new, waiters_mask = 0; + if (unlikely(options & ~OS_UNFAIR_LOCK_OPTIONS_MASK)) { + __LIBPLATFORM_CLIENT_CRASH__(options, "Invalid options"); + } + while (unlikely((current = os_atomic_load2o(l, oul_value, relaxed)) != + OS_LOCK_NO_OWNER)) { +_retry: + if (unlikely(OS_ULOCK_IS_OWNER(current, self))) { + return _os_unfair_lock_recursive_abort(self); + } + new = current & ~OS_ULOCK_NOWAITERS_BIT; + if (current != new) { + // Clear nowaiters bit in lock value before waiting + if (!os_atomic_cmpxchgv2o(l, oul_value, current, new, ¤t, + relaxed)){ + continue; + } + current = new; + } + int ret = __ulock_wait(UL_UNFAIR_LOCK | ULF_NO_ERRNO | options, + l, current, 0); + if (unlikely(ret < 0)) { + switch (-ret) { + case EINTR: + case EFAULT: + continue; + case EOWNERDEAD: + // if we get an `EOWNERDEAD` it could be corruption of the lock + // so for the Libc locks, if we can steal the lock, assume + // it is corruption and pretend we got the lock with contention + new = self & ~OS_ULOCK_NOWAITERS_BIT; + if (os_atomic_cmpxchgv2o(l, oul_value, current, new, ¤t, + acquire)) { + return; + } + break; + default: + __LIBPLATFORM_INTERNAL_CRASH__(-ret, "ulock_wait failure"); + } + } + // If there are more waiters, unset nowaiters bit when acquiring lock + waiters_mask = (ret > 0) ? OS_ULOCK_NOWAITERS_BIT : 0; + } + new = self & ~waiters_mask; + bool r = os_atomic_cmpxchgv2o(l, oul_value, OS_LOCK_NO_OWNER, new, + ¤t, acquire); + if (unlikely(!r)) goto _retry; +} + +OS_NOINLINE +static void +_os_unfair_lock_unlock_slow_4Libc(_os_unfair_lock_t l) +{ + for (;;) { + int ret = __ulock_wake(UL_UNFAIR_LOCK | ULF_NO_ERRNO, l, 0); + if (unlikely(ret < 0)) { + switch (-ret) { + case EINTR: + continue; + case ENOENT: + break; + default: + __LIBPLATFORM_INTERNAL_CRASH__(-ret, "ulock_wake failure"); + } + } + break; + } +} + +void +os_unfair_lock_lock_with_options_4Libc(os_unfair_lock_t lock, + os_unfair_lock_options_t options) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = _os_lock_owner_get_self(); + bool r = os_atomic_cmpxchg2o(l, oul_value, OS_LOCK_NO_OWNER, self, acquire); + if (likely(r)) return; + return _os_unfair_lock_lock_slow_4Libc(l, self, options); +} + +void +os_unfair_lock_unlock_4Libc(os_unfair_lock_t lock) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = _os_lock_owner_get_self(); + os_ulock_value_t current; + current = os_atomic_xchg2o(l, oul_value, OS_LOCK_NO_OWNER, release); + if (likely(current == self)) return; + return _os_unfair_lock_unlock_slow_4Libc(l); +} + +#if !OS_VARIANT_ONLY +void +os_unfair_lock_assert_owner(os_unfair_lock_t lock) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = _os_lock_owner_get_self(); + os_ulock_value_t current = os_atomic_load2o(l, oul_value, relaxed); + if (unlikely(OS_ULOCK_IS_NOT_OWNER(current, self))) { + __LIBPLATFORM_CLIENT_CRASH__(current, "Assertion failed: " + "Lock unexpectedly not owned by current thread"); + } +} + +void +os_unfair_lock_assert_not_owner(os_unfair_lock_t lock) +{ + _os_unfair_lock_t l = (_os_unfair_lock_t)lock; + os_lock_owner_t self = _os_lock_owner_get_self(); + os_ulock_value_t current = os_atomic_load2o(l, oul_value, relaxed); + if (unlikely(OS_ULOCK_IS_OWNER(current, self))) { + __LIBPLATFORM_CLIENT_CRASH__(current, "Assertion failed: " + "Lock unexpectedly owned by current thread"); + } +} +#endif + +#pragma mark - +#pragma mark _os_lock_unfair_t + +OS_LOCK_STRUCT_DECL_INTERNAL(unfair, + os_unfair_lock osl_unfair_lock; +); +#if !OS_VARIANT_ONLY +OS_LOCK_METHODS_DECL(unfair); +OS_LOCK_TYPE_INSTANCE(unfair); +#endif // !OS_VARIANT_ONLY + +#ifdef OS_VARIANT_SELECTOR +#define _os_lock_unfair_lock \ + OS_VARIANT(_os_lock_unfair_lock, OS_VARIANT_SELECTOR) +#define _os_lock_unfair_trylock \ + OS_VARIANT(_os_lock_unfair_trylock, OS_VARIANT_SELECTOR) +#define _os_lock_unfair_unlock \ + OS_VARIANT(_os_lock_unfair_unlock, OS_VARIANT_SELECTOR) +OS_LOCK_METHODS_DECL(unfair); +#endif // OS_VARIANT_SELECTOR + +void +_os_lock_unfair_lock(_os_lock_unfair_t l) +{ + return os_unfair_lock_lock(&l->osl_unfair_lock); +} + +bool +_os_lock_unfair_trylock(_os_lock_unfair_t l) +{ + return os_unfair_lock_trylock(&l->osl_unfair_lock); +} + +void +_os_lock_unfair_unlock(_os_lock_unfair_t l) +{ + return os_unfair_lock_unlock(&l->osl_unfair_lock); +} + +#pragma mark - +#pragma mark _os_nospin_lock + +typedef struct _os_nospin_lock_s { + os_ulock_value_t oul_value; +} _os_nospin_lock, *_os_nospin_lock_t; + +_Static_assert(sizeof(OSSpinLock) == + sizeof(struct _os_nospin_lock_s), "os_nospin_lock size mismatch"); + +OS_ATOMIC_EXPORT void _os_nospin_lock_lock(_os_nospin_lock_t lock); +OS_ATOMIC_EXPORT bool _os_nospin_lock_trylock(_os_nospin_lock_t lock); +OS_ATOMIC_EXPORT void _os_nospin_lock_unlock(_os_nospin_lock_t lock); + +OS_NOINLINE +static void +_os_nospin_lock_lock_slow(_os_nospin_lock_t l) +{ + os_lock_owner_t self = _os_lock_owner_get_self(); + os_ulock_value_t current, new, waiters_mask = 0; + uint32_t timeout = 1; + while (unlikely((current = os_atomic_load2o(l, oul_value, relaxed)) != + OS_LOCK_NO_OWNER)) { +_retry: + new = current & ~OS_ULOCK_NOWAITERS_BIT; + // For safer compatibility with OSSpinLock where _OSSpinLockLocked may + // be 1, check that new didn't become 0 (unlocked) by clearing this bit + if (current != new && new) { + // Clear nowaiters bit in lock value before waiting + if (!os_atomic_cmpxchgv2o(l, oul_value, current, new, ¤t, + relaxed)){ + continue; + } + current = new; + } + int ret = __ulock_wait(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, l, current, + timeout * 1000); + if (unlikely(ret < 0)) { + switch (-ret) { + case ETIMEDOUT: + timeout++; + continue; + case EINTR: + case EFAULT: + continue; + default: + __LIBPLATFORM_INTERNAL_CRASH__(-ret, "ulock_wait failure"); + } + } + // If there are more waiters, unset nowaiters bit when acquiring lock + waiters_mask = (ret > 0) ? OS_ULOCK_NOWAITERS_BIT : 0; + } + new = self & ~waiters_mask; + bool r = os_atomic_cmpxchgv2o(l, oul_value, OS_LOCK_NO_OWNER, new, + ¤t, acquire); + if (unlikely(!r)) goto _retry; +} + +OS_NOINLINE +static void +_os_nospin_lock_unlock_slow(_os_nospin_lock_t l, os_ulock_value_t current) +{ + os_lock_owner_t self = _os_lock_owner_get_self(); + if (unlikely(OS_ULOCK_OWNER(current) != self)) { + return; // no unowned_abort for drop-in compatibility with OSSpinLock + } + if (current & OS_ULOCK_NOWAITERS_BIT) { + __LIBPLATFORM_INTERNAL_CRASH__(current, "unlock_slow with no waiters"); + } + for (;;) { + int ret = __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, l, 0); + if (unlikely(ret < 0)) { + switch (-ret) { + case EINTR: + continue; + case ENOENT: + break; + default: + __LIBPLATFORM_INTERNAL_CRASH__(-ret, "ulock_wake failure"); + } + } + break; + } +} + +void +_os_nospin_lock_lock(_os_nospin_lock_t l) +{ + os_lock_owner_t self = _os_lock_owner_get_self(); + bool r = os_atomic_cmpxchg2o(l, oul_value, OS_LOCK_NO_OWNER, self, acquire); + if (likely(r)) return; + return _os_nospin_lock_lock_slow(l); +} + +bool +_os_nospin_lock_trylock(_os_nospin_lock_t l) +{ + os_lock_owner_t self = _os_lock_owner_get_self(); + bool r = os_atomic_cmpxchg2o(l, oul_value, OS_LOCK_NO_OWNER, self, acquire); + return r; +} + +void +_os_nospin_lock_unlock(_os_nospin_lock_t l) +{ + os_lock_owner_t self = _os_lock_owner_get_self(); + os_ulock_value_t current; + current = os_atomic_xchg2o(l, oul_value, OS_LOCK_NO_OWNER, release); + if (likely(current == self)) return; + return _os_nospin_lock_unlock_slow(l, current); +} + +#pragma mark - +#pragma mark _os_lock_nospin_t + +OS_LOCK_STRUCT_DECL_INTERNAL(nospin, + _os_nospin_lock osl_nospin_lock; +); +#if !OS_VARIANT_ONLY +OS_LOCK_METHODS_DECL(nospin); +OS_LOCK_TYPE_INSTANCE(nospin); +#endif // !OS_VARIANT_ONLY + +#ifdef OS_VARIANT_SELECTOR +#define _os_lock_nospin_lock \ + OS_VARIANT(_os_lock_nospin_lock, OS_VARIANT_SELECTOR) +#define _os_lock_nospin_trylock \ + OS_VARIANT(_os_lock_nospin_trylock, OS_VARIANT_SELECTOR) +#define _os_lock_nospin_unlock \ + OS_VARIANT(_os_lock_nospin_unlock, OS_VARIANT_SELECTOR) +OS_LOCK_METHODS_DECL(nospin); +#endif // OS_VARIANT_SELECTOR + +void +_os_lock_nospin_lock(_os_lock_nospin_t l) +{ + return _os_nospin_lock_lock(&l->osl_nospin_lock); +} + +bool +_os_lock_nospin_trylock(_os_lock_nospin_t l) +{ + return _os_nospin_lock_trylock(&l->osl_nospin_lock); +} + +void +_os_lock_nospin_unlock(_os_lock_nospin_t l) +{ + return _os_nospin_lock_unlock(&l->osl_nospin_lock); +} + +#pragma mark - +#pragma mark os_once_t + +typedef struct os_once_gate_s { + union { + os_ulock_value_t ogo_lock; + os_once_t ogo_once; + }; +} os_once_gate_s, *os_once_gate_t; + +#define OS_ONCE_INIT ((os_once_t)0l) +#define OS_ONCE_DONE (~(os_once_t)0l) + +OS_ATOMIC_EXPORT void _os_once(os_once_t *val, void *ctxt, os_function_t func); +OS_ATOMIC_EXPORT void __os_once_reset(os_once_t *val); + +OS_NOINLINE OS_NORETURN OS_COLD +static void +_os_once_gate_recursive_abort(os_lock_owner_t owner) +{ + __LIBPLATFORM_CLIENT_CRASH__(owner, "Trying to recursively lock an " + "os_once_t"); +} + +OS_NOINLINE OS_NORETURN OS_COLD +static void +_os_once_gate_unowned_abort(os_lock_owner_t owner) +{ + __LIBPLATFORM_CLIENT_CRASH__(owner, "Unlock of an os_once_t not " + "owned by current thread"); +} + +OS_NOINLINE OS_NORETURN OS_COLD +static void +_os_once_gate_corruption_abort(os_ulock_value_t current) +{ + __LIBPLATFORM_CLIENT_CRASH__(current, "os_once_t is corrupt"); +} + +OS_NOINLINE +static void +_os_once_gate_wait_slow(os_ulock_value_t *gate, os_lock_owner_t self) +{ + os_ulock_value_t tid_old, tid_new; + + for (;;) { + os_atomic_rmw_loop(gate, tid_old, tid_new, relaxed, { + switch (tid_old) { + case (os_ulock_value_t)OS_ONCE_INIT: // raced with __os_once_reset() + case (os_ulock_value_t)OS_ONCE_DONE: // raced with _os_once() + os_atomic_rmw_loop_give_up(return); + } + tid_new = tid_old & ~OS_ULOCK_NOWAITERS_BIT; + if (tid_new == tid_old) os_atomic_rmw_loop_give_up(break); + }); + if (unlikely(OS_ULOCK_IS_OWNER(tid_old, self))) { + return _os_once_gate_recursive_abort(self); + } + int ret = __ulock_wait(UL_UNFAIR_LOCK | ULF_NO_ERRNO, + gate, tid_new, 0); + if (unlikely(ret < 0)) { + switch (-ret) { + case EINTR: + case EFAULT: + continue; + case EOWNERDEAD: + _os_once_gate_corruption_abort(tid_old); + break; + default: + __LIBPLATFORM_INTERNAL_CRASH__(-ret, "ulock_wait failure"); + } + } + } +} + +OS_NOINLINE +static void +_os_once_gate_broadcast_slow(os_ulock_value_t *gate, os_ulock_value_t current, + os_lock_owner_t self) +{ + if (unlikely(OS_ULOCK_IS_NOT_OWNER(current, self))) { + return _os_once_gate_unowned_abort(OS_ULOCK_OWNER(current)); + } + if (current & OS_ULOCK_NOWAITERS_BIT) { + __LIBPLATFORM_INTERNAL_CRASH__(current, "unlock_slow with no waiters"); + } + for (;;) { + int ret = __ulock_wake(UL_UNFAIR_LOCK | ULF_NO_ERRNO | ULF_WAKE_ALL, + gate, 0); + if (unlikely(ret < 0)) { + switch (-ret) { + case EINTR: + continue; + case ENOENT: + break; + default: + __LIBPLATFORM_INTERNAL_CRASH__(-ret, "ulock_wake failure"); + } + } + break; + } +} + +OS_ALWAYS_INLINE +static void +_os_once_gate_set_value_and_broadcast(os_once_gate_t og, os_lock_owner_t self, + os_once_t value) +{ + // The next barrier must be long and strong. + // + // The scenario: SMP systems with weakly ordered memory models + // and aggressive out-of-order instruction execution. + // + // The problem: + // + // The os_once*() wrapper macro causes the callee's + // instruction stream to look like this (pseudo-RISC): + // + // load r5, pred-addr + // cmpi r5, -1 + // beq 1f + // call os_once*() + // 1f: + // load r6, data-addr + // + // May be re-ordered like so: + // + // load r6, data-addr + // load r5, pred-addr + // cmpi r5, -1 + // beq 1f + // call os_once*() + // 1f: + // + // Normally, a barrier on the read side is used to workaround + // the weakly ordered memory model. But barriers are expensive + // and we only need to synchronize once! After func(ctxt) + // completes, the predicate will be marked as "done" and the + // branch predictor will correctly skip the call to + // os_once*(). + // + // A far faster alternative solution: Defeat the speculative + // read-ahead of peer CPUs. + // + // Modern architectures will throw away speculative results + // once a branch mis-prediction occurs. Therefore, if we can + // ensure that the predicate is not marked as being complete + // until long after the last store by func(ctxt), then we have + // defeated the read-ahead of peer CPUs. + // + // In other words, the last "store" by func(ctxt) must complete + // and then N cycles must elapse before ~0l is stored to *val. + // The value of N is whatever is sufficient to defeat the + // read-ahead mechanism of peer CPUs. + // + // On some CPUs, the most fully synchronizing instruction might + // need to be issued. + os_atomic_maximally_synchronizing_barrier(); + + // above assumed to contain release barrier + os_ulock_value_t current = + (os_ulock_value_t)os_atomic_xchg(&og->ogo_once, value, relaxed); + if (likely(current == self)) return; + _os_once_gate_broadcast_slow(&og->ogo_lock, current, self); +} + +// Atomically resets the once value to zero and then signals all +// pending waiters to return from their _os_once_gate_wait_slow() +void +__os_once_reset(os_once_t *val) +{ + os_once_gate_t og = (os_once_gate_t)val; + os_lock_owner_t self = _os_lock_owner_get_self(); + _os_once_gate_set_value_and_broadcast(og, self, OS_ONCE_INIT); +} + +void +_os_once(os_once_t *val, void *ctxt, os_function_t func) +{ + os_once_gate_t og = (os_once_gate_t)val; + os_lock_owner_t self = _os_lock_owner_get_self(); + os_once_t v = (os_once_t)self; + + if (likely(os_atomic_cmpxchg(&og->ogo_once, OS_ONCE_INIT, v, relaxed))) { + func(ctxt); + _os_once_gate_set_value_and_broadcast(og, self, OS_ONCE_DONE); + } else { + _os_once_gate_wait_slow(&og->ogo_lock, self); + } +} + +#if !OS_VARIANT_ONLY + +#pragma mark - +#pragma mark os_lock_eliding_t + +#if !TARGET_OS_IPHONE + +#define _os_lock_eliding_t _os_lock_spin_t +#define _os_lock_eliding_lock _os_lock_spin_lock +#define _os_lock_eliding_trylock _os_lock_spin_trylock +#define _os_lock_eliding_unlock _os_lock_spin_unlock +OS_LOCK_METHODS_DECL(eliding); +OS_LOCK_TYPE_INSTANCE(eliding); + +#pragma mark - +#pragma mark os_lock_transactional_t + +OS_LOCK_STRUCT_DECL_INTERNAL(transactional, + uintptr_t volatile osl_lock; +); + +#define _os_lock_transactional_t _os_lock_eliding_t +#define _os_lock_transactional_lock _os_lock_eliding_lock +#define _os_lock_transactional_trylock _os_lock_eliding_trylock +#define _os_lock_transactional_unlock _os_lock_eliding_unlock +OS_LOCK_METHODS_DECL(transactional); +OS_LOCK_TYPE_INSTANCE(transactional); + +#endif // !TARGET_OS_IPHONE +#endif // !OS_VARIANT_ONLY +#endif // !OS_LOCK_VARIANT_ONLY diff --git a/src/external/libplatform/src/os/lock_internal.h b/src/external/libplatform/src/os/lock_internal.h new file mode 100644 index 000000000..af6a86298 --- /dev/null +++ b/src/external/libplatform/src/os/lock_internal.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_LOCK_INTERNAL__ +#define __OS_LOCK_INTERNAL__ + +#define OS_LOCK_S_INTERNAL(type) _os_lock_##type##_s +#define OS_LOCK_T_INTERNAL(type) _os_lock_##type##_t +#define OS_LOCK_STRUCT_INTERNAL(type) struct OS_LOCK_S_INTERNAL(type) +#define OS_LOCK_T_MEMBER(type) \ + OS_LOCK_STRUCT(type) *_osl_opaque_##type; \ + OS_LOCK_STRUCT_INTERNAL(type) *_osl_##type + +#define OS_LOCK_STRUCT_DECL_INTERNAL(type, ...) \ + typedef struct OS_LOCK_S_INTERNAL(type) { \ + OS_LOCK_TYPE_STRUCT(type) * const osl_type; \ + __VA_ARGS__ \ + } OS_LOCK_S_INTERNAL(type); \ + typedef OS_LOCK_STRUCT_INTERNAL(type) *OS_LOCK_T_INTERNAL(type) + +#define OS_LOCK_METHODS_DECL(type) \ + void _os_lock_##type##_lock(OS_LOCK_T_INTERNAL(type)); \ + bool _os_lock_##type##_trylock(OS_LOCK_T_INTERNAL(type)); \ + void _os_lock_##type##_unlock(OS_LOCK_T_INTERNAL(type)) + +#define OS_LOCK_TYPE_STRUCT_DECL(type) \ + OS_LOCK_TYPE_STRUCT(type) { \ + const char *osl_kind; \ + void (*osl_lock)(os_lock_t); \ + bool (*osl_trylock)(os_lock_t); \ + void (*osl_unlock)(os_lock_t); \ + } OS_LOCK_TYPE_REF(type) + +#define OS_LOCK_TYPE_INSTANCE(type) \ + OS_LOCK_TYPE_STRUCT_DECL(type) = { \ + .osl_kind = #type, \ + .osl_lock = _os_lock_##type##_lock, \ + .osl_trylock = _os_lock_##type##_trylock, \ + .osl_unlock = _os_lock_##type##_unlock, \ + } + +#include "os/internal.h" + +#endif // __OS_LOCK_INTERNAL__ diff --git a/src/external/libplatform/src/os/lock_up.c b/src/external/libplatform/src/os/lock_up.c new file mode 100644 index 000000000..e03a22d5d --- /dev/null +++ b/src/external/libplatform/src/os/lock_up.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#define OS_ATOMIC_UP 1 +#include "lock_internal.h" + +#ifdef OS_VARIANT_SELECTOR +#define OS_VARIANT_ONLY 1 +#include "lock.c" +#endif + +struct _os_empty_files_are_not_c_files; diff --git a/src/external/libplatform/src/os/lock_wfe.c b/src/external/libplatform/src/os/lock_wfe.c new file mode 100644 index 000000000..36dd1905c --- /dev/null +++ b/src/external/libplatform/src/os/lock_wfe.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include + +#if TARGET_OS_EMBEDDED + +#define OS_ATOMIC_WFE 1 +#include "lock_internal.h" + +#ifdef OS_LOCK_VARIANT_SELECTOR +#define OS_VARIANT_ONLY 1 +#define OS_LOCK_VARIANT_ONLY 1 +#include "lock.c" +#endif + +#endif // TARGET_OS_EMBEDDED + +struct _os_empty_files_are_not_c_files; diff --git a/src/external/libplatform/src/os/resolver.c b/src/external/libplatform/src/os/resolver.c new file mode 100644 index 000000000..2fa6b0a5c --- /dev/null +++ b/src/external/libplatform/src/os/resolver.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include "lock_internal.h" + +#ifdef OS_VARIANT_SELECTOR + +#if TARGET_OS_EMBEDDED +OS_VARIANT_UPMP_RESOLVER(OSAtomicAdd32Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicIncrement32Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicDecrement32Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicAdd64Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicIncrement64Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicDecrement64Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicAnd32Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicAnd32OrigBarrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicOr32Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicOr32OrigBarrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicXor32Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicXor32OrigBarrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicCompareAndSwap32Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicCompareAndSwap64Barrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicCompareAndSwapIntBarrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicCompareAndSwapLongBarrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicCompareAndSwapPtrBarrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicTestAndSetBarrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicTestAndClearBarrier) +OS_VARIANT_UPMP_RESOLVER(OSAtomicEnqueue) +OS_VARIANT_UPMP_RESOLVER(OSAtomicDequeue) +OS_VARIANT_UPMP_RESOLVER(OSMemoryBarrier) + +OS_VARIANT_UPMP_RESOLVER(OSSpinLockLock) +OS_VARIANT_UPMP_RESOLVER(OSSpinLockTry) +OS_VARIANT_UPMP_RESOLVER(OSSpinLockUnlock) +OS_VARIANT_UPMP_RESOLVER(spin_lock) +OS_VARIANT_UPMP_RESOLVER(spin_lock_try) +OS_VARIANT_UPMP_RESOLVER(spin_unlock) +OS_VARIANT_UPMP_RESOLVER(_spin_lock) +OS_VARIANT_UPMP_RESOLVER(_spin_lock_try) +OS_VARIANT_UPMP_RESOLVER(_spin_unlock) + +OS_VARIANT_UPMP_RESOLVER(os_unfair_lock_lock) +OS_VARIANT_UPMP_RESOLVER(os_unfair_lock_lock_with_options) +OS_VARIANT_UPMP_RESOLVER(os_unfair_lock_trylock) +OS_VARIANT_UPMP_RESOLVER(os_unfair_lock_unlock) +OS_VARIANT_UPMP_RESOLVER(os_unfair_lock_lock_no_tsd_4libpthread) +OS_VARIANT_UPMP_RESOLVER(os_unfair_lock_unlock_no_tsd_4libpthread) +OS_VARIANT_UPMP_RESOLVER(os_unfair_lock_lock_with_options_4Libc) +OS_VARIANT_UPMP_RESOLVER(os_unfair_lock_unlock_4Libc) +OS_VARIANT_UPMP_RESOLVER(_os_nospin_lock_lock) +OS_VARIANT_UPMP_RESOLVER(_os_nospin_lock_trylock) +OS_VARIANT_UPMP_RESOLVER(_os_nospin_lock_unlock) + +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_spin_lock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_spin_trylock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_spin_unlock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_handoff_lock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_handoff_trylock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_handoff_unlock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_unfair_lock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_unfair_trylock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_unfair_unlock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_nospin_lock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_nospin_trylock) +OS_VARIANT_UPMP_RESOLVER_INTERNAL(_os_lock_nospin_unlock) + +OS_VARIANT_UPMP_RESOLVER(_os_once) +OS_VARIANT_UPMP_RESOLVER(__os_once_reset) +#endif // TARGET_OS_EMBEDDED + +#endif // OS_VARIANT_SELECTOR + +#ifdef OS_LOCK_VARIANT_SELECTOR + +#define WFE_RESOLVER(s) \ + _OS_VARIANT_RESOLVER(s, hidden, \ + uint32_t *_c = (void*)(uintptr_t)_COMM_PAGE_CPU_CAPABILITIES; \ + if (*_c & kHasEvent) { \ + extern void OS_VARIANT(s, wfe)(void); \ + return &OS_VARIANT(s, wfe); \ + } else { \ + extern void OS_VARIANT(s, mp)(void); \ + return &OS_VARIANT(s, mp); \ + }) + +WFE_RESOLVER(_OSSpinLockLockSlow) + +#endif // OS_LOCK_VARIANT_SELECTOR + diff --git a/src/external/libplatform/src/os/resolver.h b/src/external/libplatform/src/os/resolver.h new file mode 100644 index 000000000..345a6b638 --- /dev/null +++ b/src/external/libplatform/src/os/resolver.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#ifndef __OS_RESOLVER_H__ +#define __OS_RESOLVER_H__ + +#include + +#ifdef OS_VARIANT_SELECTOR + +#if TARGET_OS_EMBEDDED +#define OSAtomicAdd32Barrier \ + OS_VARIANT(OSAtomicAdd32Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicIncrement32Barrier \ + OS_VARIANT(OSAtomicIncrement32Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicDecrement32Barrier \ + OS_VARIANT(OSAtomicDecrement32Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicAdd64Barrier \ + OS_VARIANT(OSAtomicAdd64Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicIncrement64Barrier \ + OS_VARIANT(OSAtomicIncrement64Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicDecrement64Barrier \ + OS_VARIANT(OSAtomicDecrement64Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicAnd32Barrier \ + OS_VARIANT(OSAtomicAnd32Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicAnd32OrigBarrier \ + OS_VARIANT(OSAtomicAnd32OrigBarrier, OS_VARIANT_SELECTOR) +#define OSAtomicOr32Barrier \ + OS_VARIANT(OSAtomicOr32Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicOr32OrigBarrier \ + OS_VARIANT(OSAtomicOr32OrigBarrier, OS_VARIANT_SELECTOR) +#define OSAtomicXor32Barrier \ + OS_VARIANT(OSAtomicXor32Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicXor32OrigBarrier \ + OS_VARIANT(OSAtomicXor32OrigBarrier, OS_VARIANT_SELECTOR) +#define OSAtomicCompareAndSwap32Barrier \ + OS_VARIANT(OSAtomicCompareAndSwap32Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicCompareAndSwap64Barrier \ + OS_VARIANT(OSAtomicCompareAndSwap64Barrier, OS_VARIANT_SELECTOR) +#define OSAtomicCompareAndSwapIntBarrier \ + OS_VARIANT(OSAtomicCompareAndSwapIntBarrier, OS_VARIANT_SELECTOR) +#define OSAtomicCompareAndSwapLongBarrier \ + OS_VARIANT(OSAtomicCompareAndSwapLongBarrier, OS_VARIANT_SELECTOR) +#define OSAtomicCompareAndSwapPtrBarrier \ + OS_VARIANT(OSAtomicCompareAndSwapPtrBarrier, OS_VARIANT_SELECTOR) +#define OSAtomicTestAndSetBarrier \ + OS_VARIANT(OSAtomicTestAndSetBarrier, OS_VARIANT_SELECTOR) +#define OSAtomicTestAndClearBarrier \ + OS_VARIANT(OSAtomicTestAndClearBarrier, OS_VARIANT_SELECTOR) +#define OSAtomicEnqueue \ + OS_VARIANT(OSAtomicEnqueue, OS_VARIANT_SELECTOR) +#define OSAtomicDequeue \ + OS_VARIANT(OSAtomicDequeue, OS_VARIANT_SELECTOR) +#define OSMemoryBarrier \ + OS_VARIANT(OSMemoryBarrier, OS_VARIANT_SELECTOR) + +#define OSSpinLockLock \ + OS_VARIANT(OSSpinLockLock, OS_VARIANT_SELECTOR) +#define OSSpinLockTry \ + OS_VARIANT(OSSpinLockTry, OS_VARIANT_SELECTOR) +#define OSSpinLockUnlock \ + OS_VARIANT(OSSpinLockUnlock, OS_VARIANT_SELECTOR) +#define spin_lock \ + OS_VARIANT(spin_lock, OS_VARIANT_SELECTOR) +#define spin_lock_try \ + OS_VARIANT(spin_lock_try, OS_VARIANT_SELECTOR) +#define spin_unlock \ + OS_VARIANT(spin_unlock, OS_VARIANT_SELECTOR) +#define _spin_lock \ + OS_VARIANT(_spin_lock, OS_VARIANT_SELECTOR) +#define _spin_lock_try \ + OS_VARIANT(_spin_lock_try, OS_VARIANT_SELECTOR) +#define _spin_unlock \ + OS_VARIANT(_spin_unlock, OS_VARIANT_SELECTOR) +#define os_unfair_lock_lock \ + OS_VARIANT(os_unfair_lock_lock, OS_VARIANT_SELECTOR) +#define os_unfair_lock_lock_with_options \ + OS_VARIANT(os_unfair_lock_lock_with_options, OS_VARIANT_SELECTOR) +#define os_unfair_lock_trylock \ + OS_VARIANT(os_unfair_lock_trylock, OS_VARIANT_SELECTOR) +#define os_unfair_lock_unlock \ + OS_VARIANT(os_unfair_lock_unlock, OS_VARIANT_SELECTOR) +#define os_unfair_lock_lock_no_tsd_4libpthread \ + OS_VARIANT(os_unfair_lock_lock_no_tsd_4libpthread, OS_VARIANT_SELECTOR) +#define os_unfair_lock_unlock_no_tsd_4libpthread \ + OS_VARIANT(os_unfair_lock_unlock_no_tsd_4libpthread, OS_VARIANT_SELECTOR) +#define os_unfair_lock_lock_with_options_4Libc \ + OS_VARIANT(os_unfair_lock_lock_with_options_4Libc, OS_VARIANT_SELECTOR) +#define os_unfair_lock_unlock_4Libc \ + OS_VARIANT(os_unfair_lock_unlock_4Libc, OS_VARIANT_SELECTOR) +#define _os_nospin_lock_lock \ + OS_VARIANT(_os_nospin_lock_lock, OS_VARIANT_SELECTOR) +#define _os_nospin_lock_trylock \ + OS_VARIANT(_os_nospin_lock_trylock, OS_VARIANT_SELECTOR) +#define _os_nospin_lock_unlock \ + OS_VARIANT(_os_nospin_lock_unlock, OS_VARIANT_SELECTOR) +#define _os_once \ + OS_VARIANT(_os_once, OS_VARIANT_SELECTOR) +#define __os_once_reset \ + OS_VARIANT(__os_once_reset, OS_VARIANT_SELECTOR) +#endif // TARGET_OS_EMBEDDED +#endif // OS_VARIANT_SELECTOR + +#ifdef OS_LOCK_VARIANT_SELECTOR +#define _OSSpinLockLockSlow \ + OS_VARIANT(_OSSpinLockLockSlow, OS_LOCK_VARIANT_SELECTOR) +#endif // OS_LOCK_VARIANT_SELECTOR + +#endif // __OS_RESOLVER_H__ diff --git a/src/external/libplatform/src/os/semaphore.c b/src/external/libplatform/src/os/semaphore.c new file mode 100644 index 000000000..d805afc5e --- /dev/null +++ b/src/external/libplatform/src/os/semaphore.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008-2013 Apple Inc. All rights reserved. + * + * @APPLE_APACHE_LICENSE_HEADER_START@ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @APPLE_APACHE_LICENSE_HEADER_END@ + */ + +#include "os/internal.h" +#include +#include +#include +#include + +#define OS_VERIFY_MIG(x, msg) do { \ + if (unlikely((x) == MIG_REPLY_MISMATCH)) { \ + __LIBPLATFORM_CLIENT_CRASH__(x, msg); \ + } \ + } while (0) + +#define OS_SEMAPHORE_VERIFY_KR(x, msg) do { \ + if (unlikely(x)) { \ + __LIBPLATFORM_CLIENT_CRASH__(x, msg); \ + } \ + } while (0) + +os_semaphore_t +_os_semaphore_create(void) +{ + semaphore_t s4; + kern_return_t kr; + while (unlikely(kr = semaphore_create(mach_task_self(), &s4, + SYNC_POLICY_FIFO, 0))) { + OS_VERIFY_MIG(kr, "Allocating semaphore failed with MIG_REPLY_MISMATCH"); + thread_switch(MACH_PORT_NULL, SWITCH_OPTION_WAIT, 100); + } + return (os_semaphore_t)s4; +} + +void +_os_semaphore_dispose(os_semaphore_t sema) +{ + semaphore_t s4 = (semaphore_t)sema; + kern_return_t kr = semaphore_destroy(mach_task_self(), s4); + OS_SEMAPHORE_VERIFY_KR(kr, "Destroying semaphore failed"); +} + +void +_os_semaphore_signal(os_semaphore_t sema) +{ + semaphore_t s4 = (semaphore_t)sema; + kern_return_t kr = semaphore_signal(s4); + OS_SEMAPHORE_VERIFY_KR(kr, "Signaling semaphore failed"); +} + +void +_os_semaphore_wait(os_semaphore_t sema) +{ + semaphore_t s4 = (semaphore_t)sema; + kern_return_t kr; + do { + kr = semaphore_wait(s4); + } while (unlikely(kr == KERN_ABORTED)); + OS_SEMAPHORE_VERIFY_KR(kr, "Waiting on semaphore failed"); +} diff --git a/src/libc/arm/sys/_longjmp.s b/src/external/libplatform/src/setjmp/arm/_longjmp.S similarity index 100% rename from src/libc/arm/sys/_longjmp.s rename to src/external/libplatform/src/setjmp/arm/_longjmp.S diff --git a/src/libc/arm/sys/_setjmp.s b/src/external/libplatform/src/setjmp/arm/_setjmp.S similarity index 100% rename from src/libc/arm/sys/_setjmp.s rename to src/external/libplatform/src/setjmp/arm/_setjmp.S diff --git a/src/libc/arm/sys/_setjmp.h b/src/external/libplatform/src/setjmp/arm/_setjmp.h similarity index 100% rename from src/libc/arm/sys/_setjmp.h rename to src/external/libplatform/src/setjmp/arm/_setjmp.h diff --git a/src/external/libplatform/src/setjmp/arm/longjmp.S b/src/external/libplatform/src/setjmp/arm/longjmp.S new file mode 100644 index 000000000..36bab5c63 --- /dev/null +++ b/src/external/libplatform/src/setjmp/arm/longjmp.S @@ -0,0 +1,71 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1998-2008 Apple Inc. All rights reserved. + * + * File: sys/arm/longjmp.s + * + * Implements siglongjmp(), longjmp(), _longjmp() + * + */ + +#include +#include "_setjmp.h" + +/* + * longjmp routines + */ + +/* void siglongjmp(sigjmp_buf env, int val); */ + +ENTRY_POINT(_siglongjmp) + ldr r2, [ r0, #JMP_SIGFLAG ] // load sigflag + cmp r2, #0 // test if zero + beq L__exit // if zero do _longjmp() + // else *** fall through *** to longjmp() + +/* void longjmp(jmp_buf env, int val); */ + +ENTRY_POINT(_longjmp) +#ifdef __ARM_ARCH_7K__ + sub sp, sp, #16 // armv7k stack is 16-byte aligned. +#else + sub sp, sp, #4 +#endif + mov r6, r0 // preserve args across _sigprocmask + mov r8, r1 + ldr r0, [ r6, #JMP_sig ] // restore the signal mask + mov r1, sp // set + str r0, [sp] + movs r0, #3 // SIG_SETMASK + movs r2, #0 // oset + CALL_EXTERNAL(_sigprocmask) + mov r0, r6 + mov r1, r8 +#ifdef __ARM_ARCH_7K__ + add sp, sp, #16 // armv7k stack is 16-byte aligned. +#else + add sp, sp, #4 +#endif +L__exit: + BRANCH_EXTERNAL(__longjmp) diff --git a/src/external/libplatform/src/setjmp/arm/setjmp.S b/src/external/libplatform/src/setjmp/arm/setjmp.S new file mode 100644 index 000000000..92399ecc4 --- /dev/null +++ b/src/external/libplatform/src/setjmp/arm/setjmp.S @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1998-2008 Apple Inc. All rights reserved. + * + * File: sys/arm/setjmp.s + * + * Implements sigsetjmp(), setjmp(), _setjmp() + * + */ + +#include +#include "_setjmp.h" + +/* + * setjmp routines + */ + +/* int sigsetjmp(sigjmp_buf env, int savemask); */ + +ENTRY_POINT(_sigsetjmp) + str r1, [ r0, #JMP_SIGFLAG ] // save sigflag + cmp r1, #0 // test if r1 is 0 + beq L__exit // if r1 == 0 do _setjmp() + // else *** fall through *** to setjmp() + +/* int setjmp(jmp_buf env); */ + +ENTRY_POINT(_setjmp) + str lr, [ r0, #JMP_lr ] + str r8, [ r0, #JMP_r8 ] + mov r8, r0 + mov r0, #1 // get the previous signal mask + mov r1, #0 // + add r2, r8, #JMP_sig // get address where previous mask needs to be + CALL_EXTERNAL(_sigprocmask) // make a syscall to get mask + mov r0, r8 // restore jmp_buf ptr + ldr r8, [ r0, #JMP_r8 ] + ldr lr, [ r0, #JMP_lr ] +L__exit: + BRANCH_EXTERNAL(__setjmp) diff --git a/src/external/libplatform/src/setjmp/arm64/setjmp.S b/src/external/libplatform/src/setjmp/arm64/setjmp.S new file mode 100644 index 000000000..890179df0 --- /dev/null +++ b/src/external/libplatform/src/setjmp/arm64/setjmp.S @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2011 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#define JMP_r19_20 #0x00 +#define JMP_r21_22 #0x10 +#define JMP_r23_24 #0x20 +#define JMP_r25_26 #0x30 +#define JMP_r27_28 #0x40 +#define JMP_r29_lr #0x50 +#define JMP_fp_sp #0x60 + +#define JMP_d8_d9 #0x70 +#define JMP_d10_d11 #0x80 +#define JMP_d12_d13 #0x90 +#define JMP_d14_d15 #0xA0 +#define JMP_sig #0xB0 +#define JMP_sigflag #0xB8 + +#include + +/* int _setjmp(jmp_buf env); */ +ENTRY_POINT(__setjmp) + add x1, sp, #0 /* can't STP from sp */ + stp x19, x20, [x0, JMP_r19_20] + stp x21, x22, [x0, JMP_r21_22] + stp x23, x24, [x0, JMP_r23_24] + stp x25, x26, [x0, JMP_r25_26] + stp x27, x28, [x0, JMP_r27_28] + stp x29, lr, [x0, JMP_r29_lr] + stp fp, x1, [x0, JMP_fp_sp] + stp d8, d9, [x0, JMP_d8_d9] + stp d10, d11, [x0, JMP_d10_d11] + stp d12, d13, [x0, JMP_d12_d13] + stp d14, d15, [x0, JMP_d14_d15] + mov x0, #0 + ret + +/* void _longjmp(jmp_buf env, int val); */ +ENTRY_POINT(__longjmp) + ldp x19, x20, [x0, JMP_r19_20] + ldp x21, x22, [x0, JMP_r21_22] + ldp x23, x24, [x0, JMP_r23_24] + ldp x25, x26, [x0, JMP_r25_26] + ldp x27, x28, [x0, JMP_r27_28] + ldp x29, lr, [x0, JMP_r29_lr] + ldp fp, x2, [x0, JMP_fp_sp] + ldp d8, d9, [x0, JMP_d8_d9] + ldp d10, d11, [x0, JMP_d10_d11] + ldp d12, d13, [x0, JMP_d12_d13] + ldp d14, d15, [x0, JMP_d14_d15] + add sp, x2, #0 + mov x0, x1 + cmp x0, #0 /* longjmp returns 1 if val is 0 */ + b.ne 1f + add x0, x0, #1 +1: ret + +/* int sigsetjmp(sigjmp_buf env, int savemask); */ +ENTRY_POINT(_sigsetjmp) + str x1, [x0, JMP_sigflag] + cmp x1, #0 + b.ne 1f + b __setjmp +1: + /* else, fall through */ + +/* int setjmp(jmp_buf env); */ +ENTRY_POINT(_setjmp) + stp x21, lr, [x0] + mov x21, x0 + + mov x0, #1 + mov x1, #0 + add x2, x21, JMP_sig + CALL_EXTERNAL(_sigprocmask) + + mov x0, x21 + ldp x21, lr, [x0] + b __setjmp + +/* void siglongjmp(sigjmp_buf env, int val); */ +ENTRY_POINT(_siglongjmp) + ldr x2, [x0, JMP_sigflag] + cmp x2, #0 + b.ne 1f + b __longjmp +1: + /* else, fall through */ + +/* void longjmp(jmp_buf env, int val); */ +ENTRY_POINT(_longjmp) + sub sp, sp, #16 + mov x21, x0 // x21/x22 will be restored by __longjmp + mov x22, x1 + ldr x0, [x21, JMP_sig] // restore the signal mask + str x0, [sp, #8] + add x1, sp, #8 // set + orr w0, wzr, #0x3 // SIG_SETMASK + movz x2, #0 // oset + CALL_EXTERNAL(_sigprocmask) + mov x0, x21 + mov x1, x22 + add sp, sp, #16 + b __longjmp diff --git a/src/external/libplatform/src/setjmp/generic/setjmperr.c b/src/external/libplatform/src/setjmp/generic/setjmperr.c new file mode 100644 index 000000000..1c2e2071e --- /dev/null +++ b/src/external/libplatform/src/setjmp/generic/setjmperr.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1980 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)setjmperr.c 5.4 (Berkeley) 6/27/88"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +#if !TARGET_OS_IPHONE && (defined(__i386__) || defined(__x86_64__)) +/* + * This routine is called from longjmp() when an error occurs. + * Programs that wish to exit gracefully from this error may + * write their own versions. + * If this routine returns, the program is aborted. + */ + +void +longjmperror() +{ +#define ERRMSG "longjmp botch\n" + write(2, ERRMSG, sizeof(ERRMSG) - 1); +} +#endif diff --git a/src/external/libplatform/src/setjmp/generic/sigtramp.c b/src/external/libplatform/src/setjmp/generic/sigtramp.c new file mode 100644 index 000000000..9a1bf762c --- /dev/null +++ b/src/external/libplatform/src/setjmp/generic/sigtramp.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 1999, 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved + */ + +#define _XOPEN_SOURCE 600 + +#import +#import +#import +#import +#import +#include + +extern int __sigreturn(ucontext_t *, int); + +/* + * sigvec registers _sigtramp as the handler for any signal requiring + * user-mode intervention. All _sigtramp does is find the real handler, + * calls it, then sigreturn's. + * + * Note that the kernel saves/restores all of our register state. + */ + +/* On i386, i386/sys/_sigtramp.s defines this. There is no in_sigtramp on arm */ +#if defined(__DYNAMIC__) && defined(__x86_64__) +__attribute__((visibility("hidden"))) +int __in_sigtramp = 0; +#endif + +/* These defn should match the kernel one */ +#define UC_TRAD 1 +#define UC_FLAVOR 30 +#if defined(__ppc__) || defined(__ppc64__) +#define UC_TRAD64 20 +#define UC_TRAD64_VEC 25 +#define UC_FLAVOR_VEC 35 +#define UC_FLAVOR64 40 +#define UC_FLAVOR64_VEC 45 +#define UC_DUAL 50 +#define UC_DUAL_VEC 55 + + /* The following are valid mcontext sizes */ +#define UC_FLAVOR_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int)) + +#define UC_FLAVOR_VEC_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int)) + +#define UC_FLAVOR64_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int)) + +#define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int)) +#endif + +#define UC_SET_ALT_STACK 0x40000000 +#define UC_RESET_ALT_STACK 0x80000000 + +/* + * Reset the kernel's idea of the use of an alternate stack; this is used by + * both longjmp() and siglongjmp(). Nothing other than this reset is needed, + * since restoring the registers and other operations that would normally be + * done by sigreturn() are handled in user space, so we do not pass a user + * context (in PPC, a user context is not the same as a jmpbuf mcontext, due + * to having more than one set of registers, etc., for the various 32/64 etc. + * contexts).. + */ +void +_sigunaltstack(int set) +{ + /* sigreturn(uctx, ctxstyle); */ + /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */ + __sigreturn (NULL, (set == SS_ONSTACK) ? UC_SET_ALT_STACK : UC_RESET_ALT_STACK); +} + +/* On these architectures, _sigtramp is implemented in assembly to + ensure it matches its DWARF unwind information. */ +#if !defined (__i386__) && !defined (__x86_64__) + +void +_sigtramp( + union __sigaction_u __sigaction_u, + int sigstyle, + int sig, + siginfo_t *sinfo, + ucontext_t *uctx +) { + int ctxstyle = UC_FLAVOR; + + if (sigstyle == UC_TRAD) + sa_handler(sig); + else { +#if TARGET_OS_WATCH + // + sa_sigaction(sig, sinfo, NULL); +#else + sa_sigaction(sig, sinfo, uctx); +#endif + } + + /* sigreturn(uctx, ctxstyle); */ + /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */ + __sigreturn (uctx, ctxstyle); +} + +#endif /* not ppc nor ppc64 nor i386 nor x86_64 */ diff --git a/src/libc/i386/sys/_setjmp.S b/src/external/libplatform/src/setjmp/i386/_setjmp.S similarity index 96% rename from src/libc/i386/sys/_setjmp.S rename to src/external/libplatform/src/setjmp/i386/_setjmp.S index f989c555f..58283371e 100644 --- a/src/libc/i386/sys/_setjmp.S +++ b/src/external/libplatform/src/setjmp/i386/_setjmp.S @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. * @@ -41,11 +40,6 @@ * */ -#ifdef DARLING -#define __setjmp _setjmp -#define __longjmp _longjmp -#endif - #include // The FP control word is actually two bytes, but there's no harm in diff --git a/src/external/libplatform/src/setjmp/i386/_sigtramp.S b/src/external/libplatform/src/setjmp/i386/_sigtramp.S new file mode 100644 index 000000000..edf1d6b8d --- /dev/null +++ b/src/external/libplatform/src/setjmp/i386/_sigtramp.S @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2007, 2011 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +#if defined(__DYNAMIC__) +#if IGNORE_RDAR_13625839 + .private_extern ___in_sigtramp +#endif + .globl ___in_sigtramp + .data + .align 2 +___in_sigtramp: + .space 4 +#endif + +#define UC_TRAD 1 +#define UC_FLAVOR 30 + +/* Structure fields for ucontext and mcontext. */ +#define UCONTEXT_UC_MCONTEXT 28 + +#define MCONTEXT_ES_EXCEPTION 0 +#define MCONTEXT_SS_EAX 12 +#define MCONTEXT_SS_EBX 16 +#define MCONTEXT_SS_ECX 20 +#define MCONTEXT_SS_EDX 24 +#define MCONTEXT_SS_EDI 28 +#define MCONTEXT_SS_ESI 32 +#define MCONTEXT_SS_EBP 36 +#define MCONTEXT_SS_ESP 40 +#define MCONTEXT_SS_EFLAGS 48 +#define MCONTEXT_SS_EIP 52 + +/* register use: + %ebp frame pointer + %ebx Address of "L00000000001$pb" + %esi uctx + +void +_sigtramp( + union __sigaction_u __sigaction_u, + int sigstyle, + int sig, + siginfo_t *sinfo, + ucontext_t *uctx +) +*/ + + .globl __sigtramp + .text + .align 4,0x90 +__sigtramp: +Lstart: + /* Although this routine does not need any stack frame, various parts + of the OS can't analyse the stack without them. */ + pushl %ebp + movl %esp, %ebp + subl $24, %esp + movl 8(%ebp), %ecx # get '__sigaction_u' +#if defined(__DYNAMIC__) + call 0f +"L00000000001$pb": +0: + popl %ebx + incl ___in_sigtramp-"L00000000001$pb"(%ebx) +#endif + movl 16(%ebp), %edx # get 'sig' + movl 20(%ebp), %eax # get 'sinfo' + movl 24(%ebp), %esi # get 'uctx' + /* Call the signal handler. + Some variants are not supposed to get the last two parameters, + but the test to prevent this is more expensive than just passing + them. */ + movl %esi, 8(%esp) + movl %eax, 4(%esp) + movl %edx, (%esp) + call *%ecx +#if defined(__DYNAMIC__) + decl ___in_sigtramp-"L00000000001$pb"(%ebx) +#endif + movl %esi, 4(%esp) + movl $ UC_FLAVOR, 8(%esp) + movl $ SYS_sigreturn, %eax + int $0x80 +Lend: + +/* DWARF unwind table #defines. */ +#define DW_CFA_advance_loc_4 0x44 +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_expression 0x0F +#define DW_CFA_expression 0x10 +#define DW_CFA_val_expression 0x16 +#define DW_CFA_offset(column) 0x80+(column) + +/* DWARF expression #defines. */ +#define DW_OP_deref 0x06 +#define DW_OP_const1u 0x08 +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1a +#define DW_OP_div 0x1b +#define DW_OP_minus 0x1c +#define DW_OP_mod 0x1d +#define DW_OP_mul 0x1e +#define DW_OP_neg 0x1f +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_skip 0x2f +#define DW_OP_bra 0x28 +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2A +#define DW_OP_gt 0x2B +#define DW_OP_le 0x2C +#define DW_OP_lt 0x2D +#define DW_OP_ne 0x2E +#define DW_OP_lit(n) 0x30+(n) +#define DW_OP_breg(n) 0x70+(n) +#define DW_OP_deref_size 0x94 + +/* The location expression we'll use. */ + +#define loc_expr_for_reg(regno, offs) \ + .byte DW_CFA_expression, regno, 5 /* block length */, \ + DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \ + DW_OP_plus_uconst, offs + + /* Unwind tables. */ + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 # Length of Common Information Entry +LSCIE1: + .long 0 # CIE Identifier Tag + .byte 0x1 # CIE Version + .ascii "zRS\0" # CIE Augmentation + .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor + .byte 0x7c # sleb128 -4; CIE Data Alignment Factor + .byte 0x8 # CIE RA Column + .byte 0x1 # uleb128 0x1; Augmentation size + .byte 0x10 # FDE Encoding (pcrel) + .byte DW_CFA_def_cfa + .byte 0x5 # uleb128 0x5 + .byte 0x4 # uleb128 0x4 + .byte DW_CFA_offset(8) + .byte 0x1 # uleb128 0x1 + .byte DW_CFA_offset(8) // double DW_CFA_offset (eip, -4) tells linker to not make compact unwind + .byte 0x1 # uleb128 0x1 + .align 2 +LECIE1: + .globl _sigtramp.eh +_sigtramp.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 # FDE Length +LASFDE1: + .long LASFDE1-EH_frame1 # FDE CIE offset + .long Lstart-. # FDE initial location + .set L$set$2,Lend-Lstart + .long L$set$2 # FDE address range + .byte 0x0 # uleb128 0x0; Augmentation size + + /* Now for the expressions, which all compute + uctx->uc_mcontext->register + for each register. + + Describe even the registers that are not call-saved because they + might be being used in the prologue to save other registers. + Only integer registers are described at present. */ + + loc_expr_for_reg (0, MCONTEXT_SS_EAX) + loc_expr_for_reg (1, MCONTEXT_SS_ECX) + loc_expr_for_reg (2, MCONTEXT_SS_EDX) + loc_expr_for_reg (3, MCONTEXT_SS_EBX) + loc_expr_for_reg (4, MCONTEXT_SS_EBP) # note that GCC switches + loc_expr_for_reg (5, MCONTEXT_SS_ESP) # DWARF registers 4 & 5 + loc_expr_for_reg (6, MCONTEXT_SS_ESI) + loc_expr_for_reg (7, MCONTEXT_SS_EDI) + loc_expr_for_reg (9, MCONTEXT_SS_EFLAGS) + + /* The Intel architecture classifies exceptions into three categories, + 'faults' which put the address of the faulting instruction + in EIP, 'traps' which put the following instruction in EIP, + and 'aborts' which don't typically report the instruction + causing the exception. + + The traps are #BP and #OF. */ + + .byte DW_CFA_val_expression, 8 + .set L$set$3,Lpc_end-Lpc_start + .byte L$set$3 +Lpc_start: + /* Push the mcontext address twice. */ + .byte DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref, DW_OP_dup + /* Find the value of EIP. */ + .byte DW_OP_plus_uconst, MCONTEXT_SS_EIP, DW_OP_deref, DW_OP_swap + /* Determine the exception type. */ + .byte DW_OP_plus_uconst, MCONTEXT_ES_EXCEPTION, DW_OP_deref + /* Check whether it is #BP (3) or #OF (4). */ + .byte DW_OP_dup, DW_OP_lit(3), DW_OP_ne + .byte DW_OP_swap, DW_OP_lit(4), DW_OP_ne, DW_OP_and + /* If it is, then add 1 to the instruction address, so as to point + within or past the faulting instruction. */ + .byte DW_OP_plus +Lpc_end: + + /* The CFA will have been saved as the value of ESP (it is not + ESP+4). */ + .byte DW_CFA_def_cfa_expression + .set L$set$4,Lcfa_end-Lcfa_start + .byte L$set$4 +Lcfa_start: + .byte DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref + .byte DW_OP_plus_uconst, MCONTEXT_SS_ESP, DW_OP_deref +Lcfa_end: + + .align 2 +LEFDE1: + + .subsections_via_symbols diff --git a/src/external/libplatform/src/setjmp/i386/setjmp.S b/src/external/libplatform/src/setjmp/i386/setjmp.S new file mode 100644 index 000000000..4fd84aae1 --- /dev/null +++ b/src/external/libplatform/src/setjmp/i386/setjmp.S @@ -0,0 +1,129 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved + */ +/* + * NeXT 386 setjmp/longjmp + * + * Written by Bruce Martin, NeXT Inc. 4/9/92 + */ + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from + * the last call to + * setjmp(a) + * by restoring registers from the stack, + * The previous value of the signal mask is + * restored. + * + */ + +#include + +// The FP control word is actually two bytes, but there's no harm in +// using four bytes for it and keeping the struct aligned. +#define JB_FPCW 0 +#define JB_MASK 4 +#define JB_MXCSR 8 +#define JB_EBX 12 +#define JB_ONSTACK 16 +#define JB_EDX 20 +#define JB_EDI 24 +#define JB_ESI 28 +#define JB_EBP 32 +#define JB_ESP 36 +#define JB_SS 40 +#define JB_EFLAGS 44 +#define JB_EIP 48 +#define JB_CS 52 +#define JB_DS 56 +#define JB_ES 60 +#define JB_FS 64 +#define JB_GS 68 +#define JB_SAVEMASK 72 // sigsetjmp/siglongjmp only + +LEAF(_sigsetjmp, 0) + movl 4(%esp), %eax // sigjmp_buf * jmpbuf; + movl 8(%esp), %ecx // int savemask; + movl %ecx, JB_SAVEMASK(%eax) // jmpbuf[_JBLEN] = savemask; + cmpl $0, %ecx // if savemask != 0 + jne _setjmp // setjmp(jmpbuf); + jmp L_do__setjmp // else _setjmp(jmpbuf); + +LEAF(_setjmp, 0) + subl $16, %esp // make space for return from sigprocmask + // + 12 to align stack + pushl %esp // oset + pushl $0 // set = NULL + pushl $1 // how = SIG_BLOCK + CALL_EXTERN(_sigprocmask) + movl 12(%esp),%eax // save the mask + addl $28, %esp // restore original esp + movl 4(%esp), %ecx // jmp_buf (struct sigcontext *) + movl %eax, JB_MASK(%ecx) + + subl $20, %esp // temporary struct sigaltstack + 8 to + // align stack + pushl %esp // oss + pushl $0 // ss == NULL + CALL_EXTERN(___sigaltstack) // get alternate signal stack info + movl 16(%esp), %eax // oss->ss_flags + addl $28, %esp // Restore %esp + movl %eax, JB_ONSTACK(%ecx) + +L_do__setjmp: + BRANCH_EXTERN(__setjmp) + +LEAF(_siglongjmp, 0) + movl 4(%esp), %eax // sigjmp_buf * jmpbuf; + cmpl $0, JB_SAVEMASK(%eax) // if jmpbuf[_JBLEN] != 0 + jne _longjmp // longjmp(jmpbuf, var); + jmp L_do__longjmp // else _longjmp(jmpbuf, var); + +LEAF(_longjmp, 0) + movl 4(%esp), %ecx // address of jmp_buf (saved context) + movl JB_MASK(%ecx),%eax // get the mask + subl $12, %esp // Make sure the stack is 16-byte + // aligned when we call sigprocmask + pushl %eax // store the mask + movl %esp, %edx // save the address where we stored the mask + pushl $0 // oset = NULL + pushl %edx // set + pushl $3 // how = SIG_SETMASK + CALL_EXTERN_AGAIN(_sigprocmask) + addl $28, %esp // restore original esp + + movl 4(%esp), %ecx // address of jmp_buf + movl JB_ONSTACK(%ecx), %eax // ss_flags + subl $8, %esp + pushl %eax + CALL_EXTERN(__sigunaltstack) + addl $12, %esp + +L_do__longjmp: + BRANCH_EXTERN(__longjmp) // else +END(_longjmp) diff --git a/src/libc/x86_64/sys/_setjmp.S b/src/external/libplatform/src/setjmp/x86_64/_setjmp.S similarity index 100% rename from src/libc/x86_64/sys/_setjmp.S rename to src/external/libplatform/src/setjmp/x86_64/_setjmp.S diff --git a/src/external/libplatform/src/setjmp/x86_64/_sigtramp.S b/src/external/libplatform/src/setjmp/x86_64/_sigtramp.S new file mode 100644 index 000000000..a528650e3 --- /dev/null +++ b/src/external/libplatform/src/setjmp/x86_64/_sigtramp.S @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2007, 2011 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +#define UC_TRAD 1 +#define UC_FLAVOR 30 + +/* Structure fields for ucontext and mcontext. */ +#define UCONTEXT_UC_MCONTEXT 48 + +#define MCONTEXT_ES_EXCEPTION 0 +#define MCONTEXT_SS_RAX 16 +#define MCONTEXT_SS_RBX 24 +#define MCONTEXT_SS_RCX 32 +#define MCONTEXT_SS_RDX 40 +#define MCONTEXT_SS_RDI 48 +#define MCONTEXT_SS_RSI 56 +#define MCONTEXT_SS_RBP 64 +#define MCONTEXT_SS_RSP 72 +#define MCONTEXT_SS_R8 80 +#define MCONTEXT_SS_RIP 144 + +/* register use: + %rbx uctx + +void +_sigtramp( + union __sigaction_u __sigaction_u, %rdi + int sigstyle, %rsi + int sig, %rdx + siginfo_t *sinfo, %rcx + ucontext_t *uctx %r8 +) +*/ + + .globl __sigtramp + .text + .align 4,0x90 +__sigtramp: +Lstart: + /* Although this routine does not need any stack frame, various parts + of the OS can't analyse the stack without them. */ + pushq %rbp + movq %rsp, %rbp + + movq %rdi, %rax # set up address for call + +#if defined(__DYNAMIC__) + incl ___in_sigtramp(%rip) +#endif + /* Save uctx in %rbx. */ + movq %r8, %rbx + /* Call the signal handler. + Some variants are not supposed to get the last two parameters, + but the test to prevent this is more expensive than just passing + them. */ + movl %edx, %edi + movq %rcx, %rsi + movq %r8, %rdx +Lcall_start: + call *%rax +Lcall_end: +#if defined(__DYNAMIC__) + decl ___in_sigtramp(%rip) +#endif + movq %rbx, %rdi + movl $ UC_FLAVOR, %esi + callq ___sigreturn + ret +Lend: + +/* DWARF unwind table #defines. */ +#define DW_CFA_advance_loc_4 0x44 +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_expression 0x0F +#define DW_CFA_expression 0x10 +#define DW_CFA_val_expression 0x16 +#define DW_CFA_offset(column) 0x80+(column) + +/* DWARF expression #defines. */ +#define DW_OP_deref 0x06 +#define DW_OP_const1u 0x08 +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1a +#define DW_OP_div 0x1b +#define DW_OP_minus 0x1c +#define DW_OP_mod 0x1d +#define DW_OP_mul 0x1e +#define DW_OP_neg 0x1f +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_skip 0x2f +#define DW_OP_bra 0x28 +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2A +#define DW_OP_gt 0x2B +#define DW_OP_le 0x2C +#define DW_OP_lt 0x2D +#define DW_OP_ne 0x2E +#define DW_OP_lit(n) 0x30+(n) +#define DW_OP_breg(n) 0x70+(n) +#define DW_OP_deref_size 0x94 + +/* The location expression we'll use. */ + +#define loc_expr_for_reg(regno, offs) \ + .byte DW_CFA_expression, regno, 5 /* block length */, \ + DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \ + DW_OP_plus_uconst, offs + +/* For r8 through r13 */ +#define loc_expr_rN(regno) \ + loc_expr_for_reg(regno, MCONTEXT_SS_R8+(8*(regno-8))) + +/* For r14 through r15 */ +#define loc_expr_rN_long(regno) \ + .byte DW_CFA_expression, regno, 6 /* block length */, \ + DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \ + DW_OP_plus_uconst, MCONTEXT_SS_R8+(8*(regno-8)), 1 + + /* Unwind tables. */ + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 # Length of Common Information Entry +LSCIE1: + .long 0 # CIE Identifier Tag + .byte 0x1 # CIE Version + .ascii "zRS\0" # CIE Augmentation + .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor + .byte 0x78 # sleb128 -8; CIE Data Alignment Factor + .byte 0x10 # CIE RA Column + .byte 0x1 # uleb128 0x1; Augmentation size + .byte 0x10 # FDE Encoding (pcrel) + .byte DW_CFA_def_cfa + .byte 0x7 # uleb128 0x5 + .byte 0x8 # uleb128 0x4 + .byte DW_CFA_offset(16) + .byte 0x1 # uleb128 0x1 + .byte DW_CFA_offset(16) // duplicate DW_CFA_offset (rip, -8) tells linker to not make compact unwind + .byte 0x1 # uleb128 0x1 + .align 3 +LECIE1: + .globl _sigtramp.eh +_sigtramp.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 # FDE Length +LASFDE1: + .long LASFDE1-EH_frame1 # FDE CIE offset + .quad Lstart-. # FDE initial location + .set L$set$2,Lend-Lstart + .quad L$set$2 # FDE address range + .byte 0x0 # uleb128 0x0; Augmentation size + + /* Now for the expressions, which all compute + uctx->uc_mcontext->register + for each register. + + Describe even the registers that are not call-saved because they + might be being used in the prologue to save other registers. + Only integer registers are described at present. */ + + loc_expr_for_reg (0, MCONTEXT_SS_RAX) + loc_expr_for_reg (1, MCONTEXT_SS_RDX) + loc_expr_for_reg (2, MCONTEXT_SS_RCX) + loc_expr_for_reg (3, MCONTEXT_SS_RBX) + loc_expr_for_reg (4, MCONTEXT_SS_RSI) + loc_expr_for_reg (5, MCONTEXT_SS_RDI) + loc_expr_for_reg (6, MCONTEXT_SS_RBP) + loc_expr_for_reg (7, MCONTEXT_SS_RSP) + loc_expr_rN (8) + loc_expr_rN (9) + loc_expr_rN (10) + loc_expr_rN (11) + loc_expr_rN (12) + loc_expr_rN (13) + loc_expr_rN_long (14) + loc_expr_rN_long (15) + + /* The Intel architecture classifies exceptions into three categories, + 'faults' which put the address of the faulting instruction + in EIP, 'traps' which put the following instruction in EIP, + and 'aborts' which don't typically report the instruction + causing the exception. + + The traps are #BP and #OF. */ + + .byte DW_CFA_val_expression, 16 + .set L$set$3,Lpc_end-Lpc_start + .byte L$set$3 +Lpc_start: + /* Push the mcontext address twice. */ + .byte DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, DW_OP_dup + /* Find the value of EIP. */ + .byte DW_OP_plus_uconst, MCONTEXT_SS_RIP, MCONTEXT_SS_RIP >> 7 + .byte DW_OP_deref, DW_OP_swap + /* Determine the exception type. */ + .byte DW_OP_plus_uconst, MCONTEXT_ES_EXCEPTION, DW_OP_deref_size, 4 + /* Check whether it is #BP (3) or #OF (4). */ + .byte DW_OP_dup, DW_OP_lit(3), DW_OP_ne + .byte DW_OP_swap, DW_OP_lit(4), DW_OP_ne, DW_OP_and + /* If it is not, then add 1 to the instruction address, so as to point + within or past the faulting instruction. */ + .byte DW_OP_plus +Lpc_end: + + /* The CFA will have been saved as the value of RSP (it is not + RSP+8). */ + .byte DW_CFA_def_cfa_expression + .set L$set$4,Lcfa_end-Lcfa_start + .byte L$set$4 +Lcfa_start: + .byte DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref + .byte DW_OP_plus_uconst, MCONTEXT_SS_RSP, DW_OP_deref +Lcfa_end: + + .align 3 +LEFDE1: + + .subsections_via_symbols diff --git a/src/external/libplatform/src/setjmp/x86_64/setjmp.S b/src/external/libplatform/src/setjmp/x86_64/setjmp.S new file mode 100644 index 000000000..cfee74a69 --- /dev/null +++ b/src/external/libplatform/src/setjmp/x86_64/setjmp.S @@ -0,0 +1,123 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved + */ +/* + * NeXT 386 setjmp/longjmp + * + * Written by Bruce Martin, NeXT Inc. 4/9/92 + */ + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from + * the last call to + * setjmp(a) + * by restoring registers from the stack, + * The previous value of the signal mask is + * restored. + * + */ + +#include + +#define JB_RBX 0 +#define JB_RBP 8 +#define JB_RSP 16 +#define JB_R12 24 +#define JB_R13 32 +#define JB_R14 40 +#define JB_R15 48 +#define JB_RIP 56 +#define JB_RFLAGS 64 +#define JB_MXCSR 72 +#define JB_FPCONTROL 76 +#define JB_MASK 80 +#define JB_SAVEMASK 84 // sigsetjmp/siglongjmp only +#define JB_ONSTACK 88 + +#define STACK_SSFLAGS 16 // offsetof(stack_t, ss_flags) + +LEAF(_sigsetjmp, 0) + // %rdi is sigjmp_buf * jmpbuf; + // %esi is int savemask + movl %esi, JB_SAVEMASK(%rdi) // jmpbuf[_JBLEN] = savemask; + cmpl $0, %esi // if savemask != 0 + jne _setjmp // setjmp(jmpbuf); + jmp L_do__setjmp // else _setjmp(jmpbuf); + +LEAF(_setjmp, 0) + pushq %rdi // Preserve the jmp_buf across the call + movl $1, %edi // how = SIG_BLOCK + xorq %rsi, %rsi // set = NULL + subq $16, %rsp // Allocate space for the return from sigprocmask + 8 to align stack + movq %rsp, %rdx // oset = allocated space + CALL_EXTERN(_sigprocmask) + popq %rax // Save the mask + addq $8, %rsp // Restore the stack to before we align it + movq (%rsp), %rdi // jmp_buf (struct sigcontext *). Leave pointer on the stack for _sigaltstack call) + movl %eax, JB_MASK(%rdi) + + // Get current sigaltstack status (stack_t) + subq $32, %rsp // 24 bytes for a stack_t, + 8 for the jmp_buf pointer, + 8 is correctly aligned + movq %rsp, %rsi // oss + xorq %rdi, %rdi // ss == NULL + CALL_EXTERN(___sigaltstack) // __sigaltstack(NULL, oss) + movl STACK_SSFLAGS(%rsp), %eax // oss.ss_flags + movq 32(%rsp), %rdi // jmpbuf (will be first argument to subsequent call) + movl %eax, JB_ONSTACK(%rdi) // Store ss_flags in jmpbuf + addq $40, %rsp // restore %rsp + +L_do__setjmp: + BRANCH_EXTERN(__setjmp) + +LEAF(_siglongjmp, 0) + // %rdi is sigjmp_buf * jmpbuf; + cmpl $0, JB_SAVEMASK(%rdi) // if jmpbuf[_JBLEN] != 0 + jne _longjmp // longjmp(jmpbuf, var); + jmp L_do__longjmp // else _longjmp(jmpbuf, var); + +LEAF(_longjmp, 0) + // %rdi is address of jmp_buf (saved context) + pushq %rdi // Preserve the jmp_buf across the call + pushq %rsi // Preserve the value across the call + pushq JB_MASK(%rdi) // Put the mask on the stack + movq $3, %rdi // how = SIG_SETMASK + movq %rsp, %rsi // set = address where we stored the mask + xorq %rdx, %rdx // oset = NULL + CALL_EXTERN_AGAIN(_sigprocmask) + + // Restore sigaltstack status + movq 16(%rsp), %rdi // Grab jmpbuf but leave it on the stack + movl JB_ONSTACK(%rdi), %edi // Pass old state to _sigunaltstack() + CALL_EXTERN(__sigunaltstack) + addq $8, %rsp // Restore stack + popq %rsi + popq %rdi // Pass jmpbuf to _longjmp + +L_do__longjmp: + BRANCH_EXTERN(__longjmp) // else +END(_longjmp) diff --git a/src/external/libplatform/src/simple/asl.c b/src/external/libplatform/src/simple/asl.c new file mode 100644 index 000000000..33424bfdc --- /dev/null +++ b/src/external/libplatform/src/simple/asl.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2005, 2006, 2009 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include <_simple.h> + +#include +#include +#include +#include +#include + +#define ASL_LOG_PATH _PATH_LOG + +extern ssize_t __sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); +extern int __gettimeofday(struct timeval *, struct timezone *); + +struct ProgramVars +{ + void* mh; + int* NXArgcPtr; + char*** NXArgvPtr; + char*** environPtr; + char** __prognamePtr; +}; + +struct asl_context { + bool asl_enabled; + const char *progname; + int asl_fd; +#if TARGET_IPHONE_SIMULATOR + const char *sim_log_path; + os_unfair_lock sim_connect_lock; +#else + os_once_t connect_once; +#endif +}; + +static struct asl_context* _simple_asl_get_context(void); +static void _simple_asl_init_context(void *ctx); +static int _simple_asl_connect(const char *log_path); +static void _simple_asl_connect_once(void * __unused arg); +static int _simple_asl_get_fd(void); + +/* + * Simplified ASL log interface; does not use malloc. Unfortunately, this + * requires knowledge of the format used by ASL. + */ + +static const char * +_simple_asl_escape_key(unsigned char c) +{ + switch(c) + { + case '\\': return "\\\\"; + case '[': return "\\["; + case ']': return "\\]"; + case '\n': return "\\n"; + case ' ': return "\\s"; + } + + return NULL; +} + +static const char * +_simple_asl_escape_val(unsigned char c) +{ + switch(c) + { + case '\\': return "\\\\"; + case '[': return "\\["; + case ']': return "\\]"; + case '\n': return "\\n"; + } + + return NULL; +} + +__attribute__((visibility("hidden"))) +void +_simple_asl_init(const char *envp[], const struct ProgramVars *vars) +{ + const char *str; + struct asl_context *ctx = _simple_asl_get_context(); + str = _simple_getenv(envp, "ASL_DISABLE"); + if ((str != NULL) && (!strcmp(str, "1"))) return; + ctx->asl_enabled = true; + if (vars && vars->__prognamePtr) { + ctx->progname = *(vars->__prognamePtr); +#if TARGET_IPHONE_SIMULATOR + } else { + const char * progname = *_NSGetProgname(); + if (progname) + ctx->progname = progname; +#endif + } +} + +static int +_simple_asl_connect(const char *log_path) +{ + int fd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (fd == -1) return -1; + + fcntl(fd, F_SETFD, FD_CLOEXEC); + + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + + size_t amt = strlen(log_path) + 1; + if (sizeof(addr.sun_path) < amt) + amt = sizeof(addr.sun_path); + memmove(addr.sun_path, log_path, amt); + + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { + close(fd); + return -1; + } + return fd; +} + +static void +_simple_asl_connect_once(void * __unused once_arg) +{ + struct asl_context *ctx = _simple_asl_get_context(); + ctx->asl_fd = _simple_asl_connect(ASL_LOG_PATH); +} + +static int +_simple_asl_get_fd(void) +{ + struct asl_context *ctx = _simple_asl_get_context(); + if (!ctx->asl_enabled) { + return -1; + } + +#if TARGET_IPHONE_SIMULATOR + os_unfair_lock_lock_with_options(&ctx->sim_connect_lock, + OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); + if (ctx->sim_log_path) { + // all setup has been done already + os_unfair_lock_unlock(&ctx->sim_connect_lock); + return ctx->asl_fd; + } + ctx->sim_log_path = _simple_getenv( + (const char **)*_NSGetEnviron(), "IOS_SIMULATOR_SYSLOG_SOCKET"); + if (ctx->sim_log_path) { + // the first and only time the envvar is being checked + // asl_fd procured by the end of this call will be used forever + int sim_log_fd = _simple_asl_connect(ctx->sim_log_path); + if (sim_log_fd > -1) { + // successfully connected to the SIM path + if (ctx->asl_fd > -1) { + // close the ASL_LOG_PATH fd + close(ctx->asl_fd); + } + ctx->asl_fd = sim_log_fd; + } + } + if (ctx->asl_fd < 0) { + // either there is no envvar or it didn't work. fallback to ASL_LOG_PATH + ctx->asl_fd = _simple_asl_connect(ASL_LOG_PATH); + } + os_unfair_lock_unlock(&ctx->sim_connect_lock); + return ctx->asl_fd; +#else + os_once(&ctx->connect_once, NULL, _simple_asl_connect_once); + return ctx->asl_fd; +#endif +} + +_SIMPLE_STRING +_simple_asl_msg_new(void) +{ + _SIMPLE_STRING b = _simple_salloc(); + + if (b == NULL) return NULL; + + if (_simple_sprintf(b, " 0", 0)) + { + _simple_sfree(b); + return NULL; + } + + return b; +} + +void +_simple_asl_msg_set(_SIMPLE_STRING __b, const char *__key, const char *__val) +{ + if (__b == NULL) return; + if (__key == NULL) return; + + do + { + if (_simple_sprintf(__b, " [", 0)) break; + if (_simple_esprintf(__b, _simple_asl_escape_key, "%s", __key)) break; + if (__val != NULL) + { + if (_simple_esprintf(__b, _simple_asl_escape_val, " %s", __val)) break; + if (!strcmp(__key, "Message")) + { + char *cp; + + /* remove trailing (escaped) newlines */ + cp = _simple_string(__b); + cp += strlen(cp); + for (;;) + { + cp -= 2; + if (strcmp(cp, "\\n") != 0) break; + *cp = 0; + } + + _simple_sresize(__b); + } + } + + if (_simple_sappend(__b, "]")) break; + return; + } while (0); +} + +void +_simple_asl_send(_SIMPLE_STRING __b) +{ + struct timeval tv; + int asl_fd = _simple_asl_get_fd(); + if (asl_fd < 0) return; + + __gettimeofday(&tv, NULL); + + do + { + char *cp; + + if (_simple_sprintf(__b, " [PID ", 0)) break; + if (_simple_esprintf(__b, _simple_asl_escape_val, "%u", getpid())) break; + if (_simple_sprintf(__b, "] [UID ", 0)) break; + if (_simple_esprintf(__b, _simple_asl_escape_val, "%u", getuid())) break; + if (_simple_sprintf(__b, "] [GID ", 0)) break; + if (_simple_esprintf(__b, _simple_asl_escape_val, "%u", getgid())) break; + if (_simple_sprintf(__b, "] [Time ", 0)) break; + if (_simple_esprintf(__b, _simple_asl_escape_val, "%lu", tv.tv_sec)) break; + if (_simple_sappend(__b, "] [TimeNanoSec ")) break; + if (_simple_esprintf(__b, _simple_asl_escape_val, "%d", tv.tv_usec * 1000)) break; + if (_simple_sappend(__b, "]\n")) break; + + cp = _simple_string(__b); + __sendto(asl_fd, cp, strlen(cp), 0, NULL, 0); + } while (0); +} + +void +_simple_asl_log_prog(int level, const char *facility, const char *message, const char *prog) +{ + char lstr[2]; + + _SIMPLE_STRING b = _simple_asl_msg_new(); + if (b == NULL) return; + + if (level < 0) level = 0; + if (level > 7) level = 7; + lstr[0] = level + '0'; + lstr[1] = '\0'; + + _simple_asl_msg_set(b, "Sender", prog); + _simple_asl_msg_set(b, "Level", lstr); + _simple_asl_msg_set(b, "Facility", facility); + _simple_asl_msg_set(b, "Message", message); + _simple_asl_send(b); + _simple_sfree(b); +} + +void +_simple_asl_log(int level, const char *facility, const char *message) +{ + _simple_asl_log_prog(level, facility, message, + _simple_asl_get_context()->progname); +} + +static struct asl_context * +_simple_asl_get_context(void) +{ + return os_alloc_once(OS_ALLOC_ONCE_KEY_LIBSYSTEM_PLATFORM_ASL, + sizeof(struct asl_context), _simple_asl_init_context); +} + +static void +_simple_asl_init_context(void *arg) +{ + struct asl_context *ctx = (struct asl_context *)arg; + // ctx is zero-filled when it comes out of _os_alloc_once + ctx->progname = "unknown"; + ctx->asl_fd = -1; +} diff --git a/src/external/libplatform/src/simple/getenv.c b/src/external/libplatform/src/simple/getenv.c new file mode 100644 index 000000000..b3f1b7cb9 --- /dev/null +++ b/src/external/libplatform/src/simple/getenv.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +#include + +#include <_simple.h> + +#include +#include + +const char * +_simple_getenv(const char *envp[], const char *var) { + const char **p; + size_t var_len; + + var_len = strlen(var); + + for (p = envp; p && *p; p++) { + size_t p_len = strlen(*p); + + if (p_len >= var_len && + memcmp(*p, var, var_len) == 0 && + (*p)[var_len] == '=') { + return &(*p)[var_len + 1]; + } + } + + return NULL; +} diff --git a/src/external/libplatform/src/simple/string_io.c b/src/external/libplatform/src/simple/string_io.c new file mode 100644 index 000000000..2e581e854 --- /dev/null +++ b/src/external/libplatform/src/simple/string_io.c @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2005, 2006, 2009 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include + +#include "os/internal.h" +#include "_simple.h" +#include "platform/string.h" +#include "platform/compat.h" + +#ifndef VM_PAGE_SIZE +#define VM_PAGE_SIZE 4096 +#endif + +#define BUF_SIZE(s) (((BUF *)(s))->end - ((BUF *)(s))->buf + 1) +/* we use a small buffer to minimize stack usage constraints */ +#define MYBUFSIZE 32 + +typedef struct _BUF { + char *buf; + char *ptr; + char *end; + int fd; + void (*full)(struct _BUF *); +} BUF; + +/* flush the buffer */ +static void +_flush(BUF *b) +{ + char *buf = b->buf; + ssize_t n = b->ptr - buf; + ssize_t w; + + while (n > 0) { + w = write(b->fd, buf, n); + if (w < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + break; + } + n -= w; + buf += n; + } +} + +/* flush the buffer and reset the pointer */ +static void +_flush_reset(BUF *b) +{ + _flush(b); + b->ptr = b->buf; +} + +/* enlarge the buffer */ +static void +_enlarge(BUF *b) +{ + vm_address_t new; + vm_size_t sold, snew; + intptr_t diff; + kern_return_t kr; + + new = (vm_address_t)(b->end + 1); + if(vm_allocate(mach_task_self(), &new, VM_PAGE_SIZE, 0) == 0) { + /* page is adjacent */ + b->end += VM_PAGE_SIZE; + return; + } + sold = BUF_SIZE(b); + snew = (sold + VM_PAGE_SIZE) & ~(VM_PAGE_SIZE - 1); + if ((kr = vm_allocate(mach_task_self(), &new, snew, 1)) != 0) { + __LIBPLATFORM_CLIENT_CRASH__(kr, "Failed to allocate memory for buffer"); + } + diff = new - (vm_address_t)b->buf; + memmove((void *)new, b->buf, sold); + if((intptr_t)(b->buf) & (VM_PAGE_SIZE - 1)) { + sold &= ~(VM_PAGE_SIZE - 1); + b->buf = (char *)((intptr_t)(b->buf + VM_PAGE_SIZE) & ~(VM_PAGE_SIZE - 1)); + b->end = (char *)(new + snew - 1); + } else + b->end += diff + VM_PAGE_SIZE; + if(sold > 0) { + vm_deallocate(mach_task_self(), (vm_address_t)b->buf, sold); + } + b->buf = (char *)new; + b->ptr += diff; +} + +static inline void put_s(BUF *, _esc_func, const char *); +/* output a single character */ +static inline void +put_c(BUF *b, _esc_func esc, unsigned char c) +{ + const char *cp; + + if(esc && (cp = esc(c)) != NULL) + put_s(b, NULL, cp); + else { + if(b->ptr >= b->end) + b->full(b); + *b->ptr++ = c; + } +} + +/* output a null-terminated string */ +static inline void +put_s(BUF *b, _esc_func esc, const char *str) +{ + while(*str) + put_c(b, esc, *str++); +} + +/* output a string of the specified size */ +static inline void +put_n(BUF *b, _esc_func esc, const char *str, ssize_t n) +{ + while(n-- > 0) + put_c(b, esc, *str++); +} + +/* + * Output the signed decimal string representing the number in "in". "width" is + * the minimum field width, and "zero" is a boolean value, true for zero padding + * (otherwise blank padding). + */ +static void +dec(BUF *b, _esc_func esc, long long in, int width, int zero) +{ + char buf[32]; + char *cp = buf + sizeof(buf); + ssize_t pad; + int neg = 0; + unsigned long long n = (unsigned long long)in; + + if(in < 0) { + neg++; + width--; + n = ~n + 1; + } + *--cp = 0; + if(n) { + while(n) { + *--cp = (n % 10) + '0'; + n /= 10; + } + } else + *--cp = '0'; + if(neg && zero) { + put_c(b, esc, '-'); + neg = 0; + } + pad = width - strlen(cp); + zero = zero ? '0' : ' '; + while(pad-- > 0) + put_c(b, esc, zero); + if(neg) + put_c(b, esc, '-'); + put_s(b, esc, cp); +} + +/* + * Output the hex string representing the number in "n". "width" is the + * minimum field width, and "zero" is a boolean value, true for zero padding + * (otherwise blank padding). "upper" is a boolean value, true for upper + * case hex characters, lower case otherwise. "p" is a boolean value, true + * if 0x should be prepended (for %p), otherwise nothing. + */ +static const char _h[] = "0123456789abcdef"; +static const char _H[] = "0123456789ABCDEF"; +static const char _0x[] = "0x"; + +static void +hex(BUF *b, _esc_func esc, unsigned long long n, int width, int zero, int upper, int p) +{ + char buf[32]; + char *cp = buf + sizeof(buf); + const char *h = upper ? _H : _h; + + *--cp = 0; + if(n) { + while(n) { + *--cp = h[n & 0xf]; + n >>= 4; + } + } else + *--cp = '0'; + if(p) { + width -= 2; + if(zero) { + put_s(b, esc, _0x); + p = 0; + } + } + width -= strlen(cp); + zero = zero ? '0' : ' '; + while(width-- > 0) + put_c(b, esc, zero); + if(p) + put_s(b, esc, _0x); + put_s(b, esc, cp); +} + +/* + * Output the unsigned decimal string representing the number in "n". "width" + * is the minimum field width, and "zero" is a boolean value, true for zero + * padding (otherwise blank padding). + */ +static void +udec(BUF *b, _esc_func esc, unsigned long long n, int width, int zero) +{ + char buf[32]; + char *cp = buf + sizeof(buf); + ssize_t pad; + + *--cp = 0; + if(n) { + while(n) { + *--cp = (n % 10) + '0'; + n /= 10; + } + } else + *--cp = '0'; + pad = width - strlen(cp); + zero = zero ? '0' : ' '; + while(pad-- > 0) + put_c(b, esc, zero); + put_s(b, esc, cp); +} + +/* + * Output the unsigned decimal string representing the number in "n", rounded + * to the nearest MB, KB or b. "width" is the minimum field width, and "zero" + * is a boolean value, true for zero padding (otherwise blank padding). + */ +static void +ydec(BUF *b, _esc_func esc, unsigned long long n, int width, int zero) +{ + if(n >= 10 * (1 << 20)) { + n += (1 << 19); + udec(b, esc, n >> 20, width, zero); + put_s(b, esc, "MB"); + } else if (n >= 10 * (1 << 10)) { + n += (1 << 9); + udec(b, esc, n >> 10, width, zero); + put_s(b, esc, "KB"); + } else { + udec(b, esc, n, width, zero); + put_s(b, esc, "b"); + } +} + +/* + * The actual engine for all the _simple_*printf routines. + */ +static void +__simple_bprintf(BUF *b, _esc_func esc, const char *fmt, va_list ap) +{ + while(*fmt) { + int lflag, zero, width; + char *cp; + if(!(cp = strchr(fmt, '%'))) { + put_s(b, esc, fmt); + break; + } + put_n(b, esc, fmt, cp - fmt); + fmt = cp + 1; + if(*fmt == '%') { + put_c(b, esc, '%'); + fmt++; + continue; + } + lflag = zero = width = 0; + for(;;) { + switch(*fmt) { + case '0': + zero++; + fmt++; + /* drop through */ + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + while(*fmt >= '0' && *fmt <= '9') + width = 10 * width + (*fmt++ - '0'); + continue; + case 'c': + zero = zero ? '0' : ' '; + width--; + while(width-- > 0) + put_c(b, esc, zero); + put_c(b, esc, va_arg(ap, int)); + break; + case 'd': case 'i': + switch(lflag) { + case 0: + dec(b, esc, va_arg(ap, int), width, zero); + break; + case 1: + dec(b, esc, va_arg(ap, long), width, zero); + break; + default: + dec(b, esc, va_arg(ap, long long), width, zero); + break; + } + break; + case 'l': + lflag++; + fmt++; + continue; + case 'p': + hex(b, esc, (unsigned long)va_arg(ap, void *), width, zero, 0, 1); + break; + case 's': + cp = va_arg(ap, char *); + cp = cp ? cp : "(null)"; + width -= strlen(cp); + zero = zero ? '0' : ' '; + while(width-- > 0) + put_c(b, esc, zero); + put_s(b, esc, cp); + break; + case 'u': + switch(lflag) { + case 0: + udec(b, esc, va_arg(ap, unsigned int), width, zero); + break; + case 1: + udec(b, esc, va_arg(ap, unsigned long), width, zero); + break; + default: + udec(b, esc, va_arg(ap, unsigned long long), width, zero); + break; + } + break; + case 'X': case 'x': + switch(lflag) { + case 0: + hex(b, esc, va_arg(ap, unsigned int), width, zero, + *fmt == 'X', 0); + break; + case 1: + hex(b, esc, va_arg(ap, unsigned long), width, zero, + *fmt == 'X', 0); + break; + default: + hex(b, esc, va_arg(ap, unsigned long long), width, zero, + *fmt == 'X', 0); + break; + } + break; + case 'y': + switch(lflag) { + case 0: + ydec(b, esc, va_arg(ap, unsigned int), width, zero); + break; + case 1: + ydec(b, esc, va_arg(ap, unsigned long), width, zero); + break; + default: + ydec(b, esc, va_arg(ap, unsigned long long), width, zero); + break; + } + break; + default: + put_c(b, esc, *fmt); + break; + } + break; + } + fmt++; + } +} + +/* + * A simplified vfprintf variant. The format string is interpreted with + * arguments from the va_list, and the results are written to the given + * file descriptor. + */ +void +_simple_vdprintf(int fd, const char *fmt, va_list ap) +{ + BUF b; + char buf[MYBUFSIZE]; + + b.buf = buf; + b.fd = fd; + b.ptr = b.buf; + b.end = b.buf + MYBUFSIZE; + b.full = _flush_reset; + __simple_bprintf(&b, NULL, fmt, ap); + _flush(&b); +} + +/* + * A simplified fprintf variant. The format string is interpreted with + * arguments from the variable argument list, and the results are written + * to the given file descriptor. + */ +void +_simple_dprintf(int fd, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + _simple_vdprintf(fd, fmt, ap); + va_end(ap); +} + +/* + * A simplified string allocate routine. Pass the opaque pointer to structure + * to _simple_*sprintf() routines. Use _simple_string() to retrieve the + * current string (the string is guaranteed to be null terminated only on + * the call to _simple_string()). Use _simple_sfree() to free the structure + * and string memory. + */ +_SIMPLE_STRING +_simple_salloc(void) +{ + kern_return_t kr; + BUF *b; + + kr = vm_allocate(mach_task_self(), (vm_address_t *)&b, VM_PAGE_SIZE, 1); + if (kr) { + __LIBPLATFORM_CLIENT_CRASH__(kr, "Failed to allocate memory for string"); + } + b->ptr = b->buf = (char *)b + sizeof(BUF); + b->end = (char *)b + VM_PAGE_SIZE - 1; + b->full = _enlarge; + return (_SIMPLE_STRING)b; +} + +/* + * The format string is interpreted with arguments from the va_list, and the + * results are appended to the string maintained by the opaque structure, as + * returned by a previous call to _simple_salloc(). Always returns 0. + */ +int +_simple_vsprintf(_SIMPLE_STRING b, const char *fmt, va_list ap) +{ + return _simple_vesprintf(b, NULL, fmt, ap); +} + +/* + * The format string is interpreted with arguments from the variable argument + * list, and the results are appended to the string maintained by the opaque + * structure, as returned by a previous call to _simple_salloc(). + * Always returns 0. + */ +int +_simple_sprintf(_SIMPLE_STRING b, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = _simple_vesprintf(b, NULL, fmt, ap); + va_end(ap); + return ret; +} + +/* + * Like _simple_vsprintf(), except __esc is a function to call on each + * character; the function returns NULL if the character should be passed + * as is, otherwise, the returned character string is used instead. + */ +int +_simple_vesprintf(_SIMPLE_STRING b, _esc_func esc, const char *fmt, va_list ap) +{ + __simple_bprintf((BUF *)b, esc, fmt, ap); + return 0; +} + +/* + * Like _simple_sprintf(), except __esc is a function to call on each + * character; the function returns NULL if the character should be passed + * as is, otherwise, the returned character string is used instead. + */ +int _simple_esprintf(_SIMPLE_STRING b, _esc_func esc, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = _simple_vesprintf(b, esc, fmt, ap); + va_end(ap); + return ret; +} + +/* + * Return the null terminated string from the opaque structure, as returned + * by a previous call to _simple_salloc(). + */ +char * +_simple_string(_SIMPLE_STRING b) +{ + *((BUF *)b)->ptr = 0; + return ((BUF *)b)->buf; +} + +/* + * Reposition the pointer to the first null in the buffer. After a call to + * _simple_string, the buffer can be modified, and shrunk. + */ +void +_simple_sresize(_SIMPLE_STRING b) +{ + ((BUF *)b)->ptr = ((BUF *)b)->buf + strlen(((BUF *)b)->buf); +} + +/* + * Append the null-terminated string to the string associated with the opaque + * structure. Always returns 0. + */ +int +_simple_sappend(_SIMPLE_STRING b, const char *str) +{ + return _simple_esappend(b, NULL, str); +} + +/* + * Like _simple_sappend(), except __esc is a function to call on each + * character; the function returns NULL if the character should be passed + * as is, otherwise, the returned character string is used instead. + */ +int _simple_esappend(_SIMPLE_STRING b, _esc_func esc, const char *str) +{ + put_s((BUF *)b, esc, str); + return 0; +} + +/* + * Write the string associated with the opaque structure to the file descriptor. + */ +void +_simple_put(_SIMPLE_STRING b, int fd) +{ + ((BUF *)b)->fd = fd; + _flush((BUF *)b); +} + +/* + * Write the string associated with the opaque structure and a trailing newline, + * to the file descriptor. + */ +void +_simple_putline(_SIMPLE_STRING b, int fd) +{ + ((BUF *)b)->fd = fd; + *((BUF *)b)->ptr++ = '\n'; + _flush((BUF *)b); + ((BUF *)b)->ptr--; +} + +/* + * Free the opaque structure, and the associated string. + */ +void +_simple_sfree(_SIMPLE_STRING b) +{ + vm_size_t s; + + if(b == NULL) return; + if(((intptr_t)(((BUF *)b)->buf) & (VM_PAGE_SIZE - 1)) == 0) { + vm_deallocate(mach_task_self(), (vm_address_t)((BUF *)b)->buf, BUF_SIZE(b)); + s = VM_PAGE_SIZE; + } else { + s = ((BUF *)b)->end - (char *)b + 1; + } + vm_deallocate(mach_task_self(), (vm_address_t)b, s); +} diff --git a/src/external/libplatform/src/string/generic/bzero.c b/src/external/libplatform/src/string/generic/bzero.c new file mode 100644 index 000000000..4c070a49b --- /dev/null +++ b/src/external/libplatform/src/string/generic/bzero.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +#if !_PLATFORM_OPTIMIZED_MEMSET + +void * +_platform_memset(void *b, int c, size_t len) { + unsigned char pattern[4]; + + pattern[0] = (unsigned char)c; + pattern[1] = (unsigned char)c; + pattern[2] = (unsigned char)c; + pattern[3] = (unsigned char)c; + + _platform_memset_pattern4(b, pattern, len); + return b; +} + +#if VARIANT_STATIC +void * +memset(void *b, int c, size_t len) { + return _platform_memset(b, c, len); +} +#endif + +#endif + + +#if !_PLATFORM_OPTIMIZED_BZERO + +void +_platform_bzero(void *s, size_t n) +{ + _platform_memset(s, 0, n); +} + +#if VARIANT_STATIC +void +bzero(void *s, size_t n) { + _platform_bzero(s, n); +} + +void +__bzero(void *s, size_t n) { + _platform_bzero(s, n); +} +#endif + +#endif diff --git a/src/external/libplatform/src/string/generic/ffsll.c b/src/external/libplatform/src/string/generic/ffsll.c new file mode 100644 index 000000000..12c9a0977 --- /dev/null +++ b/src/external/libplatform/src/string/generic/ffsll.c @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +__FBSDID("$FreeBSD: src/lib/libc/string/ffsll.c,v 1.1 2008/11/03 10:22:19 kib Exp $"); + +#include + +/* + * Find First Set bit + */ +int +ffsll(long long mask) +{ +#if __has_builtin(__builtin_ffsll) + return __builtin_ffsll(mask); +#elif __has_builtin(__builtin_ctzll) + if (mask == 0) + return (0); + + return __builtin_ctzll(mask) + 1; +#else + int bit; + + if (mask == 0) + return (0); + for (bit = 1; !(mask & 1); bit++) + mask = (unsigned long long)mask >> 1; + return (bit); +#endif +} + +#if VARIANT_DYLD && TARGET_IPHONE_SIMULATOR +int +ffsl(long mask) +{ +#if __has_builtin(__builtin_ffsl) + return __builtin_ffsl(mask); +#elif __has_builtin(__builtin_ctzl) + if (mask == 0) + return (0); + + return __builtin_ctzl(mask) + 1; +#else + int bit; + + if (mask == 0) + return (0); + for (bit = 1; !(mask & 1); bit++) + mask = (unsigned long)mask >> 1; + return (bit); +#endif +} + +int +ffs(int mask) +{ +#if __has_builtin(__builtin_ffs) + return __builtin_ffs(mask); +#elif __has_builtin(__builtin_ctz) + if (mask == 0) + return (0); + + return __builtin_ctz(mask) + 1; +#else + int bit; + + if (mask == 0) + return (0); + for (bit = 1; !(mask & 1); bit++) + mask = (unsigned)mask >> 1; + return (bit); +#endif +} +#endif + diff --git a/src/external/libplatform/src/string/generic/flsll.c b/src/external/libplatform/src/string/generic/flsll.c new file mode 100644 index 000000000..b6c893bf4 --- /dev/null +++ b/src/external/libplatform/src/string/generic/flsll.c @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +__FBSDID("$FreeBSD: src/lib/libc/string/flsll.c,v 1.1 2008/11/03 10:22:19 kib Exp $"); + +#include + +/* + * Find Last Set bit + */ +int +flsll(long long mask) +{ +#if __has_builtin(__builtin_flsll) + return __builtin_flsll(mask); +#elif __has_builtin(__builtin_clzll) + if (mask == 0) + return (0); + + return (sizeof(mask) << 3) - __builtin_clzll(mask); +#else + int bit; + + if (mask == 0) + return (0); + for (bit = 1; mask != 1; bit++) + mask = (unsigned long long)mask >> 1; + return (bit); +#endif +} + +#if VARIANT_DYLD && TARGET_IPHONE_SIMULATOR +int +flsl(long mask) +{ +#if __has_builtin(__builtin_flsl) + return __builtin_flsl(mask); +#elif __has_builtin(__builtin_clzl) + if (mask == 0) + return (0); + + return (sizeof(mask) << 3) - __builtin_clzl(mask); +#else + int bit; + + if (mask == 0) + return (0); + for (bit = 1; mask != 1; bit++) + mask = (unsigned long)mask >> 1; + return (bit); +#endif +} + +int +fls(int mask) +{ +#if __has_builtin(__builtin_fls) + return __builtin_fls(mask); +#elif __has_builtin(__builtin_clz) + if (mask == 0) + return (0); + + return (sizeof(mask) << 3) - __builtin_clz(mask); +#else + int bit; + + if (mask == 0) + return (0); + for (bit = 1; mask != 1; bit++) + mask = (unsigned)mask >> 1; + return (bit); +#endif +} +#endif diff --git a/src/external/libplatform/src/string/generic/memccpy.c b/src/external/libplatform/src/string/generic/memccpy.c new file mode 100644 index 000000000..f9aee5596 --- /dev/null +++ b/src/external/libplatform/src/string/generic/memccpy.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +#if !_PLATFORM_OPTIMIZED_MEMCCPY + +#include + +void * +_platform_memccpy(void *t, const void *f, int c, size_t n) +{ + void *last; + + if (n == 0) { + return NULL; + } + + last = _platform_memchr(f, c, n); + + if (last == NULL) { + _platform_memmove(t, f, n); + return NULL; + } else { + n = (char *)last - (char *)f + 1; + _platform_memmove(t, f, n); + return (void *)((char *)t + n); + } +} + +#if VARIANT_STATIC +void * +memccpy(void *t, const void *f, int c, size_t n) +{ + return _platform_memccpy(t, f, c, n); +} +#endif + +#endif diff --git a/src/libc/string/FreeBSD/memchr.c b/src/external/libplatform/src/string/generic/memchr.c similarity index 87% rename from src/libc/string/FreeBSD/memchr.c rename to src/external/libplatform/src/string/generic/memchr.c index bf8a43116..3e1dc3028 100644 --- a/src/libc/string/FreeBSD/memchr.c +++ b/src/external/libplatform/src/string/generic/memchr.c @@ -30,16 +30,14 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)memchr.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/memchr.c,v 1.8 2009/02/07 19:34:44 imp Exp $"); +#include -#include +#if !_PLATFORM_OPTIMIZED_MEMCHR + +#include void * -memchr(const void *s, int c, size_t n) +_platform_memchr(const void *s, int c, size_t n) { if (n != 0) { const unsigned char *p = s; @@ -51,3 +49,13 @@ memchr(const void *s, int c, size_t n) } return (NULL); } + +#if VARIANT_STATIC +void * +memchr(const void *s, int c, size_t n) +{ + return _platform_memchr(s, c, n); +} +#endif + +#endif diff --git a/src/libc/string/FreeBSD/memcmp.c b/src/external/libplatform/src/string/generic/memcmp.c similarity index 86% rename from src/libc/string/FreeBSD/memcmp.c rename to src/external/libplatform/src/string/generic/memcmp.c index f2ac18b95..fd4311d92 100644 --- a/src/libc/string/FreeBSD/memcmp.c +++ b/src/external/libplatform/src/string/generic/memcmp.c @@ -30,19 +30,12 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/memcmp.c,v 1.6 2009/02/03 17:58:20 danger Exp $"); +#include -#include +#if !_PLATFORM_OPTIMIZED_MEMCMP -/* - * Compare memory regions. - */ int -memcmp(const void *s1, const void *s2, size_t n) +_platform_memcmp(const void *s1, const void *s2, size_t n) { if (n != 0) { const unsigned char *p1 = s1, *p2 = s2; @@ -54,3 +47,19 @@ memcmp(const void *s1, const void *s2, size_t n) } return (0); } + +#if VARIANT_STATIC +int +memcmp(const void *s1, const void *s2, size_t n) +{ + return _platform_memcmp(s1, s2, n); +} + +int +bcmp(const void *s1, const void *s2, size_t n) +{ + return _platform_memcmp(s1, s2, n); +} +#endif + +#endif diff --git a/src/external/libplatform/src/string/generic/memmove.c b/src/external/libplatform/src/string/generic/memmove.c new file mode 100644 index 000000000..e11f68c28 --- /dev/null +++ b/src/external/libplatform/src/string/generic/memmove.c @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#if !_PLATFORM_OPTIMIZED_MEMMOVE + +#include + +/* + * sizeof(word) MUST BE A POWER OF TWO + * SO THAT wmask BELOW IS ALL ONES + */ +typedef long word; /* "word" used for optimal copy speed */ + +#define wsize sizeof(word) +#define wmask (wsize - 1) + +/* + * Copy a block of memory, handling overlap. + * This is the routine that actually implements + * (the portable versions of) bcopy, memcpy, and memmove. + */ + +void * +_platform_memmove(void *dst0, const void *src0, size_t length) +{ + char *dst = dst0; + const char *src = src0; + size_t t; + + if (length == 0 || dst == src) /* nothing to do */ + goto done; + + /* + * Macros: loop-t-times; and loop-t-times, t>0 + */ +#define TLOOP(s) if (t) TLOOP1(s) +#define TLOOP1(s) do { s; } while (--t) + + if ((unsigned long)dst < (unsigned long)src) { + /* + * Copy forward. + */ + t = (uintptr_t)src; /* only need low bits */ + if ((t | (uintptr_t)dst) & wmask) { + /* + * Try to align operands. This cannot be done + * unless the low bits match. + */ + if ((t ^ (uintptr_t)dst) & wmask || length < wsize) + t = length; + else + t = wsize - (t & wmask); + length -= t; + TLOOP1(*dst++ = *src++); + } + /* + * Copy whole words, then mop up any trailing bytes. + */ + t = length / wsize; + TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); + t = length & wmask; + TLOOP(*dst++ = *src++); + } else { + /* + * Copy backwards. Otherwise essentially the same. + * Alignment works as before, except that it takes + * (t&wmask) bytes to align, not wsize-(t&wmask). + */ + src += length; + dst += length; + t = (uintptr_t)src; + if ((t | (uintptr_t)dst) & wmask) { + if ((t ^ (uintptr_t)dst) & wmask || length <= wsize) + t = length; + else + t &= wmask; + length -= t; + TLOOP1(*--dst = *--src); + } + t = length / wsize; + TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); + t = length & wmask; + TLOOP(*--dst = *--src); + } +done: + return (dst0); +} + +#if VARIANT_STATIC +void * +memmove(void *dst0, const void *src0, size_t length) +{ + return _platform_memmove(dst0, src0, length); +} + +void * +memcpy(void *dst0, const void *src0, size_t length) +{ + return _platform_memmove(dst0, src0, length); +} +#endif + +#endif diff --git a/src/external/libplatform/src/string/generic/memset_pattern.c b/src/external/libplatform/src/string/generic/memset_pattern.c new file mode 100644 index 000000000..94aa08530 --- /dev/null +++ b/src/external/libplatform/src/string/generic/memset_pattern.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +#if !_PLATFORM_OPTIMIZED_MEMSET_PATTERN4 + +void +_platform_memset_pattern4(void *b, const void *pattern4, size_t len) +{ + char * start = (char *)b; + char * p = (char *)b; + while ((start + len) - p >= 4) { + _platform_memmove(p, pattern4, 4); + p += 4; + } + if ((start + len) - p != 0) { + _platform_memmove(p, pattern4, (start + len) - p); + } +} + +#if VARIANT_STATIC +void +memset_pattern4(void *b, const void *pattern4, size_t len) +{ + return _platform_memset_pattern4(b, pattern4, len); +} +#endif + +#endif + + +#if !_PLATFORM_OPTIMIZED_MEMSET_PATTERN8 + +void +_platform_memset_pattern8(void *b, const void *pattern8, size_t len) +{ + char * start = (char *)b; + char * p = (char *)b; + while ((start + len) - p >= 8) { + _platform_memmove(p, pattern8, 8); + p += 8; + } + if ((start + len) - p != 0) { + _platform_memmove(p, pattern8, (start + len) - p); + } +} + +#if VARIANT_STATIC +void +memset_pattern8(void *b, const void *pattern8, size_t len) +{ + return _platform_memset_pattern8(b, pattern8, len); +} +#endif + +#endif + + +#if !_PLATFORM_OPTIMIZED_MEMSET_PATTERN16 + +void +_platform_memset_pattern16(void *b, const void *pattern16, size_t len) +{ + char * start = (char *)b; + char * p = (char *)b; + while ((start + len) - p >= 16) { + _platform_memmove(p, pattern16, 16); + p += 16; + } + if ((start + len) - p != 0) { + _platform_memmove(p, pattern16, (start + len) - p); + } +} + +#if VARIANT_STATIC +void +memset_pattern16(void *b, const void *pattern16, size_t len) +{ + return _platform_memset_pattern16(b, pattern16, len); +} +#endif + +#endif diff --git a/src/external/libplatform/src/string/generic/strchr.c b/src/external/libplatform/src/string/generic/strchr.c new file mode 100644 index 000000000..d290e15e0 --- /dev/null +++ b/src/external/libplatform/src/string/generic/strchr.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#if !_PLATFORM_OPTIMIZED_STRCHR + +#include + +char * +_platform_strchr(const char *p, int ch) +{ + char c; + + c = ch; + for (;; ++p) { + if (*p == c) + return ((char *)p); + if (*p == '\0') + return (NULL); + } + /* NOTREACHED */ +} + +#if VARIANT_STATIC +char * +strchr(const char *p, int ch) +{ + return _platform_strchr(p, ch); +} +#endif + +#endif diff --git a/src/libc/string/FreeBSD/strcmp.c b/src/external/libplatform/src/string/generic/strcmp.c similarity index 82% rename from src/libc/string/FreeBSD/strcmp.c rename to src/external/libplatform/src/string/generic/strcmp.c index f1cb0b511..bc46727d6 100644 --- a/src/libc/string/FreeBSD/strcmp.c +++ b/src/external/libplatform/src/string/generic/strcmp.c @@ -30,3 +30,25 @@ * SUCH DAMAGE. */ +#include + +#if !_PLATFORM_OPTIMIZED_STRCMP + +int +_platform_strcmp(const char *s1, const char *s2) +{ + while (*s1 == *s2++) + if (*s1++ == '\0') + return (0); + return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); +} + +#if VARIANT_STATIC +int +strcmp(const char *s1, const char *s2) +{ + return _platform_strcmp(s1, s2); +} +#endif + +#endif diff --git a/src/libc/string/FreeBSD/strncmp.c b/src/external/libplatform/src/string/generic/strncmp.c similarity index 87% rename from src/libc/string/FreeBSD/strncmp.c rename to src/external/libplatform/src/string/generic/strncmp.c index 33c412b96..2f8c80f73 100644 --- a/src/libc/string/FreeBSD/strncmp.c +++ b/src/external/libplatform/src/string/generic/strncmp.c @@ -27,16 +27,12 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)strncmp.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/strncmp.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); +#include -#include +#if !_PLATFORM_OPTIMIZED_STRNCMP int -strncmp(const char *s1, const char *s2, size_t n) +_platform_strncmp(const char *s1, const char *s2, size_t n) { if (n == 0) @@ -50,3 +46,13 @@ strncmp(const char *s1, const char *s2, size_t n) } while (--n != 0); return (0); } + +#if VARIANT_STATIC +int +strncmp(const char *s1, const char *s2, size_t n) +{ + return _platform_strncmp(s1, s2, n); +} +#endif + +#endif diff --git a/src/external/libplatform/src/ucontext/generic/getmcontext.c b/src/external/libplatform/src/ucontext/generic/getmcontext.c new file mode 100644 index 000000000..255628f89 --- /dev/null +++ b/src/external/libplatform/src/ucontext/generic/getmcontext.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2007, 2008, 2009 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#define _XOPEN_SOURCE 600L +#include +#include + +#if defined(__x86_64__) || defined(__i386__) + +#include +#include +#include +#include + +extern int __sigaltstack(const stack_t * __restrict, stack_t * __restrict); + +#ifdef __DYNAMIC__ +extern int __in_sigtramp; +#endif /* __DYNAMIC_ */ + +__attribute__((visibility("hidden"))) +mcontext_t +getmcontext(ucontext_t *uctx, void *sp) +{ + mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; + size_t stacksize = 0; + stack_t stack; + + uctx->uc_stack.ss_sp = sp; + uctx->uc_stack.ss_flags = 0; + + if (0 == __sigaltstack(NULL, &stack)) { + if (stack.ss_flags & SS_ONSTACK) { + uctx->uc_stack = stack; + stacksize = stack.ss_size; + } + } + + if (stacksize == 0) { + struct rlimit rlim; + if (0 == getrlimit(RLIMIT_STACK, &rlim)) + stacksize = rlim.rlim_cur; + } + + uctx->uc_stack.ss_size = stacksize; + + if (uctx->uc_mcontext != mctx) { + uctx->uc_mcontext = mctx; + +#ifdef __DYNAMIC__ + uctx->uc_link = (ucontext_t*)(uintptr_t)__in_sigtramp; /* non-zero if in signal handler */ +#else /* !__DYNAMIC__ */ + uctx->uc_link = 0; +#endif /* __DYNAMIC__ */ + + } + + sigprocmask(0, NULL, &uctx->uc_sigmask); + return mctx; +} + +#else + +int +getcontext(ucontext_t *u) +{ + errno = ENOTSUP; + return -1; +} + +#endif diff --git a/src/external/libplatform/src/ucontext/generic/makecontext.c b/src/external/libplatform/src/ucontext/generic/makecontext.c new file mode 100644 index 000000000..4f8a39d16 --- /dev/null +++ b/src/external/libplatform/src/ucontext/generic/makecontext.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2007, 2009 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2001 Daniel M. Eischen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define _XOPEN_SOURCE 600L +#include +#include + +#if defined(__x86_64__) || defined(__i386__) +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#include +#include +#include +#include + +/* Prototypes */ +extern void _ctx_start(ucontext_t *, int argc, ...); + +__attribute__((visibility("hidden"))) +void +_ctx_done (ucontext_t *ucp) +{ + if (ucp->uc_link == NULL) + _exit(0); + else { + /* + * Since this context has finished, don't allow it + * to be restarted without being reinitialized (via + * setcontext or swapcontext). + */ + ucp->uc_mcsize = 0; + + /* Set context to next one in link */ + /* XXX - what to do for error, abort? */ + setcontext((const ucontext_t *)ucp->uc_link); + __builtin_trap(); /* should never get here */ + } +} + +void +makecontext(ucontext_t *ucp, void (*start)(), int argc, ...) +{ + va_list ap; + char *stack_top; + intptr_t *argp; + int i; + + if (ucp == NULL) + return; + else if ((ucp->uc_stack.ss_sp == NULL) || + (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { + /* + * This should really return -1 with errno set to ENOMEM + * or something, but the spec says that makecontext is + * a void function. At least make sure that the context + * isn't valid so it can't be used without an error. + */ + ucp->uc_mcsize = 0; + } + /* XXX - Do we want to sanity check argc? */ + else if ((argc < 0) || (argc > NCARGS)) { + ucp->uc_mcsize = 0; + } + /* Make sure the context is valid. */ + else { + /* + * Arrange the stack as follows: + * + * _ctx_start() - context start wrapper + * start() - user start routine + * arg1 - first argument, aligned(16) + * ... + * argn + * ucp - this context, %rbp/%ebp points here + * + * When the context is started, control will return to + * the context start wrapper which will pop the user + * start routine from the top of the stack. After that, + * the top of the stack will be setup with all arguments + * necessary for calling the start routine. When the + * start routine returns, the context wrapper then sets + * the stack pointer to %rbp/%ebp which was setup to point to + * the base of the stack (and where ucp is stored). It + * will then call _ctx_done() to swap in the next context + * (uc_link != 0) or exit the program (uc_link == 0). + */ + mcontext_t mc; + + stack_top = (char *)(ucp->uc_stack.ss_sp + + ucp->uc_stack.ss_size - sizeof(intptr_t)); + + int minargc = argc; +#if defined(__x86_64__) + /* Give 6 stack slots to _ctx_start */ + if (minargc < 6) + minargc = 6; +#endif + /* + * Adjust top of stack to allow for 3 pointers (return + * address, _ctx_start, and ucp) and argc arguments. + * We allow the arguments to be pointers also. The first + * argument to the user function must be properly aligned. + */ + + stack_top = stack_top - (sizeof(intptr_t) * (1 + minargc)); + stack_top = (char *)((intptr_t)stack_top & ~15); + stack_top = stack_top - (2 * sizeof(intptr_t)); + argp = (intptr_t *)stack_top; + + /* + * Setup the top of the stack with the user start routine + * followed by all of its aguments and the pointer to the + * ucontext. We need to leave a spare spot at the top of + * the stack because setcontext will move rip/eip to the top + * of the stack before returning. + */ + *argp = (intptr_t)_ctx_start; /* overwritten with same value */ + argp++; + *argp = (intptr_t)start; + argp++; + + /* Add all the arguments: */ + va_start(ap, argc); + for (i = 0; i < argc; i++) { + *argp = va_arg(ap, intptr_t); + argp++; + } + va_end(ap); + +#if defined(__x86_64__) + /* Always provide space for ctx_start to pop the parameter registers */ + for (;argc < minargc; argc++) { + *argp++ = 0; + } + + /* Keep stack aligned */ + if (argc & 1) { + *argp++ = 0; + } +#endif + + /* The ucontext is placed at the bottom of the stack. */ + *argp = (intptr_t)ucp; + + /* + * Set the machine context to point to the top of the + * stack and the program counter to the context start + * wrapper. Note that setcontext() pushes the return + * address onto the top of the stack, so allow for this + * by adjusting the stack downward 1 slot. Also set + * %r12/%esi to point to the base of the stack where ucp + * is stored. + */ + mc = ucp->uc_mcontext; +#if defined(__x86_64__) + /* Use callee-save and match _ctx_start implementation */ + mc->__ss.__r12 = (intptr_t)argp; + mc->__ss.__rbp = 0; + mc->__ss.__rsp = (intptr_t)stack_top + sizeof(caddr_t); + mc->__ss.__rip = (intptr_t)_ctx_start; +#else + mc->__ss.__esi = (int)argp; + mc->__ss.__ebp = 0; + mc->__ss.__esp = (int)stack_top + sizeof(caddr_t); + mc->__ss.__eip = (int)_ctx_start; +#endif + } +} + +#else + +void +makecontext(ucontext_t *u, void (*f)(void), int a, ...) +{ +} + +#endif diff --git a/src/external/libplatform/src/ucontext/generic/setcontext.c b/src/external/libplatform/src/ucontext/generic/setcontext.c new file mode 100644 index 000000000..ac2faaccd --- /dev/null +++ b/src/external/libplatform/src/ucontext/generic/setcontext.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2007, 2009 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#define _XOPEN_SOURCE 600L +#include +#include + +#if defined(__x86_64__) || defined(__i386__) + +#include +#include + +extern int _setcontext(const void *); + +int +setcontext(const ucontext_t *uctx) +{ + mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; + ucontext_t *_uctx = (ucontext_t *)uctx; + if (mctx != _uctx->uc_mcontext) + _uctx->uc_mcontext = mctx; + sigprocmask(SIG_SETMASK, &uctx->uc_sigmask, NULL); + +#if defined(__x86_64__) + return _setcontext(mctx); +#else + return _setcontext(uctx); +#endif +} + +#else + +int +setcontext(const ucontext_t *uctx) +{ + errno = ENOTSUP; + return -1; +} + +#endif diff --git a/src/external/libplatform/src/ucontext/generic/swapcontext.c b/src/external/libplatform/src/ucontext/generic/swapcontext.c new file mode 100644 index 000000000..219570040 --- /dev/null +++ b/src/external/libplatform/src/ucontext/generic/swapcontext.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2007, 2009 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2001 Daniel M. Eischen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define _XOPEN_SOURCE 600L +#include +#include + +#if defined(__x86_64__) || defined(__i386__) +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#include +#include +#include + +#define uc_flags uc_onstack +#define UCF_SWAPPED 0x80000000 + +int +swapcontext(ucontext_t *oucp, const ucontext_t *ucp) +{ + int ret; + + if ((oucp == NULL) || (ucp == NULL)) { + errno = EINVAL; + return (-1); + } + oucp->uc_flags &= ~UCF_SWAPPED; + ret = getcontext(oucp); + if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) { + oucp->uc_flags |= UCF_SWAPPED; + ret = setcontext(ucp); + } + asm(""); // Prevent tailcall + return (ret); +} + +#else + +int +swapcontext(ucontext_t *oucp, const ucontext_t *ucp) +{ + errno = ENOTSUP; + return -1; +} + +#endif diff --git a/src/external/libplatform/src/ucontext/i386/_ctx_start.S b/src/external/libplatform/src/ucontext/i386/_ctx_start.S new file mode 100644 index 000000000..f066c5b85 --- /dev/null +++ b/src/external/libplatform/src/ucontext/i386/_ctx_start.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2001 Daniel Eischen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(__i386__) + +#include + +/* + * _ctx_start((void *func)(int arg1, ..., argn), + * int arg1, ..., argn, ucontext_t *ucp) + * + * 0(%esp) - func + * 4(%esp) - arg1 + * 8(%esp) - arg2 + * ... + * (4*n)(%esp) - argn + * (4*(n + 1))(%esp) - ucp, %ebp setup to point here (base of stack) + */ +TEXT +.private_extern __ctx_start +LABEL(__ctx_start) + popl %eax /* get start function */ + call *%eax /* call start function */ + movl %esi, %esp /* + * setup stack for completion routine; + * ucp is now at top of stack + */ + CALL_EXTERN(__ctx_done) /* should never return */ + int $5 /* trap */ + +#endif /* __i386__ */ diff --git a/src/external/libplatform/src/ucontext/i386/_setcontext.S b/src/external/libplatform/src/ucontext/i386/_setcontext.S new file mode 100644 index 000000000..6989254ce --- /dev/null +++ b/src/external/libplatform/src/ucontext/i386/_setcontext.S @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if defined(__i386__) + +#include + +TEXT +.private_extern __setcontext +LABEL(__setcontext) + movl 4(%esp), %ecx + movl 28(%ecx), %ecx + movl 16(%ecx), %ebx + movl 28(%ecx), %edi + movl 32(%ecx), %esi + movl 36(%ecx), %ebp + movl 40(%ecx), %esp + pushl 48(%ecx) + popfl + movl 12(%ecx), %eax + jmp *52(%ecx) + +#endif /* __i386__ */ diff --git a/src/external/libplatform/src/ucontext/i386/getcontext.S b/src/external/libplatform/src/ucontext/i386/getcontext.S new file mode 100644 index 000000000..8cbe4c690 --- /dev/null +++ b/src/external/libplatform/src/ucontext/i386/getcontext.S @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if defined(__i386__) + +#include + +TEXT +LABEL(_getcontext) + subl $28, %esp + movl 32(%esp), %eax + movl %eax, (%esp) + movl %esp, 4(%esp) + CALL_EXTERN(_getmcontext) + movl %eax, %ecx + addl $28, %esp + movl %ebx, 16(%ecx) + movl %edi, 28(%ecx) + movl %esi, 32(%ecx) + movl %ebp, 36(%ecx) + movl (%esp), %eax + movl %eax, 52(%ecx) + movl %esp, %eax + addl $4, %eax + movl %eax, 40(%ecx) + pushf + popl %eax + movl %eax, 48(%ecx) + xorl %eax, %eax + movl %eax, 12(%ecx) + ret + +#endif /* __i386__ */ diff --git a/src/external/libplatform/src/ucontext/x86_64/_ctx_start.S b/src/external/libplatform/src/ucontext/x86_64/_ctx_start.S new file mode 100644 index 000000000..5ab64a260 --- /dev/null +++ b/src/external/libplatform/src/ucontext/x86_64/_ctx_start.S @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * Copyright (c) 2001 Daniel Eischen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(__x86_64__) + +#include + +/* + * _ctx_start((void *func)(int arg1, ..., argn), + * int arg1, ..., argn, ucontext_t *ucp) + * + * %rdi - func + * %rsi - arg1 + * %rdx - arg2 + * %rcx - arg3 + * %r8 - arg4 + * %r9 - arg5 + * WRONG! + * (8*(n-6))(%rsp) - argn + * (8*(n + 1))(%rsp) - ucp, %rbp setup to point here (base of stack) + */ +TEXT +.private_extern __ctx_start +LABEL(__ctx_start) + popq %rax /* accounted for in makecontext() */ + /* makecontext will simulate 6 parameters at least */ + /* Or it could just set these in the mcontext... */ + popq %rdi + popq %rsi + popq %rdx + popq %rcx + popq %r8 + popq %r9 + + callq *%rax /* call start function */ + movq %r12, %rsp /* + * setup stack for completion routine; + * ucp is now at top of stack + */ + movq (%rsp), %rdi + CALL_EXTERN(__ctx_done) /* should never return */ + int $5 /* trap */ + +#endif /* __x86_64__ */ diff --git a/src/external/libplatform/src/ucontext/x86_64/_setcontext.S b/src/external/libplatform/src/ucontext/x86_64/_setcontext.S new file mode 100644 index 000000000..7688adde8 --- /dev/null +++ b/src/external/libplatform/src/ucontext/x86_64/_setcontext.S @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2007,2009 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if defined(__x86_64__) + +#include + +#define MCONTEXT_SS_RAX 16 +#define MCONTEXT_SS_RBX 24 +#define MCONTEXT_SS_RCX 32 +#define MCONTEXT_SS_RDX 40 +#define MCONTEXT_SS_RDI 48 +#define MCONTEXT_SS_RSI 56 +#define MCONTEXT_SS_RBP 64 +#define MCONTEXT_SS_RSP 72 +#define MCONTEXT_SS_R8 80 +#define MCONTEXT_SS_RIP 144 +#define MCONTEXT_SS_RFLAGS 152 + +TEXT +.private_extern __setcontext +LABEL(__setcontext) + /* struct mcontext_t * %rdi */ +#if DEBUG + movq MCONTEXT_SS_RSI(%rdi), %rsi + movq MCONTEXT_SS_RCX(%rdi), %rcx + movq MCONTEXT_SS_R8+0(%rdi), %r8 + movq MCONTEXT_SS_R8+8(%rdi), %r9 + movq MCONTEXT_SS_R8+16(%rdi), %r10 + movq MCONTEXT_SS_R8+24(%rdi), %r11 +#endif + movq MCONTEXT_SS_RBX(%rdi), %rbx + movq MCONTEXT_SS_R8+32(%rdi), %r12 + movq MCONTEXT_SS_R8+40(%rdi), %r13 + movq MCONTEXT_SS_R8+48(%rdi), %r14 + movq MCONTEXT_SS_R8+56(%rdi), %r15 + + movq MCONTEXT_SS_RSP(%rdi), %rsp + movq MCONTEXT_SS_RBP(%rdi), %rbp + + xorl %eax, %eax /* force x=getcontext(); ... setcontext(); to keep x==0 */ + +#if DEBUG + movq MCONTEXT_SS_RIP(%rdi), %rdx + movq MCONTEXT_SS_RDI(%rdi), %rdi + jmp *%rdx +#else + jmp *MCONTEXT_SS_RIP(%rdi) +#endif + +#endif /* __x86_64__ */ diff --git a/src/external/libplatform/src/ucontext/x86_64/getcontext.S b/src/external/libplatform/src/ucontext/x86_64/getcontext.S new file mode 100644 index 000000000..e6a303cd0 --- /dev/null +++ b/src/external/libplatform/src/ucontext/x86_64/getcontext.S @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2007,2009 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if defined(__x86_64__) + +#include + +#define MCONTEXT_SS_RAX 16 +#define MCONTEXT_SS_RBX 24 +#define MCONTEXT_SS_RCX 32 +#define MCONTEXT_SS_RDX 40 +#define MCONTEXT_SS_RDI 48 +#define MCONTEXT_SS_RSI 56 +#define MCONTEXT_SS_RBP 64 +#define MCONTEXT_SS_RSP 72 +#define MCONTEXT_SS_R8 80 +#define MCONTEXT_SS_RIP 144 +#define MCONTEXT_SS_RFLAGS 152 + +TEXT +LABEL(_getcontext) + /* struct ucontext_t * $rdi */ + push %rbp + movq %rsp, %rbp + movq %rsp, %rsi + CALL_EXTERN(_getmcontext) /* getmcontext(uctx, sp) */ + pop %rbp + +#if DEBUG + movq $0, MCONTEXT_SS_RAX(%rax) + movq $0, MCONTEXT_SS_RDX(%rax) + movq $0, MCONTEXT_SS_RCX(%rax) + movq $0, MCONTEXT_SS_RDI(%rax) + movq $0, MCONTEXT_SS_RSI(%rax) + movq $0, MCONTEXT_SS_R8(%rax) + movq $0, MCONTEXT_SS_R8+8(%rax) + movq $0, MCONTEXT_SS_R8+16(%rax) + movq $0, MCONTEXT_SS_R8+24(%rax) + movq $0, MCONTEXT_SS_RFLAGS(%rax) +#endif + + movq %rbp, MCONTEXT_SS_RBP(%rax) + movq %rbx, MCONTEXT_SS_RBX(%rax) + movq %r12, MCONTEXT_SS_R8+32(%rax) + movq %r13, MCONTEXT_SS_R8+40(%rax) + movq %r14, MCONTEXT_SS_R8+48(%rax) + movq %r15, MCONTEXT_SS_R8+56(%rax) + movq (%rsp), %rcx /* return address */ + movq %rcx, MCONTEXT_SS_RIP(%rax) + leaq 8(%rsp), %rcx + movq %rcx, MCONTEXT_SS_RSP(%rax) + xorl %eax, %eax + ret + +#endif /* __x86_64__ */ diff --git a/src/external/libplatform/xcodeconfig/atomics.xcconfig b/src/external/libplatform/xcodeconfig/atomics.xcconfig new file mode 100644 index 000000000..e284e51e3 --- /dev/null +++ b/src/external/libplatform/xcodeconfig/atomics.xcconfig @@ -0,0 +1,12 @@ +#include "libplatform.xcconfig" +#include "perarch.xcconfig" + +// Make sure that OSAtomic isn't build unoptimised, otherwise the inlines +// don't do what they are designed to do. +COMPILER_CFLAGS = -momit-leaf-frame-pointer +OTHER_CFLAGS_debug = + +OSATOMIC_PREPROCESSOR_DEFINITIONS = OSATOMIC_USE_INLINED=0 OSATOMIC_DEPRECATED=0 + +PUBLIC_HEADERS_FOLDER_PATH = /usr/include/libkern +PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/libkern diff --git a/src/external/libplatform/xcodeconfig/libplatform.aliases b/src/external/libplatform/xcodeconfig/libplatform.aliases new file mode 100644 index 000000000..842ba78a7 --- /dev/null +++ b/src/external/libplatform/xcodeconfig/libplatform.aliases @@ -0,0 +1 @@ +__platform_bzero ___bzero diff --git a/src/external/libplatform/xcodeconfig/libplatform.xcconfig b/src/external/libplatform/xcodeconfig/libplatform.xcconfig new file mode 100644 index 000000000..e607f4b65 --- /dev/null +++ b/src/external/libplatform/xcodeconfig/libplatform.xcconfig @@ -0,0 +1,72 @@ +#include "/Makefiles/CoreOS/Xcode/BSD.xcconfig" + +VERSIONING_SYSTEM = "" + +// Standard settings +SDKROOT = macosx.internal +SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator +BUILD_VARIANTS = normal debug dyld static + +EXECUTABLE_PREFIX = lib +INSTALL_PATH = /usr/lib/system +PUBLIC_HEADERS_FOLDER_PATH = /usr/include +PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include + +USE_HEADERMAP = NO +SKIP_INSTALL = YES +INSTALLHDRS_SCRIPT_PHASE = YES + +GCC_OPTIMIZATION_LEVEL = s + +// TODO: Remove -fno-stack-protector once it has been moved down (after libproc is moved down) +OTHER_CFLAGS = -fno-stack-protector -fdollars-in-identifiers -fno-common -fverbose-asm $(COMPILER_CFLAGS) -isystem $(SYSTEM_FRAMEWORK_HEADERS) +OTHER_CFLAGS_normal = -momit-leaf-frame-pointer +OTHER_CFLAGS_debug = -fno-inline -O0 + +GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS_$(CURRENT_VARIANT)) $(OSATOMIC_PREPROCESSOR_DEFINITIONS) +GCC_PREPROCESSOR_DEFINITIONS_dyld = VARIANT_DYLD=1 VARIANT_NO_RESOLVERS=1 VARIANT_STATIC=1 +GCC_PREPROCESSOR_DEFINITIONS_static = VARIANT_NO_RESOLVERS=1 VARIANT_STATIC=1 +GCC_PREPROCESSOR_DEFINITIONS_debug = DEBUG=1 + +OSATOMIC_PREPROCESSOR_DEFINITIONS = OSATOMIC_USE_INLINED=1 OSSPINLOCK_USE_INLINED=1 OS_UNFAIR_LOCK_INLINE=0 + +STRIP_INSTALLED_PRODUCT = $(STRIP_INSTALLED_PRODUCT_$(CURRENT_VARIANT)) +STRIP_INSTALLED_PRODUCT_normal = YES +STRIP_INSTALLED_PRODUCT_dyld = NO +STRIP_INSTALLED_PRODUCT_static = NO +STRIP_INSTALLED_PRODUCT_debug = YES + +SRCROOT_SEARCH_PATHS = $(SRCROOT)/private $(SRCROOT)/include $(SRCROOT)/internal +SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders +HEADER_SEARCH_PATHS = $(SRCROOT_SEARCH_PATHS) $(SDKROOT)/usr/local/include $(SDKROOT)/usr/include $(inherited) + +DEAD_CODE_STRIPPING = NO + +LINK_WITH_STANDARD_LIBRARIES = NO +DYLIB_CURRENT_VERSION = $(CURRENT_PROJECT_VERSION) + +PLATFORM_LIBRARIES = $(CONFIGURATION_BUILD_DIR)/libsimple_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libatomics_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libcachecontrol_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libos_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libsetjmp_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libstring_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libucontext_$(CURRENT_VARIANT).a +ATOMICS_LIBRARIES = $(CONFIGURATION_BUILD_DIR)/libatomics_i386_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libatomics_x86_64_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libatomics_arm_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libatomics_arm64_$(CURRENT_VARIANT).a $(EXTRA_ATOMICS_LIBRARIES) +CACHECONTROL_LIBRARIES = $(CONFIGURATION_BUILD_DIR)/libcachecontrol_i386_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libcachecontrol_x86_64_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libcachecontrol_arm_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libcachecontrol_arm64_$(CURRENT_VARIANT).a $(EXTRA_CACHECONTROL_LIBRARIES) +SETJMP_LIBRARIES = $(CONFIGURATION_BUILD_DIR)/libsetjmp_i386_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libsetjmp_x86_64_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libsetjmp_arm_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libsetjmp_arm64_$(CURRENT_VARIANT).a $(EXTRA_SETJMP_LIBRARIES) +STRING_LIBRARIES = $(CONFIGURATION_BUILD_DIR)/libstring_i386_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libstring_x86_64_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libstring_arm_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libstring_arm64_$(CURRENT_VARIANT).a $(EXTRA_STRING_LIBRARIES) +UCONTEXT_LIBRARIES = $(CONFIGURATION_BUILD_DIR)/libucontext_i386_$(CURRENT_VARIANT).a $(CONFIGURATION_BUILD_DIR)/libucontext_x86_64_$(CURRENT_VARIANT).a + +OTHER_LDFLAGS = $(OTHER_LDFLAGS_$(TARGET_NAME)) $(CR_LDFLAGS) +OTHER_LDFLAGS_libsystem_platform = -all_load $(PLATFORM_LIBRARIES) -umbrella System -L/usr/lib/system -ldyld -lcompiler_rt $(lsystem_kernel) -Wl,-alias_list,$(SRCROOT)/xcodeconfig/libplatform.aliases,$(DIRTY_DATA_LDFLAGS) + +OTHER_LIBTOOLFLAGS = $(OTHER_LIBTOOLFLAGS_$(TARGET_NAME)) +OTHER_LIBTOOLFLAGS_libplatform_simple_dyld = $(CONFIGURATION_BUILD_DIR)/libsimple_$(CURRENT_VARIANT).a +OTHER_LIBTOOLFLAGS_libplatform_string_dyld = $(CONFIGURATION_BUILD_DIR)/libstring_$(CURRENT_VARIANT).a +OTHER_LIBTOOLFLAGS_libplatform_os_dyld = +OTHER_LIBTOOLFLAGS_libplatform_dyld = $(PLATFORM_LIBRARIES) +OTHER_LIBTOOLFLAGS_libplatform_static = $(PLATFORM_LIBRARIES) +OTHER_LIBTOOLFLAGS_libatomics = $(ATOMICS_LIBRARIES) +OTHER_LIBTOOLFLAGS_libcachecontrol = $(CACHECONTROL_LIBRARIES) +OTHER_LIBTOOLFLAGS_libsetjmp = $(SETJMP_LIBRARIES) +OTHER_LIBTOOLFLAGS_libstring = $(STRING_LIBRARIES) +OTHER_LIBTOOLFLAGS_libucontext = $(UCONTEXT_LIBRARIES) + +lsystem_kernel = -lsystem_kernel +lsystem_kernel[sdk=iphonesimulator*] = -lsystem_sim_kernel + diff --git a/src/external/libplatform/xcodeconfig/os.xcconfig b/src/external/libplatform/xcodeconfig/os.xcconfig new file mode 100644 index 000000000..b163c0f41 --- /dev/null +++ b/src/external/libplatform/xcodeconfig/os.xcconfig @@ -0,0 +1,28 @@ +#include "libplatform.xcconfig" + +GCC_STRICT_ALIASING = YES +GCC_SYMBOLS_PRIVATE_EXTERN = YES +GCC_WARN_SHADOW = YES +GCC_WARN_64_TO_32_BIT_CONVERSION = YES +GCC_WARN_ABOUT_RETURN_TYPE = YES +GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES +GCC_WARN_ABOUT_MISSING_NEWLINE = YES +GCC_WARN_UNUSED_VARIABLE = YES +GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES +GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES +GCC_WARN_SIGN_COMPARE = YES +GCC_WARN_UNINITIALIZED_AUTOS = YES +CLANG_WARN_EMPTY_BODY = YES +CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES +CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES +GCC_TREAT_WARNINGS_AS_ERRORS = YES +WARNING_CFLAGS = -Wall -Wextra -Waggregate-return -Wfloat-equal -Wpacked -Wmissing-declarations -Wstrict-overflow=4 -Wstrict-aliasing=2 -Wno-unknown-warning-option + +COMPILER_CFLAGS = -momit-leaf-frame-pointer +OTHER_CFLAGS_debug = + +OSATOMIC_PREPROCESSOR_DEFINITIONS = OSATOMIC_USE_INLINED=0 OSATOMIC_DEPRECATED=0 OSSPINLOCK_USE_INLINED=0 OSSPINLOCK_DEPRECATED=0 + +PUBLIC_HEADERS_FOLDER_PATH = /usr/include/os +PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/os +OS_INTERNAL_HEADERS_FOLDER_PATH = /usr/local/include/os/internal diff --git a/src/external/libplatform/xcodeconfig/perarch.xcconfig b/src/external/libplatform/xcodeconfig/perarch.xcconfig new file mode 100644 index 000000000..8ec49100a --- /dev/null +++ b/src/external/libplatform/xcodeconfig/perarch.xcconfig @@ -0,0 +1,27 @@ +ARCH_FAMILY = $(ARCH_FAMILY_$(CURRENT_ARCH)) +ARCH_FAMILY_x86_64 = x86_64 +ARCH_FAMILY_i386 = i386 +ARCH_FAMILY_armv6 = arm +ARCH_FAMILY_armv7 = arm +ARCH_FAMILY_armv7s = arm +ARCH_FAMILY_armv7f = arm +ARCH_FAMILY_armv7k = arm +ARCH_FAMILY_arm64 = arm64 + +EXCLUDED_SOURCE_FILE_NAMES = * + +INCLUDED_SOURCE_FILE_NAMES = force_libplatform_to_build.c $(INCLUDED_SOURCE_FILE_NAMES_$(PERARCH_TARGET)_TARGET) +INCLUDED_SOURCE_FILE_NAMES__TARGET = $(INCLUDED_SOURCE_FILE_NAMES_$(ARCH_FAMILY_THIS_SLICE)_$(ARCH_FAMILY)) + +INCLUDED_SOURCE_FILE_NAMES_arm_arm = * +INCLUDED_SOURCE_FILE_NAMES__arm = * +INCLUDED_SOURCE_FILE_NAMES_arm64_arm64 = * +INCLUDED_SOURCE_FILE_NAMES__arm64 = * +INCLUDED_SOURCE_FILE_NAMES_i386_i386 = * +INCLUDED_SOURCE_FILE_NAMES__i386 = * +INCLUDED_SOURCE_FILE_NAMES_x86_64_x86_64 = * +INCLUDED_SOURCE_FILE_NAMES__x86_64 = * + +// To force fallback to generic C implementations for dyld_Sim +INCLUDED_SOURCE_FILE_NAMES_x86_64_x86_64[sdk=iphonesimulator*] = +INCLUDED_SOURCE_FILE_NAMES_i386_i386[sdk=iphonesimulator*] = diff --git a/src/external/libplatform/xcodeconfig/static.xcconfig b/src/external/libplatform/xcodeconfig/static.xcconfig new file mode 100644 index 000000000..92ec0e31a --- /dev/null +++ b/src/external/libplatform/xcodeconfig/static.xcconfig @@ -0,0 +1,9 @@ +#include "libplatform.xcconfig" + +// pick _static in libplatform.xcconfig +BUILD_VARIANTS = static + +EXECUTABLE_PREFIX = lib +PRODUCT_NAME = platform +INSTALL_PATH = /usr/local/lib/system +SKIP_INSTALL = NO diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 920c1c4ff..6119f78ff 100644 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -6,6 +6,11 @@ if(COMMAND cmake_policy) cmake_policy(SET CMP0018 NEW) endif(COMMAND cmake_policy) +include_directories(${CMAKE_SOURCE_DIR}/kernel-include) +include_directories(${CMAKE_SOURCE_DIR}/src/libc/derived) +include_directories(${CMAKE_SOURCE_DIR}/src/libc/darwin) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + add_subdirectory(emulation/linux) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse -msse2 -msse3 -w -fblocks -ggdb") @@ -16,11 +21,9 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse -msse2 -msse3 -w -fblocks -ggdb") # -> dyld places stubs -> stubs go into dyld_stub_binder at first use # -> there is a temporary loss of 16-byte stack alignment in __darling_bsd_syscall # -> dyld_stub_binder checks for this and bails out with a SIGSEGV -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__DARWIN_UNIX03 -fPIC -w -nostdinc -Wl,-bind_at_load -Wl,-undefined,suppress -Wl,-flat_namespace") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__DARWIN_UNIX03 -fPIC -w -nostdinc -Wl,-bind_at_load") # -Wl,-undefined,suppress -Wl,-flat_namespace") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib") -include_directories(${DARLING_TOP_DIRECTORY}/kernel-include) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_definitions(-DTARGET_OS_MAC=1) add_definitions(-DHAVE_STDINT_H=1) @@ -38,6 +41,7 @@ add_darling_library(system_kernel SHARED ${extra_objs} $) target_link_libraries(system_kernel system_duct) +make_fat(system_kernel) add_library(system_kernel_static STATIC $ diff --git a/src/kernel/emulation/linux/CMakeLists.txt b/src/kernel/emulation/linux/CMakeLists.txt index 59802efbf..6e6294f2d 100644 --- a/src/kernel/emulation/linux/CMakeLists.txt +++ b/src/kernel/emulation/linux/CMakeLists.txt @@ -157,7 +157,7 @@ set(emulation_sources time/getitimer.c ioctl/ioctl.c ioctl/termios.c - ioctl/filio.c + ioctl/filio.c ext/uname.c ext/epoll_create.c ext/epoll_create1.c @@ -229,3 +229,6 @@ add_library(emulation OBJECT ${emulation_sources}) add_library(emulation_dyld OBJECT ${emulation_sources}) set_target_properties(emulation_dyld PROPERTIES COMPILE_FLAGS "-ffunction-sections -DVARIANT_DYLD") +make_fat(emulation) +make_fat(emulation_dyld) + diff --git a/src/kernel/emulation/linux/ioctl/ioctl.c b/src/kernel/emulation/linux/ioctl/ioctl.c index 9f9fe25e8..0f0e193ff 100644 --- a/src/kernel/emulation/linux/ioctl/ioctl.c +++ b/src/kernel/emulation/linux/ioctl/ioctl.c @@ -10,8 +10,7 @@ if (state == IOCTL_HANDLED) return retval; } // Emulated ioctl implementation -VISIBLE -long ioctl(int fd, int cmd, void* arg) +long sys_ioctl(int fd, int cmd, void* arg) { IOCTL_STEP(handle_filio(fd, cmd, arg, &retval)); IOCTL_STEP(handle_termios(fd, cmd, arg, &retval)); diff --git a/src/kernel/emulation/linux/ioctl/ioctl.h b/src/kernel/emulation/linux/ioctl/ioctl.h index 83f81de3c..507dcd10c 100644 --- a/src/kernel/emulation/linux/ioctl/ioctl.h +++ b/src/kernel/emulation/linux/ioctl/ioctl.h @@ -3,6 +3,7 @@ #include extern long __real_ioctl(int fd, int cmd, void* arg); +extern long sys_ioctl(int fd, int cmd, void* arg); enum { IOCTL_PASS, /** ioctl cmd not known */ diff --git a/src/kernel/emulation/linux/misc/ioctl.c b/src/kernel/emulation/linux/misc/ioctl.c index 06762c87f..6bf3f7750 100644 --- a/src/kernel/emulation/linux/misc/ioctl.c +++ b/src/kernel/emulation/linux/misc/ioctl.c @@ -3,7 +3,7 @@ #include "../errno.h" #include -long sys_ioctl(int fd, int req, void* arg) +long __real_ioctl(int fd, int req, void* arg) { int ret; diff --git a/src/kernel/emulation/linux/misc/ioctl.h b/src/kernel/emulation/linux/misc/ioctl.h index c0f2d693e..c6975244b 100644 --- a/src/kernel/emulation/linux/misc/ioctl.h +++ b/src/kernel/emulation/linux/misc/ioctl.h @@ -1,7 +1,7 @@ #ifndef LINUX_IOCTL_H #define LINUX_IOCTL_H -long sys_ioctl(int fd, int req, void* arg); +long __real_ioctl(int fd, int req, void* arg); #endif diff --git a/src/kernel/emulation/linux/stat/common.h b/src/kernel/emulation/linux/stat/common.h index 56d95fc62..613a36215 100644 --- a/src/kernel/emulation/linux/stat/common.h +++ b/src/kernel/emulation/linux/stat/common.h @@ -74,7 +74,7 @@ struct linux_stat { __kernel_ulong_t st_mtime_nsec; __kernel_ulong_t st_ctime; __kernel_ulong_t st_ctime_nsec; - __kernel_long_t __unused[3]; + __kernel_long_t __unused_var[3]; }; #endif diff --git a/src/kernel/emulation/linux/syscalls-table.S b/src/kernel/emulation/linux/syscalls-table.S index ca5a6acc5..67da81b1c 100644 --- a/src/kernel/emulation/linux/syscalls-table.S +++ b/src/kernel/emulation/linux/syscalls-table.S @@ -33,8 +33,7 @@ __darling_bsd_syscall: .L0$pb: popl %ecx .Ltmp0: - addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %ecx - movl ___bsd_syscall_table@GOT(%ecx), %ecx + movl L___bsd_syscall_table$non_lazy_ptr-.L0$pb(%ecx), %ecx andl $0xffff, %eax // Because there is some extra stuff in upper bytes we don't need movl (%ecx,%eax,4), %eax test %eax, %eax @@ -52,10 +51,17 @@ __darling_bsd_syscall: ret .no_sys: pushl %ecx - call __unknown_syscall + call ___unknown_syscall addl $4, %esp ret + .section __IMPORT,__pointers,non_lazy_symbol_pointers +L___bsd_syscall_table$non_lazy_ptr: + .indirect_symbol ___bsd_syscall_table + .long 0 + +.subsections_via_symbols + #else # error Missing assembly #endif diff --git a/src/kernel/emulation/linux/syscalls.c b/src/kernel/emulation/linux/syscalls.c index 0643ca41e..9ad01da74 100644 --- a/src/kernel/emulation/linux/syscalls.c +++ b/src/kernel/emulation/linux/syscalls.c @@ -70,7 +70,7 @@ #include "process/execve.h" #include "misc/getlogin.h" #include "misc/shared_region_check_np.h" -#include "misc/ioctl.h" +#include "ioctl/ioctl.h" #include "misc/getrlimit.h" #include "misc/setrlimit.h" #include "misc/thread_selfid.h" diff --git a/src/kernel/libsyscall/CMakeLists.txt b/src/kernel/libsyscall/CMakeLists.txt index 6a3fc6c4e..9a930558e 100644 --- a/src/kernel/libsyscall/CMakeLists.txt +++ b/src/kernel/libsyscall/CMakeLists.txt @@ -73,35 +73,47 @@ set(syscall_dynamic_sources wrappers/_libkernel_init.c) set(syscall_sources + os/alloc_once.c wrappers/libproc/libproc.c wrappers/libproc/proc_listpidspath.c - #wrappers/coalition.c - # wrappers/__commpage_gettimeofday.c - #wrappers/csr.c + wrappers/carbon_delete.c + wrappers/clonefile.c + wrappers/coalition.c + wrappers/__commpage_gettimeofday.c + wrappers/csr.c + wrappers/fs_snapshot.c wrappers/gethostuuid.c wrappers/getiopolicy_np.c - #wrappers/guarded_open_dprotected_np.c - #wrappers/guarded_open_np.c + wrappers/guarded_open_dprotected_np.c + wrappers/guarded_open_np.c wrappers/init_cpu_capabilities.c wrappers/ioctl.c + wrappers/kdebug_trace.c + wrappers/kill.c wrappers/mach_approximate_time.c + wrappers/mach_boottime.c + wrappers/mach_continuous_time.c + wrappers/mach_get_times.c + wrappers/mach_timebase_info.c wrappers/open_dprotected_np.c + wrappers/persona.c wrappers/posix_sem_obsolete.c + wrappers/quota_obsolete.c wrappers/remove-counter.c wrappers/renameat.c wrappers/rename.c - wrappers/rename_ext.c + wrappers/renamex.c wrappers/rmdir.c - #wrappers/select-base.c wrappers/setpriority.c - #wrappers/sfi.c - #wrappers/sigsuspend-base.c + wrappers/sfi.c + wrappers/stackshot.c + wrappers/terminate_with_reason.c + wrappers/thread_register_state.c wrappers/unlinkat.c wrappers/unlink.c - wrappers/kill.c - - #wrappers/legacy/select.c + wrappers/work_interval.c + wrappers/legacy/select-pre1050.c wrappers/cancelable/fcntl.c @@ -110,6 +122,8 @@ set(syscall_sources wrappers/cancelable/select-cancel.c wrappers/cancelable/sigsuspend.c wrappers/cancelable/sigsuspend-cancel.c + wrappers/cancelable/pselect-darwinext-cancel.c + wrappers/cancelable/pselect-darwinext.c wrappers/unix03/chmod.c wrappers/unix03/fchmod.c @@ -121,7 +135,6 @@ set(syscall_sources ${syscall_legacy_sources} custom/errno.c - #custom/var_errno.c # MIG generated files ${CMAKE_CURRENT_BINARY_DIR}/mach/excUser.c @@ -168,798 +181,415 @@ set(syscall_sources mach/slot_name.c mach/string.c mach/thread_act.c -) -if (BITS EQUAL 64) -set (syscall_sources ${syscall_sources} - sys_x86-64/___accept_nocancel.S - sys_x86-64/___accept.S - sys_x86-64/___access_extended.S - sys_x86-64/_access.S - sys_x86-64/_acct.S - sys_x86-64/_adjtime.S - sys_x86-64/_aio_cancel.S - sys_x86-64/_aio_error.S - sys_x86-64/_aio_fsync.S - sys_x86-64/_aio_read.S - sys_x86-64/_aio_return.S - sys_x86-64/___aio_suspend_nocancel.S - sys_x86-64/_aio_suspend.S - sys_x86-64/_aio_write.S - sys_x86-64/_auditctl.S - sys_x86-64/_auditon.S - sys_x86-64/_audit.S - sys_x86-64/_audit_session_join.S - sys_x86-64/_audit_session_port.S - sys_x86-64/_audit_session_self.S - sys_x86-64/___bind.S - sys_x86-64/___bsdthread_create.S - sys_x86-64/___bsdthread_ctl.S - sys_x86-64/___bsdthread_register.S - sys_x86-64/___bsdthread_terminate.S - sys_x86-64/___close_nocancel.S - sys_x86-64/_close.S - sys_x86-64/___coalition_info.S - sys_x86-64/___coalition.S - sys_x86-64/___connect_nocancel.S - sys_x86-64/___connect.S - sys_x86-64/_connectx.S - sys_x86-64/___copyfile.S - sys_x86-64/_csops_audittoken.S - sys_x86-64/_csops.S - sys_x86-64/___csrctl.S - sys_x86-64/custom.S - sys_x86-64/___delete.S - sys_x86-64/___disable_threadsignal.S - sys_x86-64/_disconnectx.S - sys_x86-64/_dup.S - sys_x86-64/_dup2.S - sys_x86-64/_execve.S - sys_x86-64/_exchangedata.S - sys_x86-64/___exit.S - sys_x86-64/_faccessat.S - sys_x86-64/___fcntl_nocancel.S - sys_x86-64/___fcntl.S - sys_x86-64/_fdatasync.S - sys_x86-64/_ffsctl.S - sys_x86-64/_fgetattrlist.S - sys_x86-64/_fgetxattr.S - sys_x86-64/_fhopen.S - sys_x86-64/_fchdir.S - sys_x86-64/_fchflags.S - sys_x86-64/_fchmodat.S - sys_x86-64/___fchmod_extended.S - sys_x86-64/___fchmod.S - sys_x86-64/_fchownat.S - sys_x86-64/_fchown.S - sys_x86-64/_fileport_makefd.S - sys_x86-64/_fileport_makeport.S - sys_x86-64/_flistxattr.S - sys_x86-64/_flock.S - sys_x86-64/___fork.S - sys_x86-64/_fpathconf.S - sys_x86-64/_fremovexattr.S - sys_x86-64/_fsctl.S - sys_x86-64/_fsetattrlist.S - sys_x86-64/_fsetxattr.S - sys_x86-64/___fsgetpath.S - sys_x86-64/_fstatat.S - sys_x86-64/_fstatat64.S - sys_x86-64/___fstat_extended.S - sys_x86-64/_fstatfs.S - sys_x86-64/_fstatfs64.S - sys_x86-64/_fstat.S - sys_x86-64/___fstat64_extended.S - sys_x86-64/_fstat64.S - sys_x86-64/___fsync_nocancel.S - sys_x86-64/_fsync.S - sys_x86-64/_ftruncate.S - sys_x86-64/_futimes.S - sys_x86-64/_getattrlistat.S - sys_x86-64/_getattrlistbulk.S - sys_x86-64/___getattrlist.S - sys_x86-64/_getaudit_addr.S - sys_x86-64/_getauid.S - sys_x86-64/_getdirentriesattr.S - sys_x86-64/_getdirentries.S - sys_x86-64/___getdirentries64.S - sys_x86-64/_getdtablesize.S - sys_x86-64/_getegid.S - sys_x86-64/_geteuid.S - sys_x86-64/_getfh.S - sys_x86-64/_getfsstat.S - sys_x86-64/_getfsstat64.S - sys_x86-64/_getgid.S - sys_x86-64/_getgroups.S - sys_x86-64/___gethostuuid.S - sys_x86-64/_getitimer.S - sys_x86-64/___getlogin.S - sys_x86-64/___getpeername.S - sys_x86-64/_getpgid.S - sys_x86-64/_getpgrp.S - sys_x86-64/___getpid.S - sys_x86-64/_getppid.S - sys_x86-64/_getpriority.S - sys_x86-64/___getrlimit.S - sys_x86-64/_getrusage.S - sys_x86-64/___getsgroups.S - sys_x86-64/_getsid.S - sys_x86-64/___getsockname.S - sys_x86-64/_getsockopt.S - sys_x86-64/___gettid.S - sys_x86-64/___gettimeofday.S - sys_x86-64/_getuid.S - sys_x86-64/___getwgroups.S - sys_x86-64/_getxattr.S - sys_x86-64/_grab_pgo_data.S - sys_x86-64/_guarded_close_np.S - sys_x86-64/_guarded_kqueue_np.S - sys_x86-64/___guarded_open_dprotected_np.S - sys_x86-64/___guarded_open_np.S - sys_x86-64/_guarded_pwrite_np.S - sys_x86-64/_guarded_write_np.S - sys_x86-64/_guarded_writev_np.S - sys_x86-64/_change_fdguard_np.S - sys_x86-64/_chdir.S - sys_x86-64/_chflags.S - sys_x86-64/___chmod_extended.S - sys_x86-64/___chmod.S - sys_x86-64/_chown.S - sys_x86-64/_chroot.S - sys_x86-64/___chud.S - sys_x86-64/___identitysvc.S - sys_x86-64/___initgroups.S - sys_x86-64/___ioctl.S - sys_x86-64/___iopolicysys.S - sys_x86-64/_issetugid.S - sys_x86-64/_kas_info.S - sys_x86-64/___kdebug_trace.S - sys_x86-64/___kdebug_trace_string.S - sys_x86-64/___kdebug_trace64.S - #sys_x86-64/_kevent_qos.S - #sys_x86-64/_kevent.S - #sys_x86-64/_kevent64.S - sys_x86-64/___kill.S - #sys_x86-64/_kqueue.S - sys_x86-64/_ledger.S - sys_x86-64/___lchown.S - sys_x86-64/_linkat.S - sys_x86-64/_link.S - sys_x86-64/_lio_listio.S - sys_x86-64/___listen.S - sys_x86-64/_listxattr.S - sys_x86-64/___lseek.S - sys_x86-64/___lstat_extended.S - sys_x86-64/_lstat.S - sys_x86-64/___lstat64_extended.S - sys_x86-64/_lstat64.S - sys_x86-64/___mac_execve.S - sys_x86-64/___mac_get_fd.S - sys_x86-64/___mac_get_file.S - sys_x86-64/___mac_getfsstat.S - sys_x86-64/___mac_get_link.S - sys_x86-64/___mac_get_mount.S - sys_x86-64/___mac_get_pid.S - sys_x86-64/___mac_get_proc.S - sys_x86-64/___mac_mount.S - sys_x86-64/___mac_set_fd.S - sys_x86-64/___mac_set_file.S - sys_x86-64/___mac_set_link.S - sys_x86-64/___mac_set_proc.S - sys_x86-64/___mac_syscall.S - sys_x86-64/_madvise.S - sys_x86-64/_memorystatus_control.S - sys_x86-64/_memorystatus_get_level.S - sys_x86-64/___microstackshot.S - sys_x86-64/_mincore.S - sys_x86-64/_minherit.S - sys_x86-64/_mkdirat.S - sys_x86-64/___mkdir_extended.S - sys_x86-64/_mkdir.S - sys_x86-64/___mkfifo_extended.S - sys_x86-64/_mkfifo.S - sys_x86-64/_mknod.S - sys_x86-64/_mlockall.S - sys_x86-64/_mlock.S - sys_x86-64/___mmap.S - sys_x86-64/_modwatch.S - sys_x86-64/_mount.S - sys_x86-64/___mprotect.S - sys_x86-64/_mremap_encrypted.S - sys_x86-64/___msgctl.S - sys_x86-64/_msgget.S - sys_x86-64/___msgrcv_nocancel.S - sys_x86-64/_msgrcv.S - sys_x86-64/___msgsnd_nocancel.S - sys_x86-64/_msgsnd.S - sys_x86-64/___msgsys.S - sys_x86-64/___msync_nocancel.S - sys_x86-64/___msync.S - sys_x86-64/_munlockall.S - sys_x86-64/_munlock.S - sys_x86-64/___munmap.S - sys_x86-64/_necp_match_policy.S - sys_x86-64/_netagent_trigger.S - sys_x86-64/_nfsclnt.S - sys_x86-64/_nfssvc.S - sys_x86-64/_____old_semwait_signal_nocancel.S - sys_x86-64/___old_semwait_signal.S - sys_x86-64/___openat_nocancel.S - sys_x86-64/___openat.S - sys_x86-64/_openbyid_np.S - sys_x86-64/___open_dprotected_np.S - sys_x86-64/___open_extended.S - sys_x86-64/___open_nocancel.S - sys_x86-64/___open.S - sys_x86-64/_pathconf.S - sys_x86-64/_peeloff.S - sys_x86-64/___persona.S - sys_x86-64/_pid_resume.S - sys_x86-64/_pid_suspend.S - sys_x86-64/___pipe.S - sys_x86-64/___poll_nocancel.S - sys_x86-64/_poll.S - sys_x86-64/___posix_spawn.S - sys_x86-64/___pread_nocancel.S - sys_x86-64/_pread.S - sys_x86-64/___process_policy.S - sys_x86-64/___proc_info.S - sys_x86-64/_proc_rlimit_control.S - sys_x86-64/_proc_trace_log.S - sys_x86-64/_proc_uuid_policy.S - sys_x86-64/___pselect_nocancel.S - sys_x86-64/___pselect.S - sys_x86-64/___psynch_cvbroad.S - sys_x86-64/___psynch_cvclrprepost.S - sys_x86-64/___psynch_cvsignal.S - sys_x86-64/___psynch_cvwait.S - sys_x86-64/___psynch_mutexdrop.S - sys_x86-64/___psynch_mutexwait.S - sys_x86-64/___psynch_rw_downgrade.S - sys_x86-64/___psynch_rw_longrdlock.S - sys_x86-64/___psynch_rw_rdlock.S - sys_x86-64/___psynch_rw_unlock.S - sys_x86-64/___psynch_rw_unlock2.S - sys_x86-64/___psynch_rw_upgrade.S - sys_x86-64/___psynch_rw_wrlock.S - sys_x86-64/___psynch_rw_yieldwrlock.S - sys_x86-64/___pthread_canceled.S - sys_x86-64/___pthread_fchdir.S - sys_x86-64/___pthread_chdir.S - sys_x86-64/___pthread_kill.S - sys_x86-64/___pthread_markcancel.S - sys_x86-64/___pthread_sigmask.S - sys_x86-64/___ptrace.S - sys_x86-64/___pwrite_nocancel.S - sys_x86-64/_pwrite.S - sys_x86-64/_quotactl.S - sys_x86-64/_quota.S - sys_x86-64/_readlinkat.S - sys_x86-64/_readlink.S - sys_x86-64/___read_nocancel.S - sys_x86-64/_read.S - sys_x86-64/___readv_nocancel.S - sys_x86-64/_readv.S - sys_x86-64/_reboot.S - sys_x86-64/___recvfrom_nocancel.S - sys_x86-64/___recvfrom.S - sys_x86-64/___recvmsg_nocancel.S - sys_x86-64/___recvmsg.S - sys_x86-64/_recvmsg_x.S - sys_x86-64/_removexattr.S - sys_x86-64/___renameat.S - sys_x86-64/___rename_ext.S - sys_x86-64/___rename.S - sys_x86-64/_revoke.S - sys_x86-64/___rmdir.S - sys_x86-64/_searchfs.S - sys_x86-64/___select_nocancel.S - sys_x86-64/___select.S - sys_x86-64/_sem_close.S - sys_x86-64/___semctl.S - sys_x86-64/_semget.S - sys_x86-64/___sem_open.S - sys_x86-64/_semop.S - sys_x86-64/_sem_post.S - sys_x86-64/___semsys.S - sys_x86-64/_sem_trywait.S - sys_x86-64/_sem_unlink.S - sys_x86-64/___sem_wait_nocancel.S - sys_x86-64/_sem_wait.S - sys_x86-64/___semwait_signal_nocancel.S - sys_x86-64/___semwait_signal.S - sys_x86-64/_sendfile.S - sys_x86-64/___sendmsg_nocancel.S - sys_x86-64/___sendmsg.S - sys_x86-64/_sendmsg_x.S - sys_x86-64/___sendto_nocancel.S - sys_x86-64/___sendto.S - sys_x86-64/___setattrlist.S - sys_x86-64/_setaudit_addr.S - sys_x86-64/_setauid.S - sys_x86-64/_setegid.S - sys_x86-64/_seteuid.S - sys_x86-64/_setgid.S - sys_x86-64/_setgroups.S - sys_x86-64/_setitimer.S - sys_x86-64/___setlogin.S - sys_x86-64/_setpgid.S - sys_x86-64/___setpriority.S - sys_x86-64/_setprivexec.S - sys_x86-64/_setquota.S - sys_x86-64/___setregid.S - sys_x86-64/___setreuid.S - sys_x86-64/___setrlimit.S - sys_x86-64/___setsgroups.S - sys_x86-64/_setsid.S - sys_x86-64/_setsockopt.S - sys_x86-64/___settid.S - sys_x86-64/___settid_with_pid.S - sys_x86-64/___settimeofday.S - sys_x86-64/_setuid.S - sys_x86-64/___setwgroups.S - sys_x86-64/_setxattr.S - sys_x86-64/___sfi_ctl.S - sys_x86-64/___sfi_pidctl.S - sys_x86-64/___shared_region_check_np.S - sys_x86-64/___shared_region_map_and_slide_np.S - sys_x86-64/_shmat.S - sys_x86-64/___shmctl.S - sys_x86-64/_shmdt.S - sys_x86-64/_shmget.S - sys_x86-64/___shm_open.S - sys_x86-64/___shmsys.S - sys_x86-64/_shm_unlink.S - sys_x86-64/_shutdown.S - sys_x86-64/___sigaction.S - sys_x86-64/___sigaltstack.S - sys_x86-64/_sigpending.S - sys_x86-64/_sigprocmask.S - sys_x86-64/___sigreturn.S - sys_x86-64/___sigsuspend_nocancel.S - sys_x86-64/___sigsuspend.S - sys_x86-64/_____sigwait_nocancel.S - sys_x86-64/___sigwait.S - sys_x86-64/_socket_delegate.S - sys_x86-64/___socketpair.S - sys_x86-64/_socket.S - sys_x86-64/___stack_snapshot.S - sys_x86-64/___stack_snapshot_with_config.S - sys_x86-64/___stat_extended.S - sys_x86-64/_statfs.S - sys_x86-64/_statfs64.S - sys_x86-64/_stat.S - sys_x86-64/___stat64_extended.S - sys_x86-64/_stat64.S - sys_x86-64/_swapon.S - sys_x86-64/_symlinkat.S - sys_x86-64/_symlink.S - sys_x86-64/_sync.S - sys_x86-64/___syscall.S - sys_x86-64/___sysctlbyname.S - sys_x86-64/___sysctl.S - sys_x86-64/_system_override.S - sys_x86-64/___telemetry.S - sys_x86-64/___thread_selfid.S - sys_x86-64/___thread_selfusage.S - sys_x86-64/_truncate.S - sys_x86-64/___umask_extended.S - sys_x86-64/_umask.S - sys_x86-64/_undelete.S - sys_x86-64/___unlinkat.S - sys_x86-64/___unlink.S - sys_x86-64/_unmount.S - sys_x86-64/_usrctl.S - sys_x86-64/_utimes.S - sys_x86-64/___vfork.S - sys_x86-64/_vfs_purge.S - sys_x86-64/_vm_pressure_monitor.S - sys_x86-64/_waitevent.S - sys_x86-64/___waitid_nocancel.S - sys_x86-64/_waitid.S - sys_x86-64/___wait4_nocancel.S - sys_x86-64/___wait4.S - sys_x86-64/_watchevent.S - sys_x86-64/___work_interval_ctl.S - sys_x86-64/___workq_kernreturn.S - sys_x86-64/___workq_open.S - sys_x86-64/___write_nocancel.S - sys_x86-64/_write.S - sys_x86-64/___writev_nocancel.S - sys_x86-64/_writev.S -) -elseif(BITS EQUAL 32) -set (syscall_sources ${syscall_sources} - sys_i386/__accept_nocancel.S - sys_i386/__accept.S - sys_i386/__access_extended.S - sys_i386/access.S - sys_i386/acct.S - sys_i386/adjtime.S - sys_i386/aio_cancel.S - sys_i386/aio_error.S - sys_i386/aio_fsync.S - sys_i386/aio_read.S - sys_i386/aio_return.S - sys_i386/__aio_suspend_nocancel.S - sys_i386/aio_suspend.S - sys_i386/aio_write.S - sys_i386/auditctl.S - sys_i386/auditon.S - sys_i386/audit.S - sys_i386/audit_session_join.S - sys_i386/audit_session_port.S - sys_i386/audit_session_self.S - sys_i386/__bind.S - sys_i386/__bsdthread_create.S - sys_i386/__bsdthread_ctl.S - sys_i386/__bsdthread_register.S - sys_i386/__bsdthread_terminate.S - sys_i386/change_fdguard_np.S - sys_i386/chdir.S - sys_i386/chflags.S - sys_i386/__chmod_extended.S - sys_i386/__chmod.S - sys_i386/chown.S - sys_i386/chroot.S - sys_i386/__chud.S - sys_i386/__close_nocancel.S - sys_i386/close.S - sys_i386/__coalition_info.S - sys_i386/__coalition.S - sys_i386/__connect_nocancel.S - sys_i386/__connect.S - sys_i386/connectx.S - sys_i386/__copyfile.S - sys_i386/csops_audittoken.S - sys_i386/csops.S - sys_i386/__csrctl.S - sys_i386/custom.S - sys_i386/__delete.S - sys_i386/__disable_threadsignal.S - sys_i386/disconnectx.S - sys_i386/dup2.S - sys_i386/dup.S - sys_i386/exchangedata.S - sys_i386/execve.S - sys_i386/__exit.S - sys_i386/faccessat.S - sys_i386/fchdir.S - sys_i386/fchflags.S - sys_i386/fchmodat.S - sys_i386/__fchmod_extended.S - sys_i386/__fchmod.S - sys_i386/fchownat.S - sys_i386/fchown.S - sys_i386/__fcntl_nocancel.S - sys_i386/__fcntl.S - sys_i386/fdatasync.S - sys_i386/ffsctl.S - sys_i386/fgetattrlist.S - sys_i386/fgetxattr.S - sys_i386/fhopen.S - sys_i386/fileport_makefd.S - sys_i386/fileport_makeport.S - sys_i386/flistxattr.S - sys_i386/flock.S - sys_i386/__fork.S - sys_i386/fpathconf.S - sys_i386/fremovexattr.S - sys_i386/fsctl.S - sys_i386/fsetattrlist.S - sys_i386/fsetxattr.S - sys_i386/__fsgetpath.S - sys_i386/__fstat64_extended.S - sys_i386/fstat64.S - sys_i386/fstatat64.S - sys_i386/fstatat.S - sys_i386/__fstat_extended.S - sys_i386/fstatfs64.S - sys_i386/fstatfs.S - sys_i386/fstat.S - sys_i386/__fsync_nocancel.S - sys_i386/fsync.S - sys_i386/ftruncate.S - sys_i386/futimes.S - sys_i386/getattrlistat.S - sys_i386/getattrlistbulk.S - sys_i386/__getattrlist.S - sys_i386/getaudit_addr.S - sys_i386/getauid.S - sys_i386/__getdirentries64.S - sys_i386/getdirentriesattr.S - sys_i386/getdirentries.S - sys_i386/getdtablesize.S - sys_i386/getegid.S - sys_i386/geteuid.S - sys_i386/getfh.S - sys_i386/getfsstat64.S - sys_i386/getfsstat.S - sys_i386/getgid.S - sys_i386/getgroups.S - sys_i386/__gethostuuid.S - sys_i386/getitimer.S - sys_i386/__getlcid.S - sys_i386/__getlogin.S - sys_i386/__getpeername.S - sys_i386/getpgid.S - sys_i386/getpgrp.S - sys_i386/__getpid.S - sys_i386/getppid.S - sys_i386/getpriority.S - sys_i386/__getrlimit.S - sys_i386/getrusage.S - sys_i386/__getsgroups.S - sys_i386/getsid.S - sys_i386/__getsockname.S - sys_i386/getsockopt.S - sys_i386/__gettid.S - sys_i386/__gettimeofday.S - sys_i386/getuid.S - sys_i386/__getwgroups.S - sys_i386/getxattr.S - sys_i386/guarded_close_np.S - sys_i386/guarded_kqueue_np.S - sys_i386/__guarded_open_dprotected_np.S - sys_i386/__guarded_open_np.S - sys_i386/guarded_pwrite_np.S - sys_i386/guarded_write_np.S - sys_i386/guarded_writev_np.S - sys_i386/__identitysvc.S - sys_i386/__initgroups.S - sys_i386/__ioctl.S - sys_i386/__iopolicysys.S - sys_i386/issetugid.S - sys_i386/kas_info.S - sys_i386/__kdebug_trace.S - #sys_i386/kevent64.S - #sys_i386/kevent.S - sys_i386/__kill.S - #sys_i386/kqueue.S - sys_i386/__lchown.S - sys_i386/ledger.S - sys_i386/linkat.S - sys_i386/link.S - sys_i386/lio_listio.S - sys_i386/__listen.S - sys_i386/listxattr.S - sys_i386/__lseek.S - sys_i386/__lstat64_extended.S - sys_i386/lstat64.S - sys_i386/__lstat_extended.S - sys_i386/lstat.S - sys_i386/__mac_execve.S - sys_i386/__mac_get_fd.S - sys_i386/__mac_get_file.S - sys_i386/__mac_getfsstat.S - sys_i386/__mac_get_lcid.S - sys_i386/__mac_get_lctx.S - sys_i386/__mac_get_link.S - sys_i386/__mac_get_mount.S - sys_i386/__mac_get_pid.S - sys_i386/__mac_get_proc.S - sys_i386/__mac_mount.S - sys_i386/__mac_set_fd.S - sys_i386/__mac_set_file.S - sys_i386/__mac_set_lctx.S - sys_i386/__mac_set_link.S - sys_i386/__mac_set_proc.S - sys_i386/__mac_syscall.S - sys_i386/madvise.S - sys_i386/memorystatus_control.S - sys_i386/memorystatus_get_level.S - sys_i386/mincore.S - sys_i386/minherit.S - sys_i386/mkdirat.S - sys_i386/__mkdir_extended.S - sys_i386/mkdir.S - sys_i386/__mkfifo_extended.S - sys_i386/mkfifo.S - sys_i386/mknod.S - sys_i386/mlockall.S - sys_i386/mlock.S - sys_i386/__mmap.S - sys_i386/modwatch.S - sys_i386/mount.S - sys_i386/__mprotect.S - sys_i386/mremap_encrypted.S - sys_i386/__msgctl.S - sys_i386/msgget.S - sys_i386/__msgrcv_nocancel.S - sys_i386/msgrcv.S - sys_i386/__msgsnd_nocancel.S - sys_i386/msgsnd.S - sys_i386/__msgsys.S - sys_i386/__msync_nocancel.S - sys_i386/__msync.S - sys_i386/munlockall.S - sys_i386/munlock.S - sys_i386/__munmap.S - sys_i386/necp_match_policy.S - sys_i386/nfsclnt.S - sys_i386/nfssvc.S - sys_i386/____old_semwait_signal_nocancel.S - sys_i386/__old_semwait_signal.S - sys_i386/__openat_nocancel.S - sys_i386/__openat.S - sys_i386/openbyid_np.S - sys_i386/__open_dprotected_np.S - sys_i386/__open_extended.S - sys_i386/__open_nocancel.S - sys_i386/__open.S - sys_i386/pathconf.S - sys_i386/peeloff.S - sys_i386/pid_resume.S - sys_i386/pid_suspend.S - sys_i386/__pipe.S - sys_i386/__poll_nocancel.S - sys_i386/poll.S - sys_i386/__posix_spawn.S - sys_i386/__pread_nocancel.S - sys_i386/pread.S - sys_i386/__process_policy.S - sys_i386/__proc_info.S - sys_i386/proc_rlimit_control.S - sys_i386/proc_trace_log.S - sys_i386/proc_uuid_policy.S - sys_i386/__psynch_cvbroad.S - sys_i386/__psynch_cvclrprepost.S - sys_i386/__psynch_cvsignal.S - sys_i386/__psynch_cvwait.S - sys_i386/__psynch_mutexdrop.S - sys_i386/__psynch_mutexwait.S - sys_i386/__psynch_rw_downgrade.S - sys_i386/__psynch_rw_longrdlock.S - sys_i386/__psynch_rw_rdlock.S - sys_i386/__psynch_rw_unlock2.S - sys_i386/__psynch_rw_unlock.S - sys_i386/__psynch_rw_upgrade.S - sys_i386/__psynch_rw_wrlock.S - sys_i386/__psynch_rw_yieldwrlock.S - sys_i386/__pthread_canceled.S - sys_i386/__pthread_chdir.S - sys_i386/__pthread_fchdir.S - sys_i386/__pthread_kill.S - sys_i386/__pthread_markcancel.S - sys_i386/__pthread_sigmask.S - sys_i386/__ptrace.S - sys_i386/__pwrite_nocancel.S - sys_i386/pwrite.S - sys_i386/quotactl.S - sys_i386/quota.S - sys_i386/readlinkat.S - sys_i386/readlink.S - sys_i386/__read_nocancel.S - sys_i386/read.S - sys_i386/__readv_nocancel.S - sys_i386/readv.S - sys_i386/reboot.S - sys_i386/__recvfrom_nocancel.S - sys_i386/__recvfrom.S - sys_i386/__recvmsg_nocancel.S - sys_i386/__recvmsg.S - sys_i386/recvmsg_x.S - sys_i386/removexattr.S - sys_i386/__renameat.S - sys_i386/__rename_ext.S - sys_i386/__rename.S - sys_i386/revoke.S - sys_i386/__rmdir.S - sys_i386/searchfs.S - sys_i386/__select_nocancel.S - sys_i386/__select.S - sys_i386/sem_close.S - sys_i386/__semctl.S - sys_i386/semget.S - sys_i386/__sem_open.S - sys_i386/semop.S - sys_i386/sem_post.S - sys_i386/__semsys.S - sys_i386/sem_trywait.S - sys_i386/sem_unlink.S - sys_i386/__sem_wait_nocancel.S - sys_i386/sem_wait.S - sys_i386/__semwait_signal_nocancel.S - sys_i386/__semwait_signal.S - sys_i386/sendfile.S - sys_i386/__sendmsg_nocancel.S - sys_i386/__sendmsg.S - sys_i386/sendmsg_x.S - sys_i386/__sendto_nocancel.S - sys_i386/__sendto.S - sys_i386/__setattrlist.S - sys_i386/setaudit_addr.S - sys_i386/setauid.S - sys_i386/setegid.S - sys_i386/seteuid.S - sys_i386/setgid.S - sys_i386/setgroups.S - sys_i386/setitimer.S - sys_i386/__setlcid.S - sys_i386/__setlogin.S - sys_i386/setpgid.S - sys_i386/__setpriority.S - sys_i386/setprivexec.S - sys_i386/setquota.S - sys_i386/__setregid.S - sys_i386/__setreuid.S - sys_i386/__setrlimit.S - sys_i386/__setsgroups.S - sys_i386/setsid.S - sys_i386/setsockopt.S - sys_i386/__settid.S - sys_i386/__settid_with_pid.S - sys_i386/__settimeofday.S - sys_i386/setuid.S - sys_i386/__setwgroups.S - sys_i386/setxattr.S - sys_i386/__sfi_ctl.S - sys_i386/__sfi_pidctl.S - sys_i386/__shared_region_check_np.S - sys_i386/__shared_region_map_and_slide_np.S - sys_i386/shmat.S - sys_i386/__shmctl.S - sys_i386/shmdt.S - sys_i386/shmget.S - sys_i386/__shm_open.S - sys_i386/__shmsys.S - sys_i386/shm_unlink.S - sys_i386/shutdown.S - sys_i386/__sigaction.S - sys_i386/__sigaltstack.S - sys_i386/sigpending.S - sys_i386/sigprocmask.S - sys_i386/__sigreturn.S - sys_i386/__sigsuspend_nocancel.S - sys_i386/__sigsuspend.S - sys_i386/____sigwait_nocancel.S - sys_i386/__sigwait.S - sys_i386/socket_delegate.S - sys_i386/__socketpair.S - sys_i386/socket.S - sys_i386/__stack_snapshot.S - sys_i386/__stat64_extended.S - sys_i386/stat64.S - sys_i386/__stat_extended.S - sys_i386/statfs64.S - sys_i386/statfs.S - sys_i386/stat.S - sys_i386/swapon.S - sys_i386/symlinkat.S - sys_i386/symlink.S - sys_i386/sync.S - sys_i386/__syscall.S - sys_i386/__sysctlbyname.S - sys_i386/__sysctl.S - sys_i386/system_override.S - sys_i386/__telemetry.S - sys_i386/__thread_selfid.S - sys_i386/__thread_selfusage.S - sys_i386/truncate.S - sys_i386/__umask_extended.S - sys_i386/umask.S - sys_i386/undelete.S - sys_i386/__unlinkat.S - sys_i386/__unlink.S - sys_i386/unmount.S - sys_i386/utimes.S - sys_i386/__vfork.S - sys_i386/vfs_purge.S - sys_i386/vm_pressure_monitor.S - sys_i386/__wait4_nocancel.S - sys_i386/__wait4.S - sys_i386/waitevent.S - sys_i386/__waitid_nocancel.S - sys_i386/waitid.S - sys_i386/watchevent.S - sys_i386/__workq_kernreturn.S - sys_i386/__workq_open.S - sys_i386/__write_nocancel.S - sys_i386/write.S - sys_i386/__writev_nocancel.S - sys_i386/writev.S + bsdsyscalls/___abort_with_payload.S + bsdsyscalls/___accept_nocancel.S + bsdsyscalls/___accept.S + bsdsyscalls/___access_extended.S + bsdsyscalls/_access.S + bsdsyscalls/_acct.S + bsdsyscalls/_adjtime.S + bsdsyscalls/_aio_cancel.S + bsdsyscalls/_aio_error.S + bsdsyscalls/_aio_fsync.S + bsdsyscalls/_aio_read.S + bsdsyscalls/_aio_return.S + bsdsyscalls/___aio_suspend_nocancel.S + bsdsyscalls/_aio_suspend.S + bsdsyscalls/_aio_write.S + bsdsyscalls/_auditctl.S + bsdsyscalls/_auditon.S + bsdsyscalls/_audit.S + bsdsyscalls/_audit_session_join.S + bsdsyscalls/_audit_session_port.S + bsdsyscalls/_audit_session_self.S + bsdsyscalls/___bind.S + bsdsyscalls/___bsdthread_create.S + bsdsyscalls/___bsdthread_ctl.S + bsdsyscalls/___bsdthread_register.S + bsdsyscalls/___bsdthread_terminate.S + bsdsyscalls/_clonefileat.S + bsdsyscalls/___close_nocancel.S + bsdsyscalls/_close.S + bsdsyscalls/___coalition_info.S + bsdsyscalls/___coalition.S + bsdsyscalls/___connect_nocancel.S + bsdsyscalls/___connect.S + bsdsyscalls/_connectx.S + bsdsyscalls/___copyfile.S + bsdsyscalls/_csops_audittoken.S + bsdsyscalls/_csops.S + bsdsyscalls/___csrctl.S + bsdsyscalls/custom.S + bsdsyscalls/___delete.S + bsdsyscalls/___disable_threadsignal.S + bsdsyscalls/_disconnectx.S + bsdsyscalls/_dup.S + bsdsyscalls/_dup2.S + bsdsyscalls/_execve.S + bsdsyscalls/_exchangedata.S + bsdsyscalls/___exit.S + bsdsyscalls/_faccessat.S + bsdsyscalls/_fclonefileat.S + bsdsyscalls/___fcntl_nocancel.S + bsdsyscalls/___fcntl.S + bsdsyscalls/_fdatasync.S + bsdsyscalls/_ffsctl.S + bsdsyscalls/_fgetattrlist.S + bsdsyscalls/_fgetxattr.S + bsdsyscalls/_fhopen.S + bsdsyscalls/_fchdir.S + bsdsyscalls/_fchflags.S + bsdsyscalls/_fchmodat.S + bsdsyscalls/___fchmod_extended.S + bsdsyscalls/___fchmod.S + bsdsyscalls/_fchownat.S + bsdsyscalls/_fchown.S + bsdsyscalls/_fileport_makefd.S + bsdsyscalls/_fileport_makeport.S + bsdsyscalls/_flistxattr.S + bsdsyscalls/_flock.S + bsdsyscalls/___fork.S + bsdsyscalls/_fpathconf.S + bsdsyscalls/_fremovexattr.S + bsdsyscalls/_fsctl.S + bsdsyscalls/_fsetattrlist.S + bsdsyscalls/_fsetxattr.S + bsdsyscalls/_fsgetpath.S + bsdsyscalls/___fsgetpath.S + bsdsyscalls/___fs_snapshot.S + bsdsyscalls/_fstatat.S + bsdsyscalls/_fstatat64.S + bsdsyscalls/___fstat_extended.S + bsdsyscalls/_fstatfs.S + bsdsyscalls/_fstatfs64.S + bsdsyscalls/_fstat.S + bsdsyscalls/___fstat64_extended.S + bsdsyscalls/_fstat64.S + bsdsyscalls/___fsync_nocancel.S + bsdsyscalls/_fsync.S + bsdsyscalls/_ftruncate.S + bsdsyscalls/_futimes.S + bsdsyscalls/_getattrlistat.S + bsdsyscalls/_getattrlistbulk.S + bsdsyscalls/___getattrlist.S + bsdsyscalls/_getaudit_addr.S + bsdsyscalls/_getauid.S + bsdsyscalls/_getdirentriesattr.S + bsdsyscalls/_getdirentries.S + bsdsyscalls/___getdirentries64.S + bsdsyscalls/_getdtablesize.S + bsdsyscalls/_getegid.S + bsdsyscalls/_getentropy.S + bsdsyscalls/_geteuid.S + bsdsyscalls/_getfh.S + bsdsyscalls/_getfsstat.S + bsdsyscalls/_getfsstat64.S + bsdsyscalls/_getgid.S + bsdsyscalls/_getgroups.S + bsdsyscalls/___gethostuuid.S + bsdsyscalls/_getitimer.S + bsdsyscalls/___getlogin.S + bsdsyscalls/___getpeername.S + bsdsyscalls/_getpgid.S + bsdsyscalls/_getpgrp.S + bsdsyscalls/___getpid.S + bsdsyscalls/_getppid.S + bsdsyscalls/_getpriority.S + bsdsyscalls/___getrlimit.S + bsdsyscalls/_getrusage.S + bsdsyscalls/___getsgroups.S + bsdsyscalls/_getsid.S + bsdsyscalls/___getsockname.S + bsdsyscalls/_getsockopt.S + bsdsyscalls/___gettid.S + bsdsyscalls/___gettimeofday.S + bsdsyscalls/_getuid.S + bsdsyscalls/___getwgroups.S + bsdsyscalls/_getxattr.S + bsdsyscalls/_grab_pgo_data.S + bsdsyscalls/_guarded_close_np.S + bsdsyscalls/_guarded_kqueue_np.S + bsdsyscalls/___guarded_open_dprotected_np.S + bsdsyscalls/___guarded_open_np.S + bsdsyscalls/_guarded_pwrite_np.S + bsdsyscalls/_guarded_write_np.S + bsdsyscalls/_guarded_writev_np.S + bsdsyscalls/_change_fdguard_np.S + bsdsyscalls/_chdir.S + bsdsyscalls/_chflags.S + bsdsyscalls/___chmod_extended.S + bsdsyscalls/___chmod.S + bsdsyscalls/_chown.S + bsdsyscalls/_chroot.S + bsdsyscalls/___identitysvc.S + bsdsyscalls/___initgroups.S + bsdsyscalls/___ioctl.S + bsdsyscalls/___iopolicysys.S + bsdsyscalls/_issetugid.S + bsdsyscalls/_kas_info.S + bsdsyscalls/___kdebug_trace.S + bsdsyscalls/___kdebug_trace_string.S + bsdsyscalls/___kdebug_trace64.S + bsdsyscalls/___kdebug_typefilter.S + bsdsyscalls/_kevent_qos.S + bsdsyscalls/_kevent.S + bsdsyscalls/_kevent64.S + bsdsyscalls/___kill.S + bsdsyscalls/_kqueue.S + bsdsyscalls/_ledger.S + bsdsyscalls/___lchown.S + bsdsyscalls/_linkat.S + bsdsyscalls/_link.S + bsdsyscalls/_lio_listio.S + bsdsyscalls/___listen.S + bsdsyscalls/_listxattr.S + bsdsyscalls/___lseek.S + bsdsyscalls/___lstat_extended.S + bsdsyscalls/_lstat.S + bsdsyscalls/___lstat64_extended.S + bsdsyscalls/_lstat64.S + bsdsyscalls/___mac_execve.S + bsdsyscalls/___mac_get_fd.S + bsdsyscalls/___mac_get_file.S + bsdsyscalls/___mac_getfsstat.S + bsdsyscalls/___mac_get_link.S + bsdsyscalls/___mac_get_mount.S + bsdsyscalls/___mac_get_pid.S + bsdsyscalls/___mac_get_proc.S + bsdsyscalls/___mac_mount.S + bsdsyscalls/___mac_set_fd.S + bsdsyscalls/___mac_set_file.S + bsdsyscalls/___mac_set_link.S + bsdsyscalls/___mac_set_proc.S + bsdsyscalls/___mac_syscall.S + bsdsyscalls/_madvise.S + bsdsyscalls/_memorystatus_control.S + bsdsyscalls/_memorystatus_get_level.S + bsdsyscalls/___microstackshot.S + bsdsyscalls/_mincore.S + bsdsyscalls/_minherit.S + bsdsyscalls/_mkdirat.S + bsdsyscalls/___mkdir_extended.S + bsdsyscalls/_mkdir.S + bsdsyscalls/___mkfifo_extended.S + bsdsyscalls/_mkfifo.S + bsdsyscalls/_mknod.S + bsdsyscalls/_mlockall.S + bsdsyscalls/_mlock.S + bsdsyscalls/___mmap.S + bsdsyscalls/_modwatch.S + bsdsyscalls/_mount.S + bsdsyscalls/___mprotect.S + bsdsyscalls/_mremap_encrypted.S + bsdsyscalls/___msgctl.S + bsdsyscalls/_msgget.S + bsdsyscalls/___msgrcv_nocancel.S + bsdsyscalls/_msgrcv.S + bsdsyscalls/___msgsnd_nocancel.S + bsdsyscalls/_msgsnd.S + bsdsyscalls/___msgsys.S + bsdsyscalls/___msync_nocancel.S + bsdsyscalls/___msync.S + bsdsyscalls/_munlockall.S + bsdsyscalls/_munlock.S + bsdsyscalls/___munmap.S + bsdsyscalls/_necp_client_action.S + bsdsyscalls/_necp_match_policy.S + bsdsyscalls/_necp_open.S + bsdsyscalls/_netagent_trigger.S + bsdsyscalls/_nfsclnt.S + bsdsyscalls/_nfssvc.S + bsdsyscalls/_____old_semwait_signal_nocancel.S + bsdsyscalls/___old_semwait_signal.S + bsdsyscalls/___openat_nocancel.S + bsdsyscalls/___openat.S + bsdsyscalls/_openbyid_np.S + bsdsyscalls/___open_dprotected_np.S + bsdsyscalls/___open_extended.S + bsdsyscalls/___open_nocancel.S + bsdsyscalls/___open.S + bsdsyscalls/_pathconf.S + bsdsyscalls/_peeloff.S + bsdsyscalls/___persona.S + bsdsyscalls/_pid_resume.S + bsdsyscalls/_pid_suspend.S + bsdsyscalls/___pipe.S + bsdsyscalls/___poll_nocancel.S + bsdsyscalls/_poll.S + bsdsyscalls/___posix_spawn.S + bsdsyscalls/___pread_nocancel.S + bsdsyscalls/_pread.S + bsdsyscalls/___process_policy.S + bsdsyscalls/___proc_info.S + bsdsyscalls/_proc_rlimit_control.S + bsdsyscalls/_proc_trace_log.S + bsdsyscalls/_proc_uuid_policy.S + bsdsyscalls/___pselect_nocancel.S + bsdsyscalls/___pselect.S + bsdsyscalls/___psynch_cvbroad.S + bsdsyscalls/___psynch_cvclrprepost.S + bsdsyscalls/___psynch_cvsignal.S + bsdsyscalls/___psynch_cvwait.S + bsdsyscalls/___psynch_mutexdrop.S + bsdsyscalls/___psynch_mutexwait.S + bsdsyscalls/___psynch_rw_downgrade.S + bsdsyscalls/___psynch_rw_longrdlock.S + bsdsyscalls/___psynch_rw_rdlock.S + bsdsyscalls/___psynch_rw_unlock.S + bsdsyscalls/___psynch_rw_unlock2.S + bsdsyscalls/___psynch_rw_upgrade.S + bsdsyscalls/___psynch_rw_wrlock.S + bsdsyscalls/___psynch_rw_yieldwrlock.S + bsdsyscalls/___pthread_canceled.S + bsdsyscalls/___pthread_fchdir.S + bsdsyscalls/___pthread_chdir.S + bsdsyscalls/___pthread_kill.S + bsdsyscalls/___pthread_markcancel.S + bsdsyscalls/___pthread_sigmask.S + bsdsyscalls/___ptrace.S + bsdsyscalls/___pwrite_nocancel.S + bsdsyscalls/_pwrite.S + bsdsyscalls/_quotactl.S + bsdsyscalls/_quota.S + bsdsyscalls/_readlinkat.S + bsdsyscalls/_readlink.S + bsdsyscalls/___read_nocancel.S + bsdsyscalls/_read.S + bsdsyscalls/___readv_nocancel.S + bsdsyscalls/_readv.S + bsdsyscalls/_reboot.S + bsdsyscalls/___recvfrom_nocancel.S + bsdsyscalls/___recvfrom.S + bsdsyscalls/___recvmsg_nocancel.S + bsdsyscalls/___recvmsg.S + bsdsyscalls/_recvmsg_x.S + bsdsyscalls/_removexattr.S + bsdsyscalls/___renameat.S + bsdsyscalls/___renameatx_np.S + bsdsyscalls/___rename.S + bsdsyscalls/_revoke.S + bsdsyscalls/___rmdir.S + bsdsyscalls/_searchfs.S + bsdsyscalls/___select_nocancel.S + bsdsyscalls/___select.S + bsdsyscalls/_sem_close.S + bsdsyscalls/___semctl.S + bsdsyscalls/_semget.S + bsdsyscalls/___sem_open.S + bsdsyscalls/_semop.S + bsdsyscalls/_sem_post.S + bsdsyscalls/___semsys.S + bsdsyscalls/_sem_trywait.S + bsdsyscalls/_sem_unlink.S + bsdsyscalls/___sem_wait_nocancel.S + bsdsyscalls/_sem_wait.S + bsdsyscalls/___semwait_signal_nocancel.S + bsdsyscalls/___semwait_signal.S + bsdsyscalls/_sendfile.S + bsdsyscalls/___sendmsg_nocancel.S + bsdsyscalls/___sendmsg.S + bsdsyscalls/_sendmsg_x.S + bsdsyscalls/___sendto_nocancel.S + bsdsyscalls/___sendto.S + bsdsyscalls/___setattrlist.S + bsdsyscalls/_setaudit_addr.S + bsdsyscalls/_setauid.S + bsdsyscalls/_setegid.S + bsdsyscalls/_seteuid.S + bsdsyscalls/_setgid.S + bsdsyscalls/_setgroups.S + bsdsyscalls/_setitimer.S + bsdsyscalls/___setlogin.S + bsdsyscalls/_setpgid.S + bsdsyscalls/___setpriority.S + bsdsyscalls/_setprivexec.S + bsdsyscalls/_setquota.S + bsdsyscalls/___setregid.S + bsdsyscalls/___setreuid.S + bsdsyscalls/___setrlimit.S + bsdsyscalls/___setsgroups.S + bsdsyscalls/_setsid.S + bsdsyscalls/_setsockopt.S + bsdsyscalls/___settid.S + bsdsyscalls/___settid_with_pid.S + bsdsyscalls/___settimeofday.S + bsdsyscalls/_setuid.S + bsdsyscalls/___setwgroups.S + bsdsyscalls/_setxattr.S + bsdsyscalls/___sfi_ctl.S + bsdsyscalls/___sfi_pidctl.S + bsdsyscalls/___shared_region_check_np.S + bsdsyscalls/___shared_region_map_and_slide_np.S + bsdsyscalls/_shmat.S + bsdsyscalls/___shmctl.S + bsdsyscalls/_shmdt.S + bsdsyscalls/_shmget.S + bsdsyscalls/___shm_open.S + bsdsyscalls/___shmsys.S + bsdsyscalls/_shm_unlink.S + bsdsyscalls/_shutdown.S + bsdsyscalls/___sigaction.S + bsdsyscalls/___sigaltstack.S + bsdsyscalls/_sigpending.S + bsdsyscalls/_sigprocmask.S + bsdsyscalls/___sigreturn.S + bsdsyscalls/___sigsuspend_nocancel.S + bsdsyscalls/___sigsuspend.S + bsdsyscalls/_____sigwait_nocancel.S + bsdsyscalls/___sigwait.S + bsdsyscalls/_socket_delegate.S + bsdsyscalls/___socketpair.S + bsdsyscalls/_socket.S + bsdsyscalls/___stack_snapshot_with_config.S + bsdsyscalls/___stat_extended.S + bsdsyscalls/_statfs.S + bsdsyscalls/_statfs64.S + bsdsyscalls/_stat.S + bsdsyscalls/___stat64_extended.S + bsdsyscalls/_stat64.S + bsdsyscalls/_swapon.S + bsdsyscalls/_symlinkat.S + bsdsyscalls/_symlink.S + bsdsyscalls/_sync.S + bsdsyscalls/___syscall.S + bsdsyscalls/___sysctlbyname.S + bsdsyscalls/___sysctl.S + bsdsyscalls/_system_override.S + bsdsyscalls/___telemetry.S + bsdsyscalls/___terminate_with_payload.S + bsdsyscalls/___thread_selfid.S + bsdsyscalls/___thread_selfusage.S + bsdsyscalls/_truncate.S + bsdsyscalls/___ulock_wait.S + bsdsyscalls/___ulock_wake.S + bsdsyscalls/___umask_extended.S + bsdsyscalls/_umask.S + bsdsyscalls/_undelete.S + bsdsyscalls/___unlinkat.S + bsdsyscalls/___unlink.S + bsdsyscalls/_unmount.S + bsdsyscalls/_usrctl.S + bsdsyscalls/_utimes.S + bsdsyscalls/___vfork.S + bsdsyscalls/_vfs_purge.S + bsdsyscalls/_vm_pressure_monitor.S + bsdsyscalls/_waitevent.S + bsdsyscalls/___waitid_nocancel.S + bsdsyscalls/_waitid.S + bsdsyscalls/___wait4_nocancel.S + bsdsyscalls/___wait4.S + bsdsyscalls/_watchevent.S + bsdsyscalls/___work_interval_ctl.S + bsdsyscalls/___workq_kernreturn.S + bsdsyscalls/___workq_open.S + bsdsyscalls/___write_nocancel.S + bsdsyscalls/_write.S + bsdsyscalls/___writev_nocancel.S + bsdsyscalls/_writev.S + ) -endif(BITS EQUAL 64) + mig(mach/clock.defs) mig(mach/host_priv.defs) @@ -977,7 +607,6 @@ mig(mach/task.defs) mig(mach/thread_act.defs) mig(mach/vm_map.defs) -#set_source_files_properties(custom/errno.c PROPERTIES COMPILE_FLAGS "-no-integrated-as") set_source_files_properties(${syscall_legacy_sources} PROPERTIES COMPILE_FLAGS "-U_DARWIN_C_SOURCE -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0 -U__DARWIN_C_LEVEL") set_source_files_properties(wrappers/legacy/select-pre1050.c PROPERTIES COMPILE_FLAGS "-U_DARWIN_C_SOURCE -DSYSCALL_PRE1050") set_source_files_properties(wrappers/cancelable/select-cancel.c PROPERTIES COMPILE_FLAGS "-U_DARWIN_C_SOURCE") @@ -989,9 +618,12 @@ endforeach(file) add_library(libsyscall OBJECT ${syscall_sources}) add_library(libsyscall_dynamic OBJECT ${syscall_dynamic_sources}) +make_fat(libsyscall) +make_fat(libsyscall_dynamic) add_library(libsyscall_static OBJECT wrappers/_libc_funcptr.c) set_target_properties(libsyscall_static PROPERTIES COMPILE_FLAGS "-DVARIANT_DYLD") +make_fat(libsyscall_static) # For i386 #add_library(libsyscall_legacy_extra OBJECT wrappers/legacy/select.c) diff --git a/src/kernel/libsyscall/bsdsyscalls/SYS.h b/src/kernel/libsyscall/bsdsyscalls/SYS.h new file mode 100644 index 000000000..eea226254 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/SYS.h @@ -0,0 +1,223 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2011 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. + * + * File: SYS.h + * + * Definition of the user side of the UNIX system call interface + * for M98K. + * + * Errors are flagged by the location of the trap return (ie., which + * instruction is executed upon rfi): + * + * SC PC + 4: Error (typically branch to cerror()) + * SC PC + 8: Success + * + * HISTORY + * 18-Nov-92 Ben Fathi (benf@next.com) + * Ported to m98k. + * + * 9-Jan-92 Peter King (king@next.com) + * Created. + */ + +#include + +/* Binary compatibility stubs for syscalls that no longer exist */ + +#ifndef SYS_setquota +#define SYS_setquota 148 +#endif +#ifndef SYS_quota +#define SYS_quota 149 +#endif + +#if defined(__i386__) + +#include +#include + +/* + * We have two entry points. int's is used for syscalls which need to preserve + * %ecx across the call, or return a 64-bit value in %eax:%edx. sysenter is used + * for the majority of syscalls which just return a value in %eax. + */ + +#ifndef DARLING +#define UNIX_SYSCALL_SYSENTER call __sysenter_trap +#else +#define UNIX_SYSCALL_SYSENTER call __darling_bsd_syscall +#endif + +#define UNIX_SYSCALL(name, nargs) \ + .globl tramp_cerror ;\ +LEAF(_##name, 0) ;\ + movl $ SYS_##name, %eax ;\ + UNIX_SYSCALL_SYSENTER ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_cerror) ;\ +2: + +#define UNIX_SYSCALL_INT(name, nargs) \ + .globl tramp_cerror ;\ +LEAF(_##name, 0) ;\ + movl $ SYS_##name, %eax ;\ + UNIX_SYSCALL_TRAP ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_cerror) ;\ +2: + +#if defined(__SYSCALL_32BIT_ARG_BYTES) && ((__SYSCALL_32BIT_ARG_BYTES >= 4) && (__SYSCALL_32BIT_ARG_BYTES <= 20)) +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ + movl $(SYS_##name | (__SYSCALL_32BIT_ARG_BYTES << I386_SYSCALL_ARG_BYTES_SHIFT)), %eax ;\ + UNIX_SYSCALL_SYSENTER ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_##cerror) ;\ +2: +#else /* __SYSCALL_32BIT_ARG_BYTES < 4 || > 20 */ +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ + movl $ SYS_##name, %eax ;\ + UNIX_SYSCALL_SYSENTER ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_##cerror) ;\ +2: +#endif + +#define UNIX_SYSCALL_INT_NONAME(name, nargs) \ + .globl tramp_cerror_nocancel ;\ + movl $ SYS_##name, %eax ;\ + UNIX_SYSCALL_TRAP ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_cerror_nocancel) ;\ +2: + +#define PSEUDO(pseudo, name, nargs, cerror) \ +LEAF(pseudo, 0) ;\ + UNIX_SYSCALL_NONAME(name, nargs, cerror) + +#define PSEUDO_INT(pseudo, name, nargs) \ +LEAF(pseudo, 0) ;\ + UNIX_SYSCALL_INT_NONAME(name, nargs) + +#define __SYSCALL2(pseudo, name, nargs, cerror) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret + +#define __SYSCALL(pseudo, name, nargs) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret + +#define __SYSCALL_INT(pseudo, name, nargs) \ + PSEUDO_INT(pseudo, name, nargs) ;\ + ret + +#elif defined(__x86_64__) + +#include +#include + +#ifdef DARLING + +#define UNIX_SYSCALL(name, nargs) \ + .globl cerror ;\ +LEAF(_#name, 0) ;\ + movl $ SYS_##name, %eax ;\ + call __darling_bsd_syscall ;\ + cmpq $-4095, %rax ;\ + jb 2f ;\ + movq %rax, %rdi ;\ + negq %rdi ;\ + BRANCH_EXTERN(_cerror) ;\ +2: + +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ + .globl cerror ;\ + movl $ SYS_##name, %eax ;\ + call __darling_bsd_syscall ;\ + cmpq $-4095, %rax ;\ + jb 2f ;\ + movq %rax, %rdi ;\ + negq %rdi ;\ + BRANCH_EXTERN(_##cerror) ;\ +2: + + +#else + +#define UNIX_SYSCALL_SYSCALL \ + movq %rcx, %r10 ;\ + syscall + +#define UNIX_SYSCALL(name, nargs) \ + .globl cerror ;\ +LEAF(_##name, 0) ;\ + movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ + UNIX_SYSCALL_SYSCALL ;\ + jnb 2f ;\ + movq %rax, %rdi ;\ + BRANCH_EXTERN(_cerror) ;\ +2: + +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ + .globl cerror ;\ + movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ + UNIX_SYSCALL_SYSCALL ;\ + jnb 2f ;\ + movq %rax, %rdi ;\ + BRANCH_EXTERN(_##cerror) ;\ +2: + +#endif // DARLING + +#define PSEUDO(pseudo, name, nargs, cerror) \ +LEAF(pseudo, 0) ;\ + UNIX_SYSCALL_NONAME(name, nargs, cerror) + +#define __SYSCALL2(pseudo, name, nargs, cerror) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret + +#define __SYSCALL(pseudo, name, nargs) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret + +#else +#error Unsupported architecture +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_____old_semwait_signal_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/_____old_semwait_signal_nocancel.S new file mode 100644 index 000000000..13b572f09 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_____old_semwait_signal_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS___old_semwait_signal_nocancel +#error "SYS___old_semwait_signal_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_____old_semwait_signal_nocancel, __old_semwait_signal_nocancel, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_____sigwait_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/_____sigwait_nocancel.S new file mode 100644 index 000000000..718e356f1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_____sigwait_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___sigwait_nocancel +#error "SYS___sigwait_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_____sigwait_nocancel, __sigwait_nocancel, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___abort_with_payload.S b/src/kernel/libsyscall/bsdsyscalls/___abort_with_payload.S new file mode 100644 index 000000000..4a0528d9d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___abort_with_payload.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 32 +#include "SYS.h" + +#ifndef SYS_abort_with_payload +#error "SYS_abort_with_payload not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___abort_with_payload, abort_with_payload, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___accept.S b/src/kernel/libsyscall/bsdsyscalls/___accept.S new file mode 100644 index 000000000..7a4a9d11b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___accept.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_accept +#error "SYS_accept not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___accept, accept, 3, cerror) +#endif + +#if defined(__i386__) + .globl _accept$UNIX2003 + .set _accept$UNIX2003, ___accept +#endif + +#if defined(__x86_64__) + .globl _accept + .set _accept, ___accept +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___accept_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___accept_nocancel.S new file mode 100644 index 000000000..120001073 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___accept_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_accept_nocancel +#error "SYS_accept_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___accept_nocancel, accept_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _accept$NOCANCEL$UNIX2003 + .set _accept$NOCANCEL$UNIX2003, ___accept_nocancel +#endif + +#if defined(__x86_64__) + .globl _accept$NOCANCEL + .set _accept$NOCANCEL, ___accept_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___access_extended.S b/src/kernel/libsyscall/bsdsyscalls/___access_extended.S new file mode 100644 index 000000000..b57a2968c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___access_extended.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_access_extended +#error "SYS_access_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___access_extended, access_extended, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _accessx_np + .set _accessx_np, ___access_extended +#endif + +#if defined(__x86_64__) + .globl _accessx_np + .set _accessx_np, ___access_extended +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___aio_suspend_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___aio_suspend_nocancel.S new file mode 100644 index 000000000..59ec13dc0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___aio_suspend_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_aio_suspend_nocancel +#error "SYS_aio_suspend_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___aio_suspend_nocancel, aio_suspend_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _aio_suspend + .set _aio_suspend, ___aio_suspend_nocancel + .globl _aio_suspend$NOCANCEL$UNIX2003 + .set _aio_suspend$NOCANCEL$UNIX2003, ___aio_suspend_nocancel +#endif + +#if defined(__x86_64__) + .globl _aio_suspend$NOCANCEL + .set _aio_suspend$NOCANCEL, ___aio_suspend_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___bind.S b/src/kernel/libsyscall/bsdsyscalls/___bind.S new file mode 100644 index 000000000..747530063 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___bind.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_bind +#error "SYS_bind not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bind, bind, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _bind$UNIX2003 + .set _bind$UNIX2003, ___bind +#endif + +#if defined(__x86_64__) + .globl _bind + .set _bind, ___bind +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___bsdthread_create.S b/src/kernel/libsyscall/bsdsyscalls/___bsdthread_create.S new file mode 100644 index 000000000..b2e563dd8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___bsdthread_create.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_bsdthread_create +#error "SYS_bsdthread_create not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bsdthread_create, bsdthread_create, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___bsdthread_ctl.S b/src/kernel/libsyscall/bsdsyscalls/___bsdthread_ctl.S new file mode 100644 index 000000000..f258d675e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___bsdthread_ctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_bsdthread_ctl +#error "SYS_bsdthread_ctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bsdthread_ctl, bsdthread_ctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___bsdthread_register.S b/src/kernel/libsyscall/bsdsyscalls/___bsdthread_register.S new file mode 100644 index 000000000..527a266a4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___bsdthread_register.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_bsdthread_register +#error "SYS_bsdthread_register not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bsdthread_register, bsdthread_register, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___bsdthread_terminate.S b/src/kernel/libsyscall/bsdsyscalls/___bsdthread_terminate.S new file mode 100644 index 000000000..3671d85b9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___bsdthread_terminate.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_bsdthread_terminate +#error "SYS_bsdthread_terminate not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bsdthread_terminate, bsdthread_terminate, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___chmod.S b/src/kernel/libsyscall/bsdsyscalls/___chmod.S new file mode 100644 index 000000000..d391d28fc --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___chmod.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_chmod +#error "SYS_chmod not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___chmod, chmod, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _chmod + .set _chmod, ___chmod +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___chmod_extended.S b/src/kernel/libsyscall/bsdsyscalls/___chmod_extended.S new file mode 100644 index 000000000..82db9ca05 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___chmod_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_chmod_extended +#error "SYS_chmod_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___chmod_extended, chmod_extended, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___close_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___close_nocancel.S new file mode 100644 index 000000000..9a5a1a5d7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___close_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_close_nocancel +#error "SYS_close_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___close_nocancel, close_nocancel, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _close + .set _close, ___close_nocancel + .globl _close$NOCANCEL$UNIX2003 + .set _close$NOCANCEL$UNIX2003, ___close_nocancel +#endif + +#if defined(__x86_64__) + .globl _close$NOCANCEL + .set _close$NOCANCEL, ___close_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___coalition.S b/src/kernel/libsyscall/bsdsyscalls/___coalition.S new file mode 100644 index 000000000..a49ab6019 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___coalition.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_coalition +#error "SYS_coalition not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___coalition, coalition, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___coalition_info.S b/src/kernel/libsyscall/bsdsyscalls/___coalition_info.S new file mode 100644 index 000000000..08be90c66 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___coalition_info.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_coalition_info +#error "SYS_coalition_info not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___coalition_info, coalition_info, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___connect.S b/src/kernel/libsyscall/bsdsyscalls/___connect.S new file mode 100644 index 000000000..1e7efde6b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___connect.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_connect +#error "SYS_connect not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___connect, connect, 3, cerror) +#endif + +#if defined(__i386__) + .globl _connect$UNIX2003 + .set _connect$UNIX2003, ___connect +#endif + +#if defined(__x86_64__) + .globl _connect + .set _connect, ___connect +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___connect_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___connect_nocancel.S new file mode 100644 index 000000000..1dd65ea9b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___connect_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_connect_nocancel +#error "SYS_connect_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___connect_nocancel, connect_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _connect$NOCANCEL$UNIX2003 + .set _connect$NOCANCEL$UNIX2003, ___connect_nocancel +#endif + +#if defined(__x86_64__) + .globl _connect$NOCANCEL + .set _connect$NOCANCEL, ___connect_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___copyfile.S b/src/kernel/libsyscall/bsdsyscalls/___copyfile.S new file mode 100644 index 000000000..8d2fc24e9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___copyfile.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_copyfile +#error "SYS_copyfile not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___copyfile, copyfile, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___csrctl.S b/src/kernel/libsyscall/bsdsyscalls/___csrctl.S new file mode 100644 index 000000000..c5b2984df --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___csrctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_csrctl +#error "SYS_csrctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___csrctl, csrctl, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___delete.S b/src/kernel/libsyscall/bsdsyscalls/___delete.S new file mode 100644 index 000000000..64bdadb17 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___delete.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_delete +#error "SYS_delete not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___delete, delete, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___disable_threadsignal.S b/src/kernel/libsyscall/bsdsyscalls/___disable_threadsignal.S new file mode 100644 index 000000000..4e7804613 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___disable_threadsignal.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___disable_threadsignal +#error "SYS___disable_threadsignal not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___disable_threadsignal, __disable_threadsignal, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___exit.S b/src/kernel/libsyscall/bsdsyscalls/___exit.S new file mode 100644 index 000000000..047c49602 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___exit.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_exit +#error "SYS_exit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___exit, exit, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl __exit + .set __exit, ___exit +#endif + +#if defined(__x86_64__) + .globl __exit + .set __exit, ___exit +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___fchmod.S b/src/kernel/libsyscall/bsdsyscalls/___fchmod.S new file mode 100644 index 000000000..760d006fc --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fchmod.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fchmod +#error "SYS_fchmod not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fchmod, fchmod, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fchmod + .set _fchmod, ___fchmod +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___fchmod_extended.S b/src/kernel/libsyscall/bsdsyscalls/___fchmod_extended.S new file mode 100644 index 000000000..cc0a05cc9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fchmod_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fchmod_extended +#error "SYS_fchmod_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fchmod_extended, fchmod_extended, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___fcntl.S b/src/kernel/libsyscall/bsdsyscalls/___fcntl.S new file mode 100644 index 000000000..eff97c55a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fcntl.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_fcntl +#error "SYS_fcntl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fcntl, fcntl, 3, cerror) +#endif + +#if defined(__i386__) + .globl _fcntl$UNIX2003 + .set _fcntl$UNIX2003, ___fcntl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___fcntl_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___fcntl_nocancel.S new file mode 100644 index 000000000..d300ad431 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fcntl_nocancel.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_fcntl_nocancel +#error "SYS_fcntl_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fcntl_nocancel, fcntl_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fcntl + .set _fcntl, ___fcntl_nocancel + .globl _fcntl$NOCANCEL$UNIX2003 + .set _fcntl$NOCANCEL$UNIX2003, ___fcntl_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___fork.S b/src/kernel/libsyscall/bsdsyscalls/___fork.S new file mode 100644 index 000000000..acce242db --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fork.S @@ -0,0 +1,122 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2010 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. + * + * File: libc/ppc/sys/fork.s + * + * HISTORY + * 18-Nov-92 Ben Fathi (benf@next.com) + * Created from M88K sources + * + * 11-Jan-92 Peter King (king@next.com) + * Created from M68K sources + */ + +/* + * All of the asm stubs in this file have been adjusted so the pre/post + * fork handlers and dyld fixup are done in C inside Libc. As such, Libc + * expects the __fork asm to fix up the return code to be -1, 0 or pid + * and errno if needed. + */ + +#include "SYS.h" + +#ifdef DARLING +# define ___fork __fork +# define _cerror cerror +#endif + +#if defined(__i386__) + +LEAF(___fork, 0) + subl $28, %esp // Align the stack, with 16 bytes of extra padding that we'll need + + movl $ SYS_fork,%eax; // code for fork -> eax + UNIX_SYSCALL_TRAP // do the system call + jnc L1 // jump if CF==0 + + CALL_EXTERN(tramp_cerror) + movl $-1,%eax + addl $28, %esp // restore the stack + ret + +L1: + orl %edx,%edx // CF=OF=0, ZF set if zero result + jz L2 // parent, since r1 == 0 in parent, 1 in child + + //child here... + xorl %eax,%eax // zero eax + REG_TO_EXTERN(%eax, __current_pid); +L2: + addl $28, %esp // restore the stack + // parent ends up here skipping child portion + ret + +#elif defined(__x86_64__) + +LEAF(___fork, 0) + subq $24, %rsp // Align the stack, plus room for local storage + +#ifndef DARLING + movl $ SYSCALL_CONSTRUCT_UNIX(SYS_fork),%eax; // code for fork -> rax + UNIX_SYSCALL_TRAP // do the system call + jnc L1 // jump if CF==0 +#else + movl $ SYS_fork, %eax + call __darling_bsd_syscall + cmpq $0, %rax + jnb L1 +#endif + movq %rax, %rdi + CALL_EXTERN(_cerror) + movq $-1, %rax + addq $24, %rsp // restore the stack + ret + +L1: +#ifndef DARLING + orl %edx,%edx // CF=OF=0, ZF set if zero result + jz L2 // parent, since r1 == 0 in parent, 1 in child +#else + testl %eax, %eax + jnz L2 +#endif + + //child here... + xorq %rax, %rax + PICIFY(__current_pid) + movl %eax,(%r11) +L2: + // parent ends up here skipping child portion + addq $24, %rsp // restore the stack + ret + +#else +#error Unsupported architecture +#endif diff --git a/src/kernel/libsyscall/bsdsyscalls/___fs_snapshot.S b/src/kernel/libsyscall/bsdsyscalls/___fs_snapshot.S new file mode 100644 index 000000000..890162e8a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fs_snapshot.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_fs_snapshot +#error "SYS_fs_snapshot not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fs_snapshot, fs_snapshot, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___fsgetpath.S b/src/kernel/libsyscall/bsdsyscalls/___fsgetpath.S new file mode 100644 index 000000000..bb26b3339 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fsgetpath.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fsgetpath +#error "SYS_fsgetpath not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fsgetpath, fsgetpath, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___fstat64_extended.S b/src/kernel/libsyscall/bsdsyscalls/___fstat64_extended.S new file mode 100644 index 000000000..d30b3d1ea --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fstat64_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fstat64_extended +#error "SYS_fstat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fstat64_extended, fstat64_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___fstat_extended.S b/src/kernel/libsyscall/bsdsyscalls/___fstat_extended.S new file mode 100644 index 000000000..288b41744 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fstat_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fstat_extended +#error "SYS_fstat_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fstat_extended, fstat_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___fsync_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___fsync_nocancel.S new file mode 100644 index 000000000..ceb5e7b34 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___fsync_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fsync_nocancel +#error "SYS_fsync_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fsync_nocancel, fsync_nocancel, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fsync + .set _fsync, ___fsync_nocancel + .globl _fsync$NOCANCEL$UNIX2003 + .set _fsync$NOCANCEL$UNIX2003, ___fsync_nocancel +#endif + +#if defined(__x86_64__) + .globl _fsync$NOCANCEL + .set _fsync$NOCANCEL, ___fsync_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___getattrlist.S b/src/kernel/libsyscall/bsdsyscalls/___getattrlist.S new file mode 100644 index 000000000..7c3a70a08 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___getattrlist.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_getattrlist +#error "SYS_getattrlist not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getattrlist, getattrlist, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getattrlist$UNIX2003 + .set _getattrlist$UNIX2003, ___getattrlist +#endif + +#if defined(__x86_64__) + .globl _getattrlist + .set _getattrlist, ___getattrlist +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___getdirentries64.S b/src/kernel/libsyscall/bsdsyscalls/___getdirentries64.S new file mode 100644 index 000000000..1f1e6b6f7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___getdirentries64.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_getdirentries64 +#error "SYS_getdirentries64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getdirentries64, getdirentries64, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___gethostuuid.S b/src/kernel/libsyscall/bsdsyscalls/___gethostuuid.S new file mode 100644 index 000000000..ef0485c95 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___gethostuuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_gethostuuid +#error "SYS_gethostuuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___gethostuuid, gethostuuid, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___getlogin.S b/src/kernel/libsyscall/bsdsyscalls/___getlogin.S new file mode 100644 index 000000000..e4a4f4ab5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___getlogin.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getlogin +#error "SYS_getlogin not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getlogin, getlogin, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___getpeername.S b/src/kernel/libsyscall/bsdsyscalls/___getpeername.S new file mode 100644 index 000000000..f4cb030c2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___getpeername.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_getpeername +#error "SYS_getpeername not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getpeername, getpeername, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getpeername$UNIX2003 + .set _getpeername$UNIX2003, ___getpeername +#endif + +#if defined(__x86_64__) + .globl _getpeername + .set _getpeername, ___getpeername +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___getpid.S b/src/kernel/libsyscall/bsdsyscalls/___getpid.S new file mode 100644 index 000000000..78de0824c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___getpid.S @@ -0,0 +1,104 @@ +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "SYS.h" + +#if defined(__i386__) + + .data + .globl __current_pid + .private_extern __current_pid +L__current_pid_addr: + __current_pid: + .long 0 + +#if defined(__DYNAMIC__) +#define GET_CURRENT_PID \ + call 0f ; \ +0: ; \ + popl %ecx ; \ + leal L__current_pid_addr-0b(%ecx), %ecx + +#define __current_pid (%ecx) + +#else +#define GET_CURRENT_PID +#endif + +/* + * If __current_pid is > 0, return it, else make syscall. + * If __current_pid is 0, cache result of syscall. + */ +TEXT +LEAF(___getpid, 0) + GET_CURRENT_PID + movl __current_pid, %eax + testl %eax, %eax + jle 1f + ret +1: + UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) + movl %eax, %edx + xorl %eax, %eax + GET_CURRENT_PID + lock + cmpxchgl %edx, __current_pid + movl %edx, %eax + ret + +#elif defined(__x86_64__) + + .data + .globl __current_pid + .private_extern __current_pid +__current_pid: + .long 0 + +/* + * If __current_pid is > 0, return it, else make syscall. + * If __current_pid is 0, cache result of syscall. + */ +TEXT +LEAF(___getpid, 0) + movl __current_pid(%rip), %eax + testl %eax, %eax + jle 1f + ret +1: + UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) + movl %eax, %edx + xorl %eax, %eax + leaq __current_pid(%rip), %rcx + lock + cmpxchgl %edx, (%rcx) + movl %edx, %eax + ret + +#else +#error Unsupported architecture +#endif diff --git a/src/kernel/libsyscall/bsdsyscalls/___getrlimit.S b/src/kernel/libsyscall/bsdsyscalls/___getrlimit.S new file mode 100644 index 000000000..0be60f5fa --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___getrlimit.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getrlimit +#error "SYS_getrlimit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getrlimit, getrlimit, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getrlimit + .set _getrlimit, ___getrlimit +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___getsgroups.S b/src/kernel/libsyscall/bsdsyscalls/___getsgroups.S new file mode 100644 index 000000000..eac5a0b93 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___getsgroups.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getsgroups +#error "SYS_getsgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getsgroups, getsgroups, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getsgroups_np + .set _getsgroups_np, ___getsgroups +#endif + +#if defined(__x86_64__) + .globl _getsgroups_np + .set _getsgroups_np, ___getsgroups +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___getsockname.S b/src/kernel/libsyscall/bsdsyscalls/___getsockname.S new file mode 100644 index 000000000..9c27e6ae6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___getsockname.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_getsockname +#error "SYS_getsockname not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getsockname, getsockname, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getsockname$UNIX2003 + .set _getsockname$UNIX2003, ___getsockname +#endif + +#if defined(__x86_64__) + .globl _getsockname + .set _getsockname, ___getsockname +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___gettid.S b/src/kernel/libsyscall/bsdsyscalls/___gettid.S new file mode 100644 index 000000000..5ea9309e3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___gettid.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_gettid +#error "SYS_gettid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___gettid, gettid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _pthread_getugid_np + .set _pthread_getugid_np, ___gettid +#endif + +#if defined(__x86_64__) + .globl _pthread_getugid_np + .set _pthread_getugid_np, ___gettid +#endif + diff --git a/src/kernel/libsyscall/sys_i386/__gettimeofday.S b/src/kernel/libsyscall/bsdsyscalls/___gettimeofday.S similarity index 100% rename from src/kernel/libsyscall/sys_i386/__gettimeofday.S rename to src/kernel/libsyscall/bsdsyscalls/___gettimeofday.S diff --git a/src/kernel/libsyscall/bsdsyscalls/___getwgroups.S b/src/kernel/libsyscall/bsdsyscalls/___getwgroups.S new file mode 100644 index 000000000..c9115097d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___getwgroups.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getwgroups +#error "SYS_getwgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getwgroups, getwgroups, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getwgroups_np + .set _getwgroups_np, ___getwgroups +#endif + +#if defined(__x86_64__) + .globl _getwgroups_np + .set _getwgroups_np, ___getwgroups +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___guarded_open_dprotected_np.S b/src/kernel/libsyscall/bsdsyscalls/___guarded_open_dprotected_np.S new file mode 100644 index 000000000..ac0deffe0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___guarded_open_dprotected_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_guarded_open_dprotected_np +#error "SYS_guarded_open_dprotected_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___guarded_open_dprotected_np, guarded_open_dprotected_np, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___guarded_open_np.S b/src/kernel/libsyscall/bsdsyscalls/___guarded_open_np.S new file mode 100644 index 000000000..55a778f7c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___guarded_open_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_guarded_open_np +#error "SYS_guarded_open_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___guarded_open_np, guarded_open_np, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___identitysvc.S b/src/kernel/libsyscall/bsdsyscalls/___identitysvc.S new file mode 100644 index 000000000..d07eac9ad --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___identitysvc.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_identitysvc +#error "SYS_identitysvc not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___identitysvc, identitysvc, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___initgroups.S b/src/kernel/libsyscall/bsdsyscalls/___initgroups.S new file mode 100644 index 000000000..f705f51c3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___initgroups.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_initgroups +#error "SYS_initgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___initgroups, initgroups, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___ioctl.S b/src/kernel/libsyscall/bsdsyscalls/___ioctl.S new file mode 100644 index 000000000..705f260b8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___ioctl.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_ioctl +#error "SYS_ioctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___ioctl, ioctl, 3, cerror) +#endif + +#if defined(__i386__) + .globl _ioctl + .set _ioctl, ___ioctl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___iopolicysys.S b/src/kernel/libsyscall/bsdsyscalls/___iopolicysys.S new file mode 100644 index 000000000..72b4172a5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___iopolicysys.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_iopolicysys +#error "SYS_iopolicysys not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___iopolicysys, iopolicysys, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___kdebug_trace.S b/src/kernel/libsyscall/bsdsyscalls/___kdebug_trace.S new file mode 100644 index 000000000..30dafa9f7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___kdebug_trace.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_kdebug_trace +#error "SYS_kdebug_trace not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___kdebug_trace, kdebug_trace, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___kdebug_trace64.S b/src/kernel/libsyscall/bsdsyscalls/___kdebug_trace64.S new file mode 100644 index 000000000..5482adc60 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___kdebug_trace64.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 36 +#include "SYS.h" + +#ifndef SYS_kdebug_trace64 +#error "SYS_kdebug_trace64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___kdebug_trace64, kdebug_trace64, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___kdebug_trace_string.S b/src/kernel/libsyscall/bsdsyscalls/___kdebug_trace_string.S new file mode 100644 index 000000000..e3543e6bf --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___kdebug_trace_string.S @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "SYS.h" + +#if defined(__x86_64__) + +__SYSCALL(___kdebug_trace_string, kdebug_trace_string, 3) + +#elif defined(__i386__) + +__SYSCALL_INT(___kdebug_trace_string, kdebug_trace_string, 3) + +#else +#error Unsupported architecture +#endif diff --git a/src/kernel/libsyscall/bsdsyscalls/___kdebug_typefilter.S b/src/kernel/libsyscall/bsdsyscalls/___kdebug_typefilter.S new file mode 100644 index 000000000..c23b675aa --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___kdebug_typefilter.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_kdebug_typefilter +#error "SYS_kdebug_typefilter not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___kdebug_typefilter, kdebug_typefilter, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___kill.S b/src/kernel/libsyscall/bsdsyscalls/___kill.S new file mode 100644 index 000000000..e608f7b56 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___kill.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_kill +#error "SYS_kill not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___kill, kill, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___lchown.S b/src/kernel/libsyscall/bsdsyscalls/___lchown.S new file mode 100644 index 000000000..e22bfd73f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___lchown.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_lchown +#error "SYS_lchown not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___lchown, lchown, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _lchown$UNIX2003 + .set _lchown$UNIX2003, ___lchown +#endif + +#if defined(__x86_64__) + .globl _lchown + .set _lchown, ___lchown +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___listen.S b/src/kernel/libsyscall/bsdsyscalls/___listen.S new file mode 100644 index 000000000..5184a75fb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___listen.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_listen +#error "SYS_listen not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___listen, listen, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _listen$UNIX2003 + .set _listen$UNIX2003, ___listen +#endif + +#if defined(__x86_64__) + .globl _listen + .set _listen, ___listen +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___lseek.S b/src/kernel/libsyscall/bsdsyscalls/___lseek.S new file mode 100644 index 000000000..fb3e9e49c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___lseek.S @@ -0,0 +1,56 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "SYS.h" + +#ifdef DARLING +# define ___lseek __lseek +#endif + +#if defined(__x86_64__) + +__SYSCALL(___lseek, lseek, 3) + +#elif defined(__i386__) + +__SYSCALL_INT(___lseek, lseek, 3) + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _lseek + .set _lseek, ___lseek +#endif + +#if defined(__x86_64__) + .globl _lseek + .set _lseek, ___lseek +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___lstat64_extended.S b/src/kernel/libsyscall/bsdsyscalls/___lstat64_extended.S new file mode 100644 index 000000000..98b595067 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___lstat64_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_lstat64_extended +#error "SYS_lstat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___lstat64_extended, lstat64_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___lstat_extended.S b/src/kernel/libsyscall/bsdsyscalls/___lstat_extended.S new file mode 100644 index 000000000..6c7c4f7d8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___lstat_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_lstat_extended +#error "SYS_lstat_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___lstat_extended, lstat_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_execve.S b/src/kernel/libsyscall/bsdsyscalls/___mac_execve.S new file mode 100644 index 000000000..5606ed80d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_execve.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS___mac_execve +#error "SYS___mac_execve not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_execve, __mac_execve, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl ___sandbox_me + .set ___sandbox_me, ___mac_execve +#endif + +#if defined(__x86_64__) + .globl ___sandbox_me + .set ___sandbox_me, ___mac_execve +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_get_fd.S b/src/kernel/libsyscall/bsdsyscalls/___mac_get_fd.S new file mode 100644 index 000000000..a83c4eaeb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_get_fd.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_fd +#error "SYS___mac_get_fd not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_fd, __mac_get_fd, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_get_file.S b/src/kernel/libsyscall/bsdsyscalls/___mac_get_file.S new file mode 100644 index 000000000..f520b74ea --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_get_file.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_file +#error "SYS___mac_get_file not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_file, __mac_get_file, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_get_link.S b/src/kernel/libsyscall/bsdsyscalls/___mac_get_link.S new file mode 100644 index 000000000..6e399d12c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_get_link.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_link +#error "SYS___mac_get_link not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_link, __mac_get_link, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_get_mount.S b/src/kernel/libsyscall/bsdsyscalls/___mac_get_mount.S new file mode 100644 index 000000000..9ea5c0f7d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_get_mount.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_mount +#error "SYS___mac_get_mount not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_mount, __mac_get_mount, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_get_pid.S b/src/kernel/libsyscall/bsdsyscalls/___mac_get_pid.S new file mode 100644 index 000000000..c21007634 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_get_pid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_pid +#error "SYS___mac_get_pid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_pid, __mac_get_pid, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_get_proc.S b/src/kernel/libsyscall/bsdsyscalls/___mac_get_proc.S new file mode 100644 index 000000000..d732a36aa --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_get_proc.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___mac_get_proc +#error "SYS___mac_get_proc not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_proc, __mac_get_proc, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_getfsstat.S b/src/kernel/libsyscall/bsdsyscalls/___mac_getfsstat.S new file mode 100644 index 000000000..33d18be56 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_getfsstat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS___mac_getfsstat +#error "SYS___mac_getfsstat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_getfsstat, __mac_getfsstat, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_mount.S b/src/kernel/libsyscall/bsdsyscalls/___mac_mount.S new file mode 100644 index 000000000..7f0b33fbc --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_mount.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS___mac_mount +#error "SYS___mac_mount not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_mount, __mac_mount, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl ___sandbox_mm + .set ___sandbox_mm, ___mac_mount +#endif + +#if defined(__x86_64__) + .globl ___sandbox_mm + .set ___sandbox_mm, ___mac_mount +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_set_fd.S b/src/kernel/libsyscall/bsdsyscalls/___mac_set_fd.S new file mode 100644 index 000000000..b6eaa6b5f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_set_fd.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_set_fd +#error "SYS___mac_set_fd not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_set_fd, __mac_set_fd, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_set_file.S b/src/kernel/libsyscall/bsdsyscalls/___mac_set_file.S new file mode 100644 index 000000000..cf1c0a443 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_set_file.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_set_file +#error "SYS___mac_set_file not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_set_file, __mac_set_file, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_set_link.S b/src/kernel/libsyscall/bsdsyscalls/___mac_set_link.S new file mode 100644 index 000000000..67c0b3381 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_set_link.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_set_link +#error "SYS___mac_set_link not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_set_link, __mac_set_link, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_set_proc.S b/src/kernel/libsyscall/bsdsyscalls/___mac_set_proc.S new file mode 100644 index 000000000..93517f314 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_set_proc.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___mac_set_proc +#error "SYS___mac_set_proc not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_set_proc, __mac_set_proc, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl ___sandbox_msp + .set ___sandbox_msp, ___mac_set_proc +#endif + +#if defined(__x86_64__) + .globl ___sandbox_msp + .set ___sandbox_msp, ___mac_set_proc +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mac_syscall.S b/src/kernel/libsyscall/bsdsyscalls/___mac_syscall.S new file mode 100644 index 000000000..60497bcdb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mac_syscall.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS___mac_syscall +#error "SYS___mac_syscall not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_syscall, __mac_syscall, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl ___sandbox_ms + .set ___sandbox_ms, ___mac_syscall +#endif + +#if defined(__x86_64__) + .globl ___sandbox_ms + .set ___sandbox_ms, ___mac_syscall +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___microstackshot.S b/src/kernel/libsyscall/bsdsyscalls/___microstackshot.S new file mode 100644 index 000000000..b7c712891 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___microstackshot.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_microstackshot +#error "SYS_microstackshot not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___microstackshot, microstackshot, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mkdir_extended.S b/src/kernel/libsyscall/bsdsyscalls/___mkdir_extended.S new file mode 100644 index 000000000..c0b36393a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mkdir_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_mkdir_extended +#error "SYS_mkdir_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mkdir_extended, mkdir_extended, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mkfifo_extended.S b/src/kernel/libsyscall/bsdsyscalls/___mkfifo_extended.S new file mode 100644 index 000000000..cf06eac09 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mkfifo_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_mkfifo_extended +#error "SYS_mkfifo_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mkfifo_extended, mkfifo_extended, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mmap.S b/src/kernel/libsyscall/bsdsyscalls/___mmap.S new file mode 100644 index 000000000..ba33a5587 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mmap.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_mmap +#error "SYS_mmap not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mmap, mmap, 6, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _mmap + .set _mmap, ___mmap +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___mprotect.S b/src/kernel/libsyscall/bsdsyscalls/___mprotect.S new file mode 100644 index 000000000..1f0490e23 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___mprotect.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_mprotect +#error "SYS_mprotect not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mprotect, mprotect, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _mprotect$UNIX2003 + .set _mprotect$UNIX2003, ___mprotect +#endif + +#if defined(__x86_64__) + .globl _mprotect + .set _mprotect, ___mprotect +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___msgctl.S b/src/kernel/libsyscall/bsdsyscalls/___msgctl.S new file mode 100644 index 000000000..ccfe10fe7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___msgctl.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_msgctl +#error "SYS_msgctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msgctl, msgctl, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msgctl$UNIX2003 + .set _msgctl$UNIX2003, ___msgctl +#endif + +#if defined(__x86_64__) + .globl _msgctl + .set _msgctl, ___msgctl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___msgrcv_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___msgrcv_nocancel.S new file mode 100644 index 000000000..e85ae0f2b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___msgrcv_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_msgrcv_nocancel +#error "SYS_msgrcv_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msgrcv_nocancel, msgrcv_nocancel, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msgrcv + .set _msgrcv, ___msgrcv_nocancel + .globl _msgrcv$NOCANCEL$UNIX2003 + .set _msgrcv$NOCANCEL$UNIX2003, ___msgrcv_nocancel +#endif + +#if defined(__x86_64__) + .globl _msgrcv$NOCANCEL + .set _msgrcv$NOCANCEL, ___msgrcv_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___msgsnd_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___msgsnd_nocancel.S new file mode 100644 index 000000000..5bd427693 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___msgsnd_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_msgsnd_nocancel +#error "SYS_msgsnd_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msgsnd_nocancel, msgsnd_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msgsnd + .set _msgsnd, ___msgsnd_nocancel + .globl _msgsnd$NOCANCEL$UNIX2003 + .set _msgsnd$NOCANCEL$UNIX2003, ___msgsnd_nocancel +#endif + +#if defined(__x86_64__) + .globl _msgsnd$NOCANCEL + .set _msgsnd$NOCANCEL, ___msgsnd_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___msgsys.S b/src/kernel/libsyscall/bsdsyscalls/___msgsys.S new file mode 100644 index 000000000..9337546e1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___msgsys.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_msgsys +#error "SYS_msgsys not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msgsys, msgsys, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msgsys + .set _msgsys, ___msgsys +#endif + +#if defined(__x86_64__) + .globl _msgsys + .set _msgsys, ___msgsys +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___msync.S b/src/kernel/libsyscall/bsdsyscalls/___msync.S new file mode 100644 index 000000000..638425c77 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___msync.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_msync +#error "SYS_msync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msync, msync, 3, cerror) +#endif + +#if defined(__i386__) + .globl _msync$UNIX2003 + .set _msync$UNIX2003, ___msync +#endif + +#if defined(__x86_64__) + .globl _msync + .set _msync, ___msync +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___msync_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___msync_nocancel.S new file mode 100644 index 000000000..3df28d7f1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___msync_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_msync_nocancel +#error "SYS_msync_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msync_nocancel, msync_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msync$NOCANCEL$UNIX2003 + .set _msync$NOCANCEL$UNIX2003, ___msync_nocancel +#endif + +#if defined(__x86_64__) + .globl _msync$NOCANCEL + .set _msync$NOCANCEL, ___msync_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___munmap.S b/src/kernel/libsyscall/bsdsyscalls/___munmap.S new file mode 100644 index 000000000..b6bc6f40f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___munmap.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_munmap +#error "SYS_munmap not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___munmap, munmap, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___old_semwait_signal.S b/src/kernel/libsyscall/bsdsyscalls/___old_semwait_signal.S new file mode 100644 index 000000000..e696e6876 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___old_semwait_signal.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS___old_semwait_signal +#error "SYS___old_semwait_signal not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___old_semwait_signal, __old_semwait_signal, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___open.S b/src/kernel/libsyscall/bsdsyscalls/___open.S new file mode 100644 index 000000000..91dfa4aa6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___open.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_open +#error "SYS_open not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___open, open, 3, cerror) +#endif + +#if defined(__i386__) + .globl _open$UNIX2003 + .set _open$UNIX2003, ___open +#endif + +#if defined(__x86_64__) + .globl _open + .set _open, ___open +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___open_dprotected_np.S b/src/kernel/libsyscall/bsdsyscalls/___open_dprotected_np.S new file mode 100644 index 000000000..3105a3dc2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___open_dprotected_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_open_dprotected_np +#error "SYS_open_dprotected_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___open_dprotected_np, open_dprotected_np, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___open_extended.S b/src/kernel/libsyscall/bsdsyscalls/___open_extended.S new file mode 100644 index 000000000..28bb1f3f0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___open_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_open_extended +#error "SYS_open_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___open_extended, open_extended, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___open_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___open_nocancel.S new file mode 100644 index 000000000..87c47594c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___open_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_open_nocancel +#error "SYS_open_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___open_nocancel, open_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _open$NOCANCEL$UNIX2003 + .set _open$NOCANCEL$UNIX2003, ___open_nocancel +#endif + +#if defined(__x86_64__) + .globl _open$NOCANCEL + .set _open$NOCANCEL, ___open_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___openat.S b/src/kernel/libsyscall/bsdsyscalls/___openat.S new file mode 100644 index 000000000..d15fb384b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___openat.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_openat +#error "SYS_openat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___openat, openat, 4, cerror) +#endif + +#if defined(__i386__) + .globl _openat + .set _openat, ___openat +#endif + +#if defined(__x86_64__) + .globl _openat + .set _openat, ___openat +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___openat_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___openat_nocancel.S new file mode 100644 index 000000000..e31f25725 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___openat_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_openat_nocancel +#error "SYS_openat_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___openat_nocancel, openat_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _openat$NOCANCEL + .set _openat$NOCANCEL, ___openat_nocancel +#endif + +#if defined(__x86_64__) + .globl _openat$NOCANCEL + .set _openat$NOCANCEL, ___openat_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___persona.S b/src/kernel/libsyscall/bsdsyscalls/___persona.S new file mode 100644 index 000000000..290a72e32 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___persona.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_persona +#error "SYS_persona not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___persona, persona, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pipe.S b/src/kernel/libsyscall/bsdsyscalls/___pipe.S new file mode 100644 index 000000000..615eec3bd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pipe.S @@ -0,0 +1,66 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ + +#include "SYS.h" + +#ifdef DARLING +# define ___pipe __pipe +#endif + +#if defined(__i386__) + +PSEUDO_INT(___pipe, pipe, 0) + movl 4(%esp),%ecx + movl %eax,(%ecx) + movl %edx,4(%ecx) + xorl %eax,%eax + ret + +#elif defined(__x86_64__) + +PSEUDO(___pipe, pipe, 0, cerror_nocancel) + movl %eax, (%rdi) + movl %edx, 4(%rdi) + xorl %eax, %eax + ret + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _pipe + .set _pipe, ___pipe +#endif + +#if defined(__x86_64__) + .globl _pipe + .set _pipe, ___pipe +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___poll_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___poll_nocancel.S new file mode 100644 index 000000000..8adfa6a86 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___poll_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_poll_nocancel +#error "SYS_poll_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___poll_nocancel, poll_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _poll + .set _poll, ___poll_nocancel + .globl _poll$NOCANCEL$UNIX2003 + .set _poll$NOCANCEL$UNIX2003, ___poll_nocancel +#endif + +#if defined(__x86_64__) + .globl _poll$NOCANCEL + .set _poll$NOCANCEL, ___poll_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___posix_spawn.S b/src/kernel/libsyscall/bsdsyscalls/___posix_spawn.S new file mode 100644 index 000000000..8fbc54851 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___posix_spawn.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_posix_spawn +#error "SYS_posix_spawn not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___posix_spawn, posix_spawn, 5, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pread_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___pread_nocancel.S new file mode 100644 index 000000000..99946ba78 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pread_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_pread_nocancel +#error "SYS_pread_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pread_nocancel, pread_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _pread + .set _pread, ___pread_nocancel + .globl _pread$NOCANCEL$UNIX2003 + .set _pread$NOCANCEL$UNIX2003, ___pread_nocancel +#endif + +#if defined(__x86_64__) + .globl _pread$NOCANCEL + .set _pread$NOCANCEL, ___pread_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___proc_info.S b/src/kernel/libsyscall/bsdsyscalls/___proc_info.S new file mode 100644 index 000000000..78ae50586 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___proc_info.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_proc_info +#error "SYS_proc_info not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___proc_info, proc_info, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___process_policy.S b/src/kernel/libsyscall/bsdsyscalls/___process_policy.S new file mode 100644 index 000000000..103a82d66 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___process_policy.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 32 +#include "SYS.h" + +#ifndef SYS_process_policy +#error "SYS_process_policy not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___process_policy, process_policy, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pselect.S b/src/kernel/libsyscall/bsdsyscalls/___pselect.S new file mode 100644 index 000000000..8bc4f881a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pselect.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_pselect +#error "SYS_pselect not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pselect, pselect, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pselect_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___pselect_nocancel.S new file mode 100644 index 000000000..fee781fac --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pselect_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_pselect_nocancel +#error "SYS_pselect_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pselect_nocancel, pselect_nocancel, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_cvbroad.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_cvbroad.S new file mode 100644 index 000000000..47dc0df32 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_cvbroad.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 44 +#include "SYS.h" + +#ifndef SYS_psynch_cvbroad +#error "SYS_psynch_cvbroad not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_cvbroad, psynch_cvbroad, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_cvclrprepost.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_cvclrprepost.S new file mode 100644 index 000000000..82929a7c5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_cvclrprepost.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_psynch_cvclrprepost +#error "SYS_psynch_cvclrprepost not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_cvclrprepost, psynch_cvclrprepost, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_cvsignal.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_cvsignal.S new file mode 100644 index 000000000..2e4de686d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_cvsignal.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 44 +#include "SYS.h" + +#ifndef SYS_psynch_cvsignal +#error "SYS_psynch_cvsignal not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_cvsignal, psynch_cvsignal, 8, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_cvwait.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_cvwait.S new file mode 100644 index 000000000..b53d4f5ee --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_cvwait.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 44 +#include "SYS.h" + +#ifndef SYS_psynch_cvwait +#error "SYS_psynch_cvwait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_cvwait, psynch_cvwait, 8, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_mutexdrop.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_mutexdrop.S new file mode 100644 index 000000000..e00e2e22f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_mutexdrop.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_psynch_mutexdrop +#error "SYS_psynch_mutexdrop not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_mutexdrop, psynch_mutexdrop, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_mutexwait.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_mutexwait.S new file mode 100644 index 000000000..80a3c5b5f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_mutexwait.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_psynch_mutexwait +#error "SYS_psynch_mutexwait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_mutexwait, psynch_mutexwait, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_downgrade.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_downgrade.S new file mode 100644 index 000000000..0aee0f8fa --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_downgrade.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_downgrade +#error "SYS_psynch_rw_downgrade not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_downgrade, psynch_rw_downgrade, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_longrdlock.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_longrdlock.S new file mode 100644 index 000000000..9834f388e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_longrdlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_longrdlock +#error "SYS_psynch_rw_longrdlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_longrdlock, psynch_rw_longrdlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_rdlock.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_rdlock.S new file mode 100644 index 000000000..c895923ad --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_rdlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_rdlock +#error "SYS_psynch_rw_rdlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_rdlock, psynch_rw_rdlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_unlock.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_unlock.S new file mode 100644 index 000000000..11cf93d6a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_unlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_unlock +#error "SYS_psynch_rw_unlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_unlock, psynch_rw_unlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_unlock2.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_unlock2.S new file mode 100644 index 000000000..4a6daccd0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_unlock2.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_unlock2 +#error "SYS_psynch_rw_unlock2 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_unlock2, psynch_rw_unlock2, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_upgrade.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_upgrade.S new file mode 100644 index 000000000..d832eec00 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_upgrade.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_upgrade +#error "SYS_psynch_rw_upgrade not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_upgrade, psynch_rw_upgrade, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_wrlock.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_wrlock.S new file mode 100644 index 000000000..8747b873d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_wrlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_wrlock +#error "SYS_psynch_rw_wrlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_wrlock, psynch_rw_wrlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_yieldwrlock.S b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_yieldwrlock.S new file mode 100644 index 000000000..6d194d8c7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___psynch_rw_yieldwrlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_yieldwrlock +#error "SYS_psynch_rw_yieldwrlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_yieldwrlock, psynch_rw_yieldwrlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pthread_canceled.S b/src/kernel/libsyscall/bsdsyscalls/___pthread_canceled.S new file mode 100644 index 000000000..219f63e70 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pthread_canceled.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___pthread_canceled +#error "SYS___pthread_canceled not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_canceled, __pthread_canceled, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pthread_chdir.S b/src/kernel/libsyscall/bsdsyscalls/___pthread_chdir.S new file mode 100644 index 000000000..f947fb011 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pthread_chdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___pthread_chdir +#error "SYS___pthread_chdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_chdir, __pthread_chdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pthread_fchdir.S b/src/kernel/libsyscall/bsdsyscalls/___pthread_fchdir.S new file mode 100644 index 000000000..21af883be --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pthread_fchdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___pthread_fchdir +#error "SYS___pthread_fchdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_fchdir, __pthread_fchdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pthread_kill.S b/src/kernel/libsyscall/bsdsyscalls/___pthread_kill.S new file mode 100644 index 000000000..e46f8332b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pthread_kill.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___pthread_kill +#error "SYS___pthread_kill not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_kill, __pthread_kill, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pthread_markcancel.S b/src/kernel/libsyscall/bsdsyscalls/___pthread_markcancel.S new file mode 100644 index 000000000..657709261 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pthread_markcancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___pthread_markcancel +#error "SYS___pthread_markcancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_markcancel, __pthread_markcancel, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___pthread_sigmask.S b/src/kernel/libsyscall/bsdsyscalls/___pthread_sigmask.S new file mode 100644 index 000000000..030e05621 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pthread_sigmask.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS___pthread_sigmask +#error "SYS___pthread_sigmask not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_sigmask, __pthread_sigmask, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___ptrace.S b/src/kernel/libsyscall/bsdsyscalls/___ptrace.S new file mode 100644 index 000000000..bdcbec9fb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___ptrace.S @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ + +#include "SYS.h" + +#if defined(__i386__) + + .globl _errno + +LEAF(___ptrace, 0) + xorl %eax,%eax + REG_TO_EXTERN(%eax,_errno) + UNIX_SYSCALL_NONAME(ptrace, 4, cerror) + ret + +#elif defined(__x86_64__) + + .globl _errno + +LEAF(___ptrace, 0) + xorq %rax,%rax + PICIFY(_errno) + movl %eax,(%r11) + UNIX_SYSCALL_NONAME(ptrace, 4, cerror) + ret + +#else +#error Unsupported architecture +#endif diff --git a/src/kernel/libsyscall/bsdsyscalls/___pwrite_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___pwrite_nocancel.S new file mode 100644 index 000000000..7f3dfb987 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___pwrite_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_pwrite_nocancel +#error "SYS_pwrite_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pwrite_nocancel, pwrite_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _pwrite + .set _pwrite, ___pwrite_nocancel + .globl _pwrite$NOCANCEL$UNIX2003 + .set _pwrite$NOCANCEL$UNIX2003, ___pwrite_nocancel +#endif + +#if defined(__x86_64__) + .globl _pwrite$NOCANCEL + .set _pwrite$NOCANCEL, ___pwrite_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___read_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___read_nocancel.S new file mode 100644 index 000000000..9b1164804 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___read_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_read_nocancel +#error "SYS_read_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___read_nocancel, read_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _read + .set _read, ___read_nocancel + .globl _read$NOCANCEL$UNIX2003 + .set _read$NOCANCEL$UNIX2003, ___read_nocancel +#endif + +#if defined(__x86_64__) + .globl _read$NOCANCEL + .set _read$NOCANCEL, ___read_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___readv_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___readv_nocancel.S new file mode 100644 index 000000000..18c11de68 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___readv_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_readv_nocancel +#error "SYS_readv_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___readv_nocancel, readv_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _readv + .set _readv, ___readv_nocancel + .globl _readv$NOCANCEL$UNIX2003 + .set _readv$NOCANCEL$UNIX2003, ___readv_nocancel +#endif + +#if defined(__x86_64__) + .globl _readv$NOCANCEL + .set _readv$NOCANCEL, ___readv_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___recvfrom.S b/src/kernel/libsyscall/bsdsyscalls/___recvfrom.S new file mode 100644 index 000000000..69b4f7163 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___recvfrom.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_recvfrom +#error "SYS_recvfrom not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___recvfrom, recvfrom, 6, cerror) +#endif + +#if defined(__i386__) + .globl _recvfrom$UNIX2003 + .set _recvfrom$UNIX2003, ___recvfrom +#endif + +#if defined(__x86_64__) + .globl _recvfrom + .set _recvfrom, ___recvfrom +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___recvfrom_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___recvfrom_nocancel.S new file mode 100644 index 000000000..87101758d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___recvfrom_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_recvfrom_nocancel +#error "SYS_recvfrom_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___recvfrom_nocancel, recvfrom_nocancel, 6, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _recvfrom$NOCANCEL$UNIX2003 + .set _recvfrom$NOCANCEL$UNIX2003, ___recvfrom_nocancel +#endif + +#if defined(__x86_64__) + .globl _recvfrom$NOCANCEL + .set _recvfrom$NOCANCEL, ___recvfrom_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___recvmsg.S b/src/kernel/libsyscall/bsdsyscalls/___recvmsg.S new file mode 100644 index 000000000..f19cc39e9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___recvmsg.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_recvmsg +#error "SYS_recvmsg not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___recvmsg, recvmsg, 3, cerror) +#endif + +#if defined(__i386__) + .globl _recvmsg$UNIX2003 + .set _recvmsg$UNIX2003, ___recvmsg +#endif + +#if defined(__x86_64__) + .globl _recvmsg + .set _recvmsg, ___recvmsg +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___recvmsg_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___recvmsg_nocancel.S new file mode 100644 index 000000000..ac22ccded --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___recvmsg_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_recvmsg_nocancel +#error "SYS_recvmsg_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___recvmsg_nocancel, recvmsg_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _recvmsg$NOCANCEL$UNIX2003 + .set _recvmsg$NOCANCEL$UNIX2003, ___recvmsg_nocancel +#endif + +#if defined(__x86_64__) + .globl _recvmsg$NOCANCEL + .set _recvmsg$NOCANCEL, ___recvmsg_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___rename.S b/src/kernel/libsyscall/bsdsyscalls/___rename.S new file mode 100644 index 000000000..bfd549426 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___rename.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_rename +#error "SYS_rename not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___rename, rename, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___renameat.S b/src/kernel/libsyscall/bsdsyscalls/___renameat.S new file mode 100644 index 000000000..f6180f512 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___renameat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_renameat +#error "SYS_renameat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___renameat, renameat, 4, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___renameatx_np.S b/src/kernel/libsyscall/bsdsyscalls/___renameatx_np.S new file mode 100644 index 000000000..0c69843ab --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___renameatx_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_renameatx_np +#error "SYS_renameatx_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___renameatx_np, renameatx_np, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___rmdir.S b/src/kernel/libsyscall/bsdsyscalls/___rmdir.S new file mode 100644 index 000000000..1e8d7a0a5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___rmdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_rmdir +#error "SYS_rmdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___rmdir, rmdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___select.S b/src/kernel/libsyscall/bsdsyscalls/___select.S new file mode 100644 index 000000000..a3d94b6f3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___select.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_select +#error "SYS_select not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___select, select, 5, cerror) +#endif + +#if defined(__i386__) + .globl _select$DARWIN_EXTSN + .set _select$DARWIN_EXTSN, ___select +#endif + +#if defined(__x86_64__) + .globl _select$DARWIN_EXTSN + .set _select$DARWIN_EXTSN, ___select +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___select_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___select_nocancel.S new file mode 100644 index 000000000..dbfb3f44d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___select_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_select_nocancel +#error "SYS_select_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___select_nocancel, select_nocancel, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _select$DARWIN_EXTSN$NOCANCEL + .set _select$DARWIN_EXTSN$NOCANCEL, ___select_nocancel +#endif + +#if defined(__x86_64__) + .globl _select$DARWIN_EXTSN$NOCANCEL + .set _select$DARWIN_EXTSN$NOCANCEL, ___select_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sem_open.S b/src/kernel/libsyscall/bsdsyscalls/___sem_open.S new file mode 100644 index 000000000..f02feb832 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sem_open.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_sem_open +#error "SYS_sem_open not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sem_open, sem_open, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _sem_open + .set _sem_open, ___sem_open +#endif + +#if defined(__x86_64__) + .globl _sem_open + .set _sem_open, ___sem_open +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sem_wait_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___sem_wait_nocancel.S new file mode 100644 index 000000000..5b127e28a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sem_wait_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_wait_nocancel +#error "SYS_sem_wait_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sem_wait_nocancel, sem_wait_nocancel, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _sem_wait + .set _sem_wait, ___sem_wait_nocancel + .globl _sem_wait$NOCANCEL$UNIX2003 + .set _sem_wait$NOCANCEL$UNIX2003, ___sem_wait_nocancel +#endif + +#if defined(__x86_64__) + .globl _sem_wait$NOCANCEL + .set _sem_wait$NOCANCEL, ___sem_wait_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___semctl.S b/src/kernel/libsyscall/bsdsyscalls/___semctl.S new file mode 100644 index 000000000..1571ce85e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___semctl.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_semctl +#error "SYS_semctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___semctl, semctl, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _semctl$UNIX2003 + .set _semctl$UNIX2003, ___semctl +#endif + +#if defined(__x86_64__) + .globl _semctl + .set _semctl, ___semctl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___semsys.S b/src/kernel/libsyscall/bsdsyscalls/___semsys.S new file mode 100644 index 000000000..e3099b41c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___semsys.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_semsys +#error "SYS_semsys not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___semsys, semsys, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _semsys + .set _semsys, ___semsys +#endif + +#if defined(__x86_64__) + .globl _semsys + .set _semsys, ___semsys +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___semwait_signal.S b/src/kernel/libsyscall/bsdsyscalls/___semwait_signal.S new file mode 100644 index 000000000..d447d8c6d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___semwait_signal.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS___semwait_signal +#error "SYS___semwait_signal not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___semwait_signal, __semwait_signal, 6, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___semwait_signal_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___semwait_signal_nocancel.S new file mode 100644 index 000000000..6a951178e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___semwait_signal_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS___semwait_signal_nocancel +#error "SYS___semwait_signal_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___semwait_signal_nocancel, __semwait_signal_nocancel, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sendmsg.S b/src/kernel/libsyscall/bsdsyscalls/___sendmsg.S new file mode 100644 index 000000000..ffaa4cb6d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sendmsg.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_sendmsg +#error "SYS_sendmsg not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sendmsg, sendmsg, 3, cerror) +#endif + +#if defined(__i386__) + .globl _sendmsg$UNIX2003 + .set _sendmsg$UNIX2003, ___sendmsg +#endif + +#if defined(__x86_64__) + .globl _sendmsg + .set _sendmsg, ___sendmsg +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sendmsg_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___sendmsg_nocancel.S new file mode 100644 index 000000000..f4cf57baa --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sendmsg_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_sendmsg_nocancel +#error "SYS_sendmsg_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sendmsg_nocancel, sendmsg_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _sendmsg$NOCANCEL$UNIX2003 + .set _sendmsg$NOCANCEL$UNIX2003, ___sendmsg_nocancel +#endif + +#if defined(__x86_64__) + .globl _sendmsg$NOCANCEL + .set _sendmsg$NOCANCEL, ___sendmsg_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sendto.S b/src/kernel/libsyscall/bsdsyscalls/___sendto.S new file mode 100644 index 000000000..d76f57b6c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sendto.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_sendto +#error "SYS_sendto not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sendto, sendto, 6, cerror) +#endif + +#if defined(__i386__) + .globl _sendto$UNIX2003 + .set _sendto$UNIX2003, ___sendto +#endif + +#if defined(__x86_64__) + .globl _sendto + .set _sendto, ___sendto +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sendto_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___sendto_nocancel.S new file mode 100644 index 000000000..5e7bc4c64 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sendto_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_sendto_nocancel +#error "SYS_sendto_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sendto_nocancel, sendto_nocancel, 6, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _sendto$NOCANCEL$UNIX2003 + .set _sendto$NOCANCEL$UNIX2003, ___sendto_nocancel +#endif + +#if defined(__x86_64__) + .globl _sendto$NOCANCEL + .set _sendto$NOCANCEL, ___sendto_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___setattrlist.S b/src/kernel/libsyscall/bsdsyscalls/___setattrlist.S new file mode 100644 index 000000000..af7e1cb2d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___setattrlist.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_setattrlist +#error "SYS_setattrlist not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setattrlist, setattrlist, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setattrlist$UNIX2003 + .set _setattrlist$UNIX2003, ___setattrlist +#endif + +#if defined(__x86_64__) + .globl _setattrlist + .set _setattrlist, ___setattrlist +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___setlogin.S b/src/kernel/libsyscall/bsdsyscalls/___setlogin.S new file mode 100644 index 000000000..d3042cf0b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___setlogin.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setlogin +#error "SYS_setlogin not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setlogin, setlogin, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___setpriority.S b/src/kernel/libsyscall/bsdsyscalls/___setpriority.S new file mode 100644 index 000000000..12916bb9c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___setpriority.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_setpriority +#error "SYS_setpriority not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setpriority, setpriority, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___setregid.S b/src/kernel/libsyscall/bsdsyscalls/___setregid.S new file mode 100644 index 000000000..d405a093e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___setregid.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setregid +#error "SYS_setregid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setregid, setregid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setregid$UNIX2003 + .set _setregid$UNIX2003, ___setregid +#endif + +#if defined(__x86_64__) + .globl _setregid + .set _setregid, ___setregid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___setreuid.S b/src/kernel/libsyscall/bsdsyscalls/___setreuid.S new file mode 100644 index 000000000..133748c57 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___setreuid.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setreuid +#error "SYS_setreuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setreuid, setreuid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setreuid$UNIX2003 + .set _setreuid$UNIX2003, ___setreuid +#endif + +#if defined(__x86_64__) + .globl _setreuid + .set _setreuid, ___setreuid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___setrlimit.S b/src/kernel/libsyscall/bsdsyscalls/___setrlimit.S new file mode 100644 index 000000000..2ad01e402 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___setrlimit.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setrlimit +#error "SYS_setrlimit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setrlimit, setrlimit, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setrlimit + .set _setrlimit, ___setrlimit +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___setsgroups.S b/src/kernel/libsyscall/bsdsyscalls/___setsgroups.S new file mode 100644 index 000000000..735dd8794 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___setsgroups.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setsgroups +#error "SYS_setsgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setsgroups, setsgroups, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setsgroups_np + .set _setsgroups_np, ___setsgroups +#endif + +#if defined(__x86_64__) + .globl _setsgroups_np + .set _setsgroups_np, ___setsgroups +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___settid.S b/src/kernel/libsyscall/bsdsyscalls/___settid.S new file mode 100644 index 000000000..535d96004 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___settid.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_settid +#error "SYS_settid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___settid, settid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _pthread_setugid_np + .set _pthread_setugid_np, ___settid +#endif + +#if defined(__x86_64__) + .globl _pthread_setugid_np + .set _pthread_setugid_np, ___settid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___settid_with_pid.S b/src/kernel/libsyscall/bsdsyscalls/___settid_with_pid.S new file mode 100644 index 000000000..93a02c0df --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___settid_with_pid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_settid_with_pid +#error "SYS_settid_with_pid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___settid_with_pid, settid_with_pid, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___settimeofday.S b/src/kernel/libsyscall/bsdsyscalls/___settimeofday.S new file mode 100644 index 000000000..9e6088356 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___settimeofday.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_settimeofday +#error "SYS_settimeofday not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___settimeofday, settimeofday, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___setwgroups.S b/src/kernel/libsyscall/bsdsyscalls/___setwgroups.S new file mode 100644 index 000000000..237bc2d2b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___setwgroups.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setwgroups +#error "SYS_setwgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setwgroups, setwgroups, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setwgroups_np + .set _setwgroups_np, ___setwgroups +#endif + +#if defined(__x86_64__) + .globl _setwgroups_np + .set _setwgroups_np, ___setwgroups +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sfi_ctl.S b/src/kernel/libsyscall/bsdsyscalls/___sfi_ctl.S new file mode 100644 index 000000000..8af3df105 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sfi_ctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_sfi_ctl +#error "SYS_sfi_ctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sfi_ctl, sfi_ctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sfi_pidctl.S b/src/kernel/libsyscall/bsdsyscalls/___sfi_pidctl.S new file mode 100644 index 000000000..9d73e585c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sfi_pidctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_sfi_pidctl +#error "SYS_sfi_pidctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sfi_pidctl, sfi_pidctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___shared_region_check_np.S b/src/kernel/libsyscall/bsdsyscalls/___shared_region_check_np.S new file mode 100644 index 000000000..f572b639e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___shared_region_check_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_shared_region_check_np +#error "SYS_shared_region_check_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shared_region_check_np, shared_region_check_np, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___shared_region_map_and_slide_np.S b/src/kernel/libsyscall/bsdsyscalls/___shared_region_map_and_slide_np.S new file mode 100644 index 000000000..9bcc68c11 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___shared_region_map_and_slide_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_shared_region_map_and_slide_np +#error "SYS_shared_region_map_and_slide_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shared_region_map_and_slide_np, shared_region_map_and_slide_np, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___shm_open.S b/src/kernel/libsyscall/bsdsyscalls/___shm_open.S new file mode 100644 index 000000000..bac8ff273 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___shm_open.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_shm_open +#error "SYS_shm_open not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shm_open, shm_open, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _shm_open + .set _shm_open, ___shm_open +#endif + +#if defined(__x86_64__) + .globl _shm_open + .set _shm_open, ___shm_open +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___shmctl.S b/src/kernel/libsyscall/bsdsyscalls/___shmctl.S new file mode 100644 index 000000000..fa14f151a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___shmctl.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_shmctl +#error "SYS_shmctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shmctl, shmctl, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _shmctl$UNIX2003 + .set _shmctl$UNIX2003, ___shmctl +#endif + +#if defined(__x86_64__) + .globl _shmctl + .set _shmctl, ___shmctl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___shmsys.S b/src/kernel/libsyscall/bsdsyscalls/___shmsys.S new file mode 100644 index 000000000..f5c4b4bb1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___shmsys.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_shmsys +#error "SYS_shmsys not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shmsys, shmsys, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _shmsys + .set _shmsys, ___shmsys +#endif + +#if defined(__x86_64__) + .globl _shmsys + .set _shmsys, ___shmsys +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sigaction.S b/src/kernel/libsyscall/bsdsyscalls/___sigaction.S new file mode 100644 index 000000000..87435bdb0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sigaction.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_sigaction +#error "SYS_sigaction not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sigaction, sigaction, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sigaltstack.S b/src/kernel/libsyscall/bsdsyscalls/___sigaltstack.S new file mode 100644 index 000000000..9e9946f23 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sigaltstack.S @@ -0,0 +1,51 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "SYS.h" + +#ifdef DARLING +# define ___sigaltstack __sigaltstack +#endif + +#if defined(__x86_64__) + +__SYSCALL(___sigaltstack, sigaltstack, 3) + +#elif defined(__i386__) + +__SYSCALL_INT(___sigaltstack, sigaltstack, 3) + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _sigaltstack + .set _sigaltstack, ___sigaltstack +#endif + diff --git a/src/kernel/libsyscall/sys_i386/__sigreturn.S b/src/kernel/libsyscall/bsdsyscalls/___sigreturn.S similarity index 100% rename from src/kernel/libsyscall/sys_i386/__sigreturn.S rename to src/kernel/libsyscall/bsdsyscalls/___sigreturn.S diff --git a/src/kernel/libsyscall/bsdsyscalls/___sigsuspend.S b/src/kernel/libsyscall/bsdsyscalls/___sigsuspend.S new file mode 100644 index 000000000..207d7f9d4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sigsuspend.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sigsuspend +#error "SYS_sigsuspend not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sigsuspend, sigsuspend, 1, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sigsuspend_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___sigsuspend_nocancel.S new file mode 100644 index 000000000..d6c56e150 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sigsuspend_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sigsuspend_nocancel +#error "SYS_sigsuspend_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sigsuspend_nocancel, sigsuspend_nocancel, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sigwait.S b/src/kernel/libsyscall/bsdsyscalls/___sigwait.S new file mode 100644 index 000000000..aa8e93469 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sigwait.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___sigwait +#error "SYS___sigwait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sigwait, __sigwait, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___socketpair.S b/src/kernel/libsyscall/bsdsyscalls/___socketpair.S new file mode 100644 index 000000000..cbd704721 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___socketpair.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_socketpair +#error "SYS_socketpair not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___socketpair, socketpair, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _socketpair$UNIX2003 + .set _socketpair$UNIX2003, ___socketpair +#endif + +#if defined(__x86_64__) + .globl _socketpair + .set _socketpair, ___socketpair +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___stack_snapshot_with_config.S b/src/kernel/libsyscall/bsdsyscalls/___stack_snapshot_with_config.S new file mode 100644 index 000000000..a9d2ed78e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___stack_snapshot_with_config.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_stack_snapshot_with_config +#error "SYS_stack_snapshot_with_config not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___stack_snapshot_with_config, stack_snapshot_with_config, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___stat64_extended.S b/src/kernel/libsyscall/bsdsyscalls/___stat64_extended.S new file mode 100644 index 000000000..8ba938523 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___stat64_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_stat64_extended +#error "SYS_stat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___stat64_extended, stat64_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___stat_extended.S b/src/kernel/libsyscall/bsdsyscalls/___stat_extended.S new file mode 100644 index 000000000..50d8a1a69 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___stat_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_stat_extended +#error "SYS_stat_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___stat_extended, stat_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___syscall.S b/src/kernel/libsyscall/bsdsyscalls/___syscall.S new file mode 100644 index 000000000..43f375959 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___syscall.S @@ -0,0 +1,70 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ + +#include "SYS.h" + +#ifdef DARLING +# define ___syscall __syscall +#endif + +#if defined(__i386__) + +LEAF(___syscall, 0) + popl %ecx // ret addr + popl %eax // syscall number + pushl %ecx + UNIX_SYSCALL_TRAP + movl (%esp),%edx // add one element to stack so + pushl %ecx // caller "pop" will work + jnb 2f + BRANCH_EXTERN(tramp_cerror) +2: +END(___syscall) + +#elif defined(__x86_64__) + +// For x86-64, the kernel slides the argument list for us. +// The number of arguments here is variable, but our macros ignore +// that value anyway. +__SYSCALL(___syscall, syscall, 0); + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _syscall + .set _syscall, ___syscall +#endif + +#if defined(__x86_64__) + .globl _syscall + .set _syscall, ___syscall +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sysctl.S b/src/kernel/libsyscall/bsdsyscalls/___sysctl.S new file mode 100644 index 000000000..ae662782e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sysctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_sysctl +#error "SYS_sysctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sysctl, sysctl, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___sysctlbyname.S b/src/kernel/libsyscall/bsdsyscalls/___sysctlbyname.S new file mode 100644 index 000000000..89538632e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___sysctlbyname.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_sysctlbyname +#error "SYS_sysctlbyname not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sysctlbyname, sysctlbyname, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___telemetry.S b/src/kernel/libsyscall/bsdsyscalls/___telemetry.S new file mode 100644 index 000000000..736d226b0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___telemetry.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 48 +#include "SYS.h" + +#ifndef SYS_telemetry +#error "SYS_telemetry not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___telemetry, telemetry, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___terminate_with_payload.S b/src/kernel/libsyscall/bsdsyscalls/___terminate_with_payload.S new file mode 100644 index 000000000..2ec6b1184 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___terminate_with_payload.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 36 +#include "SYS.h" + +#ifndef SYS_terminate_with_payload +#error "SYS_terminate_with_payload not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___terminate_with_payload, terminate_with_payload, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/sys_i386/__thread_selfid.S b/src/kernel/libsyscall/bsdsyscalls/___thread_selfid.S similarity index 100% rename from src/kernel/libsyscall/sys_i386/__thread_selfid.S rename to src/kernel/libsyscall/bsdsyscalls/___thread_selfid.S diff --git a/src/kernel/libsyscall/sys_i386/__thread_selfusage.S b/src/kernel/libsyscall/bsdsyscalls/___thread_selfusage.S similarity index 100% rename from src/kernel/libsyscall/sys_i386/__thread_selfusage.S rename to src/kernel/libsyscall/bsdsyscalls/___thread_selfusage.S diff --git a/src/kernel/libsyscall/bsdsyscalls/___ulock_wait.S b/src/kernel/libsyscall/bsdsyscalls/___ulock_wait.S new file mode 100644 index 000000000..950cd633a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___ulock_wait.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_ulock_wait +#error "SYS_ulock_wait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___ulock_wait, ulock_wait, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___ulock_wake.S b/src/kernel/libsyscall/bsdsyscalls/___ulock_wake.S new file mode 100644 index 000000000..b377f02da --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___ulock_wake.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_ulock_wake +#error "SYS_ulock_wake not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___ulock_wake, ulock_wake, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___umask_extended.S b/src/kernel/libsyscall/bsdsyscalls/___umask_extended.S new file mode 100644 index 000000000..2005cbfff --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___umask_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_umask_extended +#error "SYS_umask_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___umask_extended, umask_extended, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___unlink.S b/src/kernel/libsyscall/bsdsyscalls/___unlink.S new file mode 100644 index 000000000..73c31e01b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___unlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_unlink +#error "SYS_unlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___unlink, unlink, 1, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___unlinkat.S b/src/kernel/libsyscall/bsdsyscalls/___unlinkat.S new file mode 100644 index 000000000..717305d27 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___unlinkat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_unlinkat +#error "SYS_unlinkat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___unlinkat, unlinkat, 3, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___vfork.S b/src/kernel/libsyscall/bsdsyscalls/___vfork.S new file mode 100644 index 000000000..30e2ae435 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___vfork.S @@ -0,0 +1,172 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. + * + * File: libc/ppc/sys/vfork.s + * + * HISTORY + * 23-Jun-1998 Umesh Vaishampayan (umeshv@apple.com) + * Created from fork.s + * + */ + +#include "SYS.h" + +#ifdef DARLING +#define ___vfork __vfork +#define _cerror cerror +#endif + +#if defined(__i386__) + +#if defined(__DYNAMIC__) +#define GET_CURRENT_PID PICIFY(__current_pid) + + NON_LAZY_STUB(__current_pid) +#define __current_pid (%edx) +#else +#define GET_CURRENT_PID +#endif + +/* + * If __current_pid >= 0, we want to put a -1 in there + * otherwise we just decrement it + */ + +LEAF(___vfork, 0) + GET_CURRENT_PID + movl __current_pid, %eax +0: + xorl %ecx, %ecx + testl %eax, %eax + cmovs %eax, %ecx + decl %ecx + lock + cmpxchgl %ecx, __current_pid + jne 0b + popl %ecx + movl $(SYS_vfork), %eax // code for vfork -> eax + UNIX_SYSCALL_TRAP // do the system call + jnb L1 // jump if CF==0 + GET_CURRENT_PID + lock + incl __current_pid + pushl %ecx + BRANCH_EXTERN(tramp_cerror) + +L1: + testl %edx, %edx // CF=OF=0, ZF set if zero result + jz L2 // parent, since r1 == 0 in parent, 1 in child + xorl %eax, %eax // zero eax + jmp *%ecx + +L2: + GET_CURRENT_PID + lock + incl __current_pid + jmp *%ecx + +#elif defined(__x86_64__) + +/* + * If __current_pid >= 0, we want to put a -1 in there + * otherwise we just decrement it + */ + +LEAF(___vfork, 0) + movq __current_pid@GOTPCREL(%rip), %rax + movl (%rax), %eax +0: + xorl %ecx, %ecx + testl %eax, %eax + cmovs %eax, %ecx + subl $1, %ecx + movq __current_pid@GOTPCREL(%rip), %rdx + lock + cmpxchgl %ecx, (%rdx) + jne 0b + //popq %rdi // return address in %rdi +#ifndef DARLING + movq $ SYSCALL_CONSTRUCT_UNIX(SYS_vfork), %rax // code for vfork -> rax + UNIX_SYSCALL_TRAP // do the system call + jnb L1 // jump if CF==0 + pushq %rdi // put return address back on stack for cerror +#else + movl $ SYS_vfork, %eax + call __darling_bsd_syscall + cmpq $0, %rax + jnb L1 +#endif + movq __current_pid@GOTPCREL(%rip), %rcx + lock + addq $1, (%rcx) + movq %rax, %rdi + BRANCH_EXTERN(_cerror) + +L1: +#ifndef DARLING + testl %edx, %edx // CF=OF=0, ZF set if zero result + jz L2 // parent, since r1 == 0 in parent, 1 in child +#else + testl %eax, %eax + jnz L2 +#endif + xorq %rax, %rax // zero rax + jmp *%rdi + +L2: + movq __current_pid@GOTPCREL(%rip), %rdx + lock + addq $1, (%rdx) + //jmp *%rdi + ret + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _vfork + .set _vfork, ___vfork +#endif + +#if defined(__x86_64__) + .globl _vfork + .set _vfork, ___vfork +#endif + +#if defined(__i386__) + .globl _vfork + .set _vfork, ___vfork +#endif + +#if defined(__x86_64__) + .globl _vfork + .set _vfork, ___vfork +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___wait4.S b/src/kernel/libsyscall/bsdsyscalls/___wait4.S new file mode 100644 index 000000000..7115df828 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___wait4.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_wait4 +#error "SYS_wait4 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___wait4, wait4, 4, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___wait4_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___wait4_nocancel.S new file mode 100644 index 000000000..b6182defd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___wait4_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_wait4_nocancel +#error "SYS_wait4_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___wait4_nocancel, wait4_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _wait4 + .set _wait4, ___wait4_nocancel +#endif + +#if defined(__x86_64__) + .globl _wait4 + .set _wait4, ___wait4_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___waitid_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___waitid_nocancel.S new file mode 100644 index 000000000..4942cc18c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___waitid_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_waitid_nocancel +#error "SYS_waitid_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___waitid_nocancel, waitid_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _waitid + .set _waitid, ___waitid_nocancel + .globl _waitid$NOCANCEL$UNIX2003 + .set _waitid$NOCANCEL$UNIX2003, ___waitid_nocancel +#endif + +#if defined(__x86_64__) + .globl _waitid$NOCANCEL + .set _waitid$NOCANCEL, ___waitid_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___work_interval_ctl.S b/src/kernel/libsyscall/bsdsyscalls/___work_interval_ctl.S new file mode 100644 index 000000000..a2e261b04 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___work_interval_ctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_work_interval_ctl +#error "SYS_work_interval_ctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___work_interval_ctl, work_interval_ctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___workq_kernreturn.S b/src/kernel/libsyscall/bsdsyscalls/___workq_kernreturn.S new file mode 100644 index 000000000..70187d5a5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___workq_kernreturn.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_workq_kernreturn +#error "SYS_workq_kernreturn not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___workq_kernreturn, workq_kernreturn, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___workq_open.S b/src/kernel/libsyscall/bsdsyscalls/___workq_open.S new file mode 100644 index 000000000..7ddef3fca --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___workq_open.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_workq_open +#error "SYS_workq_open not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___workq_open, workq_open, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___write_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___write_nocancel.S new file mode 100644 index 000000000..a60f5a1f0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___write_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_write_nocancel +#error "SYS_write_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___write_nocancel, write_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _write + .set _write, ___write_nocancel + .globl _write$NOCANCEL$UNIX2003 + .set _write$NOCANCEL$UNIX2003, ___write_nocancel +#endif + +#if defined(__x86_64__) + .globl _write$NOCANCEL + .set _write$NOCANCEL, ___write_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/___writev_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/___writev_nocancel.S new file mode 100644 index 000000000..a75b5e5fb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/___writev_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_writev_nocancel +#error "SYS_writev_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___writev_nocancel, writev_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _writev + .set _writev, ___writev_nocancel + .globl _writev$NOCANCEL$UNIX2003 + .set _writev$NOCANCEL$UNIX2003, ___writev_nocancel +#endif + +#if defined(__x86_64__) + .globl _writev$NOCANCEL + .set _writev$NOCANCEL, ___writev_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_access.S b/src/kernel/libsyscall/bsdsyscalls/_access.S new file mode 100644 index 000000000..fd32ac990 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_access.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_access +#error "SYS_access not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_access, access, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_acct.S b/src/kernel/libsyscall/bsdsyscalls/_acct.S new file mode 100644 index 000000000..5aa830f4a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_acct.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_acct +#error "SYS_acct not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_acct, acct, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_adjtime.S b/src/kernel/libsyscall/bsdsyscalls/_adjtime.S new file mode 100644 index 000000000..e91ed9790 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_adjtime.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_adjtime +#error "SYS_adjtime not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_adjtime, adjtime, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_aio_cancel.S b/src/kernel/libsyscall/bsdsyscalls/_aio_cancel.S new file mode 100644 index 000000000..48fea7036 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_aio_cancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_aio_cancel +#error "SYS_aio_cancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_cancel, aio_cancel, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_aio_error.S b/src/kernel/libsyscall/bsdsyscalls/_aio_error.S new file mode 100644 index 000000000..1bd66ab9e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_aio_error.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_aio_error +#error "SYS_aio_error not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_error, aio_error, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_aio_fsync.S b/src/kernel/libsyscall/bsdsyscalls/_aio_fsync.S new file mode 100644 index 000000000..a4f2f0c3e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_aio_fsync.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_aio_fsync +#error "SYS_aio_fsync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_fsync, aio_fsync, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_aio_read.S b/src/kernel/libsyscall/bsdsyscalls/_aio_read.S new file mode 100644 index 000000000..c3ff5cf9c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_aio_read.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_aio_read +#error "SYS_aio_read not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_read, aio_read, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_aio_return.S b/src/kernel/libsyscall/bsdsyscalls/_aio_return.S new file mode 100644 index 000000000..6b5d3443e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_aio_return.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_aio_return +#error "SYS_aio_return not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_return, aio_return, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_aio_suspend.S b/src/kernel/libsyscall/bsdsyscalls/_aio_suspend.S new file mode 100644 index 000000000..5c1324a1a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_aio_suspend.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_aio_suspend +#error "SYS_aio_suspend not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_aio_suspend, aio_suspend, 3, cerror) +#else +__SYSCALL2(___aio_suspend, aio_suspend, 3, cerror) +#endif + +#if defined(__i386__) + .globl _aio_suspend$UNIX2003 + .set _aio_suspend$UNIX2003, ___aio_suspend +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_aio_write.S b/src/kernel/libsyscall/bsdsyscalls/_aio_write.S new file mode 100644 index 000000000..30e87c16b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_aio_write.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_aio_write +#error "SYS_aio_write not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_write, aio_write, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_audit.S b/src/kernel/libsyscall/bsdsyscalls/_audit.S new file mode 100644 index 000000000..9185fe92e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_audit.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_audit +#error "SYS_audit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_audit, audit, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_audit_session_join.S b/src/kernel/libsyscall/bsdsyscalls/_audit_session_join.S new file mode 100644 index 000000000..b38af8308 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_audit_session_join.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_audit_session_join +#error "SYS_audit_session_join not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_audit_session_join, audit_session_join, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_audit_session_port.S b/src/kernel/libsyscall/bsdsyscalls/_audit_session_port.S new file mode 100644 index 000000000..a56deebc0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_audit_session_port.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_audit_session_port +#error "SYS_audit_session_port not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_audit_session_port, audit_session_port, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_audit_session_self.S b/src/kernel/libsyscall/bsdsyscalls/_audit_session_self.S new file mode 100644 index 000000000..39e08d1c9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_audit_session_self.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_audit_session_self +#error "SYS_audit_session_self not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_audit_session_self, audit_session_self, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_auditctl.S b/src/kernel/libsyscall/bsdsyscalls/_auditctl.S new file mode 100644 index 000000000..0ea896e42 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_auditctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_auditctl +#error "SYS_auditctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_auditctl, auditctl, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_auditon.S b/src/kernel/libsyscall/bsdsyscalls/_auditon.S new file mode 100644 index 000000000..44cbd0974 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_auditon.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_auditon +#error "SYS_auditon not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_auditon, auditon, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_change_fdguard_np.S b/src/kernel/libsyscall/bsdsyscalls/_change_fdguard_np.S new file mode 100644 index 000000000..8a1715612 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_change_fdguard_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_change_fdguard_np +#error "SYS_change_fdguard_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_change_fdguard_np, change_fdguard_np, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_chdir.S b/src/kernel/libsyscall/bsdsyscalls/_chdir.S new file mode 100644 index 000000000..a981d0140 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_chdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_chdir +#error "SYS_chdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_chdir, chdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_chflags.S b/src/kernel/libsyscall/bsdsyscalls/_chflags.S new file mode 100644 index 000000000..a8c774a74 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_chflags.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_chflags +#error "SYS_chflags not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_chflags, chflags, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_chown.S b/src/kernel/libsyscall/bsdsyscalls/_chown.S new file mode 100644 index 000000000..ebe32c39b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_chown.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_chown +#error "SYS_chown not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_chown, chown, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_chroot.S b/src/kernel/libsyscall/bsdsyscalls/_chroot.S new file mode 100644 index 000000000..cc8274f96 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_chroot.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_chroot +#error "SYS_chroot not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_chroot, chroot, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_clonefileat.S b/src/kernel/libsyscall/bsdsyscalls/_clonefileat.S new file mode 100644 index 000000000..c018c8d5d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_clonefileat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_clonefileat +#error "SYS_clonefileat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_clonefileat, clonefileat, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_close.S b/src/kernel/libsyscall/bsdsyscalls/_close.S new file mode 100644 index 000000000..7d8261ec2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_close.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_close +#error "SYS_close not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_close, close, 1, cerror) +#else +__SYSCALL2(___close, close, 1, cerror) +#endif + +#if defined(__i386__) + .globl _close$UNIX2003 + .set _close$UNIX2003, ___close +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_connectx.S b/src/kernel/libsyscall/bsdsyscalls/_connectx.S new file mode 100644 index 000000000..9812e93ba --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_connectx.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 32 +#include "SYS.h" + +#ifndef SYS_connectx +#error "SYS_connectx not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_connectx, connectx, 8, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_csops.S b/src/kernel/libsyscall/bsdsyscalls/_csops.S new file mode 100644 index 000000000..70b447001 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_csops.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_csops +#error "SYS_csops not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_csops, csops, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_csops_audittoken.S b/src/kernel/libsyscall/bsdsyscalls/_csops_audittoken.S new file mode 100644 index 000000000..2699b860d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_csops_audittoken.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_csops_audittoken +#error "SYS_csops_audittoken not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_csops_audittoken, csops_audittoken, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_disconnectx.S b/src/kernel/libsyscall/bsdsyscalls/_disconnectx.S new file mode 100644 index 000000000..f9d358f60 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_disconnectx.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_disconnectx +#error "SYS_disconnectx not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_disconnectx, disconnectx, 3, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_dup.S b/src/kernel/libsyscall/bsdsyscalls/_dup.S new file mode 100644 index 000000000..b73475144 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_dup.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_dup +#error "SYS_dup not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_dup, dup, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_dup2.S b/src/kernel/libsyscall/bsdsyscalls/_dup2.S new file mode 100644 index 000000000..ff1979707 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_dup2.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_dup2 +#error "SYS_dup2 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_dup2, dup2, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_exchangedata.S b/src/kernel/libsyscall/bsdsyscalls/_exchangedata.S new file mode 100644 index 000000000..b02da7e6d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_exchangedata.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_exchangedata +#error "SYS_exchangedata not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_exchangedata, exchangedata, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_execve.S b/src/kernel/libsyscall/bsdsyscalls/_execve.S new file mode 100644 index 000000000..292830cf2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_execve.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_execve +#error "SYS_execve not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_execve, execve, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_faccessat.S b/src/kernel/libsyscall/bsdsyscalls/_faccessat.S new file mode 100644 index 000000000..63de2f6e2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_faccessat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_faccessat +#error "SYS_faccessat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_faccessat, faccessat, 4, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fchdir.S b/src/kernel/libsyscall/bsdsyscalls/_fchdir.S new file mode 100644 index 000000000..1bb4ee630 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fchdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fchdir +#error "SYS_fchdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchdir, fchdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fchflags.S b/src/kernel/libsyscall/bsdsyscalls/_fchflags.S new file mode 100644 index 000000000..bd6980b75 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fchflags.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fchflags +#error "SYS_fchflags not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchflags, fchflags, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fchmodat.S b/src/kernel/libsyscall/bsdsyscalls/_fchmodat.S new file mode 100644 index 000000000..3f6e58b08 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fchmodat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fchmodat +#error "SYS_fchmodat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchmodat, fchmodat, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fchown.S b/src/kernel/libsyscall/bsdsyscalls/_fchown.S new file mode 100644 index 000000000..2b112c30a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fchown.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_fchown +#error "SYS_fchown not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchown, fchown, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fchownat.S b/src/kernel/libsyscall/bsdsyscalls/_fchownat.S new file mode 100644 index 000000000..24e058cc4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fchownat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fchownat +#error "SYS_fchownat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchownat, fchownat, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fclonefileat.S b/src/kernel/libsyscall/bsdsyscalls/_fclonefileat.S new file mode 100644 index 000000000..6c5f188c6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fclonefileat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fclonefileat +#error "SYS_fclonefileat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fclonefileat, fclonefileat, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fdatasync.S b/src/kernel/libsyscall/bsdsyscalls/_fdatasync.S new file mode 100644 index 000000000..e93a0e5d1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fdatasync.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fdatasync +#error "SYS_fdatasync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fdatasync, fdatasync, 1, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_ffsctl.S b/src/kernel/libsyscall/bsdsyscalls/_ffsctl.S new file mode 100644 index 000000000..f5eb14eb3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_ffsctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_ffsctl +#error "SYS_ffsctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_ffsctl, ffsctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fgetattrlist.S b/src/kernel/libsyscall/bsdsyscalls/_fgetattrlist.S new file mode 100644 index 000000000..5b219f31a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fgetattrlist.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fgetattrlist +#error "SYS_fgetattrlist not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fgetattrlist, fgetattrlist, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fgetxattr.S b/src/kernel/libsyscall/bsdsyscalls/_fgetxattr.S new file mode 100644 index 000000000..eb852f149 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fgetxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_fgetxattr +#error "SYS_fgetxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fgetxattr, fgetxattr, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fhopen.S b/src/kernel/libsyscall/bsdsyscalls/_fhopen.S new file mode 100644 index 000000000..35c91d9ab --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fhopen.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fhopen +#error "SYS_fhopen not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fhopen, fhopen, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fileport_makefd.S b/src/kernel/libsyscall/bsdsyscalls/_fileport_makefd.S new file mode 100644 index 000000000..3c3974be1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fileport_makefd.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fileport_makefd +#error "SYS_fileport_makefd not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fileport_makefd, fileport_makefd, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fileport_makeport.S b/src/kernel/libsyscall/bsdsyscalls/_fileport_makeport.S new file mode 100644 index 000000000..69773f335 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fileport_makeport.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fileport_makeport +#error "SYS_fileport_makeport not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fileport_makeport, fileport_makeport, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_flistxattr.S b/src/kernel/libsyscall/bsdsyscalls/_flistxattr.S new file mode 100644 index 000000000..8c6c91a84 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_flistxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_flistxattr +#error "SYS_flistxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_flistxattr, flistxattr, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_flock.S b/src/kernel/libsyscall/bsdsyscalls/_flock.S new file mode 100644 index 000000000..6887a2946 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_flock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_flock +#error "SYS_flock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_flock, flock, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fpathconf.S b/src/kernel/libsyscall/bsdsyscalls/_fpathconf.S new file mode 100644 index 000000000..94f8f4b74 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fpathconf.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fpathconf +#error "SYS_fpathconf not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fpathconf, fpathconf, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fremovexattr.S b/src/kernel/libsyscall/bsdsyscalls/_fremovexattr.S new file mode 100644 index 000000000..1f18a66b4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fremovexattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_fremovexattr +#error "SYS_fremovexattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fremovexattr, fremovexattr, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fsctl.S b/src/kernel/libsyscall/bsdsyscalls/_fsctl.S new file mode 100644 index 000000000..8039b6cf1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fsctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fsctl +#error "SYS_fsctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fsctl, fsctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fsetattrlist.S b/src/kernel/libsyscall/bsdsyscalls/_fsetattrlist.S new file mode 100644 index 000000000..579a5539b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fsetattrlist.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fsetattrlist +#error "SYS_fsetattrlist not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fsetattrlist, fsetattrlist, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fsetxattr.S b/src/kernel/libsyscall/bsdsyscalls/_fsetxattr.S new file mode 100644 index 000000000..5a94239d5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fsetxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_fsetxattr +#error "SYS_fsetxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fsetxattr, fsetxattr, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fsgetpath.S b/src/kernel/libsyscall/bsdsyscalls/_fsgetpath.S new file mode 100644 index 000000000..97ca02c10 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fsgetpath.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fsgetpath +#error "SYS_fsgetpath not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fsgetpath, fsgetpath, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fstat.S b/src/kernel/libsyscall/bsdsyscalls/_fstat.S new file mode 100644 index 000000000..497d96c4b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fstat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fstat +#error "SYS_fstat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstat, fstat, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fstat64.S b/src/kernel/libsyscall/bsdsyscalls/_fstat64.S new file mode 100644 index 000000000..b9bc28083 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fstat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fstat64 +#error "SYS_fstat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstat64, fstat64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fstat$INODE64 + .set _fstat$INODE64, _fstat64 +#endif + +#if defined(__x86_64__) + .globl _fstat$INODE64 + .set _fstat$INODE64, _fstat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fstatat.S b/src/kernel/libsyscall/bsdsyscalls/_fstatat.S new file mode 100644 index 000000000..de7570abe --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fstatat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fstatat +#error "SYS_fstatat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstatat, fstatat, 4, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fstatat64.S b/src/kernel/libsyscall/bsdsyscalls/_fstatat64.S new file mode 100644 index 000000000..c5e534b25 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fstatat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fstatat64 +#error "SYS_fstatat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstatat64, fstatat64, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fstatat$INODE64 + .set _fstatat$INODE64, _fstatat64 +#endif + +#if defined(__x86_64__) + .globl _fstatat$INODE64 + .set _fstatat$INODE64, _fstatat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fstatfs.S b/src/kernel/libsyscall/bsdsyscalls/_fstatfs.S new file mode 100644 index 000000000..d96eab95d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fstatfs.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fstatfs +#error "SYS_fstatfs not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstatfs, fstatfs, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fstatfs64.S b/src/kernel/libsyscall/bsdsyscalls/_fstatfs64.S new file mode 100644 index 000000000..9ea5d0624 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fstatfs64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fstatfs64 +#error "SYS_fstatfs64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstatfs64, fstatfs64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fstatfs$INODE64 + .set _fstatfs$INODE64, _fstatfs64 +#endif + +#if defined(__x86_64__) + .globl _fstatfs$INODE64 + .set _fstatfs$INODE64, _fstatfs64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_fsync.S b/src/kernel/libsyscall/bsdsyscalls/_fsync.S new file mode 100644 index 000000000..d02acf4da --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_fsync.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fsync +#error "SYS_fsync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_fsync, fsync, 1, cerror) +#else +__SYSCALL2(___fsync, fsync, 1, cerror) +#endif + +#if defined(__i386__) + .globl _fsync$UNIX2003 + .set _fsync$UNIX2003, ___fsync +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_ftruncate.S b/src/kernel/libsyscall/bsdsyscalls/_ftruncate.S new file mode 100644 index 000000000..33f8d2d1e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_ftruncate.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_ftruncate +#error "SYS_ftruncate not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_ftruncate, ftruncate, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_futimes.S b/src/kernel/libsyscall/bsdsyscalls/_futimes.S new file mode 100644 index 000000000..b1ec5aa45 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_futimes.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_futimes +#error "SYS_futimes not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_futimes, futimes, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getattrlistat.S b/src/kernel/libsyscall/bsdsyscalls/_getattrlistat.S new file mode 100644 index 000000000..e317cd52f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getattrlistat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_getattrlistat +#error "SYS_getattrlistat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getattrlistat, getattrlistat, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getattrlistbulk.S b/src/kernel/libsyscall/bsdsyscalls/_getattrlistbulk.S new file mode 100644 index 000000000..4a27c68bf --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getattrlistbulk.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_getattrlistbulk +#error "SYS_getattrlistbulk not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getattrlistbulk, getattrlistbulk, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getaudit_addr.S b/src/kernel/libsyscall/bsdsyscalls/_getaudit_addr.S new file mode 100644 index 000000000..757b53d4b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getaudit_addr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getaudit_addr +#error "SYS_getaudit_addr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getaudit_addr, getaudit_addr, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getauid.S b/src/kernel/libsyscall/bsdsyscalls/_getauid.S new file mode 100644 index 000000000..b7cb3039f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getauid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_getauid +#error "SYS_getauid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getauid, getauid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getdirentries.S b/src/kernel/libsyscall/bsdsyscalls/_getdirentries.S new file mode 100644 index 000000000..98f3de0af --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getdirentries.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_getdirentries +#error "SYS_getdirentries not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getdirentries, getdirentries, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getdirentriesattr.S b/src/kernel/libsyscall/bsdsyscalls/_getdirentriesattr.S new file mode 100644 index 000000000..699d96a2c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getdirentriesattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 32 +#include "SYS.h" + +#ifndef SYS_getdirentriesattr +#error "SYS_getdirentriesattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getdirentriesattr, getdirentriesattr, 8, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getdtablesize.S b/src/kernel/libsyscall/bsdsyscalls/_getdtablesize.S new file mode 100644 index 000000000..89aacda7d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getdtablesize.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getdtablesize +#error "SYS_getdtablesize not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getdtablesize, getdtablesize, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getegid.S b/src/kernel/libsyscall/bsdsyscalls/_getegid.S new file mode 100644 index 000000000..73618ab55 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getegid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getegid +#error "SYS_getegid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getegid, getegid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getentropy.S b/src/kernel/libsyscall/bsdsyscalls/_getentropy.S new file mode 100644 index 000000000..ea9dd19a1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getentropy.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getentropy +#error "SYS_getentropy not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getentropy, getentropy, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_geteuid.S b/src/kernel/libsyscall/bsdsyscalls/_geteuid.S new file mode 100644 index 000000000..222434053 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_geteuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_geteuid +#error "SYS_geteuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_geteuid, geteuid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getfh.S b/src/kernel/libsyscall/bsdsyscalls/_getfh.S new file mode 100644 index 000000000..d5e3c5f03 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getfh.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getfh +#error "SYS_getfh not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getfh, getfh, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getfsstat.S b/src/kernel/libsyscall/bsdsyscalls/_getfsstat.S new file mode 100644 index 000000000..2a88afc1b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getfsstat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_getfsstat +#error "SYS_getfsstat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getfsstat, getfsstat, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getfsstat64.S b/src/kernel/libsyscall/bsdsyscalls/_getfsstat64.S new file mode 100644 index 000000000..543e693b7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getfsstat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_getfsstat64 +#error "SYS_getfsstat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getfsstat64, getfsstat64, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getfsstat$INODE64 + .set _getfsstat$INODE64, _getfsstat64 +#endif + +#if defined(__x86_64__) + .globl _getfsstat$INODE64 + .set _getfsstat$INODE64, _getfsstat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getgid.S b/src/kernel/libsyscall/bsdsyscalls/_getgid.S new file mode 100644 index 000000000..44c5fb1ca --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getgid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getgid +#error "SYS_getgid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getgid, getgid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getgroups.S b/src/kernel/libsyscall/bsdsyscalls/_getgroups.S new file mode 100644 index 000000000..1ef294fb1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getgroups.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getgroups +#error "SYS_getgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getgroups, getgroups, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getitimer.S b/src/kernel/libsyscall/bsdsyscalls/_getitimer.S new file mode 100644 index 000000000..cbb85db0b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getitimer.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getitimer +#error "SYS_getitimer not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getitimer, getitimer, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getpgid.S b/src/kernel/libsyscall/bsdsyscalls/_getpgid.S new file mode 100644 index 000000000..a164cbd93 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getpgid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_getpgid +#error "SYS_getpgid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getpgid, getpgid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getpgrp.S b/src/kernel/libsyscall/bsdsyscalls/_getpgrp.S new file mode 100644 index 000000000..a49c419de --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getpgrp.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getpgrp +#error "SYS_getpgrp not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getpgrp, getpgrp, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getppid.S b/src/kernel/libsyscall/bsdsyscalls/_getppid.S new file mode 100644 index 000000000..fa22d6b44 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getppid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getppid +#error "SYS_getppid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getppid, getppid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getpriority.S b/src/kernel/libsyscall/bsdsyscalls/_getpriority.S new file mode 100644 index 000000000..34f6ca9ad --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getpriority.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getpriority +#error "SYS_getpriority not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getpriority, getpriority, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getrusage.S b/src/kernel/libsyscall/bsdsyscalls/_getrusage.S new file mode 100644 index 000000000..b88b4a332 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getrusage.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getrusage +#error "SYS_getrusage not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getrusage, getrusage, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getsid.S b/src/kernel/libsyscall/bsdsyscalls/_getsid.S new file mode 100644 index 000000000..7ae4c4084 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getsid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_getsid +#error "SYS_getsid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getsid, getsid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getsockopt.S b/src/kernel/libsyscall/bsdsyscalls/_getsockopt.S new file mode 100644 index 000000000..d43313dba --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getsockopt.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_getsockopt +#error "SYS_getsockopt not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getsockopt, getsockopt, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getuid.S b/src/kernel/libsyscall/bsdsyscalls/_getuid.S new file mode 100644 index 000000000..44d14e622 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getuid +#error "SYS_getuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getuid, getuid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_getxattr.S b/src/kernel/libsyscall/bsdsyscalls/_getxattr.S new file mode 100644 index 000000000..7bbcbbec2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_getxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_getxattr +#error "SYS_getxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getxattr, getxattr, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_grab_pgo_data.S b/src/kernel/libsyscall/bsdsyscalls/_grab_pgo_data.S new file mode 100644 index 000000000..cbb171e04 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_grab_pgo_data.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_grab_pgo_data +#error "SYS_grab_pgo_data not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_grab_pgo_data, grab_pgo_data, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_guarded_close_np.S b/src/kernel/libsyscall/bsdsyscalls/_guarded_close_np.S new file mode 100644 index 000000000..85854aecc --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_guarded_close_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_guarded_close_np +#error "SYS_guarded_close_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_close_np, guarded_close_np, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_guarded_kqueue_np.S b/src/kernel/libsyscall/bsdsyscalls/_guarded_kqueue_np.S new file mode 100644 index 000000000..bcaf3aa63 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_guarded_kqueue_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_guarded_kqueue_np +#error "SYS_guarded_kqueue_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_kqueue_np, guarded_kqueue_np, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_guarded_pwrite_np.S b/src/kernel/libsyscall/bsdsyscalls/_guarded_pwrite_np.S new file mode 100644 index 000000000..161e61363 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_guarded_pwrite_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_guarded_pwrite_np +#error "SYS_guarded_pwrite_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_pwrite_np, guarded_pwrite_np, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_guarded_write_np.S b/src/kernel/libsyscall/bsdsyscalls/_guarded_write_np.S new file mode 100644 index 000000000..0200d27ce --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_guarded_write_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_guarded_write_np +#error "SYS_guarded_write_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_write_np, guarded_write_np, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_guarded_writev_np.S b/src/kernel/libsyscall/bsdsyscalls/_guarded_writev_np.S new file mode 100644 index 000000000..36cc4f061 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_guarded_writev_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_guarded_writev_np +#error "SYS_guarded_writev_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_writev_np, guarded_writev_np, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_issetugid.S b/src/kernel/libsyscall/bsdsyscalls/_issetugid.S new file mode 100644 index 000000000..9b9d53ab0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_issetugid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_issetugid +#error "SYS_issetugid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_issetugid, issetugid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_kas_info.S b/src/kernel/libsyscall/bsdsyscalls/_kas_info.S new file mode 100644 index 000000000..ba5a7d8e2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_kas_info.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_kas_info +#error "SYS_kas_info not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kas_info, kas_info, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_kevent.S b/src/kernel/libsyscall/bsdsyscalls/_kevent.S new file mode 100644 index 000000000..969f70f6f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_kevent.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_kevent +#error "SYS_kevent not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kevent, kevent, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_kevent64.S b/src/kernel/libsyscall/bsdsyscalls/_kevent64.S new file mode 100644 index 000000000..2a1d6e289 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_kevent64.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_kevent64 +#error "SYS_kevent64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kevent64, kevent64, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_kevent_qos.S b/src/kernel/libsyscall/bsdsyscalls/_kevent_qos.S new file mode 100644 index 000000000..b30eff849 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_kevent_qos.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 32 +#include "SYS.h" + +#ifndef SYS_kevent_qos +#error "SYS_kevent_qos not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kevent_qos, kevent_qos, 8, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_kqueue.S b/src/kernel/libsyscall/bsdsyscalls/_kqueue.S new file mode 100644 index 000000000..d99a8a813 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_kqueue.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_kqueue +#error "SYS_kqueue not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kqueue, kqueue, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_ledger.S b/src/kernel/libsyscall/bsdsyscalls/_ledger.S new file mode 100644 index 000000000..3c39c9521 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_ledger.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_ledger +#error "SYS_ledger not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_ledger, ledger, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_link.S b/src/kernel/libsyscall/bsdsyscalls/_link.S new file mode 100644 index 000000000..2a7d76b0c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_link.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_link +#error "SYS_link not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_link, link, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_linkat.S b/src/kernel/libsyscall/bsdsyscalls/_linkat.S new file mode 100644 index 000000000..0a702854c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_linkat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_linkat +#error "SYS_linkat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_linkat, linkat, 5, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_lio_listio.S b/src/kernel/libsyscall/bsdsyscalls/_lio_listio.S new file mode 100644 index 000000000..88d52bdef --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_lio_listio.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_lio_listio +#error "SYS_lio_listio not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_lio_listio, lio_listio, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_listxattr.S b/src/kernel/libsyscall/bsdsyscalls/_listxattr.S new file mode 100644 index 000000000..9f2855882 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_listxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_listxattr +#error "SYS_listxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_listxattr, listxattr, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_lstat.S b/src/kernel/libsyscall/bsdsyscalls/_lstat.S new file mode 100644 index 000000000..b985471b5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_lstat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_lstat +#error "SYS_lstat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_lstat, lstat, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_lstat64.S b/src/kernel/libsyscall/bsdsyscalls/_lstat64.S new file mode 100644 index 000000000..12238ac0e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_lstat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_lstat64 +#error "SYS_lstat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_lstat64, lstat64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _lstat$INODE64 + .set _lstat$INODE64, _lstat64 +#endif + +#if defined(__x86_64__) + .globl _lstat$INODE64 + .set _lstat$INODE64, _lstat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_madvise.S b/src/kernel/libsyscall/bsdsyscalls/_madvise.S new file mode 100644 index 000000000..40ac9451c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_madvise.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_madvise +#error "SYS_madvise not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_madvise, madvise, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _posix_madvise + .set _posix_madvise, _madvise +#endif + +#if defined(__x86_64__) + .globl _posix_madvise + .set _posix_madvise, _madvise +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_memorystatus_control.S b/src/kernel/libsyscall/bsdsyscalls/_memorystatus_control.S new file mode 100644 index 000000000..be7ee648b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_memorystatus_control.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_memorystatus_control +#error "SYS_memorystatus_control not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_memorystatus_control, memorystatus_control, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_memorystatus_get_level.S b/src/kernel/libsyscall/bsdsyscalls/_memorystatus_get_level.S new file mode 100644 index 000000000..323a0cb90 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_memorystatus_get_level.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_memorystatus_get_level +#error "SYS_memorystatus_get_level not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_memorystatus_get_level, memorystatus_get_level, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_mincore.S b/src/kernel/libsyscall/bsdsyscalls/_mincore.S new file mode 100644 index 000000000..d3239dee2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_mincore.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_mincore +#error "SYS_mincore not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mincore, mincore, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_minherit.S b/src/kernel/libsyscall/bsdsyscalls/_minherit.S new file mode 100644 index 000000000..65625e88a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_minherit.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_minherit +#error "SYS_minherit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_minherit, minherit, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_mkdir.S b/src/kernel/libsyscall/bsdsyscalls/_mkdir.S new file mode 100644 index 000000000..d719d8e2c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_mkdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_mkdir +#error "SYS_mkdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mkdir, mkdir, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_mkdirat.S b/src/kernel/libsyscall/bsdsyscalls/_mkdirat.S new file mode 100644 index 000000000..1c59d0560 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_mkdirat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_mkdirat +#error "SYS_mkdirat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mkdirat, mkdirat, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_mkfifo.S b/src/kernel/libsyscall/bsdsyscalls/_mkfifo.S new file mode 100644 index 000000000..684ab3f98 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_mkfifo.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_mkfifo +#error "SYS_mkfifo not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mkfifo, mkfifo, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_mknod.S b/src/kernel/libsyscall/bsdsyscalls/_mknod.S new file mode 100644 index 000000000..052d4d3b5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_mknod.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_mknod +#error "SYS_mknod not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mknod, mknod, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_mlock.S b/src/kernel/libsyscall/bsdsyscalls/_mlock.S new file mode 100644 index 000000000..be70fbe3e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_mlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_mlock +#error "SYS_mlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mlock, mlock, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_mlockall.S b/src/kernel/libsyscall/bsdsyscalls/_mlockall.S new file mode 100644 index 000000000..4aa50ef3e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_mlockall.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_mlockall +#error "SYS_mlockall not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mlockall, mlockall, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_modwatch.S b/src/kernel/libsyscall/bsdsyscalls/_modwatch.S new file mode 100644 index 000000000..0f5643266 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_modwatch.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_modwatch +#error "SYS_modwatch not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_modwatch, modwatch, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_mount.S b/src/kernel/libsyscall/bsdsyscalls/_mount.S new file mode 100644 index 000000000..cf8776da5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_mount.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_mount +#error "SYS_mount not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mount, mount, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_mremap_encrypted.S b/src/kernel/libsyscall/bsdsyscalls/_mremap_encrypted.S new file mode 100644 index 000000000..15942a767 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_mremap_encrypted.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_mremap_encrypted +#error "SYS_mremap_encrypted not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mremap_encrypted, mremap_encrypted, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_msgget.S b/src/kernel/libsyscall/bsdsyscalls/_msgget.S new file mode 100644 index 000000000..a1d68deff --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_msgget.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_msgget +#error "SYS_msgget not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_msgget, msgget, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_msgrcv.S b/src/kernel/libsyscall/bsdsyscalls/_msgrcv.S new file mode 100644 index 000000000..141593f28 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_msgrcv.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_msgrcv +#error "SYS_msgrcv not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_msgrcv, msgrcv, 5, cerror) +#else +__SYSCALL2(___msgrcv, msgrcv, 5, cerror) +#endif + +#if defined(__i386__) + .globl _msgrcv$UNIX2003 + .set _msgrcv$UNIX2003, ___msgrcv +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_msgsnd.S b/src/kernel/libsyscall/bsdsyscalls/_msgsnd.S new file mode 100644 index 000000000..ad180f926 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_msgsnd.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_msgsnd +#error "SYS_msgsnd not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_msgsnd, msgsnd, 4, cerror) +#else +__SYSCALL2(___msgsnd, msgsnd, 4, cerror) +#endif + +#if defined(__i386__) + .globl _msgsnd$UNIX2003 + .set _msgsnd$UNIX2003, ___msgsnd +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_munlock.S b/src/kernel/libsyscall/bsdsyscalls/_munlock.S new file mode 100644 index 000000000..3587867fd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_munlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_munlock +#error "SYS_munlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_munlock, munlock, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_munlockall.S b/src/kernel/libsyscall/bsdsyscalls/_munlockall.S new file mode 100644 index 000000000..d610d81a4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_munlockall.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_munlockall +#error "SYS_munlockall not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_munlockall, munlockall, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_necp_client_action.S b/src/kernel/libsyscall/bsdsyscalls/_necp_client_action.S new file mode 100644 index 000000000..be6690c82 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_necp_client_action.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_necp_client_action +#error "SYS_necp_client_action not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_necp_client_action, necp_client_action, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_necp_match_policy.S b/src/kernel/libsyscall/bsdsyscalls/_necp_match_policy.S new file mode 100644 index 000000000..ead8d659f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_necp_match_policy.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_necp_match_policy +#error "SYS_necp_match_policy not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_necp_match_policy, necp_match_policy, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_necp_open.S b/src/kernel/libsyscall/bsdsyscalls/_necp_open.S new file mode 100644 index 000000000..8e32127ac --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_necp_open.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_necp_open +#error "SYS_necp_open not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_necp_open, necp_open, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_netagent_trigger.S b/src/kernel/libsyscall/bsdsyscalls/_netagent_trigger.S new file mode 100644 index 000000000..801fab392 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_netagent_trigger.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_netagent_trigger +#error "SYS_netagent_trigger not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_netagent_trigger, netagent_trigger, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_nfsclnt.S b/src/kernel/libsyscall/bsdsyscalls/_nfsclnt.S new file mode 100644 index 000000000..aae9feae6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_nfsclnt.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_nfsclnt +#error "SYS_nfsclnt not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_nfsclnt, nfsclnt, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_nfssvc.S b/src/kernel/libsyscall/bsdsyscalls/_nfssvc.S new file mode 100644 index 000000000..a9ce08429 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_nfssvc.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_nfssvc +#error "SYS_nfssvc not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_nfssvc, nfssvc, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_openbyid_np.S b/src/kernel/libsyscall/bsdsyscalls/_openbyid_np.S new file mode 100644 index 000000000..4833ff699 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_openbyid_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_openbyid_np +#error "SYS_openbyid_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_openbyid_np, openbyid_np, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_pathconf.S b/src/kernel/libsyscall/bsdsyscalls/_pathconf.S new file mode 100644 index 000000000..4cfb9c3a8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_pathconf.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_pathconf +#error "SYS_pathconf not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_pathconf, pathconf, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_peeloff.S b/src/kernel/libsyscall/bsdsyscalls/_peeloff.S new file mode 100644 index 000000000..5f5a02a5e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_peeloff.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_peeloff +#error "SYS_peeloff not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_peeloff, peeloff, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_pid_resume.S b/src/kernel/libsyscall/bsdsyscalls/_pid_resume.S new file mode 100644 index 000000000..8dc28a2d3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_pid_resume.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_pid_resume +#error "SYS_pid_resume not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_pid_resume, pid_resume, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_pid_suspend.S b/src/kernel/libsyscall/bsdsyscalls/_pid_suspend.S new file mode 100644 index 000000000..ae2feb5c1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_pid_suspend.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_pid_suspend +#error "SYS_pid_suspend not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_pid_suspend, pid_suspend, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_poll.S b/src/kernel/libsyscall/bsdsyscalls/_poll.S new file mode 100644 index 000000000..9a824f18b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_poll.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_poll +#error "SYS_poll not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_poll, poll, 3, cerror) +#else +__SYSCALL2(___poll, poll, 3, cerror) +#endif + +#if defined(__i386__) + .globl _poll$UNIX2003 + .set _poll$UNIX2003, ___poll +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_pread.S b/src/kernel/libsyscall/bsdsyscalls/_pread.S new file mode 100644 index 000000000..0387838a0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_pread.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_pread +#error "SYS_pread not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_pread, pread, 4, cerror) +#else +__SYSCALL2(___pread, pread, 4, cerror) +#endif + +#if defined(__i386__) + .globl _pread$UNIX2003 + .set _pread$UNIX2003, ___pread +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_proc_rlimit_control.S b/src/kernel/libsyscall/bsdsyscalls/_proc_rlimit_control.S new file mode 100644 index 000000000..a4ac7e4e0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_proc_rlimit_control.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_proc_rlimit_control +#error "SYS_proc_rlimit_control not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_proc_rlimit_control, proc_rlimit_control, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_proc_trace_log.S b/src/kernel/libsyscall/bsdsyscalls/_proc_trace_log.S new file mode 100644 index 000000000..812107e58 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_proc_trace_log.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_proc_trace_log +#error "SYS_proc_trace_log not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_proc_trace_log, proc_trace_log, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_proc_uuid_policy.S b/src/kernel/libsyscall/bsdsyscalls/_proc_uuid_policy.S new file mode 100644 index 000000000..a03725489 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_proc_uuid_policy.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_proc_uuid_policy +#error "SYS_proc_uuid_policy not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_proc_uuid_policy, proc_uuid_policy, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_pwrite.S b/src/kernel/libsyscall/bsdsyscalls/_pwrite.S new file mode 100644 index 000000000..e873cf6cb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_pwrite.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_pwrite +#error "SYS_pwrite not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_pwrite, pwrite, 4, cerror) +#else +__SYSCALL2(___pwrite, pwrite, 4, cerror) +#endif + +#if defined(__i386__) + .globl _pwrite$UNIX2003 + .set _pwrite$UNIX2003, ___pwrite +#endif + diff --git a/src/kernel/libsyscall/sys_x86-64/_quota.S b/src/kernel/libsyscall/bsdsyscalls/_quota.S similarity index 84% rename from src/kernel/libsyscall/sys_x86-64/_quota.S rename to src/kernel/libsyscall/bsdsyscalls/_quota.S index f6f44bb7c..87f4f3d39 100644 --- a/src/kernel/libsyscall/sys_x86-64/_quota.S +++ b/src/kernel/libsyscall/bsdsyscalls/_quota.S @@ -5,7 +5,7 @@ #error "SYS_quota not defined. The header files libsyscall is building against do not match syscalls.master." #endif -#if defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) __SYSCALL2(_quota, quota, 4, cerror_nocancel) #endif diff --git a/src/kernel/libsyscall/bsdsyscalls/_quotactl.S b/src/kernel/libsyscall/bsdsyscalls/_quotactl.S new file mode 100644 index 000000000..b9fd252ae --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_quotactl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_quotactl +#error "SYS_quotactl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_quotactl, quotactl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_read.S b/src/kernel/libsyscall/bsdsyscalls/_read.S new file mode 100644 index 000000000..f7da3e2fd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_read.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_read +#error "SYS_read not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_read, read, 3, cerror) +#else +__SYSCALL2(___read, read, 3, cerror) +#endif + +#if defined(__i386__) + .globl _read$UNIX2003 + .set _read$UNIX2003, ___read +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_readlink.S b/src/kernel/libsyscall/bsdsyscalls/_readlink.S new file mode 100644 index 000000000..8559f19b0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_readlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_readlink +#error "SYS_readlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_readlink, readlink, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_readlinkat.S b/src/kernel/libsyscall/bsdsyscalls/_readlinkat.S new file mode 100644 index 000000000..38b1222b1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_readlinkat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_readlinkat +#error "SYS_readlinkat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_readlinkat, readlinkat, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_readv.S b/src/kernel/libsyscall/bsdsyscalls/_readv.S new file mode 100644 index 000000000..7f5450bed --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_readv.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_readv +#error "SYS_readv not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_readv, readv, 3, cerror) +#else +__SYSCALL2(___readv, readv, 3, cerror) +#endif + +#if defined(__i386__) + .globl _readv$UNIX2003 + .set _readv$UNIX2003, ___readv +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_reboot.S b/src/kernel/libsyscall/bsdsyscalls/_reboot.S new file mode 100644 index 000000000..fde5474f2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_reboot.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_reboot +#error "SYS_reboot not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_reboot, reboot, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_recvmsg_x.S b/src/kernel/libsyscall/bsdsyscalls/_recvmsg_x.S new file mode 100644 index 000000000..cf40a6570 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_recvmsg_x.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_recvmsg_x +#error "SYS_recvmsg_x not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_recvmsg_x, recvmsg_x, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_removexattr.S b/src/kernel/libsyscall/bsdsyscalls/_removexattr.S new file mode 100644 index 000000000..5b7d32a75 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_removexattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_removexattr +#error "SYS_removexattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_removexattr, removexattr, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_revoke.S b/src/kernel/libsyscall/bsdsyscalls/_revoke.S new file mode 100644 index 000000000..bc9cfc058 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_revoke.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_revoke +#error "SYS_revoke not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_revoke, revoke, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_searchfs.S b/src/kernel/libsyscall/bsdsyscalls/_searchfs.S new file mode 100644 index 000000000..db70701ea --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_searchfs.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_searchfs +#error "SYS_searchfs not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_searchfs, searchfs, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sem_close.S b/src/kernel/libsyscall/bsdsyscalls/_sem_close.S new file mode 100644 index 000000000..b64727d3b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sem_close.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_close +#error "SYS_sem_close not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sem_close, sem_close, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sem_post.S b/src/kernel/libsyscall/bsdsyscalls/_sem_post.S new file mode 100644 index 000000000..46ff43caf --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sem_post.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_post +#error "SYS_sem_post not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sem_post, sem_post, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sem_trywait.S b/src/kernel/libsyscall/bsdsyscalls/_sem_trywait.S new file mode 100644 index 000000000..a36ee1340 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sem_trywait.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_trywait +#error "SYS_sem_trywait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sem_trywait, sem_trywait, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sem_unlink.S b/src/kernel/libsyscall/bsdsyscalls/_sem_unlink.S new file mode 100644 index 000000000..c7f2bd66e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sem_unlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_unlink +#error "SYS_sem_unlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sem_unlink, sem_unlink, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sem_wait.S b/src/kernel/libsyscall/bsdsyscalls/_sem_wait.S new file mode 100644 index 000000000..e43b993d4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sem_wait.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_wait +#error "SYS_sem_wait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_sem_wait, sem_wait, 1, cerror) +#else +__SYSCALL2(___sem_wait, sem_wait, 1, cerror) +#endif + +#if defined(__i386__) + .globl _sem_wait$UNIX2003 + .set _sem_wait$UNIX2003, ___sem_wait +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_semget.S b/src/kernel/libsyscall/bsdsyscalls/_semget.S new file mode 100644 index 000000000..81c3b5932 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_semget.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_semget +#error "SYS_semget not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_semget, semget, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_semop.S b/src/kernel/libsyscall/bsdsyscalls/_semop.S new file mode 100644 index 000000000..1a5a60e4c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_semop.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_semop +#error "SYS_semop not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_semop, semop, 3, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sendfile.S b/src/kernel/libsyscall/bsdsyscalls/_sendfile.S new file mode 100644 index 000000000..0d75fd5b7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sendfile.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_sendfile +#error "SYS_sendfile not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sendfile, sendfile, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sendmsg_x.S b/src/kernel/libsyscall/bsdsyscalls/_sendmsg_x.S new file mode 100644 index 000000000..0e4f73fc7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sendmsg_x.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_sendmsg_x +#error "SYS_sendmsg_x not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sendmsg_x, sendmsg_x, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setaudit_addr.S b/src/kernel/libsyscall/bsdsyscalls/_setaudit_addr.S new file mode 100644 index 000000000..1853ca894 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setaudit_addr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setaudit_addr +#error "SYS_setaudit_addr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setaudit_addr, setaudit_addr, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setauid.S b/src/kernel/libsyscall/bsdsyscalls/_setauid.S new file mode 100644 index 000000000..6db488b09 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setauid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setauid +#error "SYS_setauid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setauid, setauid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setegid.S b/src/kernel/libsyscall/bsdsyscalls/_setegid.S new file mode 100644 index 000000000..2edaf45d3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setegid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setegid +#error "SYS_setegid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setegid, setegid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_seteuid.S b/src/kernel/libsyscall/bsdsyscalls/_seteuid.S new file mode 100644 index 000000000..44318a2c8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_seteuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_seteuid +#error "SYS_seteuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_seteuid, seteuid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setgid.S b/src/kernel/libsyscall/bsdsyscalls/_setgid.S new file mode 100644 index 000000000..22a65d88a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setgid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setgid +#error "SYS_setgid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setgid, setgid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setgroups.S b/src/kernel/libsyscall/bsdsyscalls/_setgroups.S new file mode 100644 index 000000000..1442c9f1a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setgroups.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setgroups +#error "SYS_setgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setgroups, setgroups, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setitimer.S b/src/kernel/libsyscall/bsdsyscalls/_setitimer.S new file mode 100644 index 000000000..e25d285a1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setitimer.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_setitimer +#error "SYS_setitimer not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setitimer, setitimer, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setpgid.S b/src/kernel/libsyscall/bsdsyscalls/_setpgid.S new file mode 100644 index 000000000..842a2f519 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setpgid.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setpgid +#error "SYS_setpgid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setpgid, setpgid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setpgrp + .set _setpgrp, _setpgid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setprivexec.S b/src/kernel/libsyscall/bsdsyscalls/_setprivexec.S new file mode 100644 index 000000000..e1c58a70d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setprivexec.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setprivexec +#error "SYS_setprivexec not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setprivexec, setprivexec, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/sys_x86-64/_setquota.S b/src/kernel/libsyscall/bsdsyscalls/_setquota.S similarity index 85% rename from src/kernel/libsyscall/sys_x86-64/_setquota.S rename to src/kernel/libsyscall/bsdsyscalls/_setquota.S index 334c6cd5e..e12b8779b 100644 --- a/src/kernel/libsyscall/sys_x86-64/_setquota.S +++ b/src/kernel/libsyscall/bsdsyscalls/_setquota.S @@ -5,7 +5,7 @@ #error "SYS_setquota not defined. The header files libsyscall is building against do not match syscalls.master." #endif -#if defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) __SYSCALL2(_setquota, setquota, 2, cerror_nocancel) #endif diff --git a/src/kernel/libsyscall/bsdsyscalls/_setsid.S b/src/kernel/libsyscall/bsdsyscalls/_setsid.S new file mode 100644 index 000000000..4dcf570d3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setsid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_setsid +#error "SYS_setsid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setsid, setsid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setsockopt.S b/src/kernel/libsyscall/bsdsyscalls/_setsockopt.S new file mode 100644 index 000000000..5d078e875 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setsockopt.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_setsockopt +#error "SYS_setsockopt not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setsockopt, setsockopt, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setuid.S b/src/kernel/libsyscall/bsdsyscalls/_setuid.S new file mode 100644 index 000000000..5fe4cee11 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setuid +#error "SYS_setuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setuid, setuid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_setxattr.S b/src/kernel/libsyscall/bsdsyscalls/_setxattr.S new file mode 100644 index 000000000..0378dd513 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_setxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_setxattr +#error "SYS_setxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setxattr, setxattr, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_shm_unlink.S b/src/kernel/libsyscall/bsdsyscalls/_shm_unlink.S new file mode 100644 index 000000000..6485e4835 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_shm_unlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_shm_unlink +#error "SYS_shm_unlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shm_unlink, shm_unlink, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_shmat.S b/src/kernel/libsyscall/bsdsyscalls/_shmat.S new file mode 100644 index 000000000..754f42704 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_shmat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_shmat +#error "SYS_shmat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shmat, shmat, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_shmdt.S b/src/kernel/libsyscall/bsdsyscalls/_shmdt.S new file mode 100644 index 000000000..286c90aac --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_shmdt.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_shmdt +#error "SYS_shmdt not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shmdt, shmdt, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_shmget.S b/src/kernel/libsyscall/bsdsyscalls/_shmget.S new file mode 100644 index 000000000..9bba04ac3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_shmget.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_shmget +#error "SYS_shmget not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shmget, shmget, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_shutdown.S b/src/kernel/libsyscall/bsdsyscalls/_shutdown.S new file mode 100644 index 000000000..6317cadf6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_shutdown.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_shutdown +#error "SYS_shutdown not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shutdown, shutdown, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sigpending.S b/src/kernel/libsyscall/bsdsyscalls/_sigpending.S new file mode 100644 index 000000000..1853ac33f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sigpending.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sigpending +#error "SYS_sigpending not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sigpending, sigpending, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sigprocmask.S b/src/kernel/libsyscall/bsdsyscalls/_sigprocmask.S new file mode 100644 index 000000000..df78468d3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sigprocmask.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_sigprocmask +#error "SYS_sigprocmask not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sigprocmask, sigprocmask, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_socket.S b/src/kernel/libsyscall/bsdsyscalls/_socket.S new file mode 100644 index 000000000..08d0b6bfd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_socket.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_socket +#error "SYS_socket not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_socket, socket, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_socket_delegate.S b/src/kernel/libsyscall/bsdsyscalls/_socket_delegate.S new file mode 100644 index 000000000..c80b5a1d9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_socket_delegate.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_socket_delegate +#error "SYS_socket_delegate not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_socket_delegate, socket_delegate, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_stat.S b/src/kernel/libsyscall/bsdsyscalls/_stat.S new file mode 100644 index 000000000..64296cdf6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_stat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_stat +#error "SYS_stat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_stat, stat, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_stat64.S b/src/kernel/libsyscall/bsdsyscalls/_stat64.S new file mode 100644 index 000000000..c43129ee6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_stat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_stat64 +#error "SYS_stat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_stat64, stat64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _stat$INODE64 + .set _stat$INODE64, _stat64 +#endif + +#if defined(__x86_64__) + .globl _stat$INODE64 + .set _stat$INODE64, _stat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_statfs.S b/src/kernel/libsyscall/bsdsyscalls/_statfs.S new file mode 100644 index 000000000..92b645a1b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_statfs.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_statfs +#error "SYS_statfs not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_statfs, statfs, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_statfs64.S b/src/kernel/libsyscall/bsdsyscalls/_statfs64.S new file mode 100644 index 000000000..4af10f996 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_statfs64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_statfs64 +#error "SYS_statfs64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_statfs64, statfs64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _statfs$INODE64 + .set _statfs$INODE64, _statfs64 +#endif + +#if defined(__x86_64__) + .globl _statfs$INODE64 + .set _statfs$INODE64, _statfs64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_swapon.S b/src/kernel/libsyscall/bsdsyscalls/_swapon.S new file mode 100644 index 000000000..3c82cf997 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_swapon.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_swapon +#error "SYS_swapon not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_swapon, swapon, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_symlink.S b/src/kernel/libsyscall/bsdsyscalls/_symlink.S new file mode 100644 index 000000000..2d3652c6c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_symlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_symlink +#error "SYS_symlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_symlink, symlink, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_symlinkat.S b/src/kernel/libsyscall/bsdsyscalls/_symlinkat.S new file mode 100644 index 000000000..bd559bfa2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_symlinkat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_symlinkat +#error "SYS_symlinkat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_symlinkat, symlinkat, 3, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_sync.S b/src/kernel/libsyscall/bsdsyscalls/_sync.S new file mode 100644 index 000000000..17ee5ddb3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_sync.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_sync +#error "SYS_sync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sync, sync, 0, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_system_override.S b/src/kernel/libsyscall/bsdsyscalls/_system_override.S new file mode 100644 index 000000000..8758afe7f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_system_override.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_system_override +#error "SYS_system_override not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_system_override, system_override, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_truncate.S b/src/kernel/libsyscall/bsdsyscalls/_truncate.S new file mode 100644 index 000000000..4271c4fc3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_truncate.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_truncate +#error "SYS_truncate not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_truncate, truncate, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_umask.S b/src/kernel/libsyscall/bsdsyscalls/_umask.S new file mode 100644 index 000000000..5de71d452 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_umask.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_umask +#error "SYS_umask not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_umask, umask, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_undelete.S b/src/kernel/libsyscall/bsdsyscalls/_undelete.S new file mode 100644 index 000000000..907363313 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_undelete.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_undelete +#error "SYS_undelete not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_undelete, undelete, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_unmount.S b/src/kernel/libsyscall/bsdsyscalls/_unmount.S new file mode 100644 index 000000000..a1feb0c3a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_unmount.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_unmount +#error "SYS_unmount not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_unmount, unmount, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_usrctl.S b/src/kernel/libsyscall/bsdsyscalls/_usrctl.S new file mode 100644 index 000000000..c55945d06 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_usrctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_usrctl +#error "SYS_usrctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_usrctl, usrctl, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_utimes.S b/src/kernel/libsyscall/bsdsyscalls/_utimes.S new file mode 100644 index 000000000..00b9ee69a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_utimes.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_utimes +#error "SYS_utimes not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_utimes, utimes, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_vfs_purge.S b/src/kernel/libsyscall/bsdsyscalls/_vfs_purge.S new file mode 100644 index 000000000..049c65529 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_vfs_purge.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_vfs_purge +#error "SYS_vfs_purge not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_vfs_purge, vfs_purge, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_vm_pressure_monitor.S b/src/kernel/libsyscall/bsdsyscalls/_vm_pressure_monitor.S new file mode 100644 index 000000000..9512b92e1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_vm_pressure_monitor.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_vm_pressure_monitor +#error "SYS_vm_pressure_monitor not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_vm_pressure_monitor, vm_pressure_monitor, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_waitevent.S b/src/kernel/libsyscall/bsdsyscalls/_waitevent.S new file mode 100644 index 000000000..bab768c25 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_waitevent.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_waitevent +#error "SYS_waitevent not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_waitevent, waitevent, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_waitid.S b/src/kernel/libsyscall/bsdsyscalls/_waitid.S new file mode 100644 index 000000000..5ec0ff7e5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_waitid.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_waitid +#error "SYS_waitid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_waitid, waitid, 4, cerror) +#else +__SYSCALL2(___waitid, waitid, 4, cerror) +#endif + +#if defined(__i386__) + .globl _waitid$UNIX2003 + .set _waitid$UNIX2003, ___waitid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_watchevent.S b/src/kernel/libsyscall/bsdsyscalls/_watchevent.S new file mode 100644 index 000000000..4564fd3b7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_watchevent.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_watchevent +#error "SYS_watchevent not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_watchevent, watchevent, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_write.S b/src/kernel/libsyscall/bsdsyscalls/_write.S new file mode 100644 index 000000000..78aa551ab --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_write.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_write +#error "SYS_write not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_write, write, 3, cerror) +#else +__SYSCALL2(___write, write, 3, cerror) +#endif + +#if defined(__i386__) + .globl _write$UNIX2003 + .set _write$UNIX2003, ___write +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/_writev.S b/src/kernel/libsyscall/bsdsyscalls/_writev.S new file mode 100644 index 000000000..f03a2e683 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/_writev.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_writev +#error "SYS_writev not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_writev, writev, 3, cerror) +#else +__SYSCALL2(___writev, writev, 3, cerror) +#endif + +#if defined(__i386__) + .globl _writev$UNIX2003 + .set _writev$UNIX2003, ___writev +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/SYS.h b/src/kernel/libsyscall/bsdsyscalls/bak/SYS.h new file mode 100644 index 000000000..eea226254 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/SYS.h @@ -0,0 +1,223 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2011 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. + * + * File: SYS.h + * + * Definition of the user side of the UNIX system call interface + * for M98K. + * + * Errors are flagged by the location of the trap return (ie., which + * instruction is executed upon rfi): + * + * SC PC + 4: Error (typically branch to cerror()) + * SC PC + 8: Success + * + * HISTORY + * 18-Nov-92 Ben Fathi (benf@next.com) + * Ported to m98k. + * + * 9-Jan-92 Peter King (king@next.com) + * Created. + */ + +#include + +/* Binary compatibility stubs for syscalls that no longer exist */ + +#ifndef SYS_setquota +#define SYS_setquota 148 +#endif +#ifndef SYS_quota +#define SYS_quota 149 +#endif + +#if defined(__i386__) + +#include +#include + +/* + * We have two entry points. int's is used for syscalls which need to preserve + * %ecx across the call, or return a 64-bit value in %eax:%edx. sysenter is used + * for the majority of syscalls which just return a value in %eax. + */ + +#ifndef DARLING +#define UNIX_SYSCALL_SYSENTER call __sysenter_trap +#else +#define UNIX_SYSCALL_SYSENTER call __darling_bsd_syscall +#endif + +#define UNIX_SYSCALL(name, nargs) \ + .globl tramp_cerror ;\ +LEAF(_##name, 0) ;\ + movl $ SYS_##name, %eax ;\ + UNIX_SYSCALL_SYSENTER ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_cerror) ;\ +2: + +#define UNIX_SYSCALL_INT(name, nargs) \ + .globl tramp_cerror ;\ +LEAF(_##name, 0) ;\ + movl $ SYS_##name, %eax ;\ + UNIX_SYSCALL_TRAP ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_cerror) ;\ +2: + +#if defined(__SYSCALL_32BIT_ARG_BYTES) && ((__SYSCALL_32BIT_ARG_BYTES >= 4) && (__SYSCALL_32BIT_ARG_BYTES <= 20)) +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ + movl $(SYS_##name | (__SYSCALL_32BIT_ARG_BYTES << I386_SYSCALL_ARG_BYTES_SHIFT)), %eax ;\ + UNIX_SYSCALL_SYSENTER ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_##cerror) ;\ +2: +#else /* __SYSCALL_32BIT_ARG_BYTES < 4 || > 20 */ +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ + movl $ SYS_##name, %eax ;\ + UNIX_SYSCALL_SYSENTER ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_##cerror) ;\ +2: +#endif + +#define UNIX_SYSCALL_INT_NONAME(name, nargs) \ + .globl tramp_cerror_nocancel ;\ + movl $ SYS_##name, %eax ;\ + UNIX_SYSCALL_TRAP ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ + BRANCH_EXTERN(tramp_cerror_nocancel) ;\ +2: + +#define PSEUDO(pseudo, name, nargs, cerror) \ +LEAF(pseudo, 0) ;\ + UNIX_SYSCALL_NONAME(name, nargs, cerror) + +#define PSEUDO_INT(pseudo, name, nargs) \ +LEAF(pseudo, 0) ;\ + UNIX_SYSCALL_INT_NONAME(name, nargs) + +#define __SYSCALL2(pseudo, name, nargs, cerror) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret + +#define __SYSCALL(pseudo, name, nargs) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret + +#define __SYSCALL_INT(pseudo, name, nargs) \ + PSEUDO_INT(pseudo, name, nargs) ;\ + ret + +#elif defined(__x86_64__) + +#include +#include + +#ifdef DARLING + +#define UNIX_SYSCALL(name, nargs) \ + .globl cerror ;\ +LEAF(_#name, 0) ;\ + movl $ SYS_##name, %eax ;\ + call __darling_bsd_syscall ;\ + cmpq $-4095, %rax ;\ + jb 2f ;\ + movq %rax, %rdi ;\ + negq %rdi ;\ + BRANCH_EXTERN(_cerror) ;\ +2: + +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ + .globl cerror ;\ + movl $ SYS_##name, %eax ;\ + call __darling_bsd_syscall ;\ + cmpq $-4095, %rax ;\ + jb 2f ;\ + movq %rax, %rdi ;\ + negq %rdi ;\ + BRANCH_EXTERN(_##cerror) ;\ +2: + + +#else + +#define UNIX_SYSCALL_SYSCALL \ + movq %rcx, %r10 ;\ + syscall + +#define UNIX_SYSCALL(name, nargs) \ + .globl cerror ;\ +LEAF(_##name, 0) ;\ + movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ + UNIX_SYSCALL_SYSCALL ;\ + jnb 2f ;\ + movq %rax, %rdi ;\ + BRANCH_EXTERN(_cerror) ;\ +2: + +#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ + .globl cerror ;\ + movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ + UNIX_SYSCALL_SYSCALL ;\ + jnb 2f ;\ + movq %rax, %rdi ;\ + BRANCH_EXTERN(_##cerror) ;\ +2: + +#endif // DARLING + +#define PSEUDO(pseudo, name, nargs, cerror) \ +LEAF(pseudo, 0) ;\ + UNIX_SYSCALL_NONAME(name, nargs, cerror) + +#define __SYSCALL2(pseudo, name, nargs, cerror) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret + +#define __SYSCALL(pseudo, name, nargs) \ + PSEUDO(pseudo, name, nargs, cerror) ;\ + ret + +#else +#error Unsupported architecture +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_____old_semwait_signal_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/_____old_semwait_signal_nocancel.S new file mode 100644 index 000000000..13b572f09 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_____old_semwait_signal_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS___old_semwait_signal_nocancel +#error "SYS___old_semwait_signal_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_____old_semwait_signal_nocancel, __old_semwait_signal_nocancel, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_____sigwait_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/_____sigwait_nocancel.S new file mode 100644 index 000000000..718e356f1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_____sigwait_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___sigwait_nocancel +#error "SYS___sigwait_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_____sigwait_nocancel, __sigwait_nocancel, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___accept.S b/src/kernel/libsyscall/bsdsyscalls/bak/___accept.S new file mode 100644 index 000000000..7a4a9d11b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___accept.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_accept +#error "SYS_accept not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___accept, accept, 3, cerror) +#endif + +#if defined(__i386__) + .globl _accept$UNIX2003 + .set _accept$UNIX2003, ___accept +#endif + +#if defined(__x86_64__) + .globl _accept + .set _accept, ___accept +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___accept_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___accept_nocancel.S new file mode 100644 index 000000000..120001073 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___accept_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_accept_nocancel +#error "SYS_accept_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___accept_nocancel, accept_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _accept$NOCANCEL$UNIX2003 + .set _accept$NOCANCEL$UNIX2003, ___accept_nocancel +#endif + +#if defined(__x86_64__) + .globl _accept$NOCANCEL + .set _accept$NOCANCEL, ___accept_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___access_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___access_extended.S new file mode 100644 index 000000000..b57a2968c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___access_extended.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_access_extended +#error "SYS_access_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___access_extended, access_extended, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _accessx_np + .set _accessx_np, ___access_extended +#endif + +#if defined(__x86_64__) + .globl _accessx_np + .set _accessx_np, ___access_extended +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___aio_suspend_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___aio_suspend_nocancel.S new file mode 100644 index 000000000..59ec13dc0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___aio_suspend_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_aio_suspend_nocancel +#error "SYS_aio_suspend_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___aio_suspend_nocancel, aio_suspend_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _aio_suspend + .set _aio_suspend, ___aio_suspend_nocancel + .globl _aio_suspend$NOCANCEL$UNIX2003 + .set _aio_suspend$NOCANCEL$UNIX2003, ___aio_suspend_nocancel +#endif + +#if defined(__x86_64__) + .globl _aio_suspend$NOCANCEL + .set _aio_suspend$NOCANCEL, ___aio_suspend_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___bind.S b/src/kernel/libsyscall/bsdsyscalls/bak/___bind.S new file mode 100644 index 000000000..747530063 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___bind.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_bind +#error "SYS_bind not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bind, bind, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _bind$UNIX2003 + .set _bind$UNIX2003, ___bind +#endif + +#if defined(__x86_64__) + .globl _bind + .set _bind, ___bind +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_create.S b/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_create.S new file mode 100644 index 000000000..b2e563dd8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_create.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_bsdthread_create +#error "SYS_bsdthread_create not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bsdthread_create, bsdthread_create, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_ctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_ctl.S new file mode 100644 index 000000000..f258d675e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_ctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_bsdthread_ctl +#error "SYS_bsdthread_ctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bsdthread_ctl, bsdthread_ctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_register.S b/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_register.S new file mode 100644 index 000000000..527a266a4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_register.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_bsdthread_register +#error "SYS_bsdthread_register not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bsdthread_register, bsdthread_register, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_terminate.S b/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_terminate.S new file mode 100644 index 000000000..3671d85b9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___bsdthread_terminate.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_bsdthread_terminate +#error "SYS_bsdthread_terminate not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___bsdthread_terminate, bsdthread_terminate, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___chmod.S b/src/kernel/libsyscall/bsdsyscalls/bak/___chmod.S new file mode 100644 index 000000000..d391d28fc --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___chmod.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_chmod +#error "SYS_chmod not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___chmod, chmod, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _chmod + .set _chmod, ___chmod +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___chmod_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___chmod_extended.S new file mode 100644 index 000000000..82db9ca05 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___chmod_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_chmod_extended +#error "SYS_chmod_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___chmod_extended, chmod_extended, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/sys_x86-64/___chud.S b/src/kernel/libsyscall/bsdsyscalls/bak/___chud.S similarity index 84% rename from src/kernel/libsyscall/sys_x86-64/___chud.S rename to src/kernel/libsyscall/bsdsyscalls/bak/___chud.S index 47b7d266e..30c6d4dc7 100644 --- a/src/kernel/libsyscall/sys_x86-64/___chud.S +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___chud.S @@ -5,7 +5,7 @@ #error "SYS_chud not defined. The header files libsyscall is building against do not match syscalls.master." #endif -#if defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) __SYSCALL2(___chud, chud, 6, cerror_nocancel) #endif diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___close_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___close_nocancel.S new file mode 100644 index 000000000..9a5a1a5d7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___close_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_close_nocancel +#error "SYS_close_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___close_nocancel, close_nocancel, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _close + .set _close, ___close_nocancel + .globl _close$NOCANCEL$UNIX2003 + .set _close$NOCANCEL$UNIX2003, ___close_nocancel +#endif + +#if defined(__x86_64__) + .globl _close$NOCANCEL + .set _close$NOCANCEL, ___close_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___coalition.S b/src/kernel/libsyscall/bsdsyscalls/bak/___coalition.S new file mode 100644 index 000000000..a49ab6019 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___coalition.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_coalition +#error "SYS_coalition not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___coalition, coalition, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___coalition_info.S b/src/kernel/libsyscall/bsdsyscalls/bak/___coalition_info.S new file mode 100644 index 000000000..08be90c66 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___coalition_info.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_coalition_info +#error "SYS_coalition_info not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___coalition_info, coalition_info, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___connect.S b/src/kernel/libsyscall/bsdsyscalls/bak/___connect.S new file mode 100644 index 000000000..1e7efde6b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___connect.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_connect +#error "SYS_connect not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___connect, connect, 3, cerror) +#endif + +#if defined(__i386__) + .globl _connect$UNIX2003 + .set _connect$UNIX2003, ___connect +#endif + +#if defined(__x86_64__) + .globl _connect + .set _connect, ___connect +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___connect_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___connect_nocancel.S new file mode 100644 index 000000000..1dd65ea9b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___connect_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_connect_nocancel +#error "SYS_connect_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___connect_nocancel, connect_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _connect$NOCANCEL$UNIX2003 + .set _connect$NOCANCEL$UNIX2003, ___connect_nocancel +#endif + +#if defined(__x86_64__) + .globl _connect$NOCANCEL + .set _connect$NOCANCEL, ___connect_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___copyfile.S b/src/kernel/libsyscall/bsdsyscalls/bak/___copyfile.S new file mode 100644 index 000000000..8d2fc24e9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___copyfile.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_copyfile +#error "SYS_copyfile not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___copyfile, copyfile, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___csrctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___csrctl.S new file mode 100644 index 000000000..c5b2984df --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___csrctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_csrctl +#error "SYS_csrctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___csrctl, csrctl, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___delete.S b/src/kernel/libsyscall/bsdsyscalls/bak/___delete.S new file mode 100644 index 000000000..64bdadb17 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___delete.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_delete +#error "SYS_delete not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___delete, delete, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___disable_threadsignal.S b/src/kernel/libsyscall/bsdsyscalls/bak/___disable_threadsignal.S new file mode 100644 index 000000000..4e7804613 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___disable_threadsignal.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___disable_threadsignal +#error "SYS___disable_threadsignal not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___disable_threadsignal, __disable_threadsignal, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___exit.S b/src/kernel/libsyscall/bsdsyscalls/bak/___exit.S new file mode 100644 index 000000000..047c49602 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___exit.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_exit +#error "SYS_exit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___exit, exit, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl __exit + .set __exit, ___exit +#endif + +#if defined(__x86_64__) + .globl __exit + .set __exit, ___exit +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___fchmod.S b/src/kernel/libsyscall/bsdsyscalls/bak/___fchmod.S new file mode 100644 index 000000000..760d006fc --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___fchmod.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fchmod +#error "SYS_fchmod not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fchmod, fchmod, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fchmod + .set _fchmod, ___fchmod +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___fchmod_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___fchmod_extended.S new file mode 100644 index 000000000..cc0a05cc9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___fchmod_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fchmod_extended +#error "SYS_fchmod_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fchmod_extended, fchmod_extended, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___fcntl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___fcntl.S new file mode 100644 index 000000000..eff97c55a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___fcntl.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_fcntl +#error "SYS_fcntl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fcntl, fcntl, 3, cerror) +#endif + +#if defined(__i386__) + .globl _fcntl$UNIX2003 + .set _fcntl$UNIX2003, ___fcntl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___fcntl_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___fcntl_nocancel.S new file mode 100644 index 000000000..d300ad431 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___fcntl_nocancel.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_fcntl_nocancel +#error "SYS_fcntl_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fcntl_nocancel, fcntl_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fcntl + .set _fcntl, ___fcntl_nocancel + .globl _fcntl$NOCANCEL$UNIX2003 + .set _fcntl$NOCANCEL$UNIX2003, ___fcntl_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___fork.S b/src/kernel/libsyscall/bsdsyscalls/bak/___fork.S new file mode 100644 index 000000000..acce242db --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___fork.S @@ -0,0 +1,122 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2010 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. + * + * File: libc/ppc/sys/fork.s + * + * HISTORY + * 18-Nov-92 Ben Fathi (benf@next.com) + * Created from M88K sources + * + * 11-Jan-92 Peter King (king@next.com) + * Created from M68K sources + */ + +/* + * All of the asm stubs in this file have been adjusted so the pre/post + * fork handlers and dyld fixup are done in C inside Libc. As such, Libc + * expects the __fork asm to fix up the return code to be -1, 0 or pid + * and errno if needed. + */ + +#include "SYS.h" + +#ifdef DARLING +# define ___fork __fork +# define _cerror cerror +#endif + +#if defined(__i386__) + +LEAF(___fork, 0) + subl $28, %esp // Align the stack, with 16 bytes of extra padding that we'll need + + movl $ SYS_fork,%eax; // code for fork -> eax + UNIX_SYSCALL_TRAP // do the system call + jnc L1 // jump if CF==0 + + CALL_EXTERN(tramp_cerror) + movl $-1,%eax + addl $28, %esp // restore the stack + ret + +L1: + orl %edx,%edx // CF=OF=0, ZF set if zero result + jz L2 // parent, since r1 == 0 in parent, 1 in child + + //child here... + xorl %eax,%eax // zero eax + REG_TO_EXTERN(%eax, __current_pid); +L2: + addl $28, %esp // restore the stack + // parent ends up here skipping child portion + ret + +#elif defined(__x86_64__) + +LEAF(___fork, 0) + subq $24, %rsp // Align the stack, plus room for local storage + +#ifndef DARLING + movl $ SYSCALL_CONSTRUCT_UNIX(SYS_fork),%eax; // code for fork -> rax + UNIX_SYSCALL_TRAP // do the system call + jnc L1 // jump if CF==0 +#else + movl $ SYS_fork, %eax + call __darling_bsd_syscall + cmpq $0, %rax + jnb L1 +#endif + movq %rax, %rdi + CALL_EXTERN(_cerror) + movq $-1, %rax + addq $24, %rsp // restore the stack + ret + +L1: +#ifndef DARLING + orl %edx,%edx // CF=OF=0, ZF set if zero result + jz L2 // parent, since r1 == 0 in parent, 1 in child +#else + testl %eax, %eax + jnz L2 +#endif + + //child here... + xorq %rax, %rax + PICIFY(__current_pid) + movl %eax,(%r11) +L2: + // parent ends up here skipping child portion + addq $24, %rsp // restore the stack + ret + +#else +#error Unsupported architecture +#endif diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___fsgetpath.S b/src/kernel/libsyscall/bsdsyscalls/bak/___fsgetpath.S new file mode 100644 index 000000000..bb26b3339 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___fsgetpath.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fsgetpath +#error "SYS_fsgetpath not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fsgetpath, fsgetpath, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___fstat64_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___fstat64_extended.S new file mode 100644 index 000000000..d30b3d1ea --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___fstat64_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fstat64_extended +#error "SYS_fstat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fstat64_extended, fstat64_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___fstat_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___fstat_extended.S new file mode 100644 index 000000000..288b41744 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___fstat_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fstat_extended +#error "SYS_fstat_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fstat_extended, fstat_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___fsync_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___fsync_nocancel.S new file mode 100644 index 000000000..ceb5e7b34 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___fsync_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fsync_nocancel +#error "SYS_fsync_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___fsync_nocancel, fsync_nocancel, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fsync + .set _fsync, ___fsync_nocancel + .globl _fsync$NOCANCEL$UNIX2003 + .set _fsync$NOCANCEL$UNIX2003, ___fsync_nocancel +#endif + +#if defined(__x86_64__) + .globl _fsync$NOCANCEL + .set _fsync$NOCANCEL, ___fsync_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___getattrlist.S b/src/kernel/libsyscall/bsdsyscalls/bak/___getattrlist.S new file mode 100644 index 000000000..7c3a70a08 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___getattrlist.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_getattrlist +#error "SYS_getattrlist not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getattrlist, getattrlist, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getattrlist$UNIX2003 + .set _getattrlist$UNIX2003, ___getattrlist +#endif + +#if defined(__x86_64__) + .globl _getattrlist + .set _getattrlist, ___getattrlist +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___getdirentries64.S b/src/kernel/libsyscall/bsdsyscalls/bak/___getdirentries64.S new file mode 100644 index 000000000..1f1e6b6f7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___getdirentries64.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_getdirentries64 +#error "SYS_getdirentries64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getdirentries64, getdirentries64, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___gethostuuid.S b/src/kernel/libsyscall/bsdsyscalls/bak/___gethostuuid.S new file mode 100644 index 000000000..ef0485c95 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___gethostuuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_gethostuuid +#error "SYS_gethostuuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___gethostuuid, gethostuuid, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___getlogin.S b/src/kernel/libsyscall/bsdsyscalls/bak/___getlogin.S new file mode 100644 index 000000000..e4a4f4ab5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___getlogin.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getlogin +#error "SYS_getlogin not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getlogin, getlogin, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___getpeername.S b/src/kernel/libsyscall/bsdsyscalls/bak/___getpeername.S new file mode 100644 index 000000000..f4cb030c2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___getpeername.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_getpeername +#error "SYS_getpeername not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getpeername, getpeername, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getpeername$UNIX2003 + .set _getpeername$UNIX2003, ___getpeername +#endif + +#if defined(__x86_64__) + .globl _getpeername + .set _getpeername, ___getpeername +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___getpid.S b/src/kernel/libsyscall/bsdsyscalls/bak/___getpid.S new file mode 100644 index 000000000..0398b2f33 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___getpid.S @@ -0,0 +1,115 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "SYS.h" + +#if defined(__i386__) + + .data + .globl __current_pid + .private_extern __current_pid +L__current_pid_addr: + __current_pid: + .long 0 + +#if defined(__DYNAMIC__) +#define GET_CURRENT_PID \ + call 0f ; \ +0: ; \ + popl %ecx ; \ + leal L__current_pid_addr-0b(%ecx), %ecx + +#define __current_pid (%ecx) + +#else +#define GET_CURRENT_PID +#endif + +/* + * If __current_pid is > 0, return it, else make syscall. + * If __current_pid is 0, cache result of syscall. + */ +TEXT +LEAF(___getpid, 0) + GET_CURRENT_PID + movl __current_pid, %eax + testl %eax, %eax + jle 1f + ret +1: + UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) + movl %eax, %edx + xorl %eax, %eax + GET_CURRENT_PID + lock + cmpxchgl %edx, __current_pid + movl %edx, %eax + ret + +#elif defined(__x86_64__) + + .data + .globl __current_pid + .private_extern __current_pid +__current_pid: + .long 0 + +/* + * If __current_pid is > 0, return it, else make syscall. + * If __current_pid is 0, cache result of syscall. + */ +TEXT +LEAF(___getpid, 0) + movl __current_pid(%rip), %eax + testl %eax, %eax + jle 1f + ret +1: + UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) + movl %eax, %edx + xorl %eax, %eax + leaq __current_pid(%rip), %rcx + lock + cmpxchgl %edx, (%rcx) + movl %edx, %eax + ret + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _getpid + .set _getpid, ___getpid +#endif + +#if defined(__x86_64__) + .globl _getpid + .set _getpid, ___getpid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___getrlimit.S b/src/kernel/libsyscall/bsdsyscalls/bak/___getrlimit.S new file mode 100644 index 000000000..0be60f5fa --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___getrlimit.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getrlimit +#error "SYS_getrlimit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getrlimit, getrlimit, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getrlimit + .set _getrlimit, ___getrlimit +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___getsgroups.S b/src/kernel/libsyscall/bsdsyscalls/bak/___getsgroups.S new file mode 100644 index 000000000..eac5a0b93 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___getsgroups.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getsgroups +#error "SYS_getsgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getsgroups, getsgroups, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getsgroups_np + .set _getsgroups_np, ___getsgroups +#endif + +#if defined(__x86_64__) + .globl _getsgroups_np + .set _getsgroups_np, ___getsgroups +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___getsockname.S b/src/kernel/libsyscall/bsdsyscalls/bak/___getsockname.S new file mode 100644 index 000000000..9c27e6ae6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___getsockname.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_getsockname +#error "SYS_getsockname not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getsockname, getsockname, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getsockname$UNIX2003 + .set _getsockname$UNIX2003, ___getsockname +#endif + +#if defined(__x86_64__) + .globl _getsockname + .set _getsockname, ___getsockname +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___gettid.S b/src/kernel/libsyscall/bsdsyscalls/bak/___gettid.S new file mode 100644 index 000000000..5ea9309e3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___gettid.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_gettid +#error "SYS_gettid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___gettid, gettid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _pthread_getugid_np + .set _pthread_getugid_np, ___gettid +#endif + +#if defined(__x86_64__) + .globl _pthread_getugid_np + .set _pthread_getugid_np, ___gettid +#endif + diff --git a/src/kernel/libsyscall/sys_x86-64/___gettimeofday.S b/src/kernel/libsyscall/bsdsyscalls/bak/___gettimeofday.S similarity index 96% rename from src/kernel/libsyscall/sys_x86-64/___gettimeofday.S rename to src/kernel/libsyscall/bsdsyscalls/bak/___gettimeofday.S index b8b538c19..27cf08850 100644 --- a/src/kernel/libsyscall/sys_x86-64/___gettimeofday.S +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___gettimeofday.S @@ -30,6 +30,10 @@ #include "SYS.h" +#ifdef DARLING +# define ___gettimeofday __gettimeofday +#endif + #if defined(__i386__) /* diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___getwgroups.S b/src/kernel/libsyscall/bsdsyscalls/bak/___getwgroups.S new file mode 100644 index 000000000..c9115097d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___getwgroups.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getwgroups +#error "SYS_getwgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___getwgroups, getwgroups, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getwgroups_np + .set _getwgroups_np, ___getwgroups +#endif + +#if defined(__x86_64__) + .globl _getwgroups_np + .set _getwgroups_np, ___getwgroups +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___guarded_open_dprotected_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/___guarded_open_dprotected_np.S new file mode 100644 index 000000000..ac0deffe0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___guarded_open_dprotected_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_guarded_open_dprotected_np +#error "SYS_guarded_open_dprotected_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___guarded_open_dprotected_np, guarded_open_dprotected_np, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___guarded_open_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/___guarded_open_np.S new file mode 100644 index 000000000..55a778f7c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___guarded_open_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_guarded_open_np +#error "SYS_guarded_open_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___guarded_open_np, guarded_open_np, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___identitysvc.S b/src/kernel/libsyscall/bsdsyscalls/bak/___identitysvc.S new file mode 100644 index 000000000..d07eac9ad --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___identitysvc.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_identitysvc +#error "SYS_identitysvc not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___identitysvc, identitysvc, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___initgroups.S b/src/kernel/libsyscall/bsdsyscalls/bak/___initgroups.S new file mode 100644 index 000000000..f705f51c3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___initgroups.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_initgroups +#error "SYS_initgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___initgroups, initgroups, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___ioctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___ioctl.S new file mode 100644 index 000000000..705f260b8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___ioctl.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_ioctl +#error "SYS_ioctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___ioctl, ioctl, 3, cerror) +#endif + +#if defined(__i386__) + .globl _ioctl + .set _ioctl, ___ioctl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___iopolicysys.S b/src/kernel/libsyscall/bsdsyscalls/bak/___iopolicysys.S new file mode 100644 index 000000000..72b4172a5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___iopolicysys.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_iopolicysys +#error "SYS_iopolicysys not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___iopolicysys, iopolicysys, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace.S b/src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace.S new file mode 100644 index 000000000..30dafa9f7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_kdebug_trace +#error "SYS_kdebug_trace not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___kdebug_trace, kdebug_trace, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace64.S b/src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace64.S new file mode 100644 index 000000000..5482adc60 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace64.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 36 +#include "SYS.h" + +#ifndef SYS_kdebug_trace64 +#error "SYS_kdebug_trace64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___kdebug_trace64, kdebug_trace64, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace_string.S b/src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace_string.S new file mode 100644 index 000000000..e3543e6bf --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___kdebug_trace_string.S @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "SYS.h" + +#if defined(__x86_64__) + +__SYSCALL(___kdebug_trace_string, kdebug_trace_string, 3) + +#elif defined(__i386__) + +__SYSCALL_INT(___kdebug_trace_string, kdebug_trace_string, 3) + +#else +#error Unsupported architecture +#endif diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___kill.S b/src/kernel/libsyscall/bsdsyscalls/bak/___kill.S new file mode 100644 index 000000000..e608f7b56 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___kill.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_kill +#error "SYS_kill not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___kill, kill, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___lchown.S b/src/kernel/libsyscall/bsdsyscalls/bak/___lchown.S new file mode 100644 index 000000000..e22bfd73f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___lchown.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_lchown +#error "SYS_lchown not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___lchown, lchown, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _lchown$UNIX2003 + .set _lchown$UNIX2003, ___lchown +#endif + +#if defined(__x86_64__) + .globl _lchown + .set _lchown, ___lchown +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___listen.S b/src/kernel/libsyscall/bsdsyscalls/bak/___listen.S new file mode 100644 index 000000000..5184a75fb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___listen.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_listen +#error "SYS_listen not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___listen, listen, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _listen$UNIX2003 + .set _listen$UNIX2003, ___listen +#endif + +#if defined(__x86_64__) + .globl _listen + .set _listen, ___listen +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___lseek.S b/src/kernel/libsyscall/bsdsyscalls/bak/___lseek.S new file mode 100644 index 000000000..fb3e9e49c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___lseek.S @@ -0,0 +1,56 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "SYS.h" + +#ifdef DARLING +# define ___lseek __lseek +#endif + +#if defined(__x86_64__) + +__SYSCALL(___lseek, lseek, 3) + +#elif defined(__i386__) + +__SYSCALL_INT(___lseek, lseek, 3) + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _lseek + .set _lseek, ___lseek +#endif + +#if defined(__x86_64__) + .globl _lseek + .set _lseek, ___lseek +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___lstat64_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___lstat64_extended.S new file mode 100644 index 000000000..98b595067 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___lstat64_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_lstat64_extended +#error "SYS_lstat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___lstat64_extended, lstat64_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___lstat_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___lstat_extended.S new file mode 100644 index 000000000..6c7c4f7d8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___lstat_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_lstat_extended +#error "SYS_lstat_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___lstat_extended, lstat_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_execve.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_execve.S new file mode 100644 index 000000000..5606ed80d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_execve.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS___mac_execve +#error "SYS___mac_execve not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_execve, __mac_execve, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl ___sandbox_me + .set ___sandbox_me, ___mac_execve +#endif + +#if defined(__x86_64__) + .globl ___sandbox_me + .set ___sandbox_me, ___mac_execve +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_fd.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_fd.S new file mode 100644 index 000000000..a83c4eaeb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_fd.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_fd +#error "SYS___mac_get_fd not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_fd, __mac_get_fd, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_file.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_file.S new file mode 100644 index 000000000..f520b74ea --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_file.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_file +#error "SYS___mac_get_file not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_file, __mac_get_file, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_link.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_link.S new file mode 100644 index 000000000..6e399d12c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_link.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_link +#error "SYS___mac_get_link not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_link, __mac_get_link, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_mount.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_mount.S new file mode 100644 index 000000000..9ea5c0f7d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_mount.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_mount +#error "SYS___mac_get_mount not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_mount, __mac_get_mount, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_pid.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_pid.S new file mode 100644 index 000000000..c21007634 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_pid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_get_pid +#error "SYS___mac_get_pid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_pid, __mac_get_pid, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_proc.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_proc.S new file mode 100644 index 000000000..d732a36aa --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_get_proc.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___mac_get_proc +#error "SYS___mac_get_proc not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_get_proc, __mac_get_proc, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_getfsstat.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_getfsstat.S new file mode 100644 index 000000000..33d18be56 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_getfsstat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS___mac_getfsstat +#error "SYS___mac_getfsstat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_getfsstat, __mac_getfsstat, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_mount.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_mount.S new file mode 100644 index 000000000..7f0b33fbc --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_mount.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS___mac_mount +#error "SYS___mac_mount not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_mount, __mac_mount, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl ___sandbox_mm + .set ___sandbox_mm, ___mac_mount +#endif + +#if defined(__x86_64__) + .globl ___sandbox_mm + .set ___sandbox_mm, ___mac_mount +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_fd.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_fd.S new file mode 100644 index 000000000..b6eaa6b5f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_fd.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_set_fd +#error "SYS___mac_set_fd not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_set_fd, __mac_set_fd, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_file.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_file.S new file mode 100644 index 000000000..cf1c0a443 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_file.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_set_file +#error "SYS___mac_set_file not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_set_file, __mac_set_file, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_link.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_link.S new file mode 100644 index 000000000..67c0b3381 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_link.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___mac_set_link +#error "SYS___mac_set_link not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_set_link, __mac_set_link, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_proc.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_proc.S new file mode 100644 index 000000000..93517f314 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_set_proc.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___mac_set_proc +#error "SYS___mac_set_proc not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_set_proc, __mac_set_proc, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl ___sandbox_msp + .set ___sandbox_msp, ___mac_set_proc +#endif + +#if defined(__x86_64__) + .globl ___sandbox_msp + .set ___sandbox_msp, ___mac_set_proc +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mac_syscall.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_syscall.S new file mode 100644 index 000000000..60497bcdb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mac_syscall.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS___mac_syscall +#error "SYS___mac_syscall not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mac_syscall, __mac_syscall, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl ___sandbox_ms + .set ___sandbox_ms, ___mac_syscall +#endif + +#if defined(__x86_64__) + .globl ___sandbox_ms + .set ___sandbox_ms, ___mac_syscall +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___microstackshot.S b/src/kernel/libsyscall/bsdsyscalls/bak/___microstackshot.S new file mode 100644 index 000000000..b7c712891 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___microstackshot.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_microstackshot +#error "SYS_microstackshot not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___microstackshot, microstackshot, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mkdir_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mkdir_extended.S new file mode 100644 index 000000000..c0b36393a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mkdir_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_mkdir_extended +#error "SYS_mkdir_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mkdir_extended, mkdir_extended, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mkfifo_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mkfifo_extended.S new file mode 100644 index 000000000..cf06eac09 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mkfifo_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_mkfifo_extended +#error "SYS_mkfifo_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mkfifo_extended, mkfifo_extended, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mmap.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mmap.S new file mode 100644 index 000000000..ba33a5587 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mmap.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_mmap +#error "SYS_mmap not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mmap, mmap, 6, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _mmap + .set _mmap, ___mmap +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___mprotect.S b/src/kernel/libsyscall/bsdsyscalls/bak/___mprotect.S new file mode 100644 index 000000000..1f0490e23 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___mprotect.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_mprotect +#error "SYS_mprotect not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___mprotect, mprotect, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _mprotect$UNIX2003 + .set _mprotect$UNIX2003, ___mprotect +#endif + +#if defined(__x86_64__) + .globl _mprotect + .set _mprotect, ___mprotect +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___msgctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___msgctl.S new file mode 100644 index 000000000..ccfe10fe7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___msgctl.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_msgctl +#error "SYS_msgctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msgctl, msgctl, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msgctl$UNIX2003 + .set _msgctl$UNIX2003, ___msgctl +#endif + +#if defined(__x86_64__) + .globl _msgctl + .set _msgctl, ___msgctl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___msgrcv_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___msgrcv_nocancel.S new file mode 100644 index 000000000..e85ae0f2b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___msgrcv_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_msgrcv_nocancel +#error "SYS_msgrcv_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msgrcv_nocancel, msgrcv_nocancel, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msgrcv + .set _msgrcv, ___msgrcv_nocancel + .globl _msgrcv$NOCANCEL$UNIX2003 + .set _msgrcv$NOCANCEL$UNIX2003, ___msgrcv_nocancel +#endif + +#if defined(__x86_64__) + .globl _msgrcv$NOCANCEL + .set _msgrcv$NOCANCEL, ___msgrcv_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___msgsnd_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___msgsnd_nocancel.S new file mode 100644 index 000000000..5bd427693 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___msgsnd_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_msgsnd_nocancel +#error "SYS_msgsnd_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msgsnd_nocancel, msgsnd_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msgsnd + .set _msgsnd, ___msgsnd_nocancel + .globl _msgsnd$NOCANCEL$UNIX2003 + .set _msgsnd$NOCANCEL$UNIX2003, ___msgsnd_nocancel +#endif + +#if defined(__x86_64__) + .globl _msgsnd$NOCANCEL + .set _msgsnd$NOCANCEL, ___msgsnd_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___msgsys.S b/src/kernel/libsyscall/bsdsyscalls/bak/___msgsys.S new file mode 100644 index 000000000..9337546e1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___msgsys.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_msgsys +#error "SYS_msgsys not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msgsys, msgsys, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msgsys + .set _msgsys, ___msgsys +#endif + +#if defined(__x86_64__) + .globl _msgsys + .set _msgsys, ___msgsys +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___msync.S b/src/kernel/libsyscall/bsdsyscalls/bak/___msync.S new file mode 100644 index 000000000..638425c77 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___msync.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_msync +#error "SYS_msync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msync, msync, 3, cerror) +#endif + +#if defined(__i386__) + .globl _msync$UNIX2003 + .set _msync$UNIX2003, ___msync +#endif + +#if defined(__x86_64__) + .globl _msync + .set _msync, ___msync +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___msync_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___msync_nocancel.S new file mode 100644 index 000000000..3df28d7f1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___msync_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_msync_nocancel +#error "SYS_msync_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___msync_nocancel, msync_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _msync$NOCANCEL$UNIX2003 + .set _msync$NOCANCEL$UNIX2003, ___msync_nocancel +#endif + +#if defined(__x86_64__) + .globl _msync$NOCANCEL + .set _msync$NOCANCEL, ___msync_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___munmap.S b/src/kernel/libsyscall/bsdsyscalls/bak/___munmap.S new file mode 100644 index 000000000..b6bc6f40f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___munmap.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_munmap +#error "SYS_munmap not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___munmap, munmap, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___old_semwait_signal.S b/src/kernel/libsyscall/bsdsyscalls/bak/___old_semwait_signal.S new file mode 100644 index 000000000..e696e6876 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___old_semwait_signal.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS___old_semwait_signal +#error "SYS___old_semwait_signal not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___old_semwait_signal, __old_semwait_signal, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___open.S b/src/kernel/libsyscall/bsdsyscalls/bak/___open.S new file mode 100644 index 000000000..91dfa4aa6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___open.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_open +#error "SYS_open not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___open, open, 3, cerror) +#endif + +#if defined(__i386__) + .globl _open$UNIX2003 + .set _open$UNIX2003, ___open +#endif + +#if defined(__x86_64__) + .globl _open + .set _open, ___open +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___open_dprotected_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/___open_dprotected_np.S new file mode 100644 index 000000000..3105a3dc2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___open_dprotected_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_open_dprotected_np +#error "SYS_open_dprotected_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___open_dprotected_np, open_dprotected_np, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___open_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___open_extended.S new file mode 100644 index 000000000..28bb1f3f0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___open_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_open_extended +#error "SYS_open_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___open_extended, open_extended, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___open_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___open_nocancel.S new file mode 100644 index 000000000..87c47594c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___open_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_open_nocancel +#error "SYS_open_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___open_nocancel, open_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _open$NOCANCEL$UNIX2003 + .set _open$NOCANCEL$UNIX2003, ___open_nocancel +#endif + +#if defined(__x86_64__) + .globl _open$NOCANCEL + .set _open$NOCANCEL, ___open_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___openat.S b/src/kernel/libsyscall/bsdsyscalls/bak/___openat.S new file mode 100644 index 000000000..d15fb384b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___openat.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_openat +#error "SYS_openat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___openat, openat, 4, cerror) +#endif + +#if defined(__i386__) + .globl _openat + .set _openat, ___openat +#endif + +#if defined(__x86_64__) + .globl _openat + .set _openat, ___openat +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___openat_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___openat_nocancel.S new file mode 100644 index 000000000..e31f25725 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___openat_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_openat_nocancel +#error "SYS_openat_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___openat_nocancel, openat_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _openat$NOCANCEL + .set _openat$NOCANCEL, ___openat_nocancel +#endif + +#if defined(__x86_64__) + .globl _openat$NOCANCEL + .set _openat$NOCANCEL, ___openat_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___persona.S b/src/kernel/libsyscall/bsdsyscalls/bak/___persona.S new file mode 100644 index 000000000..290a72e32 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___persona.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_persona +#error "SYS_persona not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___persona, persona, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pipe.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pipe.S new file mode 100644 index 000000000..615eec3bd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pipe.S @@ -0,0 +1,66 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ + +#include "SYS.h" + +#ifdef DARLING +# define ___pipe __pipe +#endif + +#if defined(__i386__) + +PSEUDO_INT(___pipe, pipe, 0) + movl 4(%esp),%ecx + movl %eax,(%ecx) + movl %edx,4(%ecx) + xorl %eax,%eax + ret + +#elif defined(__x86_64__) + +PSEUDO(___pipe, pipe, 0, cerror_nocancel) + movl %eax, (%rdi) + movl %edx, 4(%rdi) + xorl %eax, %eax + ret + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _pipe + .set _pipe, ___pipe +#endif + +#if defined(__x86_64__) + .globl _pipe + .set _pipe, ___pipe +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___poll_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___poll_nocancel.S new file mode 100644 index 000000000..8adfa6a86 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___poll_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_poll_nocancel +#error "SYS_poll_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___poll_nocancel, poll_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _poll + .set _poll, ___poll_nocancel + .globl _poll$NOCANCEL$UNIX2003 + .set _poll$NOCANCEL$UNIX2003, ___poll_nocancel +#endif + +#if defined(__x86_64__) + .globl _poll$NOCANCEL + .set _poll$NOCANCEL, ___poll_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___posix_spawn.S b/src/kernel/libsyscall/bsdsyscalls/bak/___posix_spawn.S new file mode 100644 index 000000000..8fbc54851 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___posix_spawn.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_posix_spawn +#error "SYS_posix_spawn not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___posix_spawn, posix_spawn, 5, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pread_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pread_nocancel.S new file mode 100644 index 000000000..99946ba78 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pread_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_pread_nocancel +#error "SYS_pread_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pread_nocancel, pread_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _pread + .set _pread, ___pread_nocancel + .globl _pread$NOCANCEL$UNIX2003 + .set _pread$NOCANCEL$UNIX2003, ___pread_nocancel +#endif + +#if defined(__x86_64__) + .globl _pread$NOCANCEL + .set _pread$NOCANCEL, ___pread_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___proc_info.S b/src/kernel/libsyscall/bsdsyscalls/bak/___proc_info.S new file mode 100644 index 000000000..78ae50586 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___proc_info.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_proc_info +#error "SYS_proc_info not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___proc_info, proc_info, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___process_policy.S b/src/kernel/libsyscall/bsdsyscalls/bak/___process_policy.S new file mode 100644 index 000000000..103a82d66 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___process_policy.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 32 +#include "SYS.h" + +#ifndef SYS_process_policy +#error "SYS_process_policy not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___process_policy, process_policy, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pselect.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pselect.S new file mode 100644 index 000000000..8bc4f881a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pselect.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_pselect +#error "SYS_pselect not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pselect, pselect, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pselect_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pselect_nocancel.S new file mode 100644 index 000000000..fee781fac --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pselect_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_pselect_nocancel +#error "SYS_pselect_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pselect_nocancel, pselect_nocancel, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvbroad.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvbroad.S new file mode 100644 index 000000000..47dc0df32 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvbroad.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 44 +#include "SYS.h" + +#ifndef SYS_psynch_cvbroad +#error "SYS_psynch_cvbroad not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_cvbroad, psynch_cvbroad, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvclrprepost.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvclrprepost.S new file mode 100644 index 000000000..82929a7c5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvclrprepost.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_psynch_cvclrprepost +#error "SYS_psynch_cvclrprepost not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_cvclrprepost, psynch_cvclrprepost, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvsignal.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvsignal.S new file mode 100644 index 000000000..2e4de686d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvsignal.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 44 +#include "SYS.h" + +#ifndef SYS_psynch_cvsignal +#error "SYS_psynch_cvsignal not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_cvsignal, psynch_cvsignal, 8, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvwait.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvwait.S new file mode 100644 index 000000000..b53d4f5ee --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_cvwait.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 44 +#include "SYS.h" + +#ifndef SYS_psynch_cvwait +#error "SYS_psynch_cvwait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_cvwait, psynch_cvwait, 8, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_mutexdrop.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_mutexdrop.S new file mode 100644 index 000000000..e00e2e22f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_mutexdrop.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_psynch_mutexdrop +#error "SYS_psynch_mutexdrop not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_mutexdrop, psynch_mutexdrop, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_mutexwait.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_mutexwait.S new file mode 100644 index 000000000..80a3c5b5f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_mutexwait.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_psynch_mutexwait +#error "SYS_psynch_mutexwait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_mutexwait, psynch_mutexwait, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_downgrade.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_downgrade.S new file mode 100644 index 000000000..0aee0f8fa --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_downgrade.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_downgrade +#error "SYS_psynch_rw_downgrade not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_downgrade, psynch_rw_downgrade, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_longrdlock.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_longrdlock.S new file mode 100644 index 000000000..9834f388e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_longrdlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_longrdlock +#error "SYS_psynch_rw_longrdlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_longrdlock, psynch_rw_longrdlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_rdlock.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_rdlock.S new file mode 100644 index 000000000..c895923ad --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_rdlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_rdlock +#error "SYS_psynch_rw_rdlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_rdlock, psynch_rw_rdlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_unlock.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_unlock.S new file mode 100644 index 000000000..11cf93d6a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_unlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_unlock +#error "SYS_psynch_rw_unlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_unlock, psynch_rw_unlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_unlock2.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_unlock2.S new file mode 100644 index 000000000..4a6daccd0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_unlock2.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_unlock2 +#error "SYS_psynch_rw_unlock2 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_unlock2, psynch_rw_unlock2, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_upgrade.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_upgrade.S new file mode 100644 index 000000000..d832eec00 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_upgrade.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_upgrade +#error "SYS_psynch_rw_upgrade not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_upgrade, psynch_rw_upgrade, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_wrlock.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_wrlock.S new file mode 100644 index 000000000..8747b873d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_wrlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_wrlock +#error "SYS_psynch_rw_wrlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_wrlock, psynch_rw_wrlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_yieldwrlock.S b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_yieldwrlock.S new file mode 100644 index 000000000..6d194d8c7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___psynch_rw_yieldwrlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_psynch_rw_yieldwrlock +#error "SYS_psynch_rw_yieldwrlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___psynch_rw_yieldwrlock, psynch_rw_yieldwrlock, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_canceled.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_canceled.S new file mode 100644 index 000000000..219f63e70 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_canceled.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___pthread_canceled +#error "SYS___pthread_canceled not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_canceled, __pthread_canceled, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_chdir.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_chdir.S new file mode 100644 index 000000000..f947fb011 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_chdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___pthread_chdir +#error "SYS___pthread_chdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_chdir, __pthread_chdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_fchdir.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_fchdir.S new file mode 100644 index 000000000..21af883be --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_fchdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___pthread_fchdir +#error "SYS___pthread_fchdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_fchdir, __pthread_fchdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_kill.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_kill.S new file mode 100644 index 000000000..e46f8332b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_kill.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___pthread_kill +#error "SYS___pthread_kill not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_kill, __pthread_kill, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_markcancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_markcancel.S new file mode 100644 index 000000000..657709261 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_markcancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS___pthread_markcancel +#error "SYS___pthread_markcancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_markcancel, __pthread_markcancel, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_sigmask.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_sigmask.S new file mode 100644 index 000000000..030e05621 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pthread_sigmask.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS___pthread_sigmask +#error "SYS___pthread_sigmask not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pthread_sigmask, __pthread_sigmask, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___ptrace.S b/src/kernel/libsyscall/bsdsyscalls/bak/___ptrace.S new file mode 100644 index 000000000..18c363a52 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___ptrace.S @@ -0,0 +1,66 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ + +#include "SYS.h" + +#if defined(__i386__) + + .globl _errno + +LEAF(___ptrace, 0) + xorl %eax,%eax + REG_TO_EXTERN(%eax,_errno) + UNIX_SYSCALL_NONAME(ptrace, 4, cerror) + ret + +#elif defined(__x86_64__) + + .globl _errno + +LEAF(___ptrace, 0) + xorq %rax,%rax + PICIFY(_errno) + movl %eax,(%r11) + UNIX_SYSCALL_NONAME(ptrace, 4, cerror) + ret + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _ptrace + .set _ptrace, ___ptrace +#endif + +#if defined(__x86_64__) + .globl _ptrace + .set _ptrace, ___ptrace +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___pwrite_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___pwrite_nocancel.S new file mode 100644 index 000000000..7f3dfb987 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___pwrite_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_pwrite_nocancel +#error "SYS_pwrite_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___pwrite_nocancel, pwrite_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _pwrite + .set _pwrite, ___pwrite_nocancel + .globl _pwrite$NOCANCEL$UNIX2003 + .set _pwrite$NOCANCEL$UNIX2003, ___pwrite_nocancel +#endif + +#if defined(__x86_64__) + .globl _pwrite$NOCANCEL + .set _pwrite$NOCANCEL, ___pwrite_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___read_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___read_nocancel.S new file mode 100644 index 000000000..9b1164804 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___read_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_read_nocancel +#error "SYS_read_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___read_nocancel, read_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _read + .set _read, ___read_nocancel + .globl _read$NOCANCEL$UNIX2003 + .set _read$NOCANCEL$UNIX2003, ___read_nocancel +#endif + +#if defined(__x86_64__) + .globl _read$NOCANCEL + .set _read$NOCANCEL, ___read_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___readv_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___readv_nocancel.S new file mode 100644 index 000000000..18c11de68 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___readv_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_readv_nocancel +#error "SYS_readv_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___readv_nocancel, readv_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _readv + .set _readv, ___readv_nocancel + .globl _readv$NOCANCEL$UNIX2003 + .set _readv$NOCANCEL$UNIX2003, ___readv_nocancel +#endif + +#if defined(__x86_64__) + .globl _readv$NOCANCEL + .set _readv$NOCANCEL, ___readv_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___recvfrom.S b/src/kernel/libsyscall/bsdsyscalls/bak/___recvfrom.S new file mode 100644 index 000000000..69b4f7163 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___recvfrom.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_recvfrom +#error "SYS_recvfrom not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___recvfrom, recvfrom, 6, cerror) +#endif + +#if defined(__i386__) + .globl _recvfrom$UNIX2003 + .set _recvfrom$UNIX2003, ___recvfrom +#endif + +#if defined(__x86_64__) + .globl _recvfrom + .set _recvfrom, ___recvfrom +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___recvfrom_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___recvfrom_nocancel.S new file mode 100644 index 000000000..87101758d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___recvfrom_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_recvfrom_nocancel +#error "SYS_recvfrom_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___recvfrom_nocancel, recvfrom_nocancel, 6, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _recvfrom$NOCANCEL$UNIX2003 + .set _recvfrom$NOCANCEL$UNIX2003, ___recvfrom_nocancel +#endif + +#if defined(__x86_64__) + .globl _recvfrom$NOCANCEL + .set _recvfrom$NOCANCEL, ___recvfrom_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___recvmsg.S b/src/kernel/libsyscall/bsdsyscalls/bak/___recvmsg.S new file mode 100644 index 000000000..f19cc39e9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___recvmsg.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_recvmsg +#error "SYS_recvmsg not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___recvmsg, recvmsg, 3, cerror) +#endif + +#if defined(__i386__) + .globl _recvmsg$UNIX2003 + .set _recvmsg$UNIX2003, ___recvmsg +#endif + +#if defined(__x86_64__) + .globl _recvmsg + .set _recvmsg, ___recvmsg +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___recvmsg_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___recvmsg_nocancel.S new file mode 100644 index 000000000..ac22ccded --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___recvmsg_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_recvmsg_nocancel +#error "SYS_recvmsg_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___recvmsg_nocancel, recvmsg_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _recvmsg$NOCANCEL$UNIX2003 + .set _recvmsg$NOCANCEL$UNIX2003, ___recvmsg_nocancel +#endif + +#if defined(__x86_64__) + .globl _recvmsg$NOCANCEL + .set _recvmsg$NOCANCEL, ___recvmsg_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___rename.S b/src/kernel/libsyscall/bsdsyscalls/bak/___rename.S new file mode 100644 index 000000000..bfd549426 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___rename.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_rename +#error "SYS_rename not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___rename, rename, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/sys_x86-64/___rename_ext.S b/src/kernel/libsyscall/bsdsyscalls/bak/___rename_ext.S similarity index 85% rename from src/kernel/libsyscall/sys_x86-64/___rename_ext.S rename to src/kernel/libsyscall/bsdsyscalls/bak/___rename_ext.S index d929009e4..bc8702c46 100644 --- a/src/kernel/libsyscall/sys_x86-64/___rename_ext.S +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___rename_ext.S @@ -5,7 +5,7 @@ #error "SYS_rename_ext not defined. The header files libsyscall is building against do not match syscalls.master." #endif -#if defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) __SYSCALL2(___rename_ext, rename_ext, 3, cerror) #endif diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___renameat.S b/src/kernel/libsyscall/bsdsyscalls/bak/___renameat.S new file mode 100644 index 000000000..f6180f512 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___renameat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_renameat +#error "SYS_renameat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___renameat, renameat, 4, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___rmdir.S b/src/kernel/libsyscall/bsdsyscalls/bak/___rmdir.S new file mode 100644 index 000000000..1e8d7a0a5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___rmdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_rmdir +#error "SYS_rmdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___rmdir, rmdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___select.S b/src/kernel/libsyscall/bsdsyscalls/bak/___select.S new file mode 100644 index 000000000..a3d94b6f3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___select.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_select +#error "SYS_select not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___select, select, 5, cerror) +#endif + +#if defined(__i386__) + .globl _select$DARWIN_EXTSN + .set _select$DARWIN_EXTSN, ___select +#endif + +#if defined(__x86_64__) + .globl _select$DARWIN_EXTSN + .set _select$DARWIN_EXTSN, ___select +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___select_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___select_nocancel.S new file mode 100644 index 000000000..dbfb3f44d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___select_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_select_nocancel +#error "SYS_select_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___select_nocancel, select_nocancel, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _select$DARWIN_EXTSN$NOCANCEL + .set _select$DARWIN_EXTSN$NOCANCEL, ___select_nocancel +#endif + +#if defined(__x86_64__) + .globl _select$DARWIN_EXTSN$NOCANCEL + .set _select$DARWIN_EXTSN$NOCANCEL, ___select_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sem_open.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sem_open.S new file mode 100644 index 000000000..f02feb832 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sem_open.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_sem_open +#error "SYS_sem_open not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sem_open, sem_open, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _sem_open + .set _sem_open, ___sem_open +#endif + +#if defined(__x86_64__) + .globl _sem_open + .set _sem_open, ___sem_open +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sem_wait_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sem_wait_nocancel.S new file mode 100644 index 000000000..5b127e28a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sem_wait_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_wait_nocancel +#error "SYS_sem_wait_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sem_wait_nocancel, sem_wait_nocancel, 1, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _sem_wait + .set _sem_wait, ___sem_wait_nocancel + .globl _sem_wait$NOCANCEL$UNIX2003 + .set _sem_wait$NOCANCEL$UNIX2003, ___sem_wait_nocancel +#endif + +#if defined(__x86_64__) + .globl _sem_wait$NOCANCEL + .set _sem_wait$NOCANCEL, ___sem_wait_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___semctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___semctl.S new file mode 100644 index 000000000..1571ce85e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___semctl.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_semctl +#error "SYS_semctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___semctl, semctl, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _semctl$UNIX2003 + .set _semctl$UNIX2003, ___semctl +#endif + +#if defined(__x86_64__) + .globl _semctl + .set _semctl, ___semctl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___semsys.S b/src/kernel/libsyscall/bsdsyscalls/bak/___semsys.S new file mode 100644 index 000000000..e3099b41c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___semsys.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_semsys +#error "SYS_semsys not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___semsys, semsys, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _semsys + .set _semsys, ___semsys +#endif + +#if defined(__x86_64__) + .globl _semsys + .set _semsys, ___semsys +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___semwait_signal.S b/src/kernel/libsyscall/bsdsyscalls/bak/___semwait_signal.S new file mode 100644 index 000000000..d447d8c6d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___semwait_signal.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS___semwait_signal +#error "SYS___semwait_signal not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___semwait_signal, __semwait_signal, 6, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___semwait_signal_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___semwait_signal_nocancel.S new file mode 100644 index 000000000..6a951178e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___semwait_signal_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS___semwait_signal_nocancel +#error "SYS___semwait_signal_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___semwait_signal_nocancel, __semwait_signal_nocancel, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sendmsg.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sendmsg.S new file mode 100644 index 000000000..ffaa4cb6d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sendmsg.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_sendmsg +#error "SYS_sendmsg not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sendmsg, sendmsg, 3, cerror) +#endif + +#if defined(__i386__) + .globl _sendmsg$UNIX2003 + .set _sendmsg$UNIX2003, ___sendmsg +#endif + +#if defined(__x86_64__) + .globl _sendmsg + .set _sendmsg, ___sendmsg +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sendmsg_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sendmsg_nocancel.S new file mode 100644 index 000000000..f4cf57baa --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sendmsg_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_sendmsg_nocancel +#error "SYS_sendmsg_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sendmsg_nocancel, sendmsg_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _sendmsg$NOCANCEL$UNIX2003 + .set _sendmsg$NOCANCEL$UNIX2003, ___sendmsg_nocancel +#endif + +#if defined(__x86_64__) + .globl _sendmsg$NOCANCEL + .set _sendmsg$NOCANCEL, ___sendmsg_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sendto.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sendto.S new file mode 100644 index 000000000..d76f57b6c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sendto.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_sendto +#error "SYS_sendto not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sendto, sendto, 6, cerror) +#endif + +#if defined(__i386__) + .globl _sendto$UNIX2003 + .set _sendto$UNIX2003, ___sendto +#endif + +#if defined(__x86_64__) + .globl _sendto + .set _sendto, ___sendto +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sendto_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sendto_nocancel.S new file mode 100644 index 000000000..5e7bc4c64 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sendto_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_sendto_nocancel +#error "SYS_sendto_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sendto_nocancel, sendto_nocancel, 6, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _sendto$NOCANCEL$UNIX2003 + .set _sendto$NOCANCEL$UNIX2003, ___sendto_nocancel +#endif + +#if defined(__x86_64__) + .globl _sendto$NOCANCEL + .set _sendto$NOCANCEL, ___sendto_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___setattrlist.S b/src/kernel/libsyscall/bsdsyscalls/bak/___setattrlist.S new file mode 100644 index 000000000..af7e1cb2d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___setattrlist.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_setattrlist +#error "SYS_setattrlist not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setattrlist, setattrlist, 5, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setattrlist$UNIX2003 + .set _setattrlist$UNIX2003, ___setattrlist +#endif + +#if defined(__x86_64__) + .globl _setattrlist + .set _setattrlist, ___setattrlist +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___setlogin.S b/src/kernel/libsyscall/bsdsyscalls/bak/___setlogin.S new file mode 100644 index 000000000..d3042cf0b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___setlogin.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setlogin +#error "SYS_setlogin not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setlogin, setlogin, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___setpriority.S b/src/kernel/libsyscall/bsdsyscalls/bak/___setpriority.S new file mode 100644 index 000000000..12916bb9c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___setpriority.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_setpriority +#error "SYS_setpriority not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setpriority, setpriority, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___setregid.S b/src/kernel/libsyscall/bsdsyscalls/bak/___setregid.S new file mode 100644 index 000000000..d405a093e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___setregid.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setregid +#error "SYS_setregid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setregid, setregid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setregid$UNIX2003 + .set _setregid$UNIX2003, ___setregid +#endif + +#if defined(__x86_64__) + .globl _setregid + .set _setregid, ___setregid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___setreuid.S b/src/kernel/libsyscall/bsdsyscalls/bak/___setreuid.S new file mode 100644 index 000000000..133748c57 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___setreuid.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setreuid +#error "SYS_setreuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setreuid, setreuid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setreuid$UNIX2003 + .set _setreuid$UNIX2003, ___setreuid +#endif + +#if defined(__x86_64__) + .globl _setreuid + .set _setreuid, ___setreuid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___setrlimit.S b/src/kernel/libsyscall/bsdsyscalls/bak/___setrlimit.S new file mode 100644 index 000000000..2ad01e402 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___setrlimit.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setrlimit +#error "SYS_setrlimit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setrlimit, setrlimit, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setrlimit + .set _setrlimit, ___setrlimit +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___setsgroups.S b/src/kernel/libsyscall/bsdsyscalls/bak/___setsgroups.S new file mode 100644 index 000000000..735dd8794 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___setsgroups.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setsgroups +#error "SYS_setsgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setsgroups, setsgroups, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setsgroups_np + .set _setsgroups_np, ___setsgroups +#endif + +#if defined(__x86_64__) + .globl _setsgroups_np + .set _setsgroups_np, ___setsgroups +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___settid.S b/src/kernel/libsyscall/bsdsyscalls/bak/___settid.S new file mode 100644 index 000000000..535d96004 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___settid.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_settid +#error "SYS_settid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___settid, settid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _pthread_setugid_np + .set _pthread_setugid_np, ___settid +#endif + +#if defined(__x86_64__) + .globl _pthread_setugid_np + .set _pthread_setugid_np, ___settid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___settid_with_pid.S b/src/kernel/libsyscall/bsdsyscalls/bak/___settid_with_pid.S new file mode 100644 index 000000000..93a02c0df --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___settid_with_pid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_settid_with_pid +#error "SYS_settid_with_pid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___settid_with_pid, settid_with_pid, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___settimeofday.S b/src/kernel/libsyscall/bsdsyscalls/bak/___settimeofday.S new file mode 100644 index 000000000..9e6088356 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___settimeofday.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_settimeofday +#error "SYS_settimeofday not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___settimeofday, settimeofday, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___setwgroups.S b/src/kernel/libsyscall/bsdsyscalls/bak/___setwgroups.S new file mode 100644 index 000000000..237bc2d2b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___setwgroups.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setwgroups +#error "SYS_setwgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___setwgroups, setwgroups, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setwgroups_np + .set _setwgroups_np, ___setwgroups +#endif + +#if defined(__x86_64__) + .globl _setwgroups_np + .set _setwgroups_np, ___setwgroups +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sfi_ctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sfi_ctl.S new file mode 100644 index 000000000..8af3df105 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sfi_ctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_sfi_ctl +#error "SYS_sfi_ctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sfi_ctl, sfi_ctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sfi_pidctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sfi_pidctl.S new file mode 100644 index 000000000..9d73e585c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sfi_pidctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_sfi_pidctl +#error "SYS_sfi_pidctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sfi_pidctl, sfi_pidctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___shared_region_check_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/___shared_region_check_np.S new file mode 100644 index 000000000..f572b639e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___shared_region_check_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_shared_region_check_np +#error "SYS_shared_region_check_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shared_region_check_np, shared_region_check_np, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___shared_region_map_and_slide_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/___shared_region_map_and_slide_np.S new file mode 100644 index 000000000..9bcc68c11 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___shared_region_map_and_slide_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_shared_region_map_and_slide_np +#error "SYS_shared_region_map_and_slide_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shared_region_map_and_slide_np, shared_region_map_and_slide_np, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___shm_open.S b/src/kernel/libsyscall/bsdsyscalls/bak/___shm_open.S new file mode 100644 index 000000000..bac8ff273 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___shm_open.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_shm_open +#error "SYS_shm_open not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shm_open, shm_open, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _shm_open + .set _shm_open, ___shm_open +#endif + +#if defined(__x86_64__) + .globl _shm_open + .set _shm_open, ___shm_open +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___shmctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___shmctl.S new file mode 100644 index 000000000..fa14f151a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___shmctl.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_shmctl +#error "SYS_shmctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shmctl, shmctl, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _shmctl$UNIX2003 + .set _shmctl$UNIX2003, ___shmctl +#endif + +#if defined(__x86_64__) + .globl _shmctl + .set _shmctl, ___shmctl +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___shmsys.S b/src/kernel/libsyscall/bsdsyscalls/bak/___shmsys.S new file mode 100644 index 000000000..f5c4b4bb1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___shmsys.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_shmsys +#error "SYS_shmsys not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___shmsys, shmsys, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _shmsys + .set _shmsys, ___shmsys +#endif + +#if defined(__x86_64__) + .globl _shmsys + .set _shmsys, ___shmsys +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sigaction.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sigaction.S new file mode 100644 index 000000000..87435bdb0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sigaction.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_sigaction +#error "SYS_sigaction not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sigaction, sigaction, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sigaltstack.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sigaltstack.S new file mode 100644 index 000000000..9e9946f23 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sigaltstack.S @@ -0,0 +1,51 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "SYS.h" + +#ifdef DARLING +# define ___sigaltstack __sigaltstack +#endif + +#if defined(__x86_64__) + +__SYSCALL(___sigaltstack, sigaltstack, 3) + +#elif defined(__i386__) + +__SYSCALL_INT(___sigaltstack, sigaltstack, 3) + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _sigaltstack + .set _sigaltstack, ___sigaltstack +#endif + diff --git a/src/kernel/libsyscall/sys_x86-64/___sigreturn.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sigreturn.S similarity index 96% rename from src/kernel/libsyscall/sys_x86-64/___sigreturn.S rename to src/kernel/libsyscall/bsdsyscalls/bak/___sigreturn.S index 635660e97..cedffff38 100644 --- a/src/kernel/libsyscall/sys_x86-64/___sigreturn.S +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sigreturn.S @@ -29,6 +29,10 @@ #include "SYS.h" +#ifdef DARLING +# define ___sigreturn __sigreturn +#endif + #if defined(__x86_64__) __SYSCALL(___sigreturn, sigreturn, 2) diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sigsuspend.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sigsuspend.S new file mode 100644 index 000000000..207d7f9d4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sigsuspend.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sigsuspend +#error "SYS_sigsuspend not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sigsuspend, sigsuspend, 1, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sigsuspend_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sigsuspend_nocancel.S new file mode 100644 index 000000000..d6c56e150 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sigsuspend_nocancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sigsuspend_nocancel +#error "SYS_sigsuspend_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sigsuspend_nocancel, sigsuspend_nocancel, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sigwait.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sigwait.S new file mode 100644 index 000000000..aa8e93469 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sigwait.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS___sigwait +#error "SYS___sigwait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sigwait, __sigwait, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___socketpair.S b/src/kernel/libsyscall/bsdsyscalls/bak/___socketpair.S new file mode 100644 index 000000000..cbd704721 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___socketpair.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_socketpair +#error "SYS_socketpair not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___socketpair, socketpair, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _socketpair$UNIX2003 + .set _socketpair$UNIX2003, ___socketpair +#endif + +#if defined(__x86_64__) + .globl _socketpair + .set _socketpair, ___socketpair +#endif + diff --git a/src/kernel/libsyscall/sys_x86-64/___stack_snapshot.S b/src/kernel/libsyscall/bsdsyscalls/bak/___stack_snapshot.S similarity index 86% rename from src/kernel/libsyscall/sys_x86-64/___stack_snapshot.S rename to src/kernel/libsyscall/bsdsyscalls/bak/___stack_snapshot.S index fa5d5082c..7e6181c0f 100644 --- a/src/kernel/libsyscall/sys_x86-64/___stack_snapshot.S +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___stack_snapshot.S @@ -5,7 +5,7 @@ #error "SYS_stack_snapshot not defined. The header files libsyscall is building against do not match syscalls.master." #endif -#if defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) __SYSCALL2(___stack_snapshot, stack_snapshot, 5, cerror_nocancel) #endif diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___stack_snapshot_with_config.S b/src/kernel/libsyscall/bsdsyscalls/bak/___stack_snapshot_with_config.S new file mode 100644 index 000000000..a9d2ed78e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___stack_snapshot_with_config.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_stack_snapshot_with_config +#error "SYS_stack_snapshot_with_config not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___stack_snapshot_with_config, stack_snapshot_with_config, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___stat64_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___stat64_extended.S new file mode 100644 index 000000000..8ba938523 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___stat64_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_stat64_extended +#error "SYS_stat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___stat64_extended, stat64_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___stat_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___stat_extended.S new file mode 100644 index 000000000..50d8a1a69 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___stat_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_stat_extended +#error "SYS_stat_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___stat_extended, stat_extended, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___syscall.S b/src/kernel/libsyscall/bsdsyscalls/bak/___syscall.S new file mode 100644 index 000000000..43f375959 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___syscall.S @@ -0,0 +1,70 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ + +#include "SYS.h" + +#ifdef DARLING +# define ___syscall __syscall +#endif + +#if defined(__i386__) + +LEAF(___syscall, 0) + popl %ecx // ret addr + popl %eax // syscall number + pushl %ecx + UNIX_SYSCALL_TRAP + movl (%esp),%edx // add one element to stack so + pushl %ecx // caller "pop" will work + jnb 2f + BRANCH_EXTERN(tramp_cerror) +2: +END(___syscall) + +#elif defined(__x86_64__) + +// For x86-64, the kernel slides the argument list for us. +// The number of arguments here is variable, but our macros ignore +// that value anyway. +__SYSCALL(___syscall, syscall, 0); + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _syscall + .set _syscall, ___syscall +#endif + +#if defined(__x86_64__) + .globl _syscall + .set _syscall, ___syscall +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sysctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sysctl.S new file mode 100644 index 000000000..ae662782e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sysctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_sysctl +#error "SYS_sysctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sysctl, sysctl, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___sysctlbyname.S b/src/kernel/libsyscall/bsdsyscalls/bak/___sysctlbyname.S new file mode 100644 index 000000000..89538632e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___sysctlbyname.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_sysctlbyname +#error "SYS_sysctlbyname not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___sysctlbyname, sysctlbyname, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___telemetry.S b/src/kernel/libsyscall/bsdsyscalls/bak/___telemetry.S new file mode 100644 index 000000000..736d226b0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___telemetry.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 48 +#include "SYS.h" + +#ifndef SYS_telemetry +#error "SYS_telemetry not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___telemetry, telemetry, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/sys_x86-64/___thread_selfid.S b/src/kernel/libsyscall/bsdsyscalls/bak/___thread_selfid.S similarity index 95% rename from src/kernel/libsyscall/sys_x86-64/___thread_selfid.S rename to src/kernel/libsyscall/bsdsyscalls/bak/___thread_selfid.S index 2ae1e6ff4..ec9256ba8 100644 --- a/src/kernel/libsyscall/sys_x86-64/___thread_selfid.S +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___thread_selfid.S @@ -29,6 +29,10 @@ #include "SYS.h" +#ifdef DARLING +# define ___thread_selfid __thread_selfid +#endif + #if defined(__x86_64__) __SYSCALL(___thread_selfid, thread_selfid, 0) diff --git a/src/kernel/libsyscall/sys_x86-64/___thread_selfusage.S b/src/kernel/libsyscall/bsdsyscalls/bak/___thread_selfusage.S similarity index 95% rename from src/kernel/libsyscall/sys_x86-64/___thread_selfusage.S rename to src/kernel/libsyscall/bsdsyscalls/bak/___thread_selfusage.S index 838b0f3e1..a4ed8e68d 100644 --- a/src/kernel/libsyscall/sys_x86-64/___thread_selfusage.S +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___thread_selfusage.S @@ -29,6 +29,10 @@ #include "SYS.h" +#ifdef DARLING +# define ___thread_selfusage __thread_selfusage +#endif + #if defined(__x86_64__) __SYSCALL(___thread_selfusage, thread_selfusage, 0) diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___umask_extended.S b/src/kernel/libsyscall/bsdsyscalls/bak/___umask_extended.S new file mode 100644 index 000000000..2005cbfff --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___umask_extended.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_umask_extended +#error "SYS_umask_extended not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___umask_extended, umask_extended, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___unlink.S b/src/kernel/libsyscall/bsdsyscalls/bak/___unlink.S new file mode 100644 index 000000000..73c31e01b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___unlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_unlink +#error "SYS_unlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___unlink, unlink, 1, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___unlinkat.S b/src/kernel/libsyscall/bsdsyscalls/bak/___unlinkat.S new file mode 100644 index 000000000..717305d27 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___unlinkat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_unlinkat +#error "SYS_unlinkat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___unlinkat, unlinkat, 3, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___vfork.S b/src/kernel/libsyscall/bsdsyscalls/bak/___vfork.S new file mode 100644 index 000000000..f23e2dade --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___vfork.S @@ -0,0 +1,162 @@ +// Modified by Lubos Dolezel for Darling +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. + * + * File: libc/ppc/sys/vfork.s + * + * HISTORY + * 23-Jun-1998 Umesh Vaishampayan (umeshv@apple.com) + * Created from fork.s + * + */ + +#include "SYS.h" + +#ifdef DARLING +#define ___vfork __vfork +#define _cerror cerror +#endif + +#if defined(__i386__) + +#if defined(__DYNAMIC__) +#define GET_CURRENT_PID PICIFY(__current_pid) + + NON_LAZY_STUB(__current_pid) +#define __current_pid (%edx) +#else +#define GET_CURRENT_PID +#endif + +/* + * If __current_pid >= 0, we want to put a -1 in there + * otherwise we just decrement it + */ + +LEAF(___vfork, 0) + GET_CURRENT_PID + movl __current_pid, %eax +0: + xorl %ecx, %ecx + testl %eax, %eax + cmovs %eax, %ecx + decl %ecx + lock + cmpxchgl %ecx, __current_pid + jne 0b + popl %ecx + movl $(SYS_vfork), %eax // code for vfork -> eax + UNIX_SYSCALL_TRAP // do the system call + jnb L1 // jump if CF==0 + GET_CURRENT_PID + lock + incl __current_pid + pushl %ecx + BRANCH_EXTERN(tramp_cerror) + +L1: + testl %edx, %edx // CF=OF=0, ZF set if zero result + jz L2 // parent, since r1 == 0 in parent, 1 in child + xorl %eax, %eax // zero eax + jmp *%ecx + +L2: + GET_CURRENT_PID + lock + incl __current_pid + jmp *%ecx + +#elif defined(__x86_64__) + +/* + * If __current_pid >= 0, we want to put a -1 in there + * otherwise we just decrement it + */ + +LEAF(___vfork, 0) + movq __current_pid@GOTPCREL(%rip), %rax + movl (%rax), %eax +0: + xorl %ecx, %ecx + testl %eax, %eax + cmovs %eax, %ecx + subl $1, %ecx + movq __current_pid@GOTPCREL(%rip), %rdx + lock + cmpxchgl %ecx, (%rdx) + jne 0b + //popq %rdi // return address in %rdi +#ifndef DARLING + movq $ SYSCALL_CONSTRUCT_UNIX(SYS_vfork), %rax // code for vfork -> rax + UNIX_SYSCALL_TRAP // do the system call + jnb L1 // jump if CF==0 + pushq %rdi // put return address back on stack for cerror +#else + movl $ SYS_vfork, %eax + call __darling_bsd_syscall + cmpq $0, %rax + jnb L1 +#endif + movq __current_pid@GOTPCREL(%rip), %rcx + lock + addq $1, (%rcx) + movq %rax, %rdi + BRANCH_EXTERN(_cerror) + +L1: +#ifndef DARLING + testl %edx, %edx // CF=OF=0, ZF set if zero result + jz L2 // parent, since r1 == 0 in parent, 1 in child +#else + testl %eax, %eax + jnz L2 +#endif + xorq %rax, %rax // zero rax + jmp *%rdi + +L2: + movq __current_pid@GOTPCREL(%rip), %rdx + lock + addq $1, (%rdx) + //jmp *%rdi + ret + +#else +#error Unsupported architecture +#endif +#if defined(__i386__) + .globl _vfork + .set _vfork, ___vfork +#endif + +#if defined(__x86_64__) + .globl _vfork + .set _vfork, ___vfork +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___wait4.S b/src/kernel/libsyscall/bsdsyscalls/bak/___wait4.S new file mode 100644 index 000000000..7115df828 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___wait4.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_wait4 +#error "SYS_wait4 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___wait4, wait4, 4, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___wait4_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___wait4_nocancel.S new file mode 100644 index 000000000..b6182defd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___wait4_nocancel.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_wait4_nocancel +#error "SYS_wait4_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___wait4_nocancel, wait4_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _wait4 + .set _wait4, ___wait4_nocancel +#endif + +#if defined(__x86_64__) + .globl _wait4 + .set _wait4, ___wait4_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___waitid_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___waitid_nocancel.S new file mode 100644 index 000000000..4942cc18c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___waitid_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_waitid_nocancel +#error "SYS_waitid_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___waitid_nocancel, waitid_nocancel, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _waitid + .set _waitid, ___waitid_nocancel + .globl _waitid$NOCANCEL$UNIX2003 + .set _waitid$NOCANCEL$UNIX2003, ___waitid_nocancel +#endif + +#if defined(__x86_64__) + .globl _waitid$NOCANCEL + .set _waitid$NOCANCEL, ___waitid_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___work_interval_ctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/___work_interval_ctl.S new file mode 100644 index 000000000..a2e261b04 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___work_interval_ctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_work_interval_ctl +#error "SYS_work_interval_ctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___work_interval_ctl, work_interval_ctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___workq_kernreturn.S b/src/kernel/libsyscall/bsdsyscalls/bak/___workq_kernreturn.S new file mode 100644 index 000000000..70187d5a5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___workq_kernreturn.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_workq_kernreturn +#error "SYS_workq_kernreturn not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___workq_kernreturn, workq_kernreturn, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___workq_open.S b/src/kernel/libsyscall/bsdsyscalls/bak/___workq_open.S new file mode 100644 index 000000000..7ddef3fca --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___workq_open.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_workq_open +#error "SYS_workq_open not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___workq_open, workq_open, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___write_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___write_nocancel.S new file mode 100644 index 000000000..a60f5a1f0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___write_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_write_nocancel +#error "SYS_write_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___write_nocancel, write_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _write + .set _write, ___write_nocancel + .globl _write$NOCANCEL$UNIX2003 + .set _write$NOCANCEL$UNIX2003, ___write_nocancel +#endif + +#if defined(__x86_64__) + .globl _write$NOCANCEL + .set _write$NOCANCEL, ___write_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/___writev_nocancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/___writev_nocancel.S new file mode 100644 index 000000000..a75b5e5fb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/___writev_nocancel.S @@ -0,0 +1,23 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_writev_nocancel +#error "SYS_writev_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(___writev_nocancel, writev_nocancel, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _writev + .set _writev, ___writev_nocancel + .globl _writev$NOCANCEL$UNIX2003 + .set _writev$NOCANCEL$UNIX2003, ___writev_nocancel +#endif + +#if defined(__x86_64__) + .globl _writev$NOCANCEL + .set _writev$NOCANCEL, ___writev_nocancel +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_access.S b/src/kernel/libsyscall/bsdsyscalls/bak/_access.S new file mode 100644 index 000000000..fd32ac990 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_access.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_access +#error "SYS_access not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_access, access, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_acct.S b/src/kernel/libsyscall/bsdsyscalls/bak/_acct.S new file mode 100644 index 000000000..5aa830f4a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_acct.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_acct +#error "SYS_acct not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_acct, acct, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_adjtime.S b/src/kernel/libsyscall/bsdsyscalls/bak/_adjtime.S new file mode 100644 index 000000000..e91ed9790 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_adjtime.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_adjtime +#error "SYS_adjtime not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_adjtime, adjtime, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_aio_cancel.S b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_cancel.S new file mode 100644 index 000000000..48fea7036 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_cancel.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_aio_cancel +#error "SYS_aio_cancel not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_cancel, aio_cancel, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_aio_error.S b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_error.S new file mode 100644 index 000000000..1bd66ab9e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_error.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_aio_error +#error "SYS_aio_error not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_error, aio_error, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_aio_fsync.S b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_fsync.S new file mode 100644 index 000000000..a4f2f0c3e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_fsync.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_aio_fsync +#error "SYS_aio_fsync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_fsync, aio_fsync, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_aio_read.S b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_read.S new file mode 100644 index 000000000..c3ff5cf9c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_read.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_aio_read +#error "SYS_aio_read not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_read, aio_read, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_aio_return.S b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_return.S new file mode 100644 index 000000000..6b5d3443e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_return.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_aio_return +#error "SYS_aio_return not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_return, aio_return, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_aio_suspend.S b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_suspend.S new file mode 100644 index 000000000..5c1324a1a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_suspend.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_aio_suspend +#error "SYS_aio_suspend not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_aio_suspend, aio_suspend, 3, cerror) +#else +__SYSCALL2(___aio_suspend, aio_suspend, 3, cerror) +#endif + +#if defined(__i386__) + .globl _aio_suspend$UNIX2003 + .set _aio_suspend$UNIX2003, ___aio_suspend +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_aio_write.S b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_write.S new file mode 100644 index 000000000..30e87c16b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_aio_write.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_aio_write +#error "SYS_aio_write not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_aio_write, aio_write, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_audit.S b/src/kernel/libsyscall/bsdsyscalls/bak/_audit.S new file mode 100644 index 000000000..9185fe92e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_audit.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_audit +#error "SYS_audit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_audit, audit, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_join.S b/src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_join.S new file mode 100644 index 000000000..b38af8308 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_join.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_audit_session_join +#error "SYS_audit_session_join not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_audit_session_join, audit_session_join, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_port.S b/src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_port.S new file mode 100644 index 000000000..a56deebc0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_port.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_audit_session_port +#error "SYS_audit_session_port not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_audit_session_port, audit_session_port, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_self.S b/src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_self.S new file mode 100644 index 000000000..39e08d1c9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_audit_session_self.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_audit_session_self +#error "SYS_audit_session_self not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_audit_session_self, audit_session_self, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_auditctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/_auditctl.S new file mode 100644 index 000000000..0ea896e42 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_auditctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_auditctl +#error "SYS_auditctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_auditctl, auditctl, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_auditon.S b/src/kernel/libsyscall/bsdsyscalls/bak/_auditon.S new file mode 100644 index 000000000..44cbd0974 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_auditon.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_auditon +#error "SYS_auditon not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_auditon, auditon, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_change_fdguard_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/_change_fdguard_np.S new file mode 100644 index 000000000..8a1715612 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_change_fdguard_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_change_fdguard_np +#error "SYS_change_fdguard_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_change_fdguard_np, change_fdguard_np, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_chdir.S b/src/kernel/libsyscall/bsdsyscalls/bak/_chdir.S new file mode 100644 index 000000000..a981d0140 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_chdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_chdir +#error "SYS_chdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_chdir, chdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_chflags.S b/src/kernel/libsyscall/bsdsyscalls/bak/_chflags.S new file mode 100644 index 000000000..a8c774a74 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_chflags.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_chflags +#error "SYS_chflags not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_chflags, chflags, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_chown.S b/src/kernel/libsyscall/bsdsyscalls/bak/_chown.S new file mode 100644 index 000000000..ebe32c39b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_chown.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_chown +#error "SYS_chown not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_chown, chown, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_chroot.S b/src/kernel/libsyscall/bsdsyscalls/bak/_chroot.S new file mode 100644 index 000000000..cc8274f96 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_chroot.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_chroot +#error "SYS_chroot not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_chroot, chroot, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_close.S b/src/kernel/libsyscall/bsdsyscalls/bak/_close.S new file mode 100644 index 000000000..7d8261ec2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_close.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_close +#error "SYS_close not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_close, close, 1, cerror) +#else +__SYSCALL2(___close, close, 1, cerror) +#endif + +#if defined(__i386__) + .globl _close$UNIX2003 + .set _close$UNIX2003, ___close +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_connectx.S b/src/kernel/libsyscall/bsdsyscalls/bak/_connectx.S new file mode 100644 index 000000000..9812e93ba --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_connectx.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 32 +#include "SYS.h" + +#ifndef SYS_connectx +#error "SYS_connectx not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_connectx, connectx, 8, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_csops.S b/src/kernel/libsyscall/bsdsyscalls/bak/_csops.S new file mode 100644 index 000000000..70b447001 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_csops.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_csops +#error "SYS_csops not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_csops, csops, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_csops_audittoken.S b/src/kernel/libsyscall/bsdsyscalls/bak/_csops_audittoken.S new file mode 100644 index 000000000..2699b860d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_csops_audittoken.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_csops_audittoken +#error "SYS_csops_audittoken not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_csops_audittoken, csops_audittoken, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_disconnectx.S b/src/kernel/libsyscall/bsdsyscalls/bak/_disconnectx.S new file mode 100644 index 000000000..f9d358f60 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_disconnectx.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_disconnectx +#error "SYS_disconnectx not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_disconnectx, disconnectx, 3, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_dup.S b/src/kernel/libsyscall/bsdsyscalls/bak/_dup.S new file mode 100644 index 000000000..b73475144 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_dup.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_dup +#error "SYS_dup not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_dup, dup, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_dup2.S b/src/kernel/libsyscall/bsdsyscalls/bak/_dup2.S new file mode 100644 index 000000000..ff1979707 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_dup2.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_dup2 +#error "SYS_dup2 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_dup2, dup2, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_exchangedata.S b/src/kernel/libsyscall/bsdsyscalls/bak/_exchangedata.S new file mode 100644 index 000000000..b02da7e6d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_exchangedata.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_exchangedata +#error "SYS_exchangedata not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_exchangedata, exchangedata, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_execve.S b/src/kernel/libsyscall/bsdsyscalls/bak/_execve.S new file mode 100644 index 000000000..292830cf2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_execve.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_execve +#error "SYS_execve not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_execve, execve, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_faccessat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_faccessat.S new file mode 100644 index 000000000..63de2f6e2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_faccessat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_faccessat +#error "SYS_faccessat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_faccessat, faccessat, 4, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fchdir.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fchdir.S new file mode 100644 index 000000000..1bb4ee630 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fchdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fchdir +#error "SYS_fchdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchdir, fchdir, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fchflags.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fchflags.S new file mode 100644 index 000000000..bd6980b75 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fchflags.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fchflags +#error "SYS_fchflags not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchflags, fchflags, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fchmodat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fchmodat.S new file mode 100644 index 000000000..3f6e58b08 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fchmodat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fchmodat +#error "SYS_fchmodat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchmodat, fchmodat, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fchown.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fchown.S new file mode 100644 index 000000000..2b112c30a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fchown.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_fchown +#error "SYS_fchown not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchown, fchown, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fchownat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fchownat.S new file mode 100644 index 000000000..24e058cc4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fchownat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fchownat +#error "SYS_fchownat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fchownat, fchownat, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fdatasync.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fdatasync.S new file mode 100644 index 000000000..e93a0e5d1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fdatasync.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fdatasync +#error "SYS_fdatasync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fdatasync, fdatasync, 1, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_ffsctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/_ffsctl.S new file mode 100644 index 000000000..f5eb14eb3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_ffsctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_ffsctl +#error "SYS_ffsctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_ffsctl, ffsctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fgetattrlist.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fgetattrlist.S new file mode 100644 index 000000000..5b219f31a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fgetattrlist.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fgetattrlist +#error "SYS_fgetattrlist not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fgetattrlist, fgetattrlist, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fgetxattr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fgetxattr.S new file mode 100644 index 000000000..eb852f149 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fgetxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_fgetxattr +#error "SYS_fgetxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fgetxattr, fgetxattr, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fhopen.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fhopen.S new file mode 100644 index 000000000..35c91d9ab --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fhopen.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fhopen +#error "SYS_fhopen not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fhopen, fhopen, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fileport_makefd.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fileport_makefd.S new file mode 100644 index 000000000..3c3974be1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fileport_makefd.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fileport_makefd +#error "SYS_fileport_makefd not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fileport_makefd, fileport_makefd, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fileport_makeport.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fileport_makeport.S new file mode 100644 index 000000000..69773f335 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fileport_makeport.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fileport_makeport +#error "SYS_fileport_makeport not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fileport_makeport, fileport_makeport, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_flistxattr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_flistxattr.S new file mode 100644 index 000000000..8c6c91a84 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_flistxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_flistxattr +#error "SYS_flistxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_flistxattr, flistxattr, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_flock.S b/src/kernel/libsyscall/bsdsyscalls/bak/_flock.S new file mode 100644 index 000000000..6887a2946 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_flock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_flock +#error "SYS_flock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_flock, flock, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fpathconf.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fpathconf.S new file mode 100644 index 000000000..94f8f4b74 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fpathconf.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fpathconf +#error "SYS_fpathconf not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fpathconf, fpathconf, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fremovexattr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fremovexattr.S new file mode 100644 index 000000000..1f18a66b4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fremovexattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_fremovexattr +#error "SYS_fremovexattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fremovexattr, fremovexattr, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fsctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fsctl.S new file mode 100644 index 000000000..8039b6cf1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fsctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fsctl +#error "SYS_fsctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fsctl, fsctl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fsetattrlist.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fsetattrlist.S new file mode 100644 index 000000000..579a5539b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fsetattrlist.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_fsetattrlist +#error "SYS_fsetattrlist not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fsetattrlist, fsetattrlist, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fsetxattr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fsetxattr.S new file mode 100644 index 000000000..5a94239d5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fsetxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_fsetxattr +#error "SYS_fsetxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fsetxattr, fsetxattr, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fstat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fstat.S new file mode 100644 index 000000000..497d96c4b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fstat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fstat +#error "SYS_fstat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstat, fstat, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fstat64.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fstat64.S new file mode 100644 index 000000000..b9bc28083 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fstat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fstat64 +#error "SYS_fstat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstat64, fstat64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fstat$INODE64 + .set _fstat$INODE64, _fstat64 +#endif + +#if defined(__x86_64__) + .globl _fstat$INODE64 + .set _fstat$INODE64, _fstat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fstatat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fstatat.S new file mode 100644 index 000000000..de7570abe --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fstatat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fstatat +#error "SYS_fstatat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstatat, fstatat, 4, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fstatat64.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fstatat64.S new file mode 100644 index 000000000..c5e534b25 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fstatat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_fstatat64 +#error "SYS_fstatat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstatat64, fstatat64, 4, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fstatat$INODE64 + .set _fstatat$INODE64, _fstatat64 +#endif + +#if defined(__x86_64__) + .globl _fstatat$INODE64 + .set _fstatat$INODE64, _fstatat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fstatfs.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fstatfs.S new file mode 100644 index 000000000..d96eab95d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fstatfs.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fstatfs +#error "SYS_fstatfs not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstatfs, fstatfs, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fstatfs64.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fstatfs64.S new file mode 100644 index 000000000..9ea5d0624 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fstatfs64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_fstatfs64 +#error "SYS_fstatfs64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_fstatfs64, fstatfs64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _fstatfs$INODE64 + .set _fstatfs$INODE64, _fstatfs64 +#endif + +#if defined(__x86_64__) + .globl _fstatfs$INODE64 + .set _fstatfs$INODE64, _fstatfs64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_fsync.S b/src/kernel/libsyscall/bsdsyscalls/bak/_fsync.S new file mode 100644 index 000000000..d02acf4da --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_fsync.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_fsync +#error "SYS_fsync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_fsync, fsync, 1, cerror) +#else +__SYSCALL2(___fsync, fsync, 1, cerror) +#endif + +#if defined(__i386__) + .globl _fsync$UNIX2003 + .set _fsync$UNIX2003, ___fsync +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_ftruncate.S b/src/kernel/libsyscall/bsdsyscalls/bak/_ftruncate.S new file mode 100644 index 000000000..33f8d2d1e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_ftruncate.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_ftruncate +#error "SYS_ftruncate not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_ftruncate, ftruncate, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_futimes.S b/src/kernel/libsyscall/bsdsyscalls/bak/_futimes.S new file mode 100644 index 000000000..b1ec5aa45 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_futimes.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_futimes +#error "SYS_futimes not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_futimes, futimes, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getattrlistat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getattrlistat.S new file mode 100644 index 000000000..e317cd52f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getattrlistat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_getattrlistat +#error "SYS_getattrlistat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getattrlistat, getattrlistat, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getattrlistbulk.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getattrlistbulk.S new file mode 100644 index 000000000..4a27c68bf --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getattrlistbulk.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_getattrlistbulk +#error "SYS_getattrlistbulk not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getattrlistbulk, getattrlistbulk, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getaudit_addr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getaudit_addr.S new file mode 100644 index 000000000..757b53d4b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getaudit_addr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getaudit_addr +#error "SYS_getaudit_addr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getaudit_addr, getaudit_addr, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getauid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getauid.S new file mode 100644 index 000000000..b7cb3039f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getauid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_getauid +#error "SYS_getauid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getauid, getauid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getdirentries.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getdirentries.S new file mode 100644 index 000000000..98f3de0af --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getdirentries.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_getdirentries +#error "SYS_getdirentries not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getdirentries, getdirentries, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getdirentriesattr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getdirentriesattr.S new file mode 100644 index 000000000..699d96a2c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getdirentriesattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 32 +#include "SYS.h" + +#ifndef SYS_getdirentriesattr +#error "SYS_getdirentriesattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getdirentriesattr, getdirentriesattr, 8, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getdtablesize.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getdtablesize.S new file mode 100644 index 000000000..89aacda7d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getdtablesize.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getdtablesize +#error "SYS_getdtablesize not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getdtablesize, getdtablesize, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getegid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getegid.S new file mode 100644 index 000000000..73618ab55 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getegid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getegid +#error "SYS_getegid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getegid, getegid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_geteuid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_geteuid.S new file mode 100644 index 000000000..222434053 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_geteuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_geteuid +#error "SYS_geteuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_geteuid, geteuid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getfh.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getfh.S new file mode 100644 index 000000000..d5e3c5f03 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getfh.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getfh +#error "SYS_getfh not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getfh, getfh, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getfsstat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getfsstat.S new file mode 100644 index 000000000..2a88afc1b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getfsstat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_getfsstat +#error "SYS_getfsstat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getfsstat, getfsstat, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getfsstat64.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getfsstat64.S new file mode 100644 index 000000000..543e693b7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getfsstat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_getfsstat64 +#error "SYS_getfsstat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getfsstat64, getfsstat64, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _getfsstat$INODE64 + .set _getfsstat$INODE64, _getfsstat64 +#endif + +#if defined(__x86_64__) + .globl _getfsstat$INODE64 + .set _getfsstat$INODE64, _getfsstat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getgid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getgid.S new file mode 100644 index 000000000..44c5fb1ca --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getgid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getgid +#error "SYS_getgid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getgid, getgid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getgroups.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getgroups.S new file mode 100644 index 000000000..1ef294fb1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getgroups.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getgroups +#error "SYS_getgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getgroups, getgroups, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getitimer.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getitimer.S new file mode 100644 index 000000000..cbb85db0b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getitimer.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getitimer +#error "SYS_getitimer not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getitimer, getitimer, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getpgid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getpgid.S new file mode 100644 index 000000000..a164cbd93 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getpgid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_getpgid +#error "SYS_getpgid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getpgid, getpgid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getpgrp.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getpgrp.S new file mode 100644 index 000000000..a49c419de --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getpgrp.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getpgrp +#error "SYS_getpgrp not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getpgrp, getpgrp, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getppid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getppid.S new file mode 100644 index 000000000..fa22d6b44 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getppid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getppid +#error "SYS_getppid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getppid, getppid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getpriority.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getpriority.S new file mode 100644 index 000000000..34f6ca9ad --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getpriority.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getpriority +#error "SYS_getpriority not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getpriority, getpriority, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getrusage.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getrusage.S new file mode 100644 index 000000000..b88b4a332 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getrusage.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_getrusage +#error "SYS_getrusage not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getrusage, getrusage, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getsid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getsid.S new file mode 100644 index 000000000..7ae4c4084 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getsid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_getsid +#error "SYS_getsid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getsid, getsid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getsockopt.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getsockopt.S new file mode 100644 index 000000000..d43313dba --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getsockopt.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_getsockopt +#error "SYS_getsockopt not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getsockopt, getsockopt, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getuid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getuid.S new file mode 100644 index 000000000..44d14e622 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_getuid +#error "SYS_getuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getuid, getuid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_getxattr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_getxattr.S new file mode 100644 index 000000000..7bbcbbec2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_getxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_getxattr +#error "SYS_getxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_getxattr, getxattr, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_grab_pgo_data.S b/src/kernel/libsyscall/bsdsyscalls/bak/_grab_pgo_data.S new file mode 100644 index 000000000..cbb171e04 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_grab_pgo_data.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_grab_pgo_data +#error "SYS_grab_pgo_data not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_grab_pgo_data, grab_pgo_data, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_close_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_close_np.S new file mode 100644 index 000000000..85854aecc --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_close_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_guarded_close_np +#error "SYS_guarded_close_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_close_np, guarded_close_np, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_kqueue_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_kqueue_np.S new file mode 100644 index 000000000..bcaf3aa63 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_kqueue_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_guarded_kqueue_np +#error "SYS_guarded_kqueue_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_kqueue_np, guarded_kqueue_np, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_pwrite_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_pwrite_np.S new file mode 100644 index 000000000..161e61363 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_pwrite_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_guarded_pwrite_np +#error "SYS_guarded_pwrite_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_pwrite_np, guarded_pwrite_np, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_write_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_write_np.S new file mode 100644 index 000000000..0200d27ce --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_write_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_guarded_write_np +#error "SYS_guarded_write_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_write_np, guarded_write_np, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_writev_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_writev_np.S new file mode 100644 index 000000000..36cc4f061 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_guarded_writev_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_guarded_writev_np +#error "SYS_guarded_writev_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_guarded_writev_np, guarded_writev_np, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_issetugid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_issetugid.S new file mode 100644 index 000000000..9b9d53ab0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_issetugid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_issetugid +#error "SYS_issetugid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_issetugid, issetugid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_kas_info.S b/src/kernel/libsyscall/bsdsyscalls/bak/_kas_info.S new file mode 100644 index 000000000..ba5a7d8e2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_kas_info.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_kas_info +#error "SYS_kas_info not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kas_info, kas_info, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_kevent.S b/src/kernel/libsyscall/bsdsyscalls/bak/_kevent.S new file mode 100644 index 000000000..969f70f6f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_kevent.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_kevent +#error "SYS_kevent not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kevent, kevent, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_kevent64.S b/src/kernel/libsyscall/bsdsyscalls/bak/_kevent64.S new file mode 100644 index 000000000..2a1d6e289 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_kevent64.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_kevent64 +#error "SYS_kevent64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kevent64, kevent64, 7, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_kevent_qos.S b/src/kernel/libsyscall/bsdsyscalls/bak/_kevent_qos.S new file mode 100644 index 000000000..b30eff849 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_kevent_qos.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 32 +#include "SYS.h" + +#ifndef SYS_kevent_qos +#error "SYS_kevent_qos not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kevent_qos, kevent_qos, 8, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_kqueue.S b/src/kernel/libsyscall/bsdsyscalls/bak/_kqueue.S new file mode 100644 index 000000000..d99a8a813 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_kqueue.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_kqueue +#error "SYS_kqueue not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_kqueue, kqueue, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_ledger.S b/src/kernel/libsyscall/bsdsyscalls/bak/_ledger.S new file mode 100644 index 000000000..3c39c9521 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_ledger.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_ledger +#error "SYS_ledger not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_ledger, ledger, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_link.S b/src/kernel/libsyscall/bsdsyscalls/bak/_link.S new file mode 100644 index 000000000..2a7d76b0c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_link.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_link +#error "SYS_link not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_link, link, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_linkat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_linkat.S new file mode 100644 index 000000000..0a702854c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_linkat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_linkat +#error "SYS_linkat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_linkat, linkat, 5, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_lio_listio.S b/src/kernel/libsyscall/bsdsyscalls/bak/_lio_listio.S new file mode 100644 index 000000000..88d52bdef --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_lio_listio.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_lio_listio +#error "SYS_lio_listio not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_lio_listio, lio_listio, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_listxattr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_listxattr.S new file mode 100644 index 000000000..9f2855882 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_listxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_listxattr +#error "SYS_listxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_listxattr, listxattr, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_lstat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_lstat.S new file mode 100644 index 000000000..b985471b5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_lstat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_lstat +#error "SYS_lstat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_lstat, lstat, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_lstat64.S b/src/kernel/libsyscall/bsdsyscalls/bak/_lstat64.S new file mode 100644 index 000000000..12238ac0e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_lstat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_lstat64 +#error "SYS_lstat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_lstat64, lstat64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _lstat$INODE64 + .set _lstat$INODE64, _lstat64 +#endif + +#if defined(__x86_64__) + .globl _lstat$INODE64 + .set _lstat$INODE64, _lstat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_madvise.S b/src/kernel/libsyscall/bsdsyscalls/bak/_madvise.S new file mode 100644 index 000000000..40ac9451c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_madvise.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_madvise +#error "SYS_madvise not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_madvise, madvise, 3, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _posix_madvise + .set _posix_madvise, _madvise +#endif + +#if defined(__x86_64__) + .globl _posix_madvise + .set _posix_madvise, _madvise +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_memorystatus_control.S b/src/kernel/libsyscall/bsdsyscalls/bak/_memorystatus_control.S new file mode 100644 index 000000000..be7ee648b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_memorystatus_control.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_memorystatus_control +#error "SYS_memorystatus_control not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_memorystatus_control, memorystatus_control, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_memorystatus_get_level.S b/src/kernel/libsyscall/bsdsyscalls/bak/_memorystatus_get_level.S new file mode 100644 index 000000000..323a0cb90 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_memorystatus_get_level.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_memorystatus_get_level +#error "SYS_memorystatus_get_level not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_memorystatus_get_level, memorystatus_get_level, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_mincore.S b/src/kernel/libsyscall/bsdsyscalls/bak/_mincore.S new file mode 100644 index 000000000..d3239dee2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_mincore.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_mincore +#error "SYS_mincore not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mincore, mincore, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_minherit.S b/src/kernel/libsyscall/bsdsyscalls/bak/_minherit.S new file mode 100644 index 000000000..65625e88a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_minherit.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_minherit +#error "SYS_minherit not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_minherit, minherit, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_mkdir.S b/src/kernel/libsyscall/bsdsyscalls/bak/_mkdir.S new file mode 100644 index 000000000..d719d8e2c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_mkdir.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_mkdir +#error "SYS_mkdir not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mkdir, mkdir, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_mkdirat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_mkdirat.S new file mode 100644 index 000000000..1c59d0560 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_mkdirat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_mkdirat +#error "SYS_mkdirat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mkdirat, mkdirat, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_mkfifo.S b/src/kernel/libsyscall/bsdsyscalls/bak/_mkfifo.S new file mode 100644 index 000000000..684ab3f98 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_mkfifo.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_mkfifo +#error "SYS_mkfifo not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mkfifo, mkfifo, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_mknod.S b/src/kernel/libsyscall/bsdsyscalls/bak/_mknod.S new file mode 100644 index 000000000..052d4d3b5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_mknod.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_mknod +#error "SYS_mknod not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mknod, mknod, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_mlock.S b/src/kernel/libsyscall/bsdsyscalls/bak/_mlock.S new file mode 100644 index 000000000..be70fbe3e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_mlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_mlock +#error "SYS_mlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mlock, mlock, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_mlockall.S b/src/kernel/libsyscall/bsdsyscalls/bak/_mlockall.S new file mode 100644 index 000000000..4aa50ef3e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_mlockall.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_mlockall +#error "SYS_mlockall not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mlockall, mlockall, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_modwatch.S b/src/kernel/libsyscall/bsdsyscalls/bak/_modwatch.S new file mode 100644 index 000000000..0f5643266 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_modwatch.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_modwatch +#error "SYS_modwatch not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_modwatch, modwatch, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_mount.S b/src/kernel/libsyscall/bsdsyscalls/bak/_mount.S new file mode 100644 index 000000000..cf8776da5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_mount.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_mount +#error "SYS_mount not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mount, mount, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_mremap_encrypted.S b/src/kernel/libsyscall/bsdsyscalls/bak/_mremap_encrypted.S new file mode 100644 index 000000000..15942a767 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_mremap_encrypted.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_mremap_encrypted +#error "SYS_mremap_encrypted not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_mremap_encrypted, mremap_encrypted, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_msgget.S b/src/kernel/libsyscall/bsdsyscalls/bak/_msgget.S new file mode 100644 index 000000000..a1d68deff --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_msgget.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_msgget +#error "SYS_msgget not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_msgget, msgget, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_msgrcv.S b/src/kernel/libsyscall/bsdsyscalls/bak/_msgrcv.S new file mode 100644 index 000000000..141593f28 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_msgrcv.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_msgrcv +#error "SYS_msgrcv not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_msgrcv, msgrcv, 5, cerror) +#else +__SYSCALL2(___msgrcv, msgrcv, 5, cerror) +#endif + +#if defined(__i386__) + .globl _msgrcv$UNIX2003 + .set _msgrcv$UNIX2003, ___msgrcv +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_msgsnd.S b/src/kernel/libsyscall/bsdsyscalls/bak/_msgsnd.S new file mode 100644 index 000000000..ad180f926 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_msgsnd.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_msgsnd +#error "SYS_msgsnd not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_msgsnd, msgsnd, 4, cerror) +#else +__SYSCALL2(___msgsnd, msgsnd, 4, cerror) +#endif + +#if defined(__i386__) + .globl _msgsnd$UNIX2003 + .set _msgsnd$UNIX2003, ___msgsnd +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_munlock.S b/src/kernel/libsyscall/bsdsyscalls/bak/_munlock.S new file mode 100644 index 000000000..3587867fd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_munlock.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_munlock +#error "SYS_munlock not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_munlock, munlock, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_munlockall.S b/src/kernel/libsyscall/bsdsyscalls/bak/_munlockall.S new file mode 100644 index 000000000..d610d81a4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_munlockall.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_munlockall +#error "SYS_munlockall not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_munlockall, munlockall, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_necp_match_policy.S b/src/kernel/libsyscall/bsdsyscalls/bak/_necp_match_policy.S new file mode 100644 index 000000000..ead8d659f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_necp_match_policy.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_necp_match_policy +#error "SYS_necp_match_policy not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_necp_match_policy, necp_match_policy, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_netagent_trigger.S b/src/kernel/libsyscall/bsdsyscalls/bak/_netagent_trigger.S new file mode 100644 index 000000000..801fab392 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_netagent_trigger.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_netagent_trigger +#error "SYS_netagent_trigger not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_netagent_trigger, netagent_trigger, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_nfsclnt.S b/src/kernel/libsyscall/bsdsyscalls/bak/_nfsclnt.S new file mode 100644 index 000000000..aae9feae6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_nfsclnt.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_nfsclnt +#error "SYS_nfsclnt not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_nfsclnt, nfsclnt, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_nfssvc.S b/src/kernel/libsyscall/bsdsyscalls/bak/_nfssvc.S new file mode 100644 index 000000000..a9ce08429 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_nfssvc.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_nfssvc +#error "SYS_nfssvc not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_nfssvc, nfssvc, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_openbyid_np.S b/src/kernel/libsyscall/bsdsyscalls/bak/_openbyid_np.S new file mode 100644 index 000000000..4833ff699 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_openbyid_np.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_openbyid_np +#error "SYS_openbyid_np not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_openbyid_np, openbyid_np, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_pathconf.S b/src/kernel/libsyscall/bsdsyscalls/bak/_pathconf.S new file mode 100644 index 000000000..4cfb9c3a8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_pathconf.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_pathconf +#error "SYS_pathconf not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_pathconf, pathconf, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_peeloff.S b/src/kernel/libsyscall/bsdsyscalls/bak/_peeloff.S new file mode 100644 index 000000000..5f5a02a5e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_peeloff.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_peeloff +#error "SYS_peeloff not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_peeloff, peeloff, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_pid_resume.S b/src/kernel/libsyscall/bsdsyscalls/bak/_pid_resume.S new file mode 100644 index 000000000..8dc28a2d3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_pid_resume.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_pid_resume +#error "SYS_pid_resume not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_pid_resume, pid_resume, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_pid_suspend.S b/src/kernel/libsyscall/bsdsyscalls/bak/_pid_suspend.S new file mode 100644 index 000000000..ae2feb5c1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_pid_suspend.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_pid_suspend +#error "SYS_pid_suspend not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_pid_suspend, pid_suspend, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_poll.S b/src/kernel/libsyscall/bsdsyscalls/bak/_poll.S new file mode 100644 index 000000000..9a824f18b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_poll.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_poll +#error "SYS_poll not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_poll, poll, 3, cerror) +#else +__SYSCALL2(___poll, poll, 3, cerror) +#endif + +#if defined(__i386__) + .globl _poll$UNIX2003 + .set _poll$UNIX2003, ___poll +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_pread.S b/src/kernel/libsyscall/bsdsyscalls/bak/_pread.S new file mode 100644 index 000000000..0387838a0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_pread.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_pread +#error "SYS_pread not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_pread, pread, 4, cerror) +#else +__SYSCALL2(___pread, pread, 4, cerror) +#endif + +#if defined(__i386__) + .globl _pread$UNIX2003 + .set _pread$UNIX2003, ___pread +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_proc_rlimit_control.S b/src/kernel/libsyscall/bsdsyscalls/bak/_proc_rlimit_control.S new file mode 100644 index 000000000..a4ac7e4e0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_proc_rlimit_control.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_proc_rlimit_control +#error "SYS_proc_rlimit_control not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_proc_rlimit_control, proc_rlimit_control, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_proc_trace_log.S b/src/kernel/libsyscall/bsdsyscalls/bak/_proc_trace_log.S new file mode 100644 index 000000000..812107e58 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_proc_trace_log.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_proc_trace_log +#error "SYS_proc_trace_log not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_proc_trace_log, proc_trace_log, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_proc_uuid_policy.S b/src/kernel/libsyscall/bsdsyscalls/bak/_proc_uuid_policy.S new file mode 100644 index 000000000..a03725489 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_proc_uuid_policy.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_proc_uuid_policy +#error "SYS_proc_uuid_policy not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_proc_uuid_policy, proc_uuid_policy, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_pwrite.S b/src/kernel/libsyscall/bsdsyscalls/bak/_pwrite.S new file mode 100644 index 000000000..e873cf6cb --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_pwrite.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_pwrite +#error "SYS_pwrite not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_pwrite, pwrite, 4, cerror) +#else +__SYSCALL2(___pwrite, pwrite, 4, cerror) +#endif + +#if defined(__i386__) + .globl _pwrite$UNIX2003 + .set _pwrite$UNIX2003, ___pwrite +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_quotactl.S b/src/kernel/libsyscall/bsdsyscalls/bak/_quotactl.S new file mode 100644 index 000000000..b9fd252ae --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_quotactl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_quotactl +#error "SYS_quotactl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_quotactl, quotactl, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_read.S b/src/kernel/libsyscall/bsdsyscalls/bak/_read.S new file mode 100644 index 000000000..f7da3e2fd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_read.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_read +#error "SYS_read not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_read, read, 3, cerror) +#else +__SYSCALL2(___read, read, 3, cerror) +#endif + +#if defined(__i386__) + .globl _read$UNIX2003 + .set _read$UNIX2003, ___read +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_readlink.S b/src/kernel/libsyscall/bsdsyscalls/bak/_readlink.S new file mode 100644 index 000000000..8559f19b0 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_readlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_readlink +#error "SYS_readlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_readlink, readlink, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_readlinkat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_readlinkat.S new file mode 100644 index 000000000..38b1222b1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_readlinkat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_readlinkat +#error "SYS_readlinkat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_readlinkat, readlinkat, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_readv.S b/src/kernel/libsyscall/bsdsyscalls/bak/_readv.S new file mode 100644 index 000000000..7f5450bed --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_readv.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_readv +#error "SYS_readv not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_readv, readv, 3, cerror) +#else +__SYSCALL2(___readv, readv, 3, cerror) +#endif + +#if defined(__i386__) + .globl _readv$UNIX2003 + .set _readv$UNIX2003, ___readv +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_reboot.S b/src/kernel/libsyscall/bsdsyscalls/bak/_reboot.S new file mode 100644 index 000000000..fde5474f2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_reboot.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_reboot +#error "SYS_reboot not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_reboot, reboot, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_recvmsg_x.S b/src/kernel/libsyscall/bsdsyscalls/bak/_recvmsg_x.S new file mode 100644 index 000000000..cf40a6570 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_recvmsg_x.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_recvmsg_x +#error "SYS_recvmsg_x not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_recvmsg_x, recvmsg_x, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_removexattr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_removexattr.S new file mode 100644 index 000000000..5b7d32a75 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_removexattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_removexattr +#error "SYS_removexattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_removexattr, removexattr, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_revoke.S b/src/kernel/libsyscall/bsdsyscalls/bak/_revoke.S new file mode 100644 index 000000000..bc9cfc058 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_revoke.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_revoke +#error "SYS_revoke not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_revoke, revoke, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_searchfs.S b/src/kernel/libsyscall/bsdsyscalls/bak/_searchfs.S new file mode 100644 index 000000000..db70701ea --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_searchfs.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_searchfs +#error "SYS_searchfs not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_searchfs, searchfs, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sem_close.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_close.S new file mode 100644 index 000000000..b64727d3b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_close.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_close +#error "SYS_sem_close not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sem_close, sem_close, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sem_post.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_post.S new file mode 100644 index 000000000..46ff43caf --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_post.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_post +#error "SYS_sem_post not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sem_post, sem_post, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sem_trywait.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_trywait.S new file mode 100644 index 000000000..a36ee1340 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_trywait.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_trywait +#error "SYS_sem_trywait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sem_trywait, sem_trywait, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sem_unlink.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_unlink.S new file mode 100644 index 000000000..c7f2bd66e --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_unlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_unlink +#error "SYS_sem_unlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sem_unlink, sem_unlink, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sem_wait.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_wait.S new file mode 100644 index 000000000..e43b993d4 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sem_wait.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sem_wait +#error "SYS_sem_wait not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_sem_wait, sem_wait, 1, cerror) +#else +__SYSCALL2(___sem_wait, sem_wait, 1, cerror) +#endif + +#if defined(__i386__) + .globl _sem_wait$UNIX2003 + .set _sem_wait$UNIX2003, ___sem_wait +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_semget.S b/src/kernel/libsyscall/bsdsyscalls/bak/_semget.S new file mode 100644 index 000000000..81c3b5932 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_semget.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_semget +#error "SYS_semget not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_semget, semget, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_semop.S b/src/kernel/libsyscall/bsdsyscalls/bak/_semop.S new file mode 100644 index 000000000..1a5a60e4c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_semop.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_semop +#error "SYS_semop not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_semop, semop, 3, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sendfile.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sendfile.S new file mode 100644 index 000000000..0d75fd5b7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sendfile.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 28 +#include "SYS.h" + +#ifndef SYS_sendfile +#error "SYS_sendfile not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sendfile, sendfile, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sendmsg_x.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sendmsg_x.S new file mode 100644 index 000000000..0e4f73fc7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sendmsg_x.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_sendmsg_x +#error "SYS_sendmsg_x not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sendmsg_x, sendmsg_x, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setaudit_addr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setaudit_addr.S new file mode 100644 index 000000000..1853ca894 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setaudit_addr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setaudit_addr +#error "SYS_setaudit_addr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setaudit_addr, setaudit_addr, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setauid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setauid.S new file mode 100644 index 000000000..6db488b09 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setauid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setauid +#error "SYS_setauid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setauid, setauid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setegid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setegid.S new file mode 100644 index 000000000..2edaf45d3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setegid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setegid +#error "SYS_setegid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setegid, setegid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_seteuid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_seteuid.S new file mode 100644 index 000000000..44318a2c8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_seteuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_seteuid +#error "SYS_seteuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_seteuid, seteuid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setgid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setgid.S new file mode 100644 index 000000000..22a65d88a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setgid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setgid +#error "SYS_setgid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setgid, setgid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setgroups.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setgroups.S new file mode 100644 index 000000000..1442c9f1a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setgroups.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setgroups +#error "SYS_setgroups not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setgroups, setgroups, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setitimer.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setitimer.S new file mode 100644 index 000000000..e25d285a1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setitimer.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_setitimer +#error "SYS_setitimer not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setitimer, setitimer, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setpgid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setpgid.S new file mode 100644 index 000000000..842a2f519 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setpgid.S @@ -0,0 +1,16 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_setpgid +#error "SYS_setpgid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setpgid, setpgid, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _setpgrp + .set _setpgrp, _setpgid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setprivexec.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setprivexec.S new file mode 100644 index 000000000..e1c58a70d --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setprivexec.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setprivexec +#error "SYS_setprivexec not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setprivexec, setprivexec, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setsid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setsid.S new file mode 100644 index 000000000..4dcf570d3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setsid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_setsid +#error "SYS_setsid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setsid, setsid, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setsockopt.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setsockopt.S new file mode 100644 index 000000000..5d078e875 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setsockopt.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 20 +#include "SYS.h" + +#ifndef SYS_setsockopt +#error "SYS_setsockopt not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setsockopt, setsockopt, 5, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setuid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setuid.S new file mode 100644 index 000000000..5fe4cee11 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setuid.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_setuid +#error "SYS_setuid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setuid, setuid, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_setxattr.S b/src/kernel/libsyscall/bsdsyscalls/bak/_setxattr.S new file mode 100644 index 000000000..0378dd513 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_setxattr.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 24 +#include "SYS.h" + +#ifndef SYS_setxattr +#error "SYS_setxattr not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_setxattr, setxattr, 6, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_shm_unlink.S b/src/kernel/libsyscall/bsdsyscalls/bak/_shm_unlink.S new file mode 100644 index 000000000..6485e4835 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_shm_unlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_shm_unlink +#error "SYS_shm_unlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shm_unlink, shm_unlink, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_shmat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_shmat.S new file mode 100644 index 000000000..754f42704 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_shmat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_shmat +#error "SYS_shmat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shmat, shmat, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_shmdt.S b/src/kernel/libsyscall/bsdsyscalls/bak/_shmdt.S new file mode 100644 index 000000000..286c90aac --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_shmdt.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_shmdt +#error "SYS_shmdt not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shmdt, shmdt, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_shmget.S b/src/kernel/libsyscall/bsdsyscalls/bak/_shmget.S new file mode 100644 index 000000000..9bba04ac3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_shmget.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_shmget +#error "SYS_shmget not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shmget, shmget, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_shutdown.S b/src/kernel/libsyscall/bsdsyscalls/bak/_shutdown.S new file mode 100644 index 000000000..6317cadf6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_shutdown.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_shutdown +#error "SYS_shutdown not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_shutdown, shutdown, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sigpending.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sigpending.S new file mode 100644 index 000000000..1853ac33f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sigpending.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_sigpending +#error "SYS_sigpending not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sigpending, sigpending, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sigprocmask.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sigprocmask.S new file mode 100644 index 000000000..df78468d3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sigprocmask.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_sigprocmask +#error "SYS_sigprocmask not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sigprocmask, sigprocmask, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_socket.S b/src/kernel/libsyscall/bsdsyscalls/bak/_socket.S new file mode 100644 index 000000000..08d0b6bfd --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_socket.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_socket +#error "SYS_socket not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_socket, socket, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_socket_delegate.S b/src/kernel/libsyscall/bsdsyscalls/bak/_socket_delegate.S new file mode 100644 index 000000000..c80b5a1d9 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_socket_delegate.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_socket_delegate +#error "SYS_socket_delegate not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_socket_delegate, socket_delegate, 4, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_stat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_stat.S new file mode 100644 index 000000000..64296cdf6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_stat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_stat +#error "SYS_stat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_stat, stat, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_stat64.S b/src/kernel/libsyscall/bsdsyscalls/bak/_stat64.S new file mode 100644 index 000000000..c43129ee6 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_stat64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_stat64 +#error "SYS_stat64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_stat64, stat64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _stat$INODE64 + .set _stat$INODE64, _stat64 +#endif + +#if defined(__x86_64__) + .globl _stat$INODE64 + .set _stat$INODE64, _stat64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_statfs.S b/src/kernel/libsyscall/bsdsyscalls/bak/_statfs.S new file mode 100644 index 000000000..92b645a1b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_statfs.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_statfs +#error "SYS_statfs not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_statfs, statfs, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_statfs64.S b/src/kernel/libsyscall/bsdsyscalls/bak/_statfs64.S new file mode 100644 index 000000000..4af10f996 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_statfs64.S @@ -0,0 +1,21 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_statfs64 +#error "SYS_statfs64 not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_statfs64, statfs64, 2, cerror_nocancel) +#endif + +#if defined(__i386__) + .globl _statfs$INODE64 + .set _statfs$INODE64, _statfs64 +#endif + +#if defined(__x86_64__) + .globl _statfs$INODE64 + .set _statfs$INODE64, _statfs64 +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_swapon.S b/src/kernel/libsyscall/bsdsyscalls/bak/_swapon.S new file mode 100644 index 000000000..3c82cf997 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_swapon.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_swapon +#error "SYS_swapon not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_swapon, swapon, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_symlink.S b/src/kernel/libsyscall/bsdsyscalls/bak/_symlink.S new file mode 100644 index 000000000..2d3652c6c --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_symlink.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_symlink +#error "SYS_symlink not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_symlink, symlink, 2, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_symlinkat.S b/src/kernel/libsyscall/bsdsyscalls/bak/_symlinkat.S new file mode 100644 index 000000000..bd559bfa2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_symlinkat.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_symlinkat +#error "SYS_symlinkat not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_symlinkat, symlinkat, 3, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_sync.S b/src/kernel/libsyscall/bsdsyscalls/bak/_sync.S new file mode 100644 index 000000000..17ee5ddb3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_sync.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_sync +#error "SYS_sync not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_sync, sync, 0, cerror) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_system_override.S b/src/kernel/libsyscall/bsdsyscalls/bak/_system_override.S new file mode 100644 index 000000000..8758afe7f --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_system_override.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_system_override +#error "SYS_system_override not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_system_override, system_override, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_truncate.S b/src/kernel/libsyscall/bsdsyscalls/bak/_truncate.S new file mode 100644 index 000000000..4271c4fc3 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_truncate.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_truncate +#error "SYS_truncate not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_truncate, truncate, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_umask.S b/src/kernel/libsyscall/bsdsyscalls/bak/_umask.S new file mode 100644 index 000000000..5de71d452 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_umask.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_umask +#error "SYS_umask not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_umask, umask, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_undelete.S b/src/kernel/libsyscall/bsdsyscalls/bak/_undelete.S new file mode 100644 index 000000000..907363313 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_undelete.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_undelete +#error "SYS_undelete not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_undelete, undelete, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_unmount.S b/src/kernel/libsyscall/bsdsyscalls/bak/_unmount.S new file mode 100644 index 000000000..a1feb0c3a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_unmount.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_unmount +#error "SYS_unmount not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_unmount, unmount, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_usrctl.S b/src/kernel/libsyscall/bsdsyscalls/bak/_usrctl.S new file mode 100644 index 000000000..c55945d06 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_usrctl.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 4 +#include "SYS.h" + +#ifndef SYS_usrctl +#error "SYS_usrctl not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_usrctl, usrctl, 1, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_utimes.S b/src/kernel/libsyscall/bsdsyscalls/bak/_utimes.S new file mode 100644 index 000000000..00b9ee69a --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_utimes.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_utimes +#error "SYS_utimes not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_utimes, utimes, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_vfs_purge.S b/src/kernel/libsyscall/bsdsyscalls/bak/_vfs_purge.S new file mode 100644 index 000000000..049c65529 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_vfs_purge.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 0 +#include "SYS.h" + +#ifndef SYS_vfs_purge +#error "SYS_vfs_purge not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_vfs_purge, vfs_purge, 0, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_vm_pressure_monitor.S b/src/kernel/libsyscall/bsdsyscalls/bak/_vm_pressure_monitor.S new file mode 100644 index 000000000..9512b92e1 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_vm_pressure_monitor.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_vm_pressure_monitor +#error "SYS_vm_pressure_monitor not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_vm_pressure_monitor, vm_pressure_monitor, 3, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_waitevent.S b/src/kernel/libsyscall/bsdsyscalls/bak/_waitevent.S new file mode 100644 index 000000000..bab768c25 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_waitevent.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_waitevent +#error "SYS_waitevent not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_waitevent, waitevent, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_waitid.S b/src/kernel/libsyscall/bsdsyscalls/bak/_waitid.S new file mode 100644 index 000000000..5ec0ff7e5 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_waitid.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 16 +#include "SYS.h" + +#ifndef SYS_waitid +#error "SYS_waitid not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_waitid, waitid, 4, cerror) +#else +__SYSCALL2(___waitid, waitid, 4, cerror) +#endif + +#if defined(__i386__) + .globl _waitid$UNIX2003 + .set _waitid$UNIX2003, ___waitid +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_watchevent.S b/src/kernel/libsyscall/bsdsyscalls/bak/_watchevent.S new file mode 100644 index 000000000..4564fd3b7 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_watchevent.S @@ -0,0 +1,11 @@ +#define __SYSCALL_32BIT_ARG_BYTES 8 +#include "SYS.h" + +#ifndef SYS_watchevent +#error "SYS_watchevent not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__i386__) || defined(__x86_64__) +__SYSCALL2(_watchevent, watchevent, 2, cerror_nocancel) +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_write.S b/src/kernel/libsyscall/bsdsyscalls/bak/_write.S new file mode 100644 index 000000000..78aa551ab --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_write.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_write +#error "SYS_write not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_write, write, 3, cerror) +#else +__SYSCALL2(___write, write, 3, cerror) +#endif + +#if defined(__i386__) + .globl _write$UNIX2003 + .set _write$UNIX2003, ___write +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/_writev.S b/src/kernel/libsyscall/bsdsyscalls/bak/_writev.S new file mode 100644 index 000000000..f03a2e683 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/_writev.S @@ -0,0 +1,18 @@ +#define __SYSCALL_32BIT_ARG_BYTES 12 +#include "SYS.h" + +#ifndef SYS_writev +#error "SYS_writev not defined. The header files libsyscall is building against do not match syscalls.master." +#endif + +#if defined(__x86_64__) +__SYSCALL2(_writev, writev, 3, cerror) +#else +__SYSCALL2(___writev, writev, 3, cerror) +#endif + +#if defined(__i386__) + .globl _writev$UNIX2003 + .set _writev$UNIX2003, ___writev +#endif + diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/custom.S b/src/kernel/libsyscall/bsdsyscalls/bak/custom.S new file mode 100644 index 000000000..ff11b20f8 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/custom.S @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1999-2011 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. + */ + +#include "SYS.h" + +#if defined(__i386__) + +/* + * i386 needs custom assembly to transform the return from syscalls + * into a proper stack for a function call out to cerror{,_nocancel}. + */ + +LABEL(tramp_cerror) + mov %esp, %edx + andl $0xfffffff0, %esp + subl $16, %esp + movl %edx, 4(%esp) + movl %eax, (%esp) + CALL_EXTERN(_cerror) + movl 4(%esp), %esp + ret + +LABEL(tramp_cerror_nocancel) + mov %esp, %edx + andl $0xfffffff0, %esp + subl $16, %esp + movl %edx, 4(%esp) + movl %eax, (%esp) + CALL_EXTERN(_cerror_nocancel) + movl 4(%esp), %esp + ret + +LABEL(__sysenter_trap) + popl %edx + movl %esp, %ecx + sysenter + + .globl _i386_get_ldt + ALIGN +_i386_get_ldt: + movl $6,%eax + MACHDEP_SYSCALL_TRAP + jnb 2f + jmp tramp_cerror +2: ret + + + .globl _i386_set_ldt + ALIGN +_i386_set_ldt: + movl $5,%eax + MACHDEP_SYSCALL_TRAP + jnb 2f + jmp tramp_cerror +2: ret + +#elif defined(__x86_64__) + + .globl _i386_get_ldt + ALIGN +_i386_get_ldt: + movl $6,%eax + MACHDEP_SYSCALL_TRAP + jnb 2f + movq %rax, %rdi + jmp cerror +2: ret + + + .globl _i386_set_ldt + ALIGN +_i386_set_ldt: + movl $5,%eax + MACHDEP_SYSCALL_TRAP + jnb 2f + movq %rax, %rdi + jmp cerror +2: ret + +#endif diff --git a/src/kernel/libsyscall/bsdsyscalls/bak/stubs.list b/src/kernel/libsyscall/bsdsyscalls/bak/stubs.list new file mode 100644 index 000000000..7c7533454 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/bak/stubs.list @@ -0,0 +1,395 @@ +sys_i386/_____old_semwait_signal_nocancel.s +sys_i386/_____sigwait_nocancel.s +sys_i386/___accept.s +sys_i386/___accept_nocancel.s +sys_i386/___access_extended.s +sys_i386/___aio_suspend_nocancel.s +sys_i386/___bind.s +sys_i386/___bsdthread_create.s +sys_i386/___bsdthread_ctl.s +sys_i386/___bsdthread_register.s +sys_i386/___bsdthread_terminate.s +sys_i386/___chmod.s +sys_i386/___chmod_extended.s +sys_i386/___chud.s +sys_i386/___close_nocancel.s +sys_i386/___coalition.s +sys_i386/___coalition_info.s +sys_i386/___connect.s +sys_i386/___connect_nocancel.s +sys_i386/___copyfile.s +sys_i386/___csrctl.s +sys_i386/___delete.s +sys_i386/___disable_threadsignal.s +sys_i386/___exit.s +sys_i386/___fchmod.s +sys_i386/___fchmod_extended.s +sys_i386/___fcntl.s +sys_i386/___fcntl_nocancel.s +sys_i386/___fork.s +sys_i386/___fsgetpath.s +sys_i386/___fstat64_extended.s +sys_i386/___fstat_extended.s +sys_i386/___fsync_nocancel.s +sys_i386/___getattrlist.s +sys_i386/___getdirentries64.s +sys_i386/___gethostuuid.s +sys_i386/___getlogin.s +sys_i386/___getpeername.s +sys_i386/___getpid.s +sys_i386/___getrlimit.s +sys_i386/___getsgroups.s +sys_i386/___getsockname.s +sys_i386/___gettid.s +sys_i386/___gettimeofday.s +sys_i386/___getwgroups.s +sys_i386/___guarded_open_dprotected_np.s +sys_i386/___guarded_open_np.s +sys_i386/___identitysvc.s +sys_i386/___initgroups.s +sys_i386/___ioctl.s +sys_i386/___iopolicysys.s +sys_i386/___kdebug_trace.s +sys_i386/___kdebug_trace64.s +sys_i386/___kdebug_trace_string.s +sys_i386/___kill.s +sys_i386/___lchown.s +sys_i386/___listen.s +sys_i386/___lseek.s +sys_i386/___lstat64_extended.s +sys_i386/___lstat_extended.s +sys_i386/___mac_execve.s +sys_i386/___mac_get_fd.s +sys_i386/___mac_get_file.s +sys_i386/___mac_get_link.s +sys_i386/___mac_get_mount.s +sys_i386/___mac_get_pid.s +sys_i386/___mac_get_proc.s +sys_i386/___mac_getfsstat.s +sys_i386/___mac_mount.s +sys_i386/___mac_set_fd.s +sys_i386/___mac_set_file.s +sys_i386/___mac_set_link.s +sys_i386/___mac_set_proc.s +sys_i386/___mac_syscall.s +sys_i386/___microstackshot.s +sys_i386/___mkdir_extended.s +sys_i386/___mkfifo_extended.s +sys_i386/___mmap.s +sys_i386/___mprotect.s +sys_i386/___msgctl.s +sys_i386/___msgrcv_nocancel.s +sys_i386/___msgsnd_nocancel.s +sys_i386/___msgsys.s +sys_i386/___msync.s +sys_i386/___msync_nocancel.s +sys_i386/___munmap.s +sys_i386/___old_semwait_signal.s +sys_i386/___open.s +sys_i386/___open_dprotected_np.s +sys_i386/___open_extended.s +sys_i386/___open_nocancel.s +sys_i386/___openat.s +sys_i386/___openat_nocancel.s +sys_i386/___persona.s +sys_i386/___pipe.s +sys_i386/___poll_nocancel.s +sys_i386/___posix_spawn.s +sys_i386/___pread_nocancel.s +sys_i386/___proc_info.s +sys_i386/___process_policy.s +sys_i386/___pselect.s +sys_i386/___pselect_nocancel.s +sys_i386/___psynch_cvbroad.s +sys_i386/___psynch_cvclrprepost.s +sys_i386/___psynch_cvsignal.s +sys_i386/___psynch_cvwait.s +sys_i386/___psynch_mutexdrop.s +sys_i386/___psynch_mutexwait.s +sys_i386/___psynch_rw_downgrade.s +sys_i386/___psynch_rw_longrdlock.s +sys_i386/___psynch_rw_rdlock.s +sys_i386/___psynch_rw_unlock.s +sys_i386/___psynch_rw_unlock2.s +sys_i386/___psynch_rw_upgrade.s +sys_i386/___psynch_rw_wrlock.s +sys_i386/___psynch_rw_yieldwrlock.s +sys_i386/___pthread_canceled.s +sys_i386/___pthread_chdir.s +sys_i386/___pthread_fchdir.s +sys_i386/___pthread_kill.s +sys_i386/___pthread_markcancel.s +sys_i386/___pthread_sigmask.s +sys_i386/___ptrace.s +sys_i386/___pwrite_nocancel.s +sys_i386/___read_nocancel.s +sys_i386/___readv_nocancel.s +sys_i386/___recvfrom.s +sys_i386/___recvfrom_nocancel.s +sys_i386/___recvmsg.s +sys_i386/___recvmsg_nocancel.s +sys_i386/___rename.s +sys_i386/___rename_ext.s +sys_i386/___renameat.s +sys_i386/___rmdir.s +sys_i386/___select.s +sys_i386/___select_nocancel.s +sys_i386/___sem_open.s +sys_i386/___sem_wait_nocancel.s +sys_i386/___semctl.s +sys_i386/___semsys.s +sys_i386/___semwait_signal.s +sys_i386/___semwait_signal_nocancel.s +sys_i386/___sendmsg.s +sys_i386/___sendmsg_nocancel.s +sys_i386/___sendto.s +sys_i386/___sendto_nocancel.s +sys_i386/___setattrlist.s +sys_i386/___setlogin.s +sys_i386/___setpriority.s +sys_i386/___setregid.s +sys_i386/___setreuid.s +sys_i386/___setrlimit.s +sys_i386/___setsgroups.s +sys_i386/___settid.s +sys_i386/___settid_with_pid.s +sys_i386/___settimeofday.s +sys_i386/___setwgroups.s +sys_i386/___sfi_ctl.s +sys_i386/___sfi_pidctl.s +sys_i386/___shared_region_check_np.s +sys_i386/___shared_region_map_and_slide_np.s +sys_i386/___shm_open.s +sys_i386/___shmctl.s +sys_i386/___shmsys.s +sys_i386/___sigaction.s +sys_i386/___sigaltstack.s +sys_i386/___sigreturn.s +sys_i386/___sigsuspend.s +sys_i386/___sigsuspend_nocancel.s +sys_i386/___sigwait.s +sys_i386/___socketpair.s +sys_i386/___stack_snapshot.s +sys_i386/___stack_snapshot_with_config.s +sys_i386/___stat64_extended.s +sys_i386/___stat_extended.s +sys_i386/___syscall.s +sys_i386/___sysctl.s +sys_i386/___sysctlbyname.s +sys_i386/___telemetry.s +sys_i386/___thread_selfid.s +sys_i386/___thread_selfusage.s +sys_i386/___umask_extended.s +sys_i386/___unlink.s +sys_i386/___unlinkat.s +sys_i386/___vfork.s +sys_i386/___wait4.s +sys_i386/___wait4_nocancel.s +sys_i386/___waitid_nocancel.s +sys_i386/___work_interval_ctl.s +sys_i386/___workq_kernreturn.s +sys_i386/___workq_open.s +sys_i386/___write_nocancel.s +sys_i386/___writev_nocancel.s +sys_i386/_access.s +sys_i386/_acct.s +sys_i386/_adjtime.s +sys_i386/_aio_cancel.s +sys_i386/_aio_error.s +sys_i386/_aio_fsync.s +sys_i386/_aio_read.s +sys_i386/_aio_return.s +sys_i386/_aio_suspend.s +sys_i386/_aio_write.s +sys_i386/_audit.s +sys_i386/_audit_session_join.s +sys_i386/_audit_session_port.s +sys_i386/_audit_session_self.s +sys_i386/_auditctl.s +sys_i386/_auditon.s +sys_i386/_change_fdguard_np.s +sys_i386/_chdir.s +sys_i386/_chflags.s +sys_i386/_chown.s +sys_i386/_chroot.s +sys_i386/_close.s +sys_i386/_connectx.s +sys_i386/_csops.s +sys_i386/_csops_audittoken.s +sys_i386/_disconnectx.s +sys_i386/_dup.s +sys_i386/_dup2.s +sys_i386/_exchangedata.s +sys_i386/_execve.s +sys_i386/_faccessat.s +sys_i386/_fchdir.s +sys_i386/_fchflags.s +sys_i386/_fchmodat.s +sys_i386/_fchown.s +sys_i386/_fchownat.s +sys_i386/_fdatasync.s +sys_i386/_ffsctl.s +sys_i386/_fgetattrlist.s +sys_i386/_fgetxattr.s +sys_i386/_fhopen.s +sys_i386/_fileport_makefd.s +sys_i386/_fileport_makeport.s +sys_i386/_flistxattr.s +sys_i386/_flock.s +sys_i386/_fpathconf.s +sys_i386/_fremovexattr.s +sys_i386/_fsctl.s +sys_i386/_fsetattrlist.s +sys_i386/_fsetxattr.s +sys_i386/_fstat.s +sys_i386/_fstat64.s +sys_i386/_fstatat.s +sys_i386/_fstatat64.s +sys_i386/_fstatfs.s +sys_i386/_fstatfs64.s +sys_i386/_fsync.s +sys_i386/_ftruncate.s +sys_i386/_futimes.s +sys_i386/_getattrlistat.s +sys_i386/_getattrlistbulk.s +sys_i386/_getaudit_addr.s +sys_i386/_getauid.s +sys_i386/_getdirentries.s +sys_i386/_getdirentriesattr.s +sys_i386/_getdtablesize.s +sys_i386/_getegid.s +sys_i386/_geteuid.s +sys_i386/_getfh.s +sys_i386/_getfsstat.s +sys_i386/_getfsstat64.s +sys_i386/_getgid.s +sys_i386/_getgroups.s +sys_i386/_getitimer.s +sys_i386/_getpgid.s +sys_i386/_getpgrp.s +sys_i386/_getppid.s +sys_i386/_getpriority.s +sys_i386/_getrusage.s +sys_i386/_getsid.s +sys_i386/_getsockopt.s +sys_i386/_getuid.s +sys_i386/_getxattr.s +sys_i386/_grab_pgo_data.s +sys_i386/_guarded_close_np.s +sys_i386/_guarded_kqueue_np.s +sys_i386/_guarded_pwrite_np.s +sys_i386/_guarded_write_np.s +sys_i386/_guarded_writev_np.s +sys_i386/_issetugid.s +sys_i386/_kas_info.s +sys_i386/_kevent.s +sys_i386/_kevent64.s +sys_i386/_kevent_qos.s +sys_i386/_kqueue.s +sys_i386/_ledger.s +sys_i386/_link.s +sys_i386/_linkat.s +sys_i386/_lio_listio.s +sys_i386/_listxattr.s +sys_i386/_lstat.s +sys_i386/_lstat64.s +sys_i386/_madvise.s +sys_i386/_memorystatus_control.s +sys_i386/_memorystatus_get_level.s +sys_i386/_mincore.s +sys_i386/_minherit.s +sys_i386/_mkdir.s +sys_i386/_mkdirat.s +sys_i386/_mkfifo.s +sys_i386/_mknod.s +sys_i386/_mlock.s +sys_i386/_mlockall.s +sys_i386/_modwatch.s +sys_i386/_mount.s +sys_i386/_mremap_encrypted.s +sys_i386/_msgget.s +sys_i386/_msgrcv.s +sys_i386/_msgsnd.s +sys_i386/_munlock.s +sys_i386/_munlockall.s +sys_i386/_necp_match_policy.s +sys_i386/_netagent_trigger.s +sys_i386/_nfsclnt.s +sys_i386/_nfssvc.s +sys_i386/_openbyid_np.s +sys_i386/_pathconf.s +sys_i386/_peeloff.s +sys_i386/_pid_resume.s +sys_i386/_pid_suspend.s +sys_i386/_poll.s +sys_i386/_pread.s +sys_i386/_proc_rlimit_control.s +sys_i386/_proc_trace_log.s +sys_i386/_proc_uuid_policy.s +sys_i386/_pwrite.s +sys_i386/_quota.s +sys_i386/_quotactl.s +sys_i386/_read.s +sys_i386/_readlink.s +sys_i386/_readlinkat.s +sys_i386/_readv.s +sys_i386/_reboot.s +sys_i386/_recvmsg_x.s +sys_i386/_removexattr.s +sys_i386/_revoke.s +sys_i386/_searchfs.s +sys_i386/_sem_close.s +sys_i386/_sem_post.s +sys_i386/_sem_trywait.s +sys_i386/_sem_unlink.s +sys_i386/_sem_wait.s +sys_i386/_semget.s +sys_i386/_semop.s +sys_i386/_sendfile.s +sys_i386/_sendmsg_x.s +sys_i386/_setaudit_addr.s +sys_i386/_setauid.s +sys_i386/_setegid.s +sys_i386/_seteuid.s +sys_i386/_setgid.s +sys_i386/_setgroups.s +sys_i386/_setitimer.s +sys_i386/_setpgid.s +sys_i386/_setprivexec.s +sys_i386/_setquota.s +sys_i386/_setsid.s +sys_i386/_setsockopt.s +sys_i386/_setuid.s +sys_i386/_setxattr.s +sys_i386/_shm_unlink.s +sys_i386/_shmat.s +sys_i386/_shmdt.s +sys_i386/_shmget.s +sys_i386/_shutdown.s +sys_i386/_sigpending.s +sys_i386/_sigprocmask.s +sys_i386/_socket.s +sys_i386/_socket_delegate.s +sys_i386/_stat.s +sys_i386/_stat64.s +sys_i386/_statfs.s +sys_i386/_statfs64.s +sys_i386/_swapon.s +sys_i386/_symlink.s +sys_i386/_symlinkat.s +sys_i386/_sync.s +sys_i386/_system_override.s +sys_i386/_truncate.s +sys_i386/_umask.s +sys_i386/_undelete.s +sys_i386/_unmount.s +sys_i386/_usrctl.s +sys_i386/_utimes.s +sys_i386/_vfs_purge.s +sys_i386/_vm_pressure_monitor.s +sys_i386/_waitevent.s +sys_i386/_waitid.s +sys_i386/_watchevent.s +sys_i386/_write.s +sys_i386/_writev.s +sys_i386/custom.s diff --git a/src/kernel/libsyscall/bsdsyscalls/custom.S b/src/kernel/libsyscall/bsdsyscalls/custom.S new file mode 100644 index 000000000..56a95cf5b --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/custom.S @@ -0,0 +1,129 @@ +/* + * Copyright (c) 1999-2015 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. + */ + +#include "SYS.h" + +#if defined(__i386__) + +/* + * i386 needs custom assembly to transform the return from syscalls + * into a proper stack for a function call out to cerror{,_nocancel}. + */ + +LABEL(tramp_cerror) + mov %esp, %edx + andl $0xfffffff0, %esp + subl $16, %esp + movl %edx, 4(%esp) + movl %eax, (%esp) + CALL_EXTERN(_cerror) + movl 4(%esp), %esp + ret + +LABEL(tramp_cerror_nocancel) + mov %esp, %edx + andl $0xfffffff0, %esp + subl $16, %esp + movl %edx, 4(%esp) + movl %eax, (%esp) + CALL_EXTERN(_cerror_nocancel) + movl 4(%esp), %esp + ret + +LABEL(__sysenter_trap) + popl %edx + movl %esp, %ecx + sysenter + + .globl _i386_get_ldt + ALIGN +_i386_get_ldt: + movl $6,%eax + MACHDEP_SYSCALL_TRAP + jnb 2f + jmp tramp_cerror +2: ret + + + .globl _i386_set_ldt + ALIGN +_i386_set_ldt: + movl $5,%eax + MACHDEP_SYSCALL_TRAP + jnb 2f + jmp tramp_cerror +2: ret + + ALIGN + .globl __thread_set_tsd_base +__thread_set_tsd_base: + pushl 4(%esp) + pushl $0 + movl $3,%eax + MACHDEP_SYSCALL_TRAP + addl $8,%esp + ret + +#elif defined(__x86_64__) + + .globl _i386_get_ldt + ALIGN +_i386_get_ldt: + movl $6,%eax + MACHDEP_SYSCALL_TRAP + jnb 2f + movq %rax, %rdi + jmp _cerror +2: ret + + + .globl _i386_set_ldt + ALIGN +_i386_set_ldt: + movl $5,%eax + MACHDEP_SYSCALL_TRAP + jnb 2f + movq %rax, %rdi + jmp _cerror +2: ret + + ALIGN + .globl __thread_set_tsd_base +__thread_set_tsd_base: + movl $0, %esi // 0 as the second argument + movl $ SYSCALL_CONSTRUCT_MDEP(3), %eax // Machine-dependent syscall number 3 + MACHDEP_SYSCALL_TRAP + ret + +#else +#error unknown architecture +#endif + +.subsections_via_symbols diff --git a/src/kernel/libsyscall/bsdsyscalls/stubs.list b/src/kernel/libsyscall/bsdsyscalls/stubs.list new file mode 100644 index 000000000..57e3ef6e2 --- /dev/null +++ b/src/kernel/libsyscall/bsdsyscalls/stubs.list @@ -0,0 +1,404 @@ +bsdsyscalls/_____old_semwait_signal_nocancel.s +bsdsyscalls/_____sigwait_nocancel.s +bsdsyscalls/___abort_with_payload.s +bsdsyscalls/___accept.s +bsdsyscalls/___accept_nocancel.s +bsdsyscalls/___access_extended.s +bsdsyscalls/___aio_suspend_nocancel.s +bsdsyscalls/___bind.s +bsdsyscalls/___bsdthread_create.s +bsdsyscalls/___bsdthread_ctl.s +bsdsyscalls/___bsdthread_register.s +bsdsyscalls/___bsdthread_terminate.s +bsdsyscalls/___chmod.s +bsdsyscalls/___chmod_extended.s +bsdsyscalls/___close_nocancel.s +bsdsyscalls/___coalition.s +bsdsyscalls/___coalition_info.s +bsdsyscalls/___connect.s +bsdsyscalls/___connect_nocancel.s +bsdsyscalls/___copyfile.s +bsdsyscalls/___csrctl.s +bsdsyscalls/___delete.s +bsdsyscalls/___disable_threadsignal.s +bsdsyscalls/___exit.s +bsdsyscalls/___fchmod.s +bsdsyscalls/___fchmod_extended.s +bsdsyscalls/___fcntl.s +bsdsyscalls/___fcntl_nocancel.s +bsdsyscalls/___fork.s +bsdsyscalls/___fs_snapshot.s +bsdsyscalls/___fstat64_extended.s +bsdsyscalls/___fstat_extended.s +bsdsyscalls/___fsync_nocancel.s +bsdsyscalls/___getattrlist.s +bsdsyscalls/___getdirentries64.s +bsdsyscalls/___gethostuuid.s +bsdsyscalls/___getlogin.s +bsdsyscalls/___getpeername.s +bsdsyscalls/___getpid.s +bsdsyscalls/___getrlimit.s +bsdsyscalls/___getsgroups.s +bsdsyscalls/___getsockname.s +bsdsyscalls/___gettid.s +bsdsyscalls/___gettimeofday.s +bsdsyscalls/___getwgroups.s +bsdsyscalls/___guarded_open_dprotected_np.s +bsdsyscalls/___guarded_open_np.s +bsdsyscalls/___identitysvc.s +bsdsyscalls/___initgroups.s +bsdsyscalls/___ioctl.s +bsdsyscalls/___iopolicysys.s +bsdsyscalls/___kdebug_trace.s +bsdsyscalls/___kdebug_trace64.s +bsdsyscalls/___kdebug_trace_string.s +bsdsyscalls/___kdebug_typefilter.s +bsdsyscalls/___kill.s +bsdsyscalls/___lchown.s +bsdsyscalls/___listen.s +bsdsyscalls/___lseek.s +bsdsyscalls/___lstat64_extended.s +bsdsyscalls/___lstat_extended.s +bsdsyscalls/___mac_execve.s +bsdsyscalls/___mac_get_fd.s +bsdsyscalls/___mac_get_file.s +bsdsyscalls/___mac_get_link.s +bsdsyscalls/___mac_get_mount.s +bsdsyscalls/___mac_get_pid.s +bsdsyscalls/___mac_get_proc.s +bsdsyscalls/___mac_getfsstat.s +bsdsyscalls/___mac_mount.s +bsdsyscalls/___mac_set_fd.s +bsdsyscalls/___mac_set_file.s +bsdsyscalls/___mac_set_link.s +bsdsyscalls/___mac_set_proc.s +bsdsyscalls/___mac_syscall.s +bsdsyscalls/___microstackshot.s +bsdsyscalls/___mkdir_extended.s +bsdsyscalls/___mkfifo_extended.s +bsdsyscalls/___mmap.s +bsdsyscalls/___mprotect.s +bsdsyscalls/___msgctl.s +bsdsyscalls/___msgrcv_nocancel.s +bsdsyscalls/___msgsnd_nocancel.s +bsdsyscalls/___msgsys.s +bsdsyscalls/___msync.s +bsdsyscalls/___msync_nocancel.s +bsdsyscalls/___munmap.s +bsdsyscalls/___old_semwait_signal.s +bsdsyscalls/___open.s +bsdsyscalls/___open_dprotected_np.s +bsdsyscalls/___open_extended.s +bsdsyscalls/___open_nocancel.s +bsdsyscalls/___openat.s +bsdsyscalls/___openat_nocancel.s +bsdsyscalls/___persona.s +bsdsyscalls/___pipe.s +bsdsyscalls/___poll_nocancel.s +bsdsyscalls/___posix_spawn.s +bsdsyscalls/___pread_nocancel.s +bsdsyscalls/___proc_info.s +bsdsyscalls/___process_policy.s +bsdsyscalls/___pselect.s +bsdsyscalls/___pselect_nocancel.s +bsdsyscalls/___psynch_cvbroad.s +bsdsyscalls/___psynch_cvclrprepost.s +bsdsyscalls/___psynch_cvsignal.s +bsdsyscalls/___psynch_cvwait.s +bsdsyscalls/___psynch_mutexdrop.s +bsdsyscalls/___psynch_mutexwait.s +bsdsyscalls/___psynch_rw_downgrade.s +bsdsyscalls/___psynch_rw_longrdlock.s +bsdsyscalls/___psynch_rw_rdlock.s +bsdsyscalls/___psynch_rw_unlock.s +bsdsyscalls/___psynch_rw_unlock2.s +bsdsyscalls/___psynch_rw_upgrade.s +bsdsyscalls/___psynch_rw_wrlock.s +bsdsyscalls/___psynch_rw_yieldwrlock.s +bsdsyscalls/___pthread_canceled.s +bsdsyscalls/___pthread_chdir.s +bsdsyscalls/___pthread_fchdir.s +bsdsyscalls/___pthread_kill.s +bsdsyscalls/___pthread_markcancel.s +bsdsyscalls/___pthread_sigmask.s +bsdsyscalls/___ptrace.s +bsdsyscalls/___pwrite_nocancel.s +bsdsyscalls/___read_nocancel.s +bsdsyscalls/___readv_nocancel.s +bsdsyscalls/___recvfrom.s +bsdsyscalls/___recvfrom_nocancel.s +bsdsyscalls/___recvmsg.s +bsdsyscalls/___recvmsg_nocancel.s +bsdsyscalls/___rename.s +bsdsyscalls/___renameat.s +bsdsyscalls/___renameatx_np.s +bsdsyscalls/___rmdir.s +bsdsyscalls/___select.s +bsdsyscalls/___select_nocancel.s +bsdsyscalls/___sem_open.s +bsdsyscalls/___sem_wait_nocancel.s +bsdsyscalls/___semctl.s +bsdsyscalls/___semsys.s +bsdsyscalls/___semwait_signal.s +bsdsyscalls/___semwait_signal_nocancel.s +bsdsyscalls/___sendmsg.s +bsdsyscalls/___sendmsg_nocancel.s +bsdsyscalls/___sendto.s +bsdsyscalls/___sendto_nocancel.s +bsdsyscalls/___setattrlist.s +bsdsyscalls/___setlogin.s +bsdsyscalls/___setpriority.s +bsdsyscalls/___setregid.s +bsdsyscalls/___setreuid.s +bsdsyscalls/___setrlimit.s +bsdsyscalls/___setsgroups.s +bsdsyscalls/___settid.s +bsdsyscalls/___settid_with_pid.s +bsdsyscalls/___settimeofday.s +bsdsyscalls/___setwgroups.s +bsdsyscalls/___sfi_ctl.s +bsdsyscalls/___sfi_pidctl.s +bsdsyscalls/___shared_region_check_np.s +bsdsyscalls/___shared_region_map_and_slide_np.s +bsdsyscalls/___shm_open.s +bsdsyscalls/___shmctl.s +bsdsyscalls/___shmsys.s +bsdsyscalls/___sigaction.s +bsdsyscalls/___sigaltstack.s +bsdsyscalls/___sigreturn.s +bsdsyscalls/___sigsuspend.s +bsdsyscalls/___sigsuspend_nocancel.s +bsdsyscalls/___sigwait.s +bsdsyscalls/___socketpair.s +bsdsyscalls/___stack_snapshot_with_config.s +bsdsyscalls/___stat64_extended.s +bsdsyscalls/___stat_extended.s +bsdsyscalls/___syscall.s +bsdsyscalls/___sysctl.s +bsdsyscalls/___sysctlbyname.s +bsdsyscalls/___telemetry.s +bsdsyscalls/___terminate_with_payload.s +bsdsyscalls/___thread_selfid.s +bsdsyscalls/___thread_selfusage.s +bsdsyscalls/___ulock_wait.s +bsdsyscalls/___ulock_wake.s +bsdsyscalls/___umask_extended.s +bsdsyscalls/___unlink.s +bsdsyscalls/___unlinkat.s +bsdsyscalls/___vfork.s +bsdsyscalls/___wait4.s +bsdsyscalls/___wait4_nocancel.s +bsdsyscalls/___waitid_nocancel.s +bsdsyscalls/___work_interval_ctl.s +bsdsyscalls/___workq_kernreturn.s +bsdsyscalls/___workq_open.s +bsdsyscalls/___write_nocancel.s +bsdsyscalls/___writev_nocancel.s +bsdsyscalls/_access.s +bsdsyscalls/_acct.s +bsdsyscalls/_adjtime.s +bsdsyscalls/_aio_cancel.s +bsdsyscalls/_aio_error.s +bsdsyscalls/_aio_fsync.s +bsdsyscalls/_aio_read.s +bsdsyscalls/_aio_return.s +bsdsyscalls/_aio_suspend.s +bsdsyscalls/_aio_write.s +bsdsyscalls/_audit.s +bsdsyscalls/_audit_session_join.s +bsdsyscalls/_audit_session_port.s +bsdsyscalls/_audit_session_self.s +bsdsyscalls/_auditctl.s +bsdsyscalls/_auditon.s +bsdsyscalls/_change_fdguard_np.s +bsdsyscalls/_chdir.s +bsdsyscalls/_chflags.s +bsdsyscalls/_chown.s +bsdsyscalls/_chroot.s +bsdsyscalls/_clonefileat.s +bsdsyscalls/_close.s +bsdsyscalls/_connectx.s +bsdsyscalls/_csops.s +bsdsyscalls/_csops_audittoken.s +bsdsyscalls/_disconnectx.s +bsdsyscalls/_dup.s +bsdsyscalls/_dup2.s +bsdsyscalls/_exchangedata.s +bsdsyscalls/_execve.s +bsdsyscalls/_faccessat.s +bsdsyscalls/_fchdir.s +bsdsyscalls/_fchflags.s +bsdsyscalls/_fchmodat.s +bsdsyscalls/_fchown.s +bsdsyscalls/_fchownat.s +bsdsyscalls/_fclonefileat.s +bsdsyscalls/_fdatasync.s +bsdsyscalls/_ffsctl.s +bsdsyscalls/_fgetattrlist.s +bsdsyscalls/_fgetxattr.s +bsdsyscalls/_fhopen.s +bsdsyscalls/_fileport_makefd.s +bsdsyscalls/_fileport_makeport.s +bsdsyscalls/_flistxattr.s +bsdsyscalls/_flock.s +bsdsyscalls/_fpathconf.s +bsdsyscalls/_fremovexattr.s +bsdsyscalls/_fsctl.s +bsdsyscalls/_fsetattrlist.s +bsdsyscalls/_fsetxattr.s +bsdsyscalls/_fsgetpath.s +bsdsyscalls/_fstat.s +bsdsyscalls/_fstat64.s +bsdsyscalls/_fstatat.s +bsdsyscalls/_fstatat64.s +bsdsyscalls/_fstatfs.s +bsdsyscalls/_fstatfs64.s +bsdsyscalls/_fsync.s +bsdsyscalls/_ftruncate.s +bsdsyscalls/_futimes.s +bsdsyscalls/_getattrlistat.s +bsdsyscalls/_getattrlistbulk.s +bsdsyscalls/_getaudit_addr.s +bsdsyscalls/_getauid.s +bsdsyscalls/_getdirentries.s +bsdsyscalls/_getdirentriesattr.s +bsdsyscalls/_getdtablesize.s +bsdsyscalls/_getegid.s +bsdsyscalls/_getentropy.s +bsdsyscalls/_geteuid.s +bsdsyscalls/_getfh.s +bsdsyscalls/_getfsstat.s +bsdsyscalls/_getfsstat64.s +bsdsyscalls/_getgid.s +bsdsyscalls/_getgroups.s +bsdsyscalls/_getitimer.s +bsdsyscalls/_getpgid.s +bsdsyscalls/_getpgrp.s +bsdsyscalls/_getppid.s +bsdsyscalls/_getpriority.s +bsdsyscalls/_getrusage.s +bsdsyscalls/_getsid.s +bsdsyscalls/_getsockopt.s +bsdsyscalls/_getuid.s +bsdsyscalls/_getxattr.s +bsdsyscalls/_grab_pgo_data.s +bsdsyscalls/_guarded_close_np.s +bsdsyscalls/_guarded_kqueue_np.s +bsdsyscalls/_guarded_pwrite_np.s +bsdsyscalls/_guarded_write_np.s +bsdsyscalls/_guarded_writev_np.s +bsdsyscalls/_issetugid.s +bsdsyscalls/_kas_info.s +bsdsyscalls/_kevent.s +bsdsyscalls/_kevent64.s +bsdsyscalls/_kevent_qos.s +bsdsyscalls/_kqueue.s +bsdsyscalls/_ledger.s +bsdsyscalls/_link.s +bsdsyscalls/_linkat.s +bsdsyscalls/_lio_listio.s +bsdsyscalls/_listxattr.s +bsdsyscalls/_lstat.s +bsdsyscalls/_lstat64.s +bsdsyscalls/_madvise.s +bsdsyscalls/_memorystatus_control.s +bsdsyscalls/_memorystatus_get_level.s +bsdsyscalls/_mincore.s +bsdsyscalls/_minherit.s +bsdsyscalls/_mkdir.s +bsdsyscalls/_mkdirat.s +bsdsyscalls/_mkfifo.s +bsdsyscalls/_mknod.s +bsdsyscalls/_mlock.s +bsdsyscalls/_mlockall.s +bsdsyscalls/_modwatch.s +bsdsyscalls/_mount.s +bsdsyscalls/_mremap_encrypted.s +bsdsyscalls/_msgget.s +bsdsyscalls/_msgrcv.s +bsdsyscalls/_msgsnd.s +bsdsyscalls/_munlock.s +bsdsyscalls/_munlockall.s +bsdsyscalls/_necp_client_action.s +bsdsyscalls/_necp_match_policy.s +bsdsyscalls/_necp_open.s +bsdsyscalls/_netagent_trigger.s +bsdsyscalls/_nfsclnt.s +bsdsyscalls/_nfssvc.s +bsdsyscalls/_openbyid_np.s +bsdsyscalls/_pathconf.s +bsdsyscalls/_peeloff.s +bsdsyscalls/_pid_resume.s +bsdsyscalls/_pid_suspend.s +bsdsyscalls/_poll.s +bsdsyscalls/_pread.s +bsdsyscalls/_proc_rlimit_control.s +bsdsyscalls/_proc_trace_log.s +bsdsyscalls/_proc_uuid_policy.s +bsdsyscalls/_pwrite.s +bsdsyscalls/_quota.s +bsdsyscalls/_quotactl.s +bsdsyscalls/_read.s +bsdsyscalls/_readlink.s +bsdsyscalls/_readlinkat.s +bsdsyscalls/_readv.s +bsdsyscalls/_reboot.s +bsdsyscalls/_recvmsg_x.s +bsdsyscalls/_removexattr.s +bsdsyscalls/_revoke.s +bsdsyscalls/_searchfs.s +bsdsyscalls/_sem_close.s +bsdsyscalls/_sem_post.s +bsdsyscalls/_sem_trywait.s +bsdsyscalls/_sem_unlink.s +bsdsyscalls/_sem_wait.s +bsdsyscalls/_semget.s +bsdsyscalls/_semop.s +bsdsyscalls/_sendfile.s +bsdsyscalls/_sendmsg_x.s +bsdsyscalls/_setaudit_addr.s +bsdsyscalls/_setauid.s +bsdsyscalls/_setegid.s +bsdsyscalls/_seteuid.s +bsdsyscalls/_setgid.s +bsdsyscalls/_setgroups.s +bsdsyscalls/_setitimer.s +bsdsyscalls/_setpgid.s +bsdsyscalls/_setprivexec.s +bsdsyscalls/_setquota.s +bsdsyscalls/_setsid.s +bsdsyscalls/_setsockopt.s +bsdsyscalls/_setuid.s +bsdsyscalls/_setxattr.s +bsdsyscalls/_shm_unlink.s +bsdsyscalls/_shmat.s +bsdsyscalls/_shmdt.s +bsdsyscalls/_shmget.s +bsdsyscalls/_shutdown.s +bsdsyscalls/_sigpending.s +bsdsyscalls/_sigprocmask.s +bsdsyscalls/_socket.s +bsdsyscalls/_socket_delegate.s +bsdsyscalls/_stat.s +bsdsyscalls/_stat64.s +bsdsyscalls/_statfs.s +bsdsyscalls/_statfs64.s +bsdsyscalls/_swapon.s +bsdsyscalls/_symlink.s +bsdsyscalls/_symlinkat.s +bsdsyscalls/_sync.s +bsdsyscalls/_system_override.s +bsdsyscalls/_truncate.s +bsdsyscalls/_umask.s +bsdsyscalls/_undelete.s +bsdsyscalls/_unmount.s +bsdsyscalls/_usrctl.s +bsdsyscalls/_utimes.s +bsdsyscalls/_vfs_purge.s +bsdsyscalls/_vm_pressure_monitor.s +bsdsyscalls/_waitevent.s +bsdsyscalls/_waitid.s +bsdsyscalls/_watchevent.s +bsdsyscalls/_write.s +bsdsyscalls/_writev.s +bsdsyscalls/custom.s diff --git a/src/kernel/libsyscall/custom/SYS.h b/src/kernel/libsyscall/custom/SYS.h index 9c0cee1e2..eea226254 100644 --- a/src/kernel/libsyscall/custom/SYS.h +++ b/src/kernel/libsyscall/custom/SYS.h @@ -80,7 +80,9 @@ LEAF(_##name, 0) ;\ movl $ SYS_##name, %eax ;\ UNIX_SYSCALL_SYSENTER ;\ - jnb 2f ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ BRANCH_EXTERN(tramp_cerror) ;\ 2: @@ -89,7 +91,9 @@ LEAF(_##name, 0) ;\ LEAF(_##name, 0) ;\ movl $ SYS_##name, %eax ;\ UNIX_SYSCALL_TRAP ;\ - jnb 2f ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ BRANCH_EXTERN(tramp_cerror) ;\ 2: @@ -97,14 +101,18 @@ LEAF(_##name, 0) ;\ #define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ movl $(SYS_##name | (__SYSCALL_32BIT_ARG_BYTES << I386_SYSCALL_ARG_BYTES_SHIFT)), %eax ;\ UNIX_SYSCALL_SYSENTER ;\ - jnb 2f ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ BRANCH_EXTERN(tramp_##cerror) ;\ 2: #else /* __SYSCALL_32BIT_ARG_BYTES < 4 || > 20 */ #define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ movl $ SYS_##name, %eax ;\ UNIX_SYSCALL_SYSENTER ;\ - jnb 2f ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ BRANCH_EXTERN(tramp_##cerror) ;\ 2: #endif @@ -113,7 +121,9 @@ LEAF(_##name, 0) ;\ .globl tramp_cerror_nocancel ;\ movl $ SYS_##name, %eax ;\ UNIX_SYSCALL_TRAP ;\ - jnb 2f ;\ + cmpl $-4095, %eax ;\ + jb 2f ;\ + negl %eax ;\ BRANCH_EXTERN(tramp_cerror_nocancel) ;\ 2: @@ -148,9 +158,11 @@ LEAF(pseudo, 0) ;\ .globl cerror ;\ LEAF(_#name, 0) ;\ movl $ SYS_##name, %eax ;\ - call __darling_bsd_syscall ;\ - jnb 2f ;\ + call __darling_bsd_syscall ;\ + cmpq $-4095, %rax ;\ + jb 2f ;\ movq %rax, %rdi ;\ + negq %rdi ;\ BRANCH_EXTERN(_cerror) ;\ 2: @@ -158,8 +170,10 @@ LEAF(_#name, 0) ;\ .globl cerror ;\ movl $ SYS_##name, %eax ;\ call __darling_bsd_syscall ;\ - jnb 2f ;\ + cmpq $-4095, %rax ;\ + jb 2f ;\ movq %rax, %rdi ;\ + negq %rdi ;\ BRANCH_EXTERN(_##cerror) ;\ 2: diff --git a/src/kernel/libsyscall/custom/__fork.s b/src/kernel/libsyscall/custom/__fork.s index 40c852859..acce242db 100644 --- a/src/kernel/libsyscall/custom/__fork.s +++ b/src/kernel/libsyscall/custom/__fork.s @@ -83,10 +83,16 @@ L2: LEAF(___fork, 0) subq $24, %rsp // Align the stack, plus room for local storage +#ifndef DARLING movl $ SYSCALL_CONSTRUCT_UNIX(SYS_fork),%eax; // code for fork -> rax UNIX_SYSCALL_TRAP // do the system call jnc L1 // jump if CF==0 - +#else + movl $ SYS_fork, %eax + call __darling_bsd_syscall + cmpq $0, %rax + jnb L1 +#endif movq %rax, %rdi CALL_EXTERN(_cerror) movq $-1, %rax @@ -94,9 +100,14 @@ LEAF(___fork, 0) ret L1: +#ifndef DARLING orl %edx,%edx // CF=OF=0, ZF set if zero result jz L2 // parent, since r1 == 0 in parent, 1 in child - +#else + testl %eax, %eax + jnz L2 +#endif + //child here... xorq %rax, %rax PICIFY(__current_pid) diff --git a/src/kernel/libsyscall/custom/__getpid.s b/src/kernel/libsyscall/custom/__getpid.s index b195cacd8..78de0824c 100644 --- a/src/kernel/libsyscall/custom/__getpid.s +++ b/src/kernel/libsyscall/custom/__getpid.s @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 1999-2007 Apple Inc. All rights reserved. * @@ -29,15 +28,11 @@ #include "SYS.h" -#ifdef DARLING -# define ___getpid __getpid -#endif - #if defined(__i386__) .data .globl __current_pid - .hidden __current_pid + .private_extern __current_pid L__current_pid_addr: __current_pid: .long 0 @@ -80,7 +75,7 @@ LEAF(___getpid, 0) .data .globl __current_pid - .hidden __current_pid + .private_extern __current_pid __current_pid: .long 0 diff --git a/src/kernel/libsyscall/custom/__kdebug_trace_string.s b/src/kernel/libsyscall/custom/__kdebug_trace_string.s new file mode 100644 index 000000000..e3543e6bf --- /dev/null +++ b/src/kernel/libsyscall/custom/__kdebug_trace_string.s @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#include "SYS.h" + +#if defined(__x86_64__) + +__SYSCALL(___kdebug_trace_string, kdebug_trace_string, 3) + +#elif defined(__i386__) + +__SYSCALL_INT(___kdebug_trace_string, kdebug_trace_string, 3) + +#else +#error Unsupported architecture +#endif diff --git a/src/kernel/libsyscall/custom/__ptrace.s b/src/kernel/libsyscall/custom/__ptrace.s index 36a2fcf28..bdcbec9fb 100644 --- a/src/kernel/libsyscall/custom/__ptrace.s +++ b/src/kernel/libsyscall/custom/__ptrace.s @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 1999-2007 Apple Inc. All rights reserved. * @@ -30,11 +29,6 @@ #include "SYS.h" -#ifdef DARLING -# define ___ptrace __ptrace -# define _errno errno -#endif - #if defined(__i386__) .globl _errno diff --git a/src/kernel/libsyscall/custom/__vfork.s b/src/kernel/libsyscall/custom/__vfork.s index 4b1d6ab02..f23e2dade 100644 --- a/src/kernel/libsyscall/custom/__vfork.s +++ b/src/kernel/libsyscall/custom/__vfork.s @@ -111,11 +111,18 @@ LEAF(___vfork, 0) lock cmpxchgl %ecx, (%rdx) jne 0b - popq %rdi // return address in %rdi + //popq %rdi // return address in %rdi +#ifndef DARLING movq $ SYSCALL_CONSTRUCT_UNIX(SYS_vfork), %rax // code for vfork -> rax UNIX_SYSCALL_TRAP // do the system call jnb L1 // jump if CF==0 pushq %rdi // put return address back on stack for cerror +#else + movl $ SYS_vfork, %eax + call __darling_bsd_syscall + cmpq $0, %rax + jnb L1 +#endif movq __current_pid@GOTPCREL(%rip), %rcx lock addq $1, (%rcx) @@ -123,8 +130,13 @@ LEAF(___vfork, 0) BRANCH_EXTERN(_cerror) L1: +#ifndef DARLING testl %edx, %edx // CF=OF=0, ZF set if zero result jz L2 // parent, since r1 == 0 in parent, 1 in child +#else + testl %eax, %eax + jnz L2 +#endif xorq %rax, %rax // zero rax jmp *%rdi @@ -132,8 +144,19 @@ L2: movq __current_pid@GOTPCREL(%rip), %rdx lock addq $1, (%rdx) - jmp *%rdi + //jmp *%rdi + ret #else #error Unsupported architecture #endif +#if defined(__i386__) + .globl _vfork + .set _vfork, ___vfork +#endif + +#if defined(__x86_64__) + .globl _vfork + .set _vfork, ___vfork +#endif + diff --git a/src/kernel/libsyscall/custom/custom.s b/src/kernel/libsyscall/custom/custom.s index c47e89953..56a95cf5b 100644 --- a/src/kernel/libsyscall/custom/custom.s +++ b/src/kernel/libsyscall/custom/custom.s @@ -1,6 +1,5 @@ -// Modified by Lubos Dolezel for Darling /* - * Copyright (c) 1999-2011 Apple Inc. All rights reserved. + * Copyright (c) 1999-2015 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -44,7 +43,7 @@ LABEL(tramp_cerror) subl $16, %esp movl %edx, 4(%esp) movl %eax, (%esp) - CALL_EXTERN(cerror) + CALL_EXTERN(_cerror) movl 4(%esp), %esp ret @@ -54,7 +53,7 @@ LABEL(tramp_cerror_nocancel) subl $16, %esp movl %edx, 4(%esp) movl %eax, (%esp) - CALL_EXTERN(cerror_nocancel) + CALL_EXTERN(_cerror_nocancel) movl 4(%esp), %esp ret @@ -82,6 +81,16 @@ _i386_set_ldt: jmp tramp_cerror 2: ret + ALIGN + .globl __thread_set_tsd_base +__thread_set_tsd_base: + pushl 4(%esp) + pushl $0 + movl $3,%eax + MACHDEP_SYSCALL_TRAP + addl $8,%esp + ret + #elif defined(__x86_64__) .globl _i386_get_ldt @@ -91,7 +100,7 @@ _i386_get_ldt: MACHDEP_SYSCALL_TRAP jnb 2f movq %rax, %rdi - jmp cerror + jmp _cerror 2: ret @@ -102,7 +111,19 @@ _i386_set_ldt: MACHDEP_SYSCALL_TRAP jnb 2f movq %rax, %rdi - jmp cerror + jmp _cerror 2: ret + ALIGN + .globl __thread_set_tsd_base +__thread_set_tsd_base: + movl $0, %esi // 0 as the second argument + movl $ SYSCALL_CONSTRUCT_MDEP(3), %eax // Machine-dependent syscall number 3 + MACHDEP_SYSCALL_TRAP + ret + +#else +#error unknown architecture #endif + +.subsections_via_symbols diff --git a/src/kernel/libsyscall/sys_i386/SYS.h b/src/kernel/libsyscall/sys_i386/SYS.h deleted file mode 100644 index 6c064a50a..000000000 --- a/src/kernel/libsyscall/sys_i386/SYS.h +++ /dev/null @@ -1,221 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2011 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: SYS.h - * - * Definition of the user side of the UNIX system call interface - * for M98K. - * - * Errors are flagged by the location of the trap return (ie., which - * instruction is executed upon rfi): - * - * SC PC + 4: Error (typically branch to cerror()) - * SC PC + 8: Success - * - * HISTORY - * 18-Nov-92 Ben Fathi (benf@next.com) - * Ported to m98k. - * - * 9-Jan-92 Peter King (king@next.com) - * Created. - */ - -#include - -/* Binary compatibility stubs for syscalls that no longer exist */ - -#ifndef SYS_setquota -#define SYS_setquota 148 -#endif -#ifndef SYS_quota -#define SYS_quota 149 -#endif - -#if defined(__i386__) - -#include -#include - -/* - * We have two entry points. int's is used for syscalls which need to preserve - * %ecx across the call, or return a 64-bit value in %eax:%edx. sysenter is used - * for the majority of syscalls which just return a value in %eax. - */ - -#ifndef DARLING -#define UNIX_SYSCALL_SYSENTER call __sysenter_trap -#else -#define UNIX_SYSCALL_SYSENTER call __darling_bsd_syscall -#endif - -#define UNIX_SYSCALL(name, nargs) \ - .globl tramp_cerror ;\ -LEAF(_##name, 0) ;\ - movl $ SYS_##name, %eax ;\ - UNIX_SYSCALL_SYSENTER ;\ - cmpl $-4095, %eax ;\ - jb 3f ;\ - negl %eax ;\ - BRANCH_EXTERN(tramp_cerror) ;\ -3: - -#define UNIX_SYSCALL_INT(name, nargs) \ - .globl tramp_cerror ;\ -LEAF(_##name, 0) ;\ - movl $ SYS_##name, %eax ;\ - UNIX_SYSCALL_TRAP ;\ - cmpl $-4095, %eax ;\ - jb 3f ;\ - negl %eax ;\ - BRANCH_EXTERN(tramp_cerror) ;\ -3: - -#if defined(__SYSCALL_32BIT_ARG_BYTES) && ((__SYSCALL_32BIT_ARG_BYTES >= 4) && (__SYSCALL_32BIT_ARG_BYTES <= 20)) -#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ - movl $(SYS_##name | (__SYSCALL_32BIT_ARG_BYTES << I386_SYSCALL_ARG_BYTES_SHIFT)), %eax ;\ - UNIX_SYSCALL_SYSENTER ;\ - cmpl $-4095, %eax ;\ - jb 3f ;\ - negl %eax ;\ - BRANCH_EXTERN(tramp_##cerror) ;\ -3: -#else /* __SYSCALL_32BIT_ARG_BYTES < 4 || > 20 */ -#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ - movl $ SYS_##name, %eax ;\ - UNIX_SYSCALL_SYSENTER ;\ - cmpl $-4095, %eax ;\ - jb 3f ;\ - negl %eax ;\ - BRANCH_EXTERN(tramp_##cerror) ;\ -3: -#endif - -#define UNIX_SYSCALL_INT_NONAME(name, nargs) \ - .globl tramp_cerror_nocancel ;\ - movl $ SYS_##name, %eax ;\ - UNIX_SYSCALL_TRAP ;\ - cmpl $-4095, %eax ;\ - jb 3f ;\ - negl %eax ;\ - BRANCH_EXTERN(tramp_cerror_nocancel) ;\ -3: - -#define PSEUDO(pseudo, name, nargs, cerror) \ -LEAF(pseudo, 0) ;\ - UNIX_SYSCALL_NONAME(name, nargs, cerror) - -#define PSEUDO_INT(pseudo, name, nargs) \ -LEAF(pseudo, 0) ;\ - UNIX_SYSCALL_INT_NONAME(name, nargs) - -#define __SYSCALL2(pseudo, name, nargs, cerror) \ - PSEUDO(pseudo, name, nargs, cerror) ;\ - ret - -#define __SYSCALL(pseudo, name, nargs) \ - PSEUDO(pseudo, name, nargs, cerror) ;\ - ret - -#define __SYSCALL_INT(pseudo, name, nargs) \ - PSEUDO_INT(pseudo, name, nargs) ;\ - ret - -#elif defined(__x86_64__) - -#include -#include - -#ifdef DARLING - -#define UNIX_SYSCALL(name, nargs) \ - .globl cerror ;\ -LEAF(name, 0) ;\ - movl $ SYS_##name, %eax ;\ - call __darling_bsd_syscall ;\ - cmpl $-4095, %eax ;\ - jb 3f ;\ - movq %rax, %rdi ;\ - BRANCH_EXTERN(cerror) ;\ -3: - -#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ - .globl cerror ;\ - movl $ SYS_##name, %eax ;\ - call __darling_bsd_syscall ;\ - cmpl $-4095, %eax ;\ - jb 3f ;\ - movq %rax, %rdi ;\ - BRANCH_EXTERN(cerror) ;\ -3: - - -#else - -#define UNIX_SYSCALL_SYSCALL \ - movq %rcx, %r10 ;\ - syscall - -#define UNIX_SYSCALL(name, nargs) \ - .globl cerror ;\ -LEAF(_##name, 0) ;\ - movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ - UNIX_SYSCALL_SYSCALL ;\ - jnb 2f ;\ - movq %rax, %rdi ;\ - BRANCH_EXTERN(_cerror) ;\ -2: - -#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ - .globl cerror ;\ - movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ - UNIX_SYSCALL_SYSCALL ;\ - jnb 2f ;\ - movq %rax, %rdi ;\ - BRANCH_EXTERN(_##cerror) ;\ -2: - -#endif // DARLING - -#define PSEUDO(pseudo, name, nargs, cerror) \ -LEAF(pseudo, 0) ;\ - UNIX_SYSCALL_NONAME(name, nargs, cerror) - -#define __SYSCALL2(pseudo, name, nargs, cerror) \ - PSEUDO(pseudo, name, nargs, cerror) ;\ - ret - -#define __SYSCALL(pseudo, name, nargs) \ - PSEUDO(pseudo, name, nargs, cerror) ;\ - ret - -#else -#error Unsupported architecture -#endif - diff --git a/src/kernel/libsyscall/sys_i386/____old_semwait_signal_nocancel.S b/src/kernel/libsyscall/sys_i386/____old_semwait_signal_nocancel.S deleted file mode 100644 index 1d86925ad..000000000 --- a/src/kernel/libsyscall/sys_i386/____old_semwait_signal_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS___old_semwait_signal_nocancel -#error "SYS___old_semwait_signal_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(____old_semwait_signal_nocancel, __old_semwait_signal_nocancel, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/____sigwait_nocancel.S b/src/kernel/libsyscall/sys_i386/____sigwait_nocancel.S deleted file mode 100644 index 1ed184414..000000000 --- a/src/kernel/libsyscall/sys_i386/____sigwait_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___sigwait_nocancel -#error "SYS___sigwait_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(____sigwait_nocancel, __sigwait_nocancel, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__accept.S b/src/kernel/libsyscall/sys_i386/__accept.S deleted file mode 100644 index dee2ba21d..000000000 --- a/src/kernel/libsyscall/sys_i386/__accept.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_accept -#error "SYS_accept not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__accept, accept, 3, cerror) -#endif - -#if defined(__i386__) - .globl accept$UNIX2003 - accept$UNIX2003 = __accept -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__accept_nocancel.S b/src/kernel/libsyscall/sys_i386/__accept_nocancel.S deleted file mode 100644 index eeae2d07a..000000000 --- a/src/kernel/libsyscall/sys_i386/__accept_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_accept_nocancel -#error "SYS_accept_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__accept_nocancel, accept_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl accept$NOCANCEL$UNIX2003 - accept$NOCANCEL$UNIX2003 = __accept_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__access_extended.S b/src/kernel/libsyscall/sys_i386/__access_extended.S deleted file mode 100644 index 0fcdb7f37..000000000 --- a/src/kernel/libsyscall/sys_i386/__access_extended.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_access_extended -#error "SYS_access_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__access_extended, access_extended, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl accessx_np - accessx_np = __access_extended -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__aio_suspend_nocancel.S b/src/kernel/libsyscall/sys_i386/__aio_suspend_nocancel.S deleted file mode 100644 index 5a9c145d7..000000000 --- a/src/kernel/libsyscall/sys_i386/__aio_suspend_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_aio_suspend_nocancel -#error "SYS_aio_suspend_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__aio_suspend_nocancel, aio_suspend_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl aio_suspend - aio_suspend = __aio_suspend_nocancel - .globl aio_suspend$NOCANCEL$UNIX2003 - aio_suspend$NOCANCEL$UNIX2003 = __aio_suspend_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__bind.S b/src/kernel/libsyscall/sys_i386/__bind.S deleted file mode 100644 index 19be337bc..000000000 --- a/src/kernel/libsyscall/sys_i386/__bind.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_bind -#error "SYS_bind not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__bind, bind, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl bind$UNIX2003 - bind$UNIX2003 = __bind -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__bsdthread_create.S b/src/kernel/libsyscall/sys_i386/__bsdthread_create.S deleted file mode 100644 index 96eba7baa..000000000 --- a/src/kernel/libsyscall/sys_i386/__bsdthread_create.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_bsdthread_create -#error "SYS_bsdthread_create not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__bsdthread_create, bsdthread_create, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__bsdthread_ctl.S b/src/kernel/libsyscall/sys_i386/__bsdthread_ctl.S deleted file mode 100644 index 538488b7b..000000000 --- a/src/kernel/libsyscall/sys_i386/__bsdthread_ctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_bsdthread_ctl -#error "SYS_bsdthread_ctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__bsdthread_ctl, bsdthread_ctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__bsdthread_register.S b/src/kernel/libsyscall/sys_i386/__bsdthread_register.S deleted file mode 100644 index 7fd24949f..000000000 --- a/src/kernel/libsyscall/sys_i386/__bsdthread_register.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_bsdthread_register -#error "SYS_bsdthread_register not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__bsdthread_register, bsdthread_register, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__bsdthread_terminate.S b/src/kernel/libsyscall/sys_i386/__bsdthread_terminate.S deleted file mode 100644 index adc2d4978..000000000 --- a/src/kernel/libsyscall/sys_i386/__bsdthread_terminate.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_bsdthread_terminate -#error "SYS_bsdthread_terminate not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__bsdthread_terminate, bsdthread_terminate, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__chmod.S b/src/kernel/libsyscall/sys_i386/__chmod.S deleted file mode 100644 index d414873bf..000000000 --- a/src/kernel/libsyscall/sys_i386/__chmod.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_chmod -#error "SYS_chmod not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__chmod, chmod, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl chmod - chmod = __chmod -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__chmod_extended.S b/src/kernel/libsyscall/sys_i386/__chmod_extended.S deleted file mode 100644 index c87776c01..000000000 --- a/src/kernel/libsyscall/sys_i386/__chmod_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_chmod_extended -#error "SYS_chmod_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__chmod_extended, chmod_extended, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__chud.S b/src/kernel/libsyscall/sys_i386/__chud.S deleted file mode 100644 index 34307e254..000000000 --- a/src/kernel/libsyscall/sys_i386/__chud.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 48 -#include "SYS.h" - -#ifndef SYS_chud -#error "SYS_chud not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__chud, chud, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__close_nocancel.S b/src/kernel/libsyscall/sys_i386/__close_nocancel.S deleted file mode 100644 index 13fddcba7..000000000 --- a/src/kernel/libsyscall/sys_i386/__close_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_close_nocancel -#error "SYS_close_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__close_nocancel, close_nocancel, 1, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl close - close = __close_nocancel - .globl close$NOCANCEL$UNIX2003 - close$NOCANCEL$UNIX2003 = __close_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__coalition.S b/src/kernel/libsyscall/sys_i386/__coalition.S deleted file mode 100644 index 31f2f16d3..000000000 --- a/src/kernel/libsyscall/sys_i386/__coalition.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_coalition -#error "SYS_coalition not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__coalition, coalition, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__coalition_info.S b/src/kernel/libsyscall/sys_i386/__coalition_info.S deleted file mode 100644 index fb3aa00df..000000000 --- a/src/kernel/libsyscall/sys_i386/__coalition_info.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_coalition_info -#error "SYS_coalition_info not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__coalition_info, coalition_info, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__connect.S b/src/kernel/libsyscall/sys_i386/__connect.S deleted file mode 100644 index 881e56037..000000000 --- a/src/kernel/libsyscall/sys_i386/__connect.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_connect -#error "SYS_connect not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__connect, connect, 3, cerror) -#endif - -#if defined(__i386__) - .globl connect$UNIX2003 - connect$UNIX2003 = __connect -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__connect_nocancel.S b/src/kernel/libsyscall/sys_i386/__connect_nocancel.S deleted file mode 100644 index 8733dc3c6..000000000 --- a/src/kernel/libsyscall/sys_i386/__connect_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_connect_nocancel -#error "SYS_connect_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__connect_nocancel, connect_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl connect$NOCANCEL$UNIX2003 - connect$NOCANCEL$UNIX2003 = __connect_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__copyfile.S b/src/kernel/libsyscall/sys_i386/__copyfile.S deleted file mode 100644 index 0a8430e7f..000000000 --- a/src/kernel/libsyscall/sys_i386/__copyfile.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_copyfile -#error "SYS_copyfile not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__copyfile, copyfile, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__csrctl.S b/src/kernel/libsyscall/sys_i386/__csrctl.S deleted file mode 100644 index 3b89a9a00..000000000 --- a/src/kernel/libsyscall/sys_i386/__csrctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_csrctl -#error "SYS_csrctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__csrctl, csrctl, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__delete.S b/src/kernel/libsyscall/sys_i386/__delete.S deleted file mode 100644 index 6a76423f0..000000000 --- a/src/kernel/libsyscall/sys_i386/__delete.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_delete -#error "SYS_delete not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__delete, delete, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__disable_threadsignal.S b/src/kernel/libsyscall/sys_i386/__disable_threadsignal.S deleted file mode 100644 index c8450df8e..000000000 --- a/src/kernel/libsyscall/sys_i386/__disable_threadsignal.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___disable_threadsignal -#error "SYS___disable_threadsignal not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__disable_threadsignal, __disable_threadsignal, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__exit.S b/src/kernel/libsyscall/sys_i386/__exit.S deleted file mode 100644 index a96332dfa..000000000 --- a/src/kernel/libsyscall/sys_i386/__exit.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_exit -#error "SYS_exit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__exit, exit, 1, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl _exit - _exit = __exit -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__fchmod.S b/src/kernel/libsyscall/sys_i386/__fchmod.S deleted file mode 100644 index fac17e418..000000000 --- a/src/kernel/libsyscall/sys_i386/__fchmod.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fchmod -#error "SYS_fchmod not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__fchmod, fchmod, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl fchmod - fchmod = __fchmod -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__fchmod_extended.S b/src/kernel/libsyscall/sys_i386/__fchmod_extended.S deleted file mode 100644 index 82a429d2d..000000000 --- a/src/kernel/libsyscall/sys_i386/__fchmod_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fchmod_extended -#error "SYS_fchmod_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__fchmod_extended, fchmod_extended, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__fcntl.S b/src/kernel/libsyscall/sys_i386/__fcntl.S deleted file mode 100644 index 0477f7b06..000000000 --- a/src/kernel/libsyscall/sys_i386/__fcntl.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_fcntl -#error "SYS_fcntl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__fcntl, fcntl, 3, cerror) -#endif - -#if defined(__i386__) - .globl fcntl$UNIX2003 - fcntl$UNIX2003 = __fcntl -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__fcntl_nocancel.S b/src/kernel/libsyscall/sys_i386/__fcntl_nocancel.S deleted file mode 100644 index 05c9df07d..000000000 --- a/src/kernel/libsyscall/sys_i386/__fcntl_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_fcntl_nocancel -#error "SYS_fcntl_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__fcntl_nocancel, fcntl_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl fcntl - fcntl = __fcntl_nocancel - .globl fcntl$NOCANCEL$UNIX2003 - fcntl$NOCANCEL$UNIX2003 = __fcntl_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__fork.S b/src/kernel/libsyscall/sys_i386/__fork.S deleted file mode 100644 index 40c852859..000000000 --- a/src/kernel/libsyscall/sys_i386/__fork.S +++ /dev/null @@ -1,111 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2010 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: libc/ppc/sys/fork.s - * - * HISTORY - * 18-Nov-92 Ben Fathi (benf@next.com) - * Created from M88K sources - * - * 11-Jan-92 Peter King (king@next.com) - * Created from M68K sources - */ - -/* - * All of the asm stubs in this file have been adjusted so the pre/post - * fork handlers and dyld fixup are done in C inside Libc. As such, Libc - * expects the __fork asm to fix up the return code to be -1, 0 or pid - * and errno if needed. - */ - -#include "SYS.h" - -#ifdef DARLING -# define ___fork __fork -# define _cerror cerror -#endif - -#if defined(__i386__) - -LEAF(___fork, 0) - subl $28, %esp // Align the stack, with 16 bytes of extra padding that we'll need - - movl $ SYS_fork,%eax; // code for fork -> eax - UNIX_SYSCALL_TRAP // do the system call - jnc L1 // jump if CF==0 - - CALL_EXTERN(tramp_cerror) - movl $-1,%eax - addl $28, %esp // restore the stack - ret - -L1: - orl %edx,%edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - - //child here... - xorl %eax,%eax // zero eax - REG_TO_EXTERN(%eax, __current_pid); -L2: - addl $28, %esp // restore the stack - // parent ends up here skipping child portion - ret - -#elif defined(__x86_64__) - -LEAF(___fork, 0) - subq $24, %rsp // Align the stack, plus room for local storage - - movl $ SYSCALL_CONSTRUCT_UNIX(SYS_fork),%eax; // code for fork -> rax - UNIX_SYSCALL_TRAP // do the system call - jnc L1 // jump if CF==0 - - movq %rax, %rdi - CALL_EXTERN(_cerror) - movq $-1, %rax - addq $24, %rsp // restore the stack - ret - -L1: - orl %edx,%edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - - //child here... - xorq %rax, %rax - PICIFY(__current_pid) - movl %eax,(%r11) -L2: - // parent ends up here skipping child portion - addq $24, %rsp // restore the stack - ret - -#else -#error Unsupported architecture -#endif diff --git a/src/kernel/libsyscall/sys_i386/__fsgetpath.S b/src/kernel/libsyscall/sys_i386/__fsgetpath.S deleted file mode 100644 index c58ef0861..000000000 --- a/src/kernel/libsyscall/sys_i386/__fsgetpath.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fsgetpath -#error "SYS_fsgetpath not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__fsgetpath, fsgetpath, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__fstat64_extended.S b/src/kernel/libsyscall/sys_i386/__fstat64_extended.S deleted file mode 100644 index 3417dfdd6..000000000 --- a/src/kernel/libsyscall/sys_i386/__fstat64_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fstat64_extended -#error "SYS_fstat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__fstat64_extended, fstat64_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__fstat_extended.S b/src/kernel/libsyscall/sys_i386/__fstat_extended.S deleted file mode 100644 index ee6df4811..000000000 --- a/src/kernel/libsyscall/sys_i386/__fstat_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fstat_extended -#error "SYS_fstat_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__fstat_extended, fstat_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__fsync_nocancel.S b/src/kernel/libsyscall/sys_i386/__fsync_nocancel.S deleted file mode 100644 index e9dd93679..000000000 --- a/src/kernel/libsyscall/sys_i386/__fsync_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fsync_nocancel -#error "SYS_fsync_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__fsync_nocancel, fsync_nocancel, 1, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl fsync - fsync = __fsync_nocancel - .globl fsync$NOCANCEL$UNIX2003 - fsync$NOCANCEL$UNIX2003 = __fsync_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getattrlist.S b/src/kernel/libsyscall/sys_i386/__getattrlist.S deleted file mode 100644 index e8fdef01f..000000000 --- a/src/kernel/libsyscall/sys_i386/__getattrlist.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_getattrlist -#error "SYS_getattrlist not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__getattrlist, getattrlist, 5, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl getattrlist$UNIX2003 - getattrlist$UNIX2003 = __getattrlist -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getdirentries64.S b/src/kernel/libsyscall/sys_i386/__getdirentries64.S deleted file mode 100644 index 631482d1d..000000000 --- a/src/kernel/libsyscall/sys_i386/__getdirentries64.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_getdirentries64 -#error "SYS_getdirentries64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__getdirentries64, getdirentries64, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__gethostuuid.S b/src/kernel/libsyscall/sys_i386/__gethostuuid.S deleted file mode 100644 index a4fb2e025..000000000 --- a/src/kernel/libsyscall/sys_i386/__gethostuuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_gethostuuid -#error "SYS_gethostuuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__gethostuuid, gethostuuid, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getlcid.S b/src/kernel/libsyscall/sys_i386/__getlcid.S deleted file mode 100644 index b8619a6a7..000000000 --- a/src/kernel/libsyscall/sys_i386/__getlcid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_getlcid -#error "SYS_getlcid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__getlcid, getlcid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getlogin.S b/src/kernel/libsyscall/sys_i386/__getlogin.S deleted file mode 100644 index 308cdfa9f..000000000 --- a/src/kernel/libsyscall/sys_i386/__getlogin.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getlogin -#error "SYS_getlogin not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__getlogin, getlogin, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getpeername.S b/src/kernel/libsyscall/sys_i386/__getpeername.S deleted file mode 100644 index dfd06d0e9..000000000 --- a/src/kernel/libsyscall/sys_i386/__getpeername.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_getpeername -#error "SYS_getpeername not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__getpeername, getpeername, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl getpeername$UNIX2003 - getpeername$UNIX2003 = __getpeername -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getpid.S b/src/kernel/libsyscall/sys_i386/__getpid.S deleted file mode 100644 index 908f8eef2..000000000 --- a/src/kernel/libsyscall/sys_i386/__getpid.S +++ /dev/null @@ -1,114 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include "SYS.h" - -#ifdef DARLING -# define ___getpid __getpid -#endif - -#if defined(__i386__) - - .data - .globl __current_pid - .hidden __current_pid -L__current_pid_addr: - __current_pid: - .long 0 - -#if defined(__DYNAMIC__) -#define GET_CURRENT_PID \ - call 0f ; \ -0: ; \ - popl %ecx ; \ - leal L__current_pid_addr-0b(%ecx), %ecx - -#define __current_pid (%ecx) - -#else -#define GET_CURRENT_PID -#endif - -/* - * If __current_pid is > 0, return it, else make syscall. - * If __current_pid is 0, cache result of syscall. - */ -TEXT -LEAF(___getpid, 0) - GET_CURRENT_PID - movl __current_pid, %eax - testl %eax, %eax - jle 1f - ret -1: - UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) - movl %eax, %edx - xorl %eax, %eax - GET_CURRENT_PID - lock - cmpxchgl %edx, __current_pid - movl %edx, %eax - ret - -#elif defined(__x86_64__) - - .data - .globl __current_pid - .hidden __current_pid -__current_pid: - .long 0 - -/* - * If __current_pid is > 0, return it, else make syscall. - * If __current_pid is 0, cache result of syscall. - */ -TEXT -LEAF(___getpid, 0) - movl __current_pid(%rip), %eax - testl %eax, %eax - jle 1f - ret -1: - UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) - movl %eax, %edx - xorl %eax, %eax - leaq __current_pid(%rip), %rcx - lock - cmpxchgl %edx, (%rcx) - movl %edx, %eax - ret - -#else -#error Unsupported architecture -#endif -#if defined(__i386__) - .globl getpid - getpid = __getpid -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getrlimit.S b/src/kernel/libsyscall/sys_i386/__getrlimit.S deleted file mode 100644 index 90393fe51..000000000 --- a/src/kernel/libsyscall/sys_i386/__getrlimit.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getrlimit -#error "SYS_getrlimit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__getrlimit, getrlimit, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl getrlimit - getrlimit = __getrlimit -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getsgroups.S b/src/kernel/libsyscall/sys_i386/__getsgroups.S deleted file mode 100644 index af3fdb6f9..000000000 --- a/src/kernel/libsyscall/sys_i386/__getsgroups.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getsgroups -#error "SYS_getsgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__getsgroups, getsgroups, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl getsgroups_np - getsgroups_np = __getsgroups -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getsockname.S b/src/kernel/libsyscall/sys_i386/__getsockname.S deleted file mode 100644 index 74e135e7f..000000000 --- a/src/kernel/libsyscall/sys_i386/__getsockname.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_getsockname -#error "SYS_getsockname not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__getsockname, getsockname, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl getsockname$UNIX2003 - getsockname$UNIX2003 = __getsockname -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__gettid.S b/src/kernel/libsyscall/sys_i386/__gettid.S deleted file mode 100644 index 07aa53448..000000000 --- a/src/kernel/libsyscall/sys_i386/__gettid.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_gettid -#error "SYS_gettid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__gettid, gettid, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl pthread_getugid_np - pthread_getugid_np = __gettid -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__getwgroups.S b/src/kernel/libsyscall/sys_i386/__getwgroups.S deleted file mode 100644 index 05faf4342..000000000 --- a/src/kernel/libsyscall/sys_i386/__getwgroups.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getwgroups -#error "SYS_getwgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__getwgroups, getwgroups, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl getwgroups_np - getwgroups_np = __getwgroups -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__guarded_open_dprotected_np.S b/src/kernel/libsyscall/sys_i386/__guarded_open_dprotected_np.S deleted file mode 100644 index a93da76c2..000000000 --- a/src/kernel/libsyscall/sys_i386/__guarded_open_dprotected_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_guarded_open_dprotected_np -#error "SYS_guarded_open_dprotected_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__guarded_open_dprotected_np, guarded_open_dprotected_np, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__guarded_open_np.S b/src/kernel/libsyscall/sys_i386/__guarded_open_np.S deleted file mode 100644 index a1b1b439d..000000000 --- a/src/kernel/libsyscall/sys_i386/__guarded_open_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_guarded_open_np -#error "SYS_guarded_open_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__guarded_open_np, guarded_open_np, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__identitysvc.S b/src/kernel/libsyscall/sys_i386/__identitysvc.S deleted file mode 100644 index 8046d4f16..000000000 --- a/src/kernel/libsyscall/sys_i386/__identitysvc.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_identitysvc -#error "SYS_identitysvc not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__identitysvc, identitysvc, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__initgroups.S b/src/kernel/libsyscall/sys_i386/__initgroups.S deleted file mode 100644 index 379ac1a6c..000000000 --- a/src/kernel/libsyscall/sys_i386/__initgroups.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_initgroups -#error "SYS_initgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__initgroups, initgroups, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__ioctl.S b/src/kernel/libsyscall/sys_i386/__ioctl.S deleted file mode 100644 index ba4c45c9d..000000000 --- a/src/kernel/libsyscall/sys_i386/__ioctl.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_ioctl -#error "SYS_ioctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__ioctl, ioctl, 3, cerror) -#endif - -#define ioctl __real_ioctl - -#if defined(__i386__) - .globl ioctl - ioctl = __ioctl -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__iopolicysys.S b/src/kernel/libsyscall/sys_i386/__iopolicysys.S deleted file mode 100644 index 50b9e66fc..000000000 --- a/src/kernel/libsyscall/sys_i386/__iopolicysys.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_iopolicysys -#error "SYS_iopolicysys not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__iopolicysys, iopolicysys, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__kdebug_trace.S b/src/kernel/libsyscall/sys_i386/__kdebug_trace.S deleted file mode 100644 index 39325609f..000000000 --- a/src/kernel/libsyscall/sys_i386/__kdebug_trace.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_kdebug_trace -#error "SYS_kdebug_trace not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__kdebug_trace, kdebug_trace, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__kill.S b/src/kernel/libsyscall/sys_i386/__kill.S deleted file mode 100644 index af11db7cc..000000000 --- a/src/kernel/libsyscall/sys_i386/__kill.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_kill -#error "SYS_kill not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__kill, kill, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__lchown.S b/src/kernel/libsyscall/sys_i386/__lchown.S deleted file mode 100644 index 18aa8687c..000000000 --- a/src/kernel/libsyscall/sys_i386/__lchown.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_lchown -#error "SYS_lchown not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__lchown, lchown, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl lchown$UNIX2003 - lchown$UNIX2003 = __lchown -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__listen.S b/src/kernel/libsyscall/sys_i386/__listen.S deleted file mode 100644 index 4d4a7e95f..000000000 --- a/src/kernel/libsyscall/sys_i386/__listen.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_listen -#error "SYS_listen not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__listen, listen, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl listen$UNIX2003 - listen$UNIX2003 = __listen -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__lseek.S b/src/kernel/libsyscall/sys_i386/__lseek.S deleted file mode 100644 index b46b6ebf6..000000000 --- a/src/kernel/libsyscall/sys_i386/__lseek.S +++ /dev/null @@ -1,51 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include "SYS.h" - -#ifdef DARLING -# define ___lseek __lseek -#endif - -#if defined(__x86_64__) - -__SYSCALL(___lseek, lseek, 3) - -#elif defined(__i386__) - -__SYSCALL_INT(___lseek, lseek, 3) - -#else -#error Unsupported architecture -#endif -#if defined(__i386__) - .globl lseek - lseek = __lseek -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__lstat64_extended.S b/src/kernel/libsyscall/sys_i386/__lstat64_extended.S deleted file mode 100644 index 4ac85c3de..000000000 --- a/src/kernel/libsyscall/sys_i386/__lstat64_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_lstat64_extended -#error "SYS_lstat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__lstat64_extended, lstat64_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__lstat_extended.S b/src/kernel/libsyscall/sys_i386/__lstat_extended.S deleted file mode 100644 index bac6674f1..000000000 --- a/src/kernel/libsyscall/sys_i386/__lstat_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_lstat_extended -#error "SYS_lstat_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__lstat_extended, lstat_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_execve.S b/src/kernel/libsyscall/sys_i386/__mac_execve.S deleted file mode 100644 index 596cafb18..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_execve.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS___mac_execve -#error "SYS___mac_execve not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_execve, __mac_execve, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl __sandbox_me - __sandbox_me = __mac_execve -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_get_fd.S b/src/kernel/libsyscall/sys_i386/__mac_get_fd.S deleted file mode 100644 index b5703af42..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_get_fd.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_fd -#error "SYS___mac_get_fd not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_get_fd, __mac_get_fd, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_get_file.S b/src/kernel/libsyscall/sys_i386/__mac_get_file.S deleted file mode 100644 index 55facd0c7..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_get_file.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_file -#error "SYS___mac_get_file not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_get_file, __mac_get_file, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_get_lcid.S b/src/kernel/libsyscall/sys_i386/__mac_get_lcid.S deleted file mode 100644 index 3882cd52f..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_get_lcid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_lcid -#error "SYS___mac_get_lcid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_get_lcid, __mac_get_lcid, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_get_lctx.S b/src/kernel/libsyscall/sys_i386/__mac_get_lctx.S deleted file mode 100644 index d94d149e8..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_get_lctx.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___mac_get_lctx -#error "SYS___mac_get_lctx not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_get_lctx, __mac_get_lctx, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_get_link.S b/src/kernel/libsyscall/sys_i386/__mac_get_link.S deleted file mode 100644 index 79b0d83ab..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_get_link.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_link -#error "SYS___mac_get_link not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_get_link, __mac_get_link, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_get_mount.S b/src/kernel/libsyscall/sys_i386/__mac_get_mount.S deleted file mode 100644 index 5d4c079df..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_get_mount.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_mount -#error "SYS___mac_get_mount not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_get_mount, __mac_get_mount, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_get_pid.S b/src/kernel/libsyscall/sys_i386/__mac_get_pid.S deleted file mode 100644 index 1bf8e5b55..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_get_pid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_pid -#error "SYS___mac_get_pid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_get_pid, __mac_get_pid, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_get_proc.S b/src/kernel/libsyscall/sys_i386/__mac_get_proc.S deleted file mode 100644 index f0fe121ba..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_get_proc.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___mac_get_proc -#error "SYS___mac_get_proc not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_get_proc, __mac_get_proc, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_getfsstat.S b/src/kernel/libsyscall/sys_i386/__mac_getfsstat.S deleted file mode 100644 index 2d2679c2c..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_getfsstat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS___mac_getfsstat -#error "SYS___mac_getfsstat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_getfsstat, __mac_getfsstat, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_mount.S b/src/kernel/libsyscall/sys_i386/__mac_mount.S deleted file mode 100644 index 8b4a4e0f4..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_mount.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS___mac_mount -#error "SYS___mac_mount not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_mount, __mac_mount, 5, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl __sandbox_mm - __sandbox_mm = __mac_mount -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_set_fd.S b/src/kernel/libsyscall/sys_i386/__mac_set_fd.S deleted file mode 100644 index 546426afe..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_set_fd.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_set_fd -#error "SYS___mac_set_fd not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_set_fd, __mac_set_fd, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_set_file.S b/src/kernel/libsyscall/sys_i386/__mac_set_file.S deleted file mode 100644 index bdce16449..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_set_file.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_set_file -#error "SYS___mac_set_file not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_set_file, __mac_set_file, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_set_lctx.S b/src/kernel/libsyscall/sys_i386/__mac_set_lctx.S deleted file mode 100644 index 922fb58bf..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_set_lctx.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___mac_set_lctx -#error "SYS___mac_set_lctx not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_set_lctx, __mac_set_lctx, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_set_link.S b/src/kernel/libsyscall/sys_i386/__mac_set_link.S deleted file mode 100644 index 6217d3db8..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_set_link.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_set_link -#error "SYS___mac_set_link not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_set_link, __mac_set_link, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_set_proc.S b/src/kernel/libsyscall/sys_i386/__mac_set_proc.S deleted file mode 100644 index bf94fdca5..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_set_proc.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___mac_set_proc -#error "SYS___mac_set_proc not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_set_proc, __mac_set_proc, 1, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl __sandbox_msp - __sandbox_msp = __mac_set_proc -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mac_syscall.S b/src/kernel/libsyscall/sys_i386/__mac_syscall.S deleted file mode 100644 index 82f55a64d..000000000 --- a/src/kernel/libsyscall/sys_i386/__mac_syscall.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS___mac_syscall -#error "SYS___mac_syscall not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mac_syscall, __mac_syscall, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl __sandbox_ms - __sandbox_ms = __mac_syscall -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mkdir_extended.S b/src/kernel/libsyscall/sys_i386/__mkdir_extended.S deleted file mode 100644 index f642c1829..000000000 --- a/src/kernel/libsyscall/sys_i386/__mkdir_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_mkdir_extended -#error "SYS_mkdir_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mkdir_extended, mkdir_extended, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mkfifo_extended.S b/src/kernel/libsyscall/sys_i386/__mkfifo_extended.S deleted file mode 100644 index 654b692f9..000000000 --- a/src/kernel/libsyscall/sys_i386/__mkfifo_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_mkfifo_extended -#error "SYS_mkfifo_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mkfifo_extended, mkfifo_extended, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mmap.S b/src/kernel/libsyscall/sys_i386/__mmap.S deleted file mode 100644 index 030398ae2..000000000 --- a/src/kernel/libsyscall/sys_i386/__mmap.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_mmap -#error "SYS_mmap not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mmap, mmap, 6, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl mmap - mmap = __mmap -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__mprotect.S b/src/kernel/libsyscall/sys_i386/__mprotect.S deleted file mode 100644 index b11701607..000000000 --- a/src/kernel/libsyscall/sys_i386/__mprotect.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_mprotect -#error "SYS_mprotect not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__mprotect, mprotect, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl mprotect$UNIX2003 - mprotect$UNIX2003 = __mprotect -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__msgctl.S b/src/kernel/libsyscall/sys_i386/__msgctl.S deleted file mode 100644 index 7a49e3473..000000000 --- a/src/kernel/libsyscall/sys_i386/__msgctl.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_msgctl -#error "SYS_msgctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__msgctl, msgctl, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl msgctl$UNIX2003 - msgctl$UNIX2003 = __msgctl -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__msgrcv_nocancel.S b/src/kernel/libsyscall/sys_i386/__msgrcv_nocancel.S deleted file mode 100644 index f4dae55e6..000000000 --- a/src/kernel/libsyscall/sys_i386/__msgrcv_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_msgrcv_nocancel -#error "SYS_msgrcv_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__msgrcv_nocancel, msgrcv_nocancel, 5, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl msgrcv - msgrcv = __msgrcv_nocancel - .globl msgrcv$NOCANCEL$UNIX2003 - msgrcv$NOCANCEL$UNIX2003 = __msgrcv_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__msgsnd_nocancel.S b/src/kernel/libsyscall/sys_i386/__msgsnd_nocancel.S deleted file mode 100644 index f7faa59ff..000000000 --- a/src/kernel/libsyscall/sys_i386/__msgsnd_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_msgsnd_nocancel -#error "SYS_msgsnd_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__msgsnd_nocancel, msgsnd_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl msgsnd - msgsnd = __msgsnd_nocancel - .globl msgsnd$NOCANCEL$UNIX2003 - msgsnd$NOCANCEL$UNIX2003 = __msgsnd_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__msgsys.S b/src/kernel/libsyscall/sys_i386/__msgsys.S deleted file mode 100644 index 82cd097c4..000000000 --- a/src/kernel/libsyscall/sys_i386/__msgsys.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_msgsys -#error "SYS_msgsys not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__msgsys, msgsys, 5, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl msgsys - msgsys = __msgsys -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__msync.S b/src/kernel/libsyscall/sys_i386/__msync.S deleted file mode 100644 index 66e70060d..000000000 --- a/src/kernel/libsyscall/sys_i386/__msync.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_msync -#error "SYS_msync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__msync, msync, 3, cerror) -#endif - -#if defined(__i386__) - .globl msync$UNIX2003 - msync$UNIX2003 = __msync -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__msync_nocancel.S b/src/kernel/libsyscall/sys_i386/__msync_nocancel.S deleted file mode 100644 index eebeef3bb..000000000 --- a/src/kernel/libsyscall/sys_i386/__msync_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_msync_nocancel -#error "SYS_msync_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__msync_nocancel, msync_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl msync$NOCANCEL$UNIX2003 - msync$NOCANCEL$UNIX2003 = __msync_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__munmap.S b/src/kernel/libsyscall/sys_i386/__munmap.S deleted file mode 100644 index 85299f075..000000000 --- a/src/kernel/libsyscall/sys_i386/__munmap.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_munmap -#error "SYS_munmap not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__munmap, munmap, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__old_semwait_signal.S b/src/kernel/libsyscall/sys_i386/__old_semwait_signal.S deleted file mode 100644 index efe041c5f..000000000 --- a/src/kernel/libsyscall/sys_i386/__old_semwait_signal.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS___old_semwait_signal -#error "SYS___old_semwait_signal not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__old_semwait_signal, __old_semwait_signal, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__open.S b/src/kernel/libsyscall/sys_i386/__open.S deleted file mode 100644 index d8da44a6a..000000000 --- a/src/kernel/libsyscall/sys_i386/__open.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_open -#error "SYS_open not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__open, open, 3, cerror) -#endif - -#if defined(__i386__) - .globl open$UNIX2003 - open$UNIX2003 = __open -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__open_dprotected_np.S b/src/kernel/libsyscall/sys_i386/__open_dprotected_np.S deleted file mode 100644 index 3102411bb..000000000 --- a/src/kernel/libsyscall/sys_i386/__open_dprotected_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_open_dprotected_np -#error "SYS_open_dprotected_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__open_dprotected_np, open_dprotected_np, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__open_extended.S b/src/kernel/libsyscall/sys_i386/__open_extended.S deleted file mode 100644 index 473c92183..000000000 --- a/src/kernel/libsyscall/sys_i386/__open_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_open_extended -#error "SYS_open_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__open_extended, open_extended, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__open_nocancel.S b/src/kernel/libsyscall/sys_i386/__open_nocancel.S deleted file mode 100644 index 289d2111c..000000000 --- a/src/kernel/libsyscall/sys_i386/__open_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_open_nocancel -#error "SYS_open_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__open_nocancel, open_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl open$NOCANCEL$UNIX2003 - open$NOCANCEL$UNIX2003 = __open_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__openat.S b/src/kernel/libsyscall/sys_i386/__openat.S deleted file mode 100644 index 37ca9787f..000000000 --- a/src/kernel/libsyscall/sys_i386/__openat.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_openat -#error "SYS_openat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__openat, openat, 4, cerror) -#endif - -#if defined(__i386__) - .globl openat - openat = __openat -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__openat_nocancel.S b/src/kernel/libsyscall/sys_i386/__openat_nocancel.S deleted file mode 100644 index db9b65d81..000000000 --- a/src/kernel/libsyscall/sys_i386/__openat_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_openat_nocancel -#error "SYS_openat_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__openat_nocancel, openat_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl openat$NOCANCEL - openat$NOCANCEL = __openat_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__pipe.S b/src/kernel/libsyscall/sys_i386/__pipe.S deleted file mode 100644 index f1c43db21..000000000 --- a/src/kernel/libsyscall/sys_i386/__pipe.S +++ /dev/null @@ -1,52 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ - -#include "SYS.h" - -#ifdef DARLING -# define ___pipe __pipe -#endif - -#if defined(__i386__) - -__SYSCALL2(___pipe, pipe, 1, cerror) - -#elif defined(__x86_64__) - -__SYSCALL2(___pipe, pipe, 1, cerror) - -#else -#error Unsupported architecture -#endif -#if defined(__x86_64__) - .globl pipe - pipe = __pipe -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__poll_nocancel.S b/src/kernel/libsyscall/sys_i386/__poll_nocancel.S deleted file mode 100644 index 233652c61..000000000 --- a/src/kernel/libsyscall/sys_i386/__poll_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_poll_nocancel -#error "SYS_poll_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__poll_nocancel, poll_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl poll - poll = __poll_nocancel - .globl poll$NOCANCEL$UNIX2003 - poll$NOCANCEL$UNIX2003 = __poll_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__posix_spawn.S b/src/kernel/libsyscall/sys_i386/__posix_spawn.S deleted file mode 100644 index 8b5392785..000000000 --- a/src/kernel/libsyscall/sys_i386/__posix_spawn.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_posix_spawn -#error "SYS_posix_spawn not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__posix_spawn, posix_spawn, 5, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__pread_nocancel.S b/src/kernel/libsyscall/sys_i386/__pread_nocancel.S deleted file mode 100644 index fca7cb0d4..000000000 --- a/src/kernel/libsyscall/sys_i386/__pread_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_pread_nocancel -#error "SYS_pread_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pread_nocancel, pread_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl pread - pread = __pread_nocancel - .globl pread$NOCANCEL$UNIX2003 - pread$NOCANCEL$UNIX2003 = __pread_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__proc_info.S b/src/kernel/libsyscall/sys_i386/__proc_info.S deleted file mode 100644 index 53bb484be..000000000 --- a/src/kernel/libsyscall/sys_i386/__proc_info.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_proc_info -#error "SYS_proc_info not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__proc_info, proc_info, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__process_policy.S b/src/kernel/libsyscall/sys_i386/__process_policy.S deleted file mode 100644 index 039441e24..000000000 --- a/src/kernel/libsyscall/sys_i386/__process_policy.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 32 -#include "SYS.h" - -#ifndef SYS_process_policy -#error "SYS_process_policy not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__process_policy, process_policy, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_cvbroad.S b/src/kernel/libsyscall/sys_i386/__psynch_cvbroad.S deleted file mode 100644 index b0b590be3..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_cvbroad.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 44 -#include "SYS.h" - -#ifndef SYS_psynch_cvbroad -#error "SYS_psynch_cvbroad not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_cvbroad, psynch_cvbroad, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_cvclrprepost.S b/src/kernel/libsyscall/sys_i386/__psynch_cvclrprepost.S deleted file mode 100644 index 64495ca68..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_cvclrprepost.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_psynch_cvclrprepost -#error "SYS_psynch_cvclrprepost not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_cvclrprepost, psynch_cvclrprepost, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_cvsignal.S b/src/kernel/libsyscall/sys_i386/__psynch_cvsignal.S deleted file mode 100644 index f608c0107..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_cvsignal.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 44 -#include "SYS.h" - -#ifndef SYS_psynch_cvsignal -#error "SYS_psynch_cvsignal not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_cvsignal, psynch_cvsignal, 8, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_cvwait.S b/src/kernel/libsyscall/sys_i386/__psynch_cvwait.S deleted file mode 100644 index 72e4477a1..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_cvwait.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 44 -#include "SYS.h" - -#ifndef SYS_psynch_cvwait -#error "SYS_psynch_cvwait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_cvwait, psynch_cvwait, 8, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_mutexdrop.S b/src/kernel/libsyscall/sys_i386/__psynch_mutexdrop.S deleted file mode 100644 index 09a829ed1..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_mutexdrop.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_psynch_mutexdrop -#error "SYS_psynch_mutexdrop not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_mutexdrop, psynch_mutexdrop, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_mutexwait.S b/src/kernel/libsyscall/sys_i386/__psynch_mutexwait.S deleted file mode 100644 index c3cfded51..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_mutexwait.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_psynch_mutexwait -#error "SYS_psynch_mutexwait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_mutexwait, psynch_mutexwait, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_rw_downgrade.S b/src/kernel/libsyscall/sys_i386/__psynch_rw_downgrade.S deleted file mode 100644 index 8675abbf3..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_rw_downgrade.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_downgrade -#error "SYS_psynch_rw_downgrade not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_rw_downgrade, psynch_rw_downgrade, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_rw_longrdlock.S b/src/kernel/libsyscall/sys_i386/__psynch_rw_longrdlock.S deleted file mode 100644 index 787f0c330..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_rw_longrdlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_longrdlock -#error "SYS_psynch_rw_longrdlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_rw_longrdlock, psynch_rw_longrdlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_rw_rdlock.S b/src/kernel/libsyscall/sys_i386/__psynch_rw_rdlock.S deleted file mode 100644 index 6da93f811..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_rw_rdlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_rdlock -#error "SYS_psynch_rw_rdlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_rw_rdlock, psynch_rw_rdlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_rw_unlock.S b/src/kernel/libsyscall/sys_i386/__psynch_rw_unlock.S deleted file mode 100644 index 9784036d5..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_rw_unlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_unlock -#error "SYS_psynch_rw_unlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_rw_unlock, psynch_rw_unlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_rw_unlock2.S b/src/kernel/libsyscall/sys_i386/__psynch_rw_unlock2.S deleted file mode 100644 index 8db103a2c..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_rw_unlock2.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_unlock2 -#error "SYS_psynch_rw_unlock2 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_rw_unlock2, psynch_rw_unlock2, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_rw_upgrade.S b/src/kernel/libsyscall/sys_i386/__psynch_rw_upgrade.S deleted file mode 100644 index afc64cf23..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_rw_upgrade.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_upgrade -#error "SYS_psynch_rw_upgrade not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_rw_upgrade, psynch_rw_upgrade, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_rw_wrlock.S b/src/kernel/libsyscall/sys_i386/__psynch_rw_wrlock.S deleted file mode 100644 index ce308b669..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_rw_wrlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_wrlock -#error "SYS_psynch_rw_wrlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_rw_wrlock, psynch_rw_wrlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__psynch_rw_yieldwrlock.S b/src/kernel/libsyscall/sys_i386/__psynch_rw_yieldwrlock.S deleted file mode 100644 index 15125599e..000000000 --- a/src/kernel/libsyscall/sys_i386/__psynch_rw_yieldwrlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_yieldwrlock -#error "SYS_psynch_rw_yieldwrlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__psynch_rw_yieldwrlock, psynch_rw_yieldwrlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__pthread_canceled.S b/src/kernel/libsyscall/sys_i386/__pthread_canceled.S deleted file mode 100644 index ba2fd0f93..000000000 --- a/src/kernel/libsyscall/sys_i386/__pthread_canceled.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___pthread_canceled -#error "SYS___pthread_canceled not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pthread_canceled, __pthread_canceled, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__pthread_chdir.S b/src/kernel/libsyscall/sys_i386/__pthread_chdir.S deleted file mode 100644 index f8f1d471f..000000000 --- a/src/kernel/libsyscall/sys_i386/__pthread_chdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___pthread_chdir -#error "SYS___pthread_chdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pthread_chdir, __pthread_chdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__pthread_fchdir.S b/src/kernel/libsyscall/sys_i386/__pthread_fchdir.S deleted file mode 100644 index c0f8162f1..000000000 --- a/src/kernel/libsyscall/sys_i386/__pthread_fchdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___pthread_fchdir -#error "SYS___pthread_fchdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pthread_fchdir, __pthread_fchdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__pthread_kill.S b/src/kernel/libsyscall/sys_i386/__pthread_kill.S deleted file mode 100644 index a7db63957..000000000 --- a/src/kernel/libsyscall/sys_i386/__pthread_kill.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___pthread_kill -#error "SYS___pthread_kill not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pthread_kill, __pthread_kill, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__pthread_markcancel.S b/src/kernel/libsyscall/sys_i386/__pthread_markcancel.S deleted file mode 100644 index 940d2f5ad..000000000 --- a/src/kernel/libsyscall/sys_i386/__pthread_markcancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___pthread_markcancel -#error "SYS___pthread_markcancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pthread_markcancel, __pthread_markcancel, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__pthread_sigmask.S b/src/kernel/libsyscall/sys_i386/__pthread_sigmask.S deleted file mode 100644 index c89af8ba7..000000000 --- a/src/kernel/libsyscall/sys_i386/__pthread_sigmask.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS___pthread_sigmask -#error "SYS___pthread_sigmask not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pthread_sigmask, __pthread_sigmask, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__ptrace.S b/src/kernel/libsyscall/sys_i386/__ptrace.S deleted file mode 100644 index dcbe5d640..000000000 --- a/src/kernel/libsyscall/sys_i386/__ptrace.S +++ /dev/null @@ -1,66 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ - -#include "SYS.h" - -#ifdef DARLING -# define ___ptrace __ptrace -# define _errno darwin_errno -#endif - -#if defined(__i386__) - - .globl _errno - -LEAF(___ptrace, 0) - xorl %eax,%eax - REG_TO_EXTERN(%eax,_errno) - UNIX_SYSCALL_NONAME(ptrace, 4, cerror) - ret - -#elif defined(__x86_64__) - - .globl _errno - -LEAF(___ptrace, 0) - xorq %rax,%rax - PICIFY(_errno) - movl %eax,(%r11) - UNIX_SYSCALL_NONAME(ptrace, 4, cerror) - ret - -#else -#error Unsupported architecture -#endif -#if defined(__i386__) - .globl ptrace - ptrace = __ptrace -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__pwrite_nocancel.S b/src/kernel/libsyscall/sys_i386/__pwrite_nocancel.S deleted file mode 100644 index 9718b1b93..000000000 --- a/src/kernel/libsyscall/sys_i386/__pwrite_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_pwrite_nocancel -#error "SYS_pwrite_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pwrite_nocancel, pwrite_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl pwrite - pwrite = __pwrite_nocancel - .globl pwrite$NOCANCEL$UNIX2003 - pwrite$NOCANCEL$UNIX2003 = __pwrite_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__read_nocancel.S b/src/kernel/libsyscall/sys_i386/__read_nocancel.S deleted file mode 100644 index 048524300..000000000 --- a/src/kernel/libsyscall/sys_i386/__read_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_read_nocancel -#error "SYS_read_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__read_nocancel, read_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl read - read = __read_nocancel - .globl read$NOCANCEL$UNIX2003 - read$NOCANCEL$UNIX2003 = __read_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__readv_nocancel.S b/src/kernel/libsyscall/sys_i386/__readv_nocancel.S deleted file mode 100644 index 50d57691d..000000000 --- a/src/kernel/libsyscall/sys_i386/__readv_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_readv_nocancel -#error "SYS_readv_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__readv_nocancel, readv_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl readv - readv = __readv_nocancel - .globl readv$NOCANCEL$UNIX2003 - readv$NOCANCEL$UNIX2003 = __readv_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__recvfrom.S b/src/kernel/libsyscall/sys_i386/__recvfrom.S deleted file mode 100644 index b16393679..000000000 --- a/src/kernel/libsyscall/sys_i386/__recvfrom.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_recvfrom -#error "SYS_recvfrom not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__recvfrom, recvfrom, 6, cerror) -#endif - -#if defined(__i386__) - .globl recvfrom$UNIX2003 - recvfrom$UNIX2003 = __recvfrom -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__recvfrom_nocancel.S b/src/kernel/libsyscall/sys_i386/__recvfrom_nocancel.S deleted file mode 100644 index fce9721fa..000000000 --- a/src/kernel/libsyscall/sys_i386/__recvfrom_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_recvfrom_nocancel -#error "SYS_recvfrom_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__recvfrom_nocancel, recvfrom_nocancel, 6, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl recvfrom$NOCANCEL$UNIX2003 - recvfrom$NOCANCEL$UNIX2003 = __recvfrom_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__recvmsg.S b/src/kernel/libsyscall/sys_i386/__recvmsg.S deleted file mode 100644 index efb088d53..000000000 --- a/src/kernel/libsyscall/sys_i386/__recvmsg.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_recvmsg -#error "SYS_recvmsg not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__recvmsg, recvmsg, 3, cerror) -#endif - -#if defined(__i386__) - .globl recvmsg$UNIX2003 - recvmsg$UNIX2003 = __recvmsg -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__recvmsg_nocancel.S b/src/kernel/libsyscall/sys_i386/__recvmsg_nocancel.S deleted file mode 100644 index a156d55a9..000000000 --- a/src/kernel/libsyscall/sys_i386/__recvmsg_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_recvmsg_nocancel -#error "SYS_recvmsg_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__recvmsg_nocancel, recvmsg_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl recvmsg$NOCANCEL$UNIX2003 - recvmsg$NOCANCEL$UNIX2003 = __recvmsg_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__rename.S b/src/kernel/libsyscall/sys_i386/__rename.S deleted file mode 100644 index ec8c2133c..000000000 --- a/src/kernel/libsyscall/sys_i386/__rename.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_rename -#error "SYS_rename not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__rename, rename, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__rename_ext.S b/src/kernel/libsyscall/sys_i386/__rename_ext.S deleted file mode 100644 index 01e1a3e62..000000000 --- a/src/kernel/libsyscall/sys_i386/__rename_ext.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_rename_ext -#error "SYS_rename_ext not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__rename_ext, rename_ext, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__renameat.S b/src/kernel/libsyscall/sys_i386/__renameat.S deleted file mode 100644 index 2f44eb3bc..000000000 --- a/src/kernel/libsyscall/sys_i386/__renameat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_renameat -#error "SYS_renameat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__renameat, renameat, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__rmdir.S b/src/kernel/libsyscall/sys_i386/__rmdir.S deleted file mode 100644 index d2da68b13..000000000 --- a/src/kernel/libsyscall/sys_i386/__rmdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_rmdir -#error "SYS_rmdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__rmdir, rmdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__select.S b/src/kernel/libsyscall/sys_i386/__select.S deleted file mode 100644 index 856aec901..000000000 --- a/src/kernel/libsyscall/sys_i386/__select.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_select -#error "SYS_select not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__select, select, 5, cerror) -#endif - -#if defined(__i386__) - .globl select$DARWIN_EXTSN - select$DARWIN_EXTSN = __select -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__select_nocancel.S b/src/kernel/libsyscall/sys_i386/__select_nocancel.S deleted file mode 100644 index 702124ada..000000000 --- a/src/kernel/libsyscall/sys_i386/__select_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_select_nocancel -#error "SYS_select_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__select_nocancel, select_nocancel, 5, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl select$DARWIN_EXTSN$NOCANCEL - select$DARWIN_EXTSN$NOCANCEL = __select_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sem_open.S b/src/kernel/libsyscall/sys_i386/__sem_open.S deleted file mode 100644 index d181f5412..000000000 --- a/src/kernel/libsyscall/sys_i386/__sem_open.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_sem_open -#error "SYS_sem_open not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sem_open, sem_open, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl sem_open - sem_open = __sem_open -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sem_wait_nocancel.S b/src/kernel/libsyscall/sys_i386/__sem_wait_nocancel.S deleted file mode 100644 index b44c231df..000000000 --- a/src/kernel/libsyscall/sys_i386/__sem_wait_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_wait_nocancel -#error "SYS_sem_wait_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sem_wait_nocancel, sem_wait_nocancel, 1, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl sem_wait - sem_wait = __sem_wait_nocancel - .globl sem_wait$NOCANCEL$UNIX2003 - sem_wait$NOCANCEL$UNIX2003 = __sem_wait_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__semctl.S b/src/kernel/libsyscall/sys_i386/__semctl.S deleted file mode 100644 index d5bf2ad4b..000000000 --- a/src/kernel/libsyscall/sys_i386/__semctl.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_semctl -#error "SYS_semctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__semctl, semctl, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl semctl$UNIX2003 - semctl$UNIX2003 = __semctl -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__semsys.S b/src/kernel/libsyscall/sys_i386/__semsys.S deleted file mode 100644 index 68e0f951e..000000000 --- a/src/kernel/libsyscall/sys_i386/__semsys.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_semsys -#error "SYS_semsys not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__semsys, semsys, 5, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl semsys - semsys = __semsys -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__semwait_signal.S b/src/kernel/libsyscall/sys_i386/__semwait_signal.S deleted file mode 100644 index 514211454..000000000 --- a/src/kernel/libsyscall/sys_i386/__semwait_signal.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS___semwait_signal -#error "SYS___semwait_signal not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__semwait_signal, __semwait_signal, 6, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__semwait_signal_nocancel.S b/src/kernel/libsyscall/sys_i386/__semwait_signal_nocancel.S deleted file mode 100644 index 51e251c7f..000000000 --- a/src/kernel/libsyscall/sys_i386/__semwait_signal_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS___semwait_signal_nocancel -#error "SYS___semwait_signal_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__semwait_signal_nocancel, __semwait_signal_nocancel, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sendmsg.S b/src/kernel/libsyscall/sys_i386/__sendmsg.S deleted file mode 100644 index f301dbfe0..000000000 --- a/src/kernel/libsyscall/sys_i386/__sendmsg.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_sendmsg -#error "SYS_sendmsg not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sendmsg, sendmsg, 3, cerror) -#endif - -#if defined(__i386__) - .globl sendmsg$UNIX2003 - sendmsg$UNIX2003 = __sendmsg -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sendmsg_nocancel.S b/src/kernel/libsyscall/sys_i386/__sendmsg_nocancel.S deleted file mode 100644 index 010a2b489..000000000 --- a/src/kernel/libsyscall/sys_i386/__sendmsg_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_sendmsg_nocancel -#error "SYS_sendmsg_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sendmsg_nocancel, sendmsg_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl sendmsg$NOCANCEL$UNIX2003 - sendmsg$NOCANCEL$UNIX2003 = __sendmsg_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sendto.S b/src/kernel/libsyscall/sys_i386/__sendto.S deleted file mode 100644 index a53c01f0f..000000000 --- a/src/kernel/libsyscall/sys_i386/__sendto.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_sendto -#error "SYS_sendto not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sendto, sendto, 6, cerror) -#endif - -#if defined(__i386__) - .globl sendto$UNIX2003 - sendto$UNIX2003 = __sendto -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sendto_nocancel.S b/src/kernel/libsyscall/sys_i386/__sendto_nocancel.S deleted file mode 100644 index 6c9ea25b5..000000000 --- a/src/kernel/libsyscall/sys_i386/__sendto_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_sendto_nocancel -#error "SYS_sendto_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sendto_nocancel, sendto_nocancel, 6, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl sendto$NOCANCEL$UNIX2003 - sendto$NOCANCEL$UNIX2003 = __sendto_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__setattrlist.S b/src/kernel/libsyscall/sys_i386/__setattrlist.S deleted file mode 100644 index 648eb4f43..000000000 --- a/src/kernel/libsyscall/sys_i386/__setattrlist.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_setattrlist -#error "SYS_setattrlist not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__setattrlist, setattrlist, 5, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl setattrlist$UNIX2003 - setattrlist$UNIX2003 = __setattrlist -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__setlcid.S b/src/kernel/libsyscall/sys_i386/__setlcid.S deleted file mode 100644 index 5d79a01e3..000000000 --- a/src/kernel/libsyscall/sys_i386/__setlcid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setlcid -#error "SYS_setlcid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__setlcid, setlcid, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__setlogin.S b/src/kernel/libsyscall/sys_i386/__setlogin.S deleted file mode 100644 index 107d30a8e..000000000 --- a/src/kernel/libsyscall/sys_i386/__setlogin.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setlogin -#error "SYS_setlogin not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__setlogin, setlogin, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__setpriority.S b/src/kernel/libsyscall/sys_i386/__setpriority.S deleted file mode 100644 index aee548566..000000000 --- a/src/kernel/libsyscall/sys_i386/__setpriority.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_setpriority -#error "SYS_setpriority not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__setpriority, setpriority, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__setregid.S b/src/kernel/libsyscall/sys_i386/__setregid.S deleted file mode 100644 index 6729c8fd9..000000000 --- a/src/kernel/libsyscall/sys_i386/__setregid.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setregid -#error "SYS_setregid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__setregid, setregid, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl setregid$UNIX2003 - setregid$UNIX2003 = __setregid -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__setreuid.S b/src/kernel/libsyscall/sys_i386/__setreuid.S deleted file mode 100644 index 7b37e80d7..000000000 --- a/src/kernel/libsyscall/sys_i386/__setreuid.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setreuid -#error "SYS_setreuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__setreuid, setreuid, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl setreuid$UNIX2003 - setreuid$UNIX2003 = __setreuid -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__setrlimit.S b/src/kernel/libsyscall/sys_i386/__setrlimit.S deleted file mode 100644 index 43ea9be42..000000000 --- a/src/kernel/libsyscall/sys_i386/__setrlimit.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setrlimit -#error "SYS_setrlimit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__setrlimit, setrlimit, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl setrlimit - setrlimit = __setrlimit -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__setsgroups.S b/src/kernel/libsyscall/sys_i386/__setsgroups.S deleted file mode 100644 index a5a7cac65..000000000 --- a/src/kernel/libsyscall/sys_i386/__setsgroups.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setsgroups -#error "SYS_setsgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__setsgroups, setsgroups, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl setsgroups_np - setsgroups_np = __setsgroups -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__settid.S b/src/kernel/libsyscall/sys_i386/__settid.S deleted file mode 100644 index c078851ec..000000000 --- a/src/kernel/libsyscall/sys_i386/__settid.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_settid -#error "SYS_settid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__settid, settid, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl pthread_setugid_np - pthread_setugid_np = __settid -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__settid_with_pid.S b/src/kernel/libsyscall/sys_i386/__settid_with_pid.S deleted file mode 100644 index 60294a086..000000000 --- a/src/kernel/libsyscall/sys_i386/__settid_with_pid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_settid_with_pid -#error "SYS_settid_with_pid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__settid_with_pid, settid_with_pid, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__settimeofday.S b/src/kernel/libsyscall/sys_i386/__settimeofday.S deleted file mode 100644 index 4862703c6..000000000 --- a/src/kernel/libsyscall/sys_i386/__settimeofday.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_settimeofday -#error "SYS_settimeofday not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__settimeofday, settimeofday, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__setwgroups.S b/src/kernel/libsyscall/sys_i386/__setwgroups.S deleted file mode 100644 index 7b3cf0750..000000000 --- a/src/kernel/libsyscall/sys_i386/__setwgroups.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setwgroups -#error "SYS_setwgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__setwgroups, setwgroups, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl setwgroups_np - setwgroups_np = __setwgroups -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sfi_ctl.S b/src/kernel/libsyscall/sys_i386/__sfi_ctl.S deleted file mode 100644 index 7a41937cb..000000000 --- a/src/kernel/libsyscall/sys_i386/__sfi_ctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_sfi_ctl -#error "SYS_sfi_ctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sfi_ctl, sfi_ctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sfi_pidctl.S b/src/kernel/libsyscall/sys_i386/__sfi_pidctl.S deleted file mode 100644 index 7505ca481..000000000 --- a/src/kernel/libsyscall/sys_i386/__sfi_pidctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_sfi_pidctl -#error "SYS_sfi_pidctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sfi_pidctl, sfi_pidctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__shared_region_check_np.S b/src/kernel/libsyscall/sys_i386/__shared_region_check_np.S deleted file mode 100644 index 834659888..000000000 --- a/src/kernel/libsyscall/sys_i386/__shared_region_check_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_shared_region_check_np -#error "SYS_shared_region_check_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__shared_region_check_np, shared_region_check_np, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__shared_region_map_and_slide_np.S b/src/kernel/libsyscall/sys_i386/__shared_region_map_and_slide_np.S deleted file mode 100644 index 02636ac39..000000000 --- a/src/kernel/libsyscall/sys_i386/__shared_region_map_and_slide_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_shared_region_map_and_slide_np -#error "SYS_shared_region_map_and_slide_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__shared_region_map_and_slide_np, shared_region_map_and_slide_np, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__shm_open.S b/src/kernel/libsyscall/sys_i386/__shm_open.S deleted file mode 100644 index 0f7b1c998..000000000 --- a/src/kernel/libsyscall/sys_i386/__shm_open.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_shm_open -#error "SYS_shm_open not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__shm_open, shm_open, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl shm_open - shm_open = __shm_open -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__shmctl.S b/src/kernel/libsyscall/sys_i386/__shmctl.S deleted file mode 100644 index 8f363f426..000000000 --- a/src/kernel/libsyscall/sys_i386/__shmctl.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_shmctl -#error "SYS_shmctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__shmctl, shmctl, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl shmctl$UNIX2003 - shmctl$UNIX2003 = __shmctl -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__shmsys.S b/src/kernel/libsyscall/sys_i386/__shmsys.S deleted file mode 100644 index 543c654d6..000000000 --- a/src/kernel/libsyscall/sys_i386/__shmsys.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_shmsys -#error "SYS_shmsys not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__shmsys, shmsys, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl shmsys - shmsys = __shmsys -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sigaction.S b/src/kernel/libsyscall/sys_i386/__sigaction.S deleted file mode 100644 index 0e3ba4ca8..000000000 --- a/src/kernel/libsyscall/sys_i386/__sigaction.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_sigaction -#error "SYS_sigaction not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sigaction, sigaction, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sigaltstack.S b/src/kernel/libsyscall/sys_i386/__sigaltstack.S deleted file mode 100644 index 3e42e2452..000000000 --- a/src/kernel/libsyscall/sys_i386/__sigaltstack.S +++ /dev/null @@ -1,51 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include "SYS.h" - -#ifdef DARLING -# define ___sigaltstack __sigaltstack -#endif - -#if defined(__x86_64__) - -__SYSCALL(___sigaltstack, sigaltstack, 3) - -#elif defined(__i386__) - -__SYSCALL_INT(___sigaltstack, sigaltstack, 3) - -#else -#error Unsupported architecture -#endif -#if defined(__i386__) - .globl sigaltstack - sigaltstack = __sigaltstack -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sigsuspend.S b/src/kernel/libsyscall/sys_i386/__sigsuspend.S deleted file mode 100644 index 146dd52ec..000000000 --- a/src/kernel/libsyscall/sys_i386/__sigsuspend.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sigsuspend -#error "SYS_sigsuspend not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sigsuspend, sigsuspend, 1, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sigsuspend_nocancel.S b/src/kernel/libsyscall/sys_i386/__sigsuspend_nocancel.S deleted file mode 100644 index d2563640b..000000000 --- a/src/kernel/libsyscall/sys_i386/__sigsuspend_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sigsuspend_nocancel -#error "SYS_sigsuspend_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sigsuspend_nocancel, sigsuspend_nocancel, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sigwait.S b/src/kernel/libsyscall/sys_i386/__sigwait.S deleted file mode 100644 index 8ee31f0f0..000000000 --- a/src/kernel/libsyscall/sys_i386/__sigwait.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___sigwait -#error "SYS___sigwait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sigwait, __sigwait, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__socketpair.S b/src/kernel/libsyscall/sys_i386/__socketpair.S deleted file mode 100644 index 675eb0bcc..000000000 --- a/src/kernel/libsyscall/sys_i386/__socketpair.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_socketpair -#error "SYS_socketpair not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__socketpair, socketpair, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl socketpair$UNIX2003 - socketpair$UNIX2003 = __socketpair -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__stack_snapshot.S b/src/kernel/libsyscall/sys_i386/__stack_snapshot.S deleted file mode 100644 index 840db258f..000000000 --- a/src/kernel/libsyscall/sys_i386/__stack_snapshot.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_stack_snapshot -#error "SYS_stack_snapshot not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__stack_snapshot, stack_snapshot, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__stat64_extended.S b/src/kernel/libsyscall/sys_i386/__stat64_extended.S deleted file mode 100644 index 9147b52c7..000000000 --- a/src/kernel/libsyscall/sys_i386/__stat64_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_stat64_extended -#error "SYS_stat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__stat64_extended, stat64_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__stat_extended.S b/src/kernel/libsyscall/sys_i386/__stat_extended.S deleted file mode 100644 index 6fca237ae..000000000 --- a/src/kernel/libsyscall/sys_i386/__stat_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_stat_extended -#error "SYS_stat_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__stat_extended, stat_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__syscall.S b/src/kernel/libsyscall/sys_i386/__syscall.S deleted file mode 100644 index 67b2bd29a..000000000 --- a/src/kernel/libsyscall/sys_i386/__syscall.S +++ /dev/null @@ -1,65 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ - -#include "SYS.h" - -#ifdef DARLING -# define ___syscall __syscall -#endif - -#if defined(__i386__) - -LEAF(___syscall, 0) - popl %ecx // ret addr - popl %eax // syscall number - pushl %ecx - UNIX_SYSCALL_TRAP - movl (%esp),%edx // add one element to stack so - pushl %ecx // caller "pop" will work - jnb 2f - BRANCH_EXTERN(tramp_cerror) -2: -END(___syscall) - -#elif defined(__x86_64__) - -// For x86-64, the kernel slides the argument list for us. -// The number of arguments here is variable, but our macros ignore -// that value anyway. -__SYSCALL(___syscall, syscall, 0); - -#else -#error Unsupported architecture -#endif -#if defined(__i386__) - .globl syscall - syscall = __syscall -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sysctl.S b/src/kernel/libsyscall/sys_i386/__sysctl.S deleted file mode 100644 index d90a1677c..000000000 --- a/src/kernel/libsyscall/sys_i386/__sysctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_sysctl -#error "SYS_sysctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sysctl, sysctl, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__sysctlbyname.S b/src/kernel/libsyscall/sys_i386/__sysctlbyname.S deleted file mode 100644 index 00db7996b..000000000 --- a/src/kernel/libsyscall/sys_i386/__sysctlbyname.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_sysctlbyname -#error "SYS_sysctlbyname not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sysctlbyname, sysctlbyname, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__telemetry.S b/src/kernel/libsyscall/sys_i386/__telemetry.S deleted file mode 100644 index 4acdc1ab9..000000000 --- a/src/kernel/libsyscall/sys_i386/__telemetry.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 48 -#include "SYS.h" - -#ifndef SYS_telemetry -#error "SYS_telemetry not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__telemetry, telemetry, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__umask_extended.S b/src/kernel/libsyscall/sys_i386/__umask_extended.S deleted file mode 100644 index 888197081..000000000 --- a/src/kernel/libsyscall/sys_i386/__umask_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_umask_extended -#error "SYS_umask_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__umask_extended, umask_extended, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__unlink.S b/src/kernel/libsyscall/sys_i386/__unlink.S deleted file mode 100644 index 7049e3e3c..000000000 --- a/src/kernel/libsyscall/sys_i386/__unlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_unlink -#error "SYS_unlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__unlink, unlink, 1, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__unlinkat.S b/src/kernel/libsyscall/sys_i386/__unlinkat.S deleted file mode 100644 index d762bc42f..000000000 --- a/src/kernel/libsyscall/sys_i386/__unlinkat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_unlinkat -#error "SYS_unlinkat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__unlinkat, unlinkat, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__vfork.S b/src/kernel/libsyscall/sys_i386/__vfork.S deleted file mode 100644 index 582eb0d0b..000000000 --- a/src/kernel/libsyscall/sys_i386/__vfork.S +++ /dev/null @@ -1,144 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. - * - * File: libc/ppc/sys/vfork.s - * - * HISTORY - * 23-Jun-1998 Umesh Vaishampayan (umeshv@apple.com) - * Created from fork.s - * - */ - -#include "SYS.h" - -#ifdef DARLING -#define ___vfork __vfork -#define _cerror cerror -#endif - -#if defined(__i386__) - -#if defined(__DYNAMIC__) -#define GET_CURRENT_PID PICIFY(__current_pid) - - NON_LAZY_STUB(__current_pid) -#define __current_pid_var (%edx) -#else -#define GET_CURRENT_PID -#endif - -/* - * If __current_pid_var >= 0, we want to put a -1 in there - * otherwise we just decrement it - */ - -LEAF(___vfork, 0) - GET_CURRENT_PID - movl __current_pid_var, %eax -0: - xorl %ecx, %ecx - testl %eax, %eax - cmovs %eax, %ecx - decl %ecx - lock - cmpxchgl %ecx, __current_pid_var - jne 0b - popl %ecx - movl $(SYS_vfork), %eax // code for vfork -> eax - UNIX_SYSCALL_TRAP // do the system call - jnb L1 // jump if CF==0 - GET_CURRENT_PID - lock - incl __current_pid_var - pushl %ecx - BRANCH_EXTERN(tramp_cerror) - -L1: - testl %edx, %edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - xorl %eax, %eax // zero eax - jmp *%ecx - -L2: - GET_CURRENT_PID - lock - incl __current_pid_var - jmp *%ecx - -#elif defined(__x86_64__) - -/* - * If __current_pid_var >= 0, we want to put a -1 in there - * otherwise we just decrement it - */ - -LEAF(___vfork, 0) - movq __current_pid_var@GOTPCREL(%rip), %rax - movl (%rax), %eax -0: - xorl %ecx, %ecx - testl %eax, %eax - cmovs %eax, %ecx - subl $1, %ecx - movq __current_pid_var@GOTPCREL(%rip), %rdx - lock - cmpxchgl %ecx, (%rdx) - jne 0b - popq %rdi // return address in %rdi - movq $ SYSCALL_CONSTRUCT_UNIX(SYS_vfork), %rax // code for vfork -> rax - UNIX_SYSCALL_TRAP // do the system call - jnb L1 // jump if CF==0 - pushq %rdi // put return address back on stack for cerror - movq __current_pid_var@GOTPCREL(%rip), %rcx - lock - addq $1, (%rcx) - movq %rax, %rdi - BRANCH_EXTERN(_cerror) - -L1: - testl %edx, %edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - xorq %rax, %rax // zero rax - jmp *%rdi - -L2: - movq __current_pid_var@GOTPCREL(%rip), %rdx - lock - addq $1, (%rdx) - jmp *%rdi - -#else -#error Unsupported architecture -#endif -#if defined(__i386__) - .globl vfork - vfork = __vfork -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__wait4.S b/src/kernel/libsyscall/sys_i386/__wait4.S deleted file mode 100644 index 8c716cec8..000000000 --- a/src/kernel/libsyscall/sys_i386/__wait4.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_wait4 -#error "SYS_wait4 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__wait4, wait4, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__wait4_nocancel.S b/src/kernel/libsyscall/sys_i386/__wait4_nocancel.S deleted file mode 100644 index 7b9a52ad7..000000000 --- a/src/kernel/libsyscall/sys_i386/__wait4_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_wait4_nocancel -#error "SYS_wait4_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__wait4_nocancel, wait4_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl wait4 - wait4 = __wait4_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__waitid_nocancel.S b/src/kernel/libsyscall/sys_i386/__waitid_nocancel.S deleted file mode 100644 index 55322abe8..000000000 --- a/src/kernel/libsyscall/sys_i386/__waitid_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_waitid_nocancel -#error "SYS_waitid_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__waitid_nocancel, waitid_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl waitid - waitid = __waitid_nocancel - .globl waitid$NOCANCEL$UNIX2003 - waitid$NOCANCEL$UNIX2003 = __waitid_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__workq_kernreturn.S b/src/kernel/libsyscall/sys_i386/__workq_kernreturn.S deleted file mode 100644 index e66d1cc06..000000000 --- a/src/kernel/libsyscall/sys_i386/__workq_kernreturn.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_workq_kernreturn -#error "SYS_workq_kernreturn not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__workq_kernreturn, workq_kernreturn, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__workq_open.S b/src/kernel/libsyscall/sys_i386/__workq_open.S deleted file mode 100644 index fd463ab47..000000000 --- a/src/kernel/libsyscall/sys_i386/__workq_open.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_workq_open -#error "SYS_workq_open not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__workq_open, workq_open, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__write_nocancel.S b/src/kernel/libsyscall/sys_i386/__write_nocancel.S deleted file mode 100644 index 91b055462..000000000 --- a/src/kernel/libsyscall/sys_i386/__write_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_write_nocancel -#error "SYS_write_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__write_nocancel, write_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl write - write = __write_nocancel - .globl write$NOCANCEL$UNIX2003 - write$NOCANCEL$UNIX2003 = __write_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/__writev_nocancel.S b/src/kernel/libsyscall/sys_i386/__writev_nocancel.S deleted file mode 100644 index fc2266b8f..000000000 --- a/src/kernel/libsyscall/sys_i386/__writev_nocancel.S +++ /dev/null @@ -1,18 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_writev_nocancel -#error "SYS_writev_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__writev_nocancel, writev_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl writev - writev = __writev_nocancel - .globl writev$NOCANCEL$UNIX2003 - writev$NOCANCEL$UNIX2003 = __writev_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_i386/access.S b/src/kernel/libsyscall/sys_i386/access.S deleted file mode 100644 index ac0f0e779..000000000 --- a/src/kernel/libsyscall/sys_i386/access.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_access -#error "SYS_access not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(access, access, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/acct.S b/src/kernel/libsyscall/sys_i386/acct.S deleted file mode 100644 index a43855f7e..000000000 --- a/src/kernel/libsyscall/sys_i386/acct.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_acct -#error "SYS_acct not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(acct, acct, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/adjtime.S b/src/kernel/libsyscall/sys_i386/adjtime.S deleted file mode 100644 index 6df2cd8e7..000000000 --- a/src/kernel/libsyscall/sys_i386/adjtime.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_adjtime -#error "SYS_adjtime not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(adjtime, adjtime, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/aio_cancel.S b/src/kernel/libsyscall/sys_i386/aio_cancel.S deleted file mode 100644 index 8c1a814b1..000000000 --- a/src/kernel/libsyscall/sys_i386/aio_cancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_aio_cancel -#error "SYS_aio_cancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(aio_cancel, aio_cancel, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/aio_error.S b/src/kernel/libsyscall/sys_i386/aio_error.S deleted file mode 100644 index ce3a47fb6..000000000 --- a/src/kernel/libsyscall/sys_i386/aio_error.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_aio_error -#error "SYS_aio_error not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(aio_error, aio_error, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/aio_fsync.S b/src/kernel/libsyscall/sys_i386/aio_fsync.S deleted file mode 100644 index 857a47c9f..000000000 --- a/src/kernel/libsyscall/sys_i386/aio_fsync.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_aio_fsync -#error "SYS_aio_fsync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(aio_fsync, aio_fsync, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/aio_read.S b/src/kernel/libsyscall/sys_i386/aio_read.S deleted file mode 100644 index 9b1ae1e08..000000000 --- a/src/kernel/libsyscall/sys_i386/aio_read.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_aio_read -#error "SYS_aio_read not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(aio_read, aio_read, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/aio_return.S b/src/kernel/libsyscall/sys_i386/aio_return.S deleted file mode 100644 index 2be28809c..000000000 --- a/src/kernel/libsyscall/sys_i386/aio_return.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_aio_return -#error "SYS_aio_return not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(aio_return, aio_return, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/aio_suspend.S b/src/kernel/libsyscall/sys_i386/aio_suspend.S deleted file mode 100644 index 4625bb8a1..000000000 --- a/src/kernel/libsyscall/sys_i386/aio_suspend.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_aio_suspend -#error "SYS_aio_suspend not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__aio_suspend, aio_suspend, 1, cerror) -#endif - - -#if defined(__i386__) - .globl aio_suspend$UNIX2003 - aio_suspend$UNIX2003 = __aio_suspend -#endif - diff --git a/src/kernel/libsyscall/sys_i386/aio_write.S b/src/kernel/libsyscall/sys_i386/aio_write.S deleted file mode 100644 index df6fc67c4..000000000 --- a/src/kernel/libsyscall/sys_i386/aio_write.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_aio_write -#error "SYS_aio_write not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(aio_write, aio_write, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/audit.S b/src/kernel/libsyscall/sys_i386/audit.S deleted file mode 100644 index 27a835780..000000000 --- a/src/kernel/libsyscall/sys_i386/audit.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_audit -#error "SYS_audit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(audit, audit, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/audit_session_join.S b/src/kernel/libsyscall/sys_i386/audit_session_join.S deleted file mode 100644 index a6c1cba00..000000000 --- a/src/kernel/libsyscall/sys_i386/audit_session_join.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_audit_session_join -#error "SYS_audit_session_join not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(audit_session_join, audit_session_join, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/audit_session_port.S b/src/kernel/libsyscall/sys_i386/audit_session_port.S deleted file mode 100644 index 87d89389b..000000000 --- a/src/kernel/libsyscall/sys_i386/audit_session_port.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_audit_session_port -#error "SYS_audit_session_port not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(audit_session_port, audit_session_port, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/audit_session_self.S b/src/kernel/libsyscall/sys_i386/audit_session_self.S deleted file mode 100644 index b7db1b54d..000000000 --- a/src/kernel/libsyscall/sys_i386/audit_session_self.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_audit_session_self -#error "SYS_audit_session_self not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(audit_session_self, audit_session_self, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/auditctl.S b/src/kernel/libsyscall/sys_i386/auditctl.S deleted file mode 100644 index 6aa88353d..000000000 --- a/src/kernel/libsyscall/sys_i386/auditctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_auditctl -#error "SYS_auditctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(auditctl, auditctl, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/auditon.S b/src/kernel/libsyscall/sys_i386/auditon.S deleted file mode 100644 index 78ef2c2f9..000000000 --- a/src/kernel/libsyscall/sys_i386/auditon.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_auditon -#error "SYS_auditon not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(auditon, auditon, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/change_fdguard_np.S b/src/kernel/libsyscall/sys_i386/change_fdguard_np.S deleted file mode 100644 index ad128ec5b..000000000 --- a/src/kernel/libsyscall/sys_i386/change_fdguard_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_change_fdguard_np -#error "SYS_change_fdguard_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(change_fdguard_np, change_fdguard_np, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/chdir.S b/src/kernel/libsyscall/sys_i386/chdir.S deleted file mode 100644 index 47c46ebae..000000000 --- a/src/kernel/libsyscall/sys_i386/chdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_chdir -#error "SYS_chdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(chdir, chdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/chflags.S b/src/kernel/libsyscall/sys_i386/chflags.S deleted file mode 100644 index ffa65fa59..000000000 --- a/src/kernel/libsyscall/sys_i386/chflags.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_chflags -#error "SYS_chflags not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(chflags, chflags, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/chown.S b/src/kernel/libsyscall/sys_i386/chown.S deleted file mode 100644 index 97b50f8cc..000000000 --- a/src/kernel/libsyscall/sys_i386/chown.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_chown -#error "SYS_chown not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(chown, chown, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/chroot.S b/src/kernel/libsyscall/sys_i386/chroot.S deleted file mode 100644 index 9db99d713..000000000 --- a/src/kernel/libsyscall/sys_i386/chroot.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_chroot -#error "SYS_chroot not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(chroot, chroot, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/close.S b/src/kernel/libsyscall/sys_i386/close.S deleted file mode 100644 index 068b1dee5..000000000 --- a/src/kernel/libsyscall/sys_i386/close.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_close -#error "SYS_close not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__close, close, 1, cerror) -#endif - -#if defined(__i386__) - .globl close$UNIX2003 - close$UNIX2003 = __close -#endif - diff --git a/src/kernel/libsyscall/sys_i386/connectx.S b/src/kernel/libsyscall/sys_i386/connectx.S deleted file mode 100644 index 44d3d52de..000000000 --- a/src/kernel/libsyscall/sys_i386/connectx.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 32 -#include "SYS.h" - -#ifndef SYS_connectx -#error "SYS_connectx not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(connectx, connectx, 8, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/csops.S b/src/kernel/libsyscall/sys_i386/csops.S deleted file mode 100644 index 89a841a18..000000000 --- a/src/kernel/libsyscall/sys_i386/csops.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_csops -#error "SYS_csops not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(csops, csops, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/csops_audittoken.S b/src/kernel/libsyscall/sys_i386/csops_audittoken.S deleted file mode 100644 index 3bc246726..000000000 --- a/src/kernel/libsyscall/sys_i386/csops_audittoken.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_csops_audittoken -#error "SYS_csops_audittoken not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(csops_audittoken, csops_audittoken, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/custom.S b/src/kernel/libsyscall/sys_i386/custom.S deleted file mode 100644 index c47e89953..000000000 --- a/src/kernel/libsyscall/sys_i386/custom.S +++ /dev/null @@ -1,108 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2011 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - */ - -#include "SYS.h" - -#if defined(__i386__) - -/* - * i386 needs custom assembly to transform the return from syscalls - * into a proper stack for a function call out to cerror{,_nocancel}. - */ - -LABEL(tramp_cerror) - mov %esp, %edx - andl $0xfffffff0, %esp - subl $16, %esp - movl %edx, 4(%esp) - movl %eax, (%esp) - CALL_EXTERN(cerror) - movl 4(%esp), %esp - ret - -LABEL(tramp_cerror_nocancel) - mov %esp, %edx - andl $0xfffffff0, %esp - subl $16, %esp - movl %edx, 4(%esp) - movl %eax, (%esp) - CALL_EXTERN(cerror_nocancel) - movl 4(%esp), %esp - ret - -LABEL(__sysenter_trap) - popl %edx - movl %esp, %ecx - sysenter - - .globl _i386_get_ldt - ALIGN -_i386_get_ldt: - movl $6,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - jmp tramp_cerror -2: ret - - - .globl _i386_set_ldt - ALIGN -_i386_set_ldt: - movl $5,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - jmp tramp_cerror -2: ret - -#elif defined(__x86_64__) - - .globl _i386_get_ldt - ALIGN -_i386_get_ldt: - movl $6,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - movq %rax, %rdi - jmp cerror -2: ret - - - .globl _i386_set_ldt - ALIGN -_i386_set_ldt: - movl $5,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - movq %rax, %rdi - jmp cerror -2: ret - -#endif diff --git a/src/kernel/libsyscall/sys_i386/disconnectx.S b/src/kernel/libsyscall/sys_i386/disconnectx.S deleted file mode 100644 index 3e07f6da8..000000000 --- a/src/kernel/libsyscall/sys_i386/disconnectx.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_disconnectx -#error "SYS_disconnectx not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(disconnectx, disconnectx, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/dup.S b/src/kernel/libsyscall/sys_i386/dup.S deleted file mode 100644 index 3139f0db4..000000000 --- a/src/kernel/libsyscall/sys_i386/dup.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_dup -#error "SYS_dup not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(dup, dup, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/dup2.S b/src/kernel/libsyscall/sys_i386/dup2.S deleted file mode 100644 index 257885640..000000000 --- a/src/kernel/libsyscall/sys_i386/dup2.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_dup2 -#error "SYS_dup2 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(dup2, dup2, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/exchangedata.S b/src/kernel/libsyscall/sys_i386/exchangedata.S deleted file mode 100644 index 1a09435fc..000000000 --- a/src/kernel/libsyscall/sys_i386/exchangedata.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_exchangedata -#error "SYS_exchangedata not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(exchangedata, exchangedata, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/execve.S b/src/kernel/libsyscall/sys_i386/execve.S deleted file mode 100644 index 267e81b1a..000000000 --- a/src/kernel/libsyscall/sys_i386/execve.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_execve -#error "SYS_execve not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(execve, execve, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/faccessat.S b/src/kernel/libsyscall/sys_i386/faccessat.S deleted file mode 100644 index 2447b1aa9..000000000 --- a/src/kernel/libsyscall/sys_i386/faccessat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_faccessat -#error "SYS_faccessat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(faccessat, faccessat, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fchdir.S b/src/kernel/libsyscall/sys_i386/fchdir.S deleted file mode 100644 index ec9ce85e1..000000000 --- a/src/kernel/libsyscall/sys_i386/fchdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fchdir -#error "SYS_fchdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fchdir, fchdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fchflags.S b/src/kernel/libsyscall/sys_i386/fchflags.S deleted file mode 100644 index b52314611..000000000 --- a/src/kernel/libsyscall/sys_i386/fchflags.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fchflags -#error "SYS_fchflags not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fchflags, fchflags, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fchmodat.S b/src/kernel/libsyscall/sys_i386/fchmodat.S deleted file mode 100644 index 5950cca73..000000000 --- a/src/kernel/libsyscall/sys_i386/fchmodat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fchmodat -#error "SYS_fchmodat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fchmodat, fchmodat, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fchown.S b/src/kernel/libsyscall/sys_i386/fchown.S deleted file mode 100644 index 56b79c801..000000000 --- a/src/kernel/libsyscall/sys_i386/fchown.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_fchown -#error "SYS_fchown not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fchown, fchown, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fchownat.S b/src/kernel/libsyscall/sys_i386/fchownat.S deleted file mode 100644 index 796014ec7..000000000 --- a/src/kernel/libsyscall/sys_i386/fchownat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fchownat -#error "SYS_fchownat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fchownat, fchownat, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fdatasync.S b/src/kernel/libsyscall/sys_i386/fdatasync.S deleted file mode 100644 index ee0a0360b..000000000 --- a/src/kernel/libsyscall/sys_i386/fdatasync.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fdatasync -#error "SYS_fdatasync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fdatasync, fdatasync, 1, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/ffsctl.S b/src/kernel/libsyscall/sys_i386/ffsctl.S deleted file mode 100644 index 2311e3a59..000000000 --- a/src/kernel/libsyscall/sys_i386/ffsctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_ffsctl -#error "SYS_ffsctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(ffsctl, ffsctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fgetattrlist.S b/src/kernel/libsyscall/sys_i386/fgetattrlist.S deleted file mode 100644 index d85ce50ae..000000000 --- a/src/kernel/libsyscall/sys_i386/fgetattrlist.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fgetattrlist -#error "SYS_fgetattrlist not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fgetattrlist, fgetattrlist, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fgetxattr.S b/src/kernel/libsyscall/sys_i386/fgetxattr.S deleted file mode 100644 index 665c74680..000000000 --- a/src/kernel/libsyscall/sys_i386/fgetxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_fgetxattr -#error "SYS_fgetxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fgetxattr, fgetxattr, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fhopen.S b/src/kernel/libsyscall/sys_i386/fhopen.S deleted file mode 100644 index 14dce02f3..000000000 --- a/src/kernel/libsyscall/sys_i386/fhopen.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fhopen -#error "SYS_fhopen not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fhopen, fhopen, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fileport_makefd.S b/src/kernel/libsyscall/sys_i386/fileport_makefd.S deleted file mode 100644 index e1f4204e2..000000000 --- a/src/kernel/libsyscall/sys_i386/fileport_makefd.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fileport_makefd -#error "SYS_fileport_makefd not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fileport_makefd, fileport_makefd, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fileport_makeport.S b/src/kernel/libsyscall/sys_i386/fileport_makeport.S deleted file mode 100644 index acaaff5e8..000000000 --- a/src/kernel/libsyscall/sys_i386/fileport_makeport.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fileport_makeport -#error "SYS_fileport_makeport not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fileport_makeport, fileport_makeport, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/flistxattr.S b/src/kernel/libsyscall/sys_i386/flistxattr.S deleted file mode 100644 index 33a00153d..000000000 --- a/src/kernel/libsyscall/sys_i386/flistxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_flistxattr -#error "SYS_flistxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(flistxattr, flistxattr, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/flock.S b/src/kernel/libsyscall/sys_i386/flock.S deleted file mode 100644 index d747b5c6c..000000000 --- a/src/kernel/libsyscall/sys_i386/flock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_flock -#error "SYS_flock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(flock, flock, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fpathconf.S b/src/kernel/libsyscall/sys_i386/fpathconf.S deleted file mode 100644 index 78a27af41..000000000 --- a/src/kernel/libsyscall/sys_i386/fpathconf.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fpathconf -#error "SYS_fpathconf not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fpathconf, fpathconf, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fremovexattr.S b/src/kernel/libsyscall/sys_i386/fremovexattr.S deleted file mode 100644 index ac07c9f34..000000000 --- a/src/kernel/libsyscall/sys_i386/fremovexattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_fremovexattr -#error "SYS_fremovexattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fremovexattr, fremovexattr, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fsctl.S b/src/kernel/libsyscall/sys_i386/fsctl.S deleted file mode 100644 index 1d9be18d5..000000000 --- a/src/kernel/libsyscall/sys_i386/fsctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fsctl -#error "SYS_fsctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fsctl, fsctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fsetattrlist.S b/src/kernel/libsyscall/sys_i386/fsetattrlist.S deleted file mode 100644 index a5bf19f28..000000000 --- a/src/kernel/libsyscall/sys_i386/fsetattrlist.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fsetattrlist -#error "SYS_fsetattrlist not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fsetattrlist, fsetattrlist, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fsetxattr.S b/src/kernel/libsyscall/sys_i386/fsetxattr.S deleted file mode 100644 index ab30bd2a6..000000000 --- a/src/kernel/libsyscall/sys_i386/fsetxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_fsetxattr -#error "SYS_fsetxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fsetxattr, fsetxattr, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fstat.S b/src/kernel/libsyscall/sys_i386/fstat.S deleted file mode 100644 index 64b5618d4..000000000 --- a/src/kernel/libsyscall/sys_i386/fstat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fstat -#error "SYS_fstat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fstat, fstat, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fstat64.S b/src/kernel/libsyscall/sys_i386/fstat64.S deleted file mode 100644 index 224d47749..000000000 --- a/src/kernel/libsyscall/sys_i386/fstat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fstat64 -#error "SYS_fstat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fstat64, fstat64, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl fstat$INODE64 - fstat$INODE64 = fstat64 -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fstatat.S b/src/kernel/libsyscall/sys_i386/fstatat.S deleted file mode 100644 index e68f48fba..000000000 --- a/src/kernel/libsyscall/sys_i386/fstatat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fstatat -#error "SYS_fstatat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fstatat, fstatat, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fstatat64.S b/src/kernel/libsyscall/sys_i386/fstatat64.S deleted file mode 100644 index 6f7f39c69..000000000 --- a/src/kernel/libsyscall/sys_i386/fstatat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fstatat64 -#error "SYS_fstatat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fstatat64, fstatat64, 4, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl fstatat$INODE64 - fstatat$INODE64 = fstatat64 -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fstatfs.S b/src/kernel/libsyscall/sys_i386/fstatfs.S deleted file mode 100644 index 639f06e75..000000000 --- a/src/kernel/libsyscall/sys_i386/fstatfs.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fstatfs -#error "SYS_fstatfs not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fstatfs, fstatfs, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fstatfs64.S b/src/kernel/libsyscall/sys_i386/fstatfs64.S deleted file mode 100644 index 400cdd03f..000000000 --- a/src/kernel/libsyscall/sys_i386/fstatfs64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fstatfs64 -#error "SYS_fstatfs64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(fstatfs64, fstatfs64, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl fstatfs$INODE64 - fstatfs$INODE64 = fstatfs64 -#endif - diff --git a/src/kernel/libsyscall/sys_i386/fsync.S b/src/kernel/libsyscall/sys_i386/fsync.S deleted file mode 100644 index 278bca776..000000000 --- a/src/kernel/libsyscall/sys_i386/fsync.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fsync -#error "SYS_fsync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__fsync, fsync, 1, cerror) -#endif - - -#if defined(__i386__) - .globl fsync$UNIX2003 - fsync$UNIX2003 = __fsync -#endif - diff --git a/src/kernel/libsyscall/sys_i386/ftruncate.S b/src/kernel/libsyscall/sys_i386/ftruncate.S deleted file mode 100644 index 3f99ee8c3..000000000 --- a/src/kernel/libsyscall/sys_i386/ftruncate.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_ftruncate -#error "SYS_ftruncate not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(ftruncate, ftruncate, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/futimes.S b/src/kernel/libsyscall/sys_i386/futimes.S deleted file mode 100644 index f9d47c5b7..000000000 --- a/src/kernel/libsyscall/sys_i386/futimes.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_futimes -#error "SYS_futimes not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(futimes, futimes, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getattrlistat.S b/src/kernel/libsyscall/sys_i386/getattrlistat.S deleted file mode 100644 index e8de69ddd..000000000 --- a/src/kernel/libsyscall/sys_i386/getattrlistat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_getattrlistat -#error "SYS_getattrlistat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getattrlistat, getattrlistat, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getattrlistbulk.S b/src/kernel/libsyscall/sys_i386/getattrlistbulk.S deleted file mode 100644 index 2bc80c40d..000000000 --- a/src/kernel/libsyscall/sys_i386/getattrlistbulk.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_getattrlistbulk -#error "SYS_getattrlistbulk not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getattrlistbulk, getattrlistbulk, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getaudit_addr.S b/src/kernel/libsyscall/sys_i386/getaudit_addr.S deleted file mode 100644 index a59dabb7c..000000000 --- a/src/kernel/libsyscall/sys_i386/getaudit_addr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getaudit_addr -#error "SYS_getaudit_addr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getaudit_addr, getaudit_addr, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getauid.S b/src/kernel/libsyscall/sys_i386/getauid.S deleted file mode 100644 index abab4010e..000000000 --- a/src/kernel/libsyscall/sys_i386/getauid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_getauid -#error "SYS_getauid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getauid, getauid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getdirentries.S b/src/kernel/libsyscall/sys_i386/getdirentries.S deleted file mode 100644 index b77682a37..000000000 --- a/src/kernel/libsyscall/sys_i386/getdirentries.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_getdirentries -#error "SYS_getdirentries not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getdirentries, getdirentries, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getdirentriesattr.S b/src/kernel/libsyscall/sys_i386/getdirentriesattr.S deleted file mode 100644 index 1c71b659d..000000000 --- a/src/kernel/libsyscall/sys_i386/getdirentriesattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 32 -#include "SYS.h" - -#ifndef SYS_getdirentriesattr -#error "SYS_getdirentriesattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getdirentriesattr, getdirentriesattr, 8, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getdtablesize.S b/src/kernel/libsyscall/sys_i386/getdtablesize.S deleted file mode 100644 index a11a82399..000000000 --- a/src/kernel/libsyscall/sys_i386/getdtablesize.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getdtablesize -#error "SYS_getdtablesize not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getdtablesize, getdtablesize, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getegid.S b/src/kernel/libsyscall/sys_i386/getegid.S deleted file mode 100644 index 0968fbe4b..000000000 --- a/src/kernel/libsyscall/sys_i386/getegid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getegid -#error "SYS_getegid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getegid, getegid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/geteuid.S b/src/kernel/libsyscall/sys_i386/geteuid.S deleted file mode 100644 index 3d305cbec..000000000 --- a/src/kernel/libsyscall/sys_i386/geteuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_geteuid -#error "SYS_geteuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(geteuid, geteuid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getfh.S b/src/kernel/libsyscall/sys_i386/getfh.S deleted file mode 100644 index 7777e460c..000000000 --- a/src/kernel/libsyscall/sys_i386/getfh.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getfh -#error "SYS_getfh not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getfh, getfh, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getfsstat.S b/src/kernel/libsyscall/sys_i386/getfsstat.S deleted file mode 100644 index 5842ecbc5..000000000 --- a/src/kernel/libsyscall/sys_i386/getfsstat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_getfsstat -#error "SYS_getfsstat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getfsstat, getfsstat, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getfsstat64.S b/src/kernel/libsyscall/sys_i386/getfsstat64.S deleted file mode 100644 index 3ba922f64..000000000 --- a/src/kernel/libsyscall/sys_i386/getfsstat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_getfsstat64 -#error "SYS_getfsstat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getfsstat64, getfsstat64, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl getfsstat$INODE64 - getfsstat$INODE64 = getfsstat64 -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getgid.S b/src/kernel/libsyscall/sys_i386/getgid.S deleted file mode 100644 index 049b2d810..000000000 --- a/src/kernel/libsyscall/sys_i386/getgid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getgid -#error "SYS_getgid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getgid, getgid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getgroups.S b/src/kernel/libsyscall/sys_i386/getgroups.S deleted file mode 100644 index f833e44f6..000000000 --- a/src/kernel/libsyscall/sys_i386/getgroups.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getgroups -#error "SYS_getgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getgroups, getgroups, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getitimer.S b/src/kernel/libsyscall/sys_i386/getitimer.S deleted file mode 100644 index 2e2016953..000000000 --- a/src/kernel/libsyscall/sys_i386/getitimer.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getitimer -#error "SYS_getitimer not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getitimer, getitimer, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getpgid.S b/src/kernel/libsyscall/sys_i386/getpgid.S deleted file mode 100644 index 446bb9c84..000000000 --- a/src/kernel/libsyscall/sys_i386/getpgid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_getpgid -#error "SYS_getpgid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getpgid, getpgid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getpgrp.S b/src/kernel/libsyscall/sys_i386/getpgrp.S deleted file mode 100644 index 517b1a36c..000000000 --- a/src/kernel/libsyscall/sys_i386/getpgrp.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getpgrp -#error "SYS_getpgrp not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getpgrp, getpgrp, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getppid.S b/src/kernel/libsyscall/sys_i386/getppid.S deleted file mode 100644 index a76c00ca2..000000000 --- a/src/kernel/libsyscall/sys_i386/getppid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getppid -#error "SYS_getppid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getppid, getppid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getpriority.S b/src/kernel/libsyscall/sys_i386/getpriority.S deleted file mode 100644 index f5b5f8481..000000000 --- a/src/kernel/libsyscall/sys_i386/getpriority.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getpriority -#error "SYS_getpriority not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getpriority, getpriority, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getrusage.S b/src/kernel/libsyscall/sys_i386/getrusage.S deleted file mode 100644 index fa7f83a26..000000000 --- a/src/kernel/libsyscall/sys_i386/getrusage.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getrusage -#error "SYS_getrusage not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getrusage, getrusage, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getsid.S b/src/kernel/libsyscall/sys_i386/getsid.S deleted file mode 100644 index 32067a3f7..000000000 --- a/src/kernel/libsyscall/sys_i386/getsid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_getsid -#error "SYS_getsid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getsid, getsid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getsockopt.S b/src/kernel/libsyscall/sys_i386/getsockopt.S deleted file mode 100644 index 7c8bb1298..000000000 --- a/src/kernel/libsyscall/sys_i386/getsockopt.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_getsockopt -#error "SYS_getsockopt not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getsockopt, getsockopt, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getuid.S b/src/kernel/libsyscall/sys_i386/getuid.S deleted file mode 100644 index 51c6b1437..000000000 --- a/src/kernel/libsyscall/sys_i386/getuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getuid -#error "SYS_getuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getuid, getuid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/getxattr.S b/src/kernel/libsyscall/sys_i386/getxattr.S deleted file mode 100644 index 669c421ae..000000000 --- a/src/kernel/libsyscall/sys_i386/getxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_getxattr -#error "SYS_getxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(getxattr, getxattr, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/guarded_close_np.S b/src/kernel/libsyscall/sys_i386/guarded_close_np.S deleted file mode 100644 index 7833258f4..000000000 --- a/src/kernel/libsyscall/sys_i386/guarded_close_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_guarded_close_np -#error "SYS_guarded_close_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(guarded_close_np, guarded_close_np, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/guarded_kqueue_np.S b/src/kernel/libsyscall/sys_i386/guarded_kqueue_np.S deleted file mode 100644 index 34a1c9d6f..000000000 --- a/src/kernel/libsyscall/sys_i386/guarded_kqueue_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_guarded_kqueue_np -#error "SYS_guarded_kqueue_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(guarded_kqueue_np, guarded_kqueue_np, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/guarded_pwrite_np.S b/src/kernel/libsyscall/sys_i386/guarded_pwrite_np.S deleted file mode 100644 index 9228e10ad..000000000 --- a/src/kernel/libsyscall/sys_i386/guarded_pwrite_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_guarded_pwrite_np -#error "SYS_guarded_pwrite_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(guarded_pwrite_np, guarded_pwrite_np, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/guarded_write_np.S b/src/kernel/libsyscall/sys_i386/guarded_write_np.S deleted file mode 100644 index c1ac51f7c..000000000 --- a/src/kernel/libsyscall/sys_i386/guarded_write_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_guarded_write_np -#error "SYS_guarded_write_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(guarded_write_np, guarded_write_np, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/guarded_writev_np.S b/src/kernel/libsyscall/sys_i386/guarded_writev_np.S deleted file mode 100644 index e97b1f836..000000000 --- a/src/kernel/libsyscall/sys_i386/guarded_writev_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_guarded_writev_np -#error "SYS_guarded_writev_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(guarded_writev_np, guarded_writev_np, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/issetugid.S b/src/kernel/libsyscall/sys_i386/issetugid.S deleted file mode 100644 index 7edd3ca7e..000000000 --- a/src/kernel/libsyscall/sys_i386/issetugid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_issetugid -#error "SYS_issetugid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(issetugid, issetugid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/kas_info.S b/src/kernel/libsyscall/sys_i386/kas_info.S deleted file mode 100644 index 0da790daa..000000000 --- a/src/kernel/libsyscall/sys_i386/kas_info.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_kas_info -#error "SYS_kas_info not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(kas_info, kas_info, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/kevent.S b/src/kernel/libsyscall/sys_i386/kevent.S deleted file mode 100644 index 8f0b1efb2..000000000 --- a/src/kernel/libsyscall/sys_i386/kevent.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_kevent -#error "SYS_kevent not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(kevent, kevent, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/kevent64.S b/src/kernel/libsyscall/sys_i386/kevent64.S deleted file mode 100644 index c5344e4a5..000000000 --- a/src/kernel/libsyscall/sys_i386/kevent64.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_kevent64 -#error "SYS_kevent64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(kevent64, kevent64, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/kqueue.S b/src/kernel/libsyscall/sys_i386/kqueue.S deleted file mode 100644 index a37a8752a..000000000 --- a/src/kernel/libsyscall/sys_i386/kqueue.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_kqueue -#error "SYS_kqueue not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(kqueue, kqueue, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/ledger.S b/src/kernel/libsyscall/sys_i386/ledger.S deleted file mode 100644 index 425dd7c3e..000000000 --- a/src/kernel/libsyscall/sys_i386/ledger.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_ledger -#error "SYS_ledger not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(ledger, ledger, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/link.S b/src/kernel/libsyscall/sys_i386/link.S deleted file mode 100644 index 03e9c9f43..000000000 --- a/src/kernel/libsyscall/sys_i386/link.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_link -#error "SYS_link not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(link, link, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/linkat.S b/src/kernel/libsyscall/sys_i386/linkat.S deleted file mode 100644 index db0defff9..000000000 --- a/src/kernel/libsyscall/sys_i386/linkat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_linkat -#error "SYS_linkat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(linkat, linkat, 5, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/lio_listio.S b/src/kernel/libsyscall/sys_i386/lio_listio.S deleted file mode 100644 index 8507bf3a5..000000000 --- a/src/kernel/libsyscall/sys_i386/lio_listio.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_lio_listio -#error "SYS_lio_listio not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(lio_listio, lio_listio, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/listxattr.S b/src/kernel/libsyscall/sys_i386/listxattr.S deleted file mode 100644 index 208a78c6d..000000000 --- a/src/kernel/libsyscall/sys_i386/listxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_listxattr -#error "SYS_listxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(listxattr, listxattr, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/lstat.S b/src/kernel/libsyscall/sys_i386/lstat.S deleted file mode 100644 index 25fd0c7ef..000000000 --- a/src/kernel/libsyscall/sys_i386/lstat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_lstat -#error "SYS_lstat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(lstat, lstat, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/lstat64.S b/src/kernel/libsyscall/sys_i386/lstat64.S deleted file mode 100644 index a93960faf..000000000 --- a/src/kernel/libsyscall/sys_i386/lstat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_lstat64 -#error "SYS_lstat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(lstat64, lstat64, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl lstat$INODE64 - lstat$INODE64 = lstat64 -#endif - diff --git a/src/kernel/libsyscall/sys_i386/madvise.S b/src/kernel/libsyscall/sys_i386/madvise.S deleted file mode 100644 index 73c63b8b4..000000000 --- a/src/kernel/libsyscall/sys_i386/madvise.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_madvise -#error "SYS_madvise not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(madvise, madvise, 3, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl posix_madvise - posix_madvise = madvise -#endif - diff --git a/src/kernel/libsyscall/sys_i386/memorystatus_control.S b/src/kernel/libsyscall/sys_i386/memorystatus_control.S deleted file mode 100644 index 1aba5af0c..000000000 --- a/src/kernel/libsyscall/sys_i386/memorystatus_control.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_memorystatus_control -#error "SYS_memorystatus_control not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(memorystatus_control, memorystatus_control, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/memorystatus_get_level.S b/src/kernel/libsyscall/sys_i386/memorystatus_get_level.S deleted file mode 100644 index dc5673783..000000000 --- a/src/kernel/libsyscall/sys_i386/memorystatus_get_level.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_memorystatus_get_level -#error "SYS_memorystatus_get_level not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(memorystatus_get_level, memorystatus_get_level, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/mincore.S b/src/kernel/libsyscall/sys_i386/mincore.S deleted file mode 100644 index cda12f974..000000000 --- a/src/kernel/libsyscall/sys_i386/mincore.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_mincore -#error "SYS_mincore not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(mincore, mincore, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/minherit.S b/src/kernel/libsyscall/sys_i386/minherit.S deleted file mode 100644 index 2893e51b4..000000000 --- a/src/kernel/libsyscall/sys_i386/minherit.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_minherit -#error "SYS_minherit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(minherit, minherit, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/mkdir.S b/src/kernel/libsyscall/sys_i386/mkdir.S deleted file mode 100644 index 65c0eeabc..000000000 --- a/src/kernel/libsyscall/sys_i386/mkdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_mkdir -#error "SYS_mkdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(mkdir, mkdir, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/mkdirat.S b/src/kernel/libsyscall/sys_i386/mkdirat.S deleted file mode 100644 index 3e3f309cc..000000000 --- a/src/kernel/libsyscall/sys_i386/mkdirat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_mkdirat -#error "SYS_mkdirat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(mkdirat, mkdirat, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/mkfifo.S b/src/kernel/libsyscall/sys_i386/mkfifo.S deleted file mode 100644 index 8a9bda679..000000000 --- a/src/kernel/libsyscall/sys_i386/mkfifo.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_mkfifo -#error "SYS_mkfifo not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(mkfifo, mkfifo, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/mknod.S b/src/kernel/libsyscall/sys_i386/mknod.S deleted file mode 100644 index c8757f2a5..000000000 --- a/src/kernel/libsyscall/sys_i386/mknod.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_mknod -#error "SYS_mknod not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(mknod, mknod, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/mlock.S b/src/kernel/libsyscall/sys_i386/mlock.S deleted file mode 100644 index ecde17cff..000000000 --- a/src/kernel/libsyscall/sys_i386/mlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_mlock -#error "SYS_mlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(mlock, mlock, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/mlockall.S b/src/kernel/libsyscall/sys_i386/mlockall.S deleted file mode 100644 index 63f9c0155..000000000 --- a/src/kernel/libsyscall/sys_i386/mlockall.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_mlockall -#error "SYS_mlockall not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(mlockall, mlockall, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/modwatch.S b/src/kernel/libsyscall/sys_i386/modwatch.S deleted file mode 100644 index 5485e0fd7..000000000 --- a/src/kernel/libsyscall/sys_i386/modwatch.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_modwatch -#error "SYS_modwatch not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(modwatch, modwatch, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/mount.S b/src/kernel/libsyscall/sys_i386/mount.S deleted file mode 100644 index 31d67cca7..000000000 --- a/src/kernel/libsyscall/sys_i386/mount.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_mount -#error "SYS_mount not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(mount, mount, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/mremap_encrypted.S b/src/kernel/libsyscall/sys_i386/mremap_encrypted.S deleted file mode 100644 index b1fbd1180..000000000 --- a/src/kernel/libsyscall/sys_i386/mremap_encrypted.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_mremap_encrypted -#error "SYS_mremap_encrypted not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(mremap_encrypted, mremap_encrypted, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/msgget.S b/src/kernel/libsyscall/sys_i386/msgget.S deleted file mode 100644 index 05845f5d2..000000000 --- a/src/kernel/libsyscall/sys_i386/msgget.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_msgget -#error "SYS_msgget not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(msgget, msgget, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/msgrcv.S b/src/kernel/libsyscall/sys_i386/msgrcv.S deleted file mode 100644 index fe89e7236..000000000 --- a/src/kernel/libsyscall/sys_i386/msgrcv.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_msgrcv -#error "SYS_msgrcv not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__msgrcv, msgrcv, 1, cerror) -#endif - - -#if defined(__i386__) - .globl msgrcv$UNIX2003 - msgrcv$UNIX2003 = __msgrcv -#endif - diff --git a/src/kernel/libsyscall/sys_i386/msgsnd.S b/src/kernel/libsyscall/sys_i386/msgsnd.S deleted file mode 100644 index 9dda86d24..000000000 --- a/src/kernel/libsyscall/sys_i386/msgsnd.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_msgsnd -#error "SYS_msgsnd not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__msgsnd, msgsnd, 1, cerror) -#endif - - -#if defined(__i386__) - .globl msgsnd$UNIX2003 - msgsnd$UNIX2003 = __msgsnd -#endif - diff --git a/src/kernel/libsyscall/sys_i386/munlock.S b/src/kernel/libsyscall/sys_i386/munlock.S deleted file mode 100644 index cb0410c0d..000000000 --- a/src/kernel/libsyscall/sys_i386/munlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_munlock -#error "SYS_munlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(munlock, munlock, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/munlockall.S b/src/kernel/libsyscall/sys_i386/munlockall.S deleted file mode 100644 index 7c4659df1..000000000 --- a/src/kernel/libsyscall/sys_i386/munlockall.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_munlockall -#error "SYS_munlockall not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(munlockall, munlockall, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/necp_match_policy.S b/src/kernel/libsyscall/sys_i386/necp_match_policy.S deleted file mode 100644 index 0ccf8a009..000000000 --- a/src/kernel/libsyscall/sys_i386/necp_match_policy.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_necp_match_policy -#error "SYS_necp_match_policy not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(necp_match_policy, necp_match_policy, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/nfsclnt.S b/src/kernel/libsyscall/sys_i386/nfsclnt.S deleted file mode 100644 index 93aad5363..000000000 --- a/src/kernel/libsyscall/sys_i386/nfsclnt.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_nfsclnt -#error "SYS_nfsclnt not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(nfsclnt, nfsclnt, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/nfssvc.S b/src/kernel/libsyscall/sys_i386/nfssvc.S deleted file mode 100644 index a791b4235..000000000 --- a/src/kernel/libsyscall/sys_i386/nfssvc.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_nfssvc -#error "SYS_nfssvc not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(nfssvc, nfssvc, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/openbyid_np.S b/src/kernel/libsyscall/sys_i386/openbyid_np.S deleted file mode 100644 index 771ab6b4b..000000000 --- a/src/kernel/libsyscall/sys_i386/openbyid_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_openbyid_np -#error "SYS_openbyid_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(openbyid_np, openbyid_np, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/pathconf.S b/src/kernel/libsyscall/sys_i386/pathconf.S deleted file mode 100644 index 11682b4dc..000000000 --- a/src/kernel/libsyscall/sys_i386/pathconf.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_pathconf -#error "SYS_pathconf not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(pathconf, pathconf, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/peeloff.S b/src/kernel/libsyscall/sys_i386/peeloff.S deleted file mode 100644 index c18842c3a..000000000 --- a/src/kernel/libsyscall/sys_i386/peeloff.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_peeloff -#error "SYS_peeloff not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(peeloff, peeloff, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/pid_resume.S b/src/kernel/libsyscall/sys_i386/pid_resume.S deleted file mode 100644 index edf83b16b..000000000 --- a/src/kernel/libsyscall/sys_i386/pid_resume.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_pid_resume -#error "SYS_pid_resume not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(pid_resume, pid_resume, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/pid_suspend.S b/src/kernel/libsyscall/sys_i386/pid_suspend.S deleted file mode 100644 index e21f49bbb..000000000 --- a/src/kernel/libsyscall/sys_i386/pid_suspend.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_pid_suspend -#error "SYS_pid_suspend not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(pid_suspend, pid_suspend, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/poll.S b/src/kernel/libsyscall/sys_i386/poll.S deleted file mode 100644 index 8607370c2..000000000 --- a/src/kernel/libsyscall/sys_i386/poll.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_poll -#error "SYS_poll not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__poll, poll, 1, cerror) -#endif - - -#if defined(__i386__) - .globl poll$UNIX2003 - poll$UNIX2003 = __poll -#endif - diff --git a/src/kernel/libsyscall/sys_i386/pread.S b/src/kernel/libsyscall/sys_i386/pread.S deleted file mode 100644 index e404f6146..000000000 --- a/src/kernel/libsyscall/sys_i386/pread.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_pread -#error "SYS_pread not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pread, pread, 1, cerror) -#endif - - -#if defined(__i386__) - .globl pread$UNIX2003 - pread$UNIX2003 = __pread -#endif - diff --git a/src/kernel/libsyscall/sys_i386/proc_rlimit_control.S b/src/kernel/libsyscall/sys_i386/proc_rlimit_control.S deleted file mode 100644 index 2341e54fc..000000000 --- a/src/kernel/libsyscall/sys_i386/proc_rlimit_control.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_proc_rlimit_control -#error "SYS_proc_rlimit_control not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(proc_rlimit_control, proc_rlimit_control, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/proc_trace_log.S b/src/kernel/libsyscall/sys_i386/proc_trace_log.S deleted file mode 100644 index f9ad806c7..000000000 --- a/src/kernel/libsyscall/sys_i386/proc_trace_log.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_proc_trace_log -#error "SYS_proc_trace_log not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(proc_trace_log, proc_trace_log, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/proc_uuid_policy.S b/src/kernel/libsyscall/sys_i386/proc_uuid_policy.S deleted file mode 100644 index 18254ae6b..000000000 --- a/src/kernel/libsyscall/sys_i386/proc_uuid_policy.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_proc_uuid_policy -#error "SYS_proc_uuid_policy not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(proc_uuid_policy, proc_uuid_policy, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/pwrite.S b/src/kernel/libsyscall/sys_i386/pwrite.S deleted file mode 100644 index 79dc65a63..000000000 --- a/src/kernel/libsyscall/sys_i386/pwrite.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_pwrite -#error "SYS_pwrite not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__pwrite, pwrite, 1, cerror) -#endif - - -#if defined(__i386__) - .globl pwrite$UNIX2003 - pwrite$UNIX2003 = __pwrite -#endif - diff --git a/src/kernel/libsyscall/sys_i386/quota.S b/src/kernel/libsyscall/sys_i386/quota.S deleted file mode 100644 index 03a50f58f..000000000 --- a/src/kernel/libsyscall/sys_i386/quota.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_quota -#error "SYS_quota not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(quota, quota, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/quotactl.S b/src/kernel/libsyscall/sys_i386/quotactl.S deleted file mode 100644 index 0d8ce06a9..000000000 --- a/src/kernel/libsyscall/sys_i386/quotactl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_quotactl -#error "SYS_quotactl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(quotactl, quotactl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/read.S b/src/kernel/libsyscall/sys_i386/read.S deleted file mode 100644 index 3e8e8dbc4..000000000 --- a/src/kernel/libsyscall/sys_i386/read.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_read -#error "SYS_read not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__read, read, 1, cerror) -#endif - - -#if defined(__i386__) - .globl read$UNIX2003 - read$UNIX2003 = __read -#endif - diff --git a/src/kernel/libsyscall/sys_i386/readlink.S b/src/kernel/libsyscall/sys_i386/readlink.S deleted file mode 100644 index d9e1becc7..000000000 --- a/src/kernel/libsyscall/sys_i386/readlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_readlink -#error "SYS_readlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(readlink, readlink, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/readlinkat.S b/src/kernel/libsyscall/sys_i386/readlinkat.S deleted file mode 100644 index 07497b4a7..000000000 --- a/src/kernel/libsyscall/sys_i386/readlinkat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_readlinkat -#error "SYS_readlinkat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(readlinkat, readlinkat, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/readv.S b/src/kernel/libsyscall/sys_i386/readv.S deleted file mode 100644 index 4be93703d..000000000 --- a/src/kernel/libsyscall/sys_i386/readv.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_readv -#error "SYS_readv not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__readv, readv, 1, cerror) -#endif - - -#if defined(__i386__) - .globl readv$UNIX2003 - readv$UNIX2003 = __readv -#endif - diff --git a/src/kernel/libsyscall/sys_i386/reboot.S b/src/kernel/libsyscall/sys_i386/reboot.S deleted file mode 100644 index 3959b90b8..000000000 --- a/src/kernel/libsyscall/sys_i386/reboot.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_reboot -#error "SYS_reboot not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(reboot, reboot, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/recvmsg_x.S b/src/kernel/libsyscall/sys_i386/recvmsg_x.S deleted file mode 100644 index fab4e0366..000000000 --- a/src/kernel/libsyscall/sys_i386/recvmsg_x.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_recvmsg_x -#error "SYS_recvmsg_x not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(recvmsg_x, recvmsg_x, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/removexattr.S b/src/kernel/libsyscall/sys_i386/removexattr.S deleted file mode 100644 index 14951de7d..000000000 --- a/src/kernel/libsyscall/sys_i386/removexattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_removexattr -#error "SYS_removexattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(removexattr, removexattr, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/revoke.S b/src/kernel/libsyscall/sys_i386/revoke.S deleted file mode 100644 index 468f6c161..000000000 --- a/src/kernel/libsyscall/sys_i386/revoke.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_revoke -#error "SYS_revoke not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(revoke, revoke, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/searchfs.S b/src/kernel/libsyscall/sys_i386/searchfs.S deleted file mode 100644 index 378f398a7..000000000 --- a/src/kernel/libsyscall/sys_i386/searchfs.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_searchfs -#error "SYS_searchfs not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(searchfs, searchfs, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sem_close.S b/src/kernel/libsyscall/sys_i386/sem_close.S deleted file mode 100644 index 0bbf2ece4..000000000 --- a/src/kernel/libsyscall/sys_i386/sem_close.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_close -#error "SYS_sem_close not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(sem_close, sem_close, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sem_post.S b/src/kernel/libsyscall/sys_i386/sem_post.S deleted file mode 100644 index 41c1e4a43..000000000 --- a/src/kernel/libsyscall/sys_i386/sem_post.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_post -#error "SYS_sem_post not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(sem_post, sem_post, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sem_trywait.S b/src/kernel/libsyscall/sys_i386/sem_trywait.S deleted file mode 100644 index 509cddb70..000000000 --- a/src/kernel/libsyscall/sys_i386/sem_trywait.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_trywait -#error "SYS_sem_trywait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(sem_trywait, sem_trywait, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sem_unlink.S b/src/kernel/libsyscall/sys_i386/sem_unlink.S deleted file mode 100644 index c88c0ffba..000000000 --- a/src/kernel/libsyscall/sys_i386/sem_unlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_unlink -#error "SYS_sem_unlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(sem_unlink, sem_unlink, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sem_wait.S b/src/kernel/libsyscall/sys_i386/sem_wait.S deleted file mode 100644 index 2f8b4f82d..000000000 --- a/src/kernel/libsyscall/sys_i386/sem_wait.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_wait -#error "SYS_sem_wait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__sem_wait, sem_wait, 1, cerror) -#endif - - -#if defined(__i386__) - .globl sem_wait$UNIX2003 - sem_wait$UNIX2003 = __sem_wait -#endif - diff --git a/src/kernel/libsyscall/sys_i386/semget.S b/src/kernel/libsyscall/sys_i386/semget.S deleted file mode 100644 index 4e8ceeb41..000000000 --- a/src/kernel/libsyscall/sys_i386/semget.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_semget -#error "SYS_semget not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(semget, semget, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/semop.S b/src/kernel/libsyscall/sys_i386/semop.S deleted file mode 100644 index 8d2d4e3b3..000000000 --- a/src/kernel/libsyscall/sys_i386/semop.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_semop -#error "SYS_semop not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(semop, semop, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sendfile.S b/src/kernel/libsyscall/sys_i386/sendfile.S deleted file mode 100644 index 4a7dcbf63..000000000 --- a/src/kernel/libsyscall/sys_i386/sendfile.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_sendfile -#error "SYS_sendfile not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(sendfile, sendfile, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sendmsg_x.S b/src/kernel/libsyscall/sys_i386/sendmsg_x.S deleted file mode 100644 index 03d5c9f29..000000000 --- a/src/kernel/libsyscall/sys_i386/sendmsg_x.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_sendmsg_x -#error "SYS_sendmsg_x not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(sendmsg_x, sendmsg_x, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setaudit_addr.S b/src/kernel/libsyscall/sys_i386/setaudit_addr.S deleted file mode 100644 index 83e5c6a3b..000000000 --- a/src/kernel/libsyscall/sys_i386/setaudit_addr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setaudit_addr -#error "SYS_setaudit_addr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setaudit_addr, setaudit_addr, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setauid.S b/src/kernel/libsyscall/sys_i386/setauid.S deleted file mode 100644 index 005e46a95..000000000 --- a/src/kernel/libsyscall/sys_i386/setauid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setauid -#error "SYS_setauid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setauid, setauid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setegid.S b/src/kernel/libsyscall/sys_i386/setegid.S deleted file mode 100644 index 077167d94..000000000 --- a/src/kernel/libsyscall/sys_i386/setegid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setegid -#error "SYS_setegid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setegid, setegid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/seteuid.S b/src/kernel/libsyscall/sys_i386/seteuid.S deleted file mode 100644 index a7465329f..000000000 --- a/src/kernel/libsyscall/sys_i386/seteuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_seteuid -#error "SYS_seteuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(seteuid, seteuid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setgid.S b/src/kernel/libsyscall/sys_i386/setgid.S deleted file mode 100644 index c1d2c406c..000000000 --- a/src/kernel/libsyscall/sys_i386/setgid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setgid -#error "SYS_setgid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setgid, setgid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setgroups.S b/src/kernel/libsyscall/sys_i386/setgroups.S deleted file mode 100644 index c4f08144a..000000000 --- a/src/kernel/libsyscall/sys_i386/setgroups.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setgroups -#error "SYS_setgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setgroups, setgroups, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setitimer.S b/src/kernel/libsyscall/sys_i386/setitimer.S deleted file mode 100644 index a54b523dd..000000000 --- a/src/kernel/libsyscall/sys_i386/setitimer.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_setitimer -#error "SYS_setitimer not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setitimer, setitimer, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setpgid.S b/src/kernel/libsyscall/sys_i386/setpgid.S deleted file mode 100644 index 5d7ebab8a..000000000 --- a/src/kernel/libsyscall/sys_i386/setpgid.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setpgid -#error "SYS_setpgid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setpgid, setpgid, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl setpgrp - setpgrp = setpgid -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setprivexec.S b/src/kernel/libsyscall/sys_i386/setprivexec.S deleted file mode 100644 index 1c63459d9..000000000 --- a/src/kernel/libsyscall/sys_i386/setprivexec.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setprivexec -#error "SYS_setprivexec not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setprivexec, setprivexec, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setquota.S b/src/kernel/libsyscall/sys_i386/setquota.S deleted file mode 100644 index 99487c218..000000000 --- a/src/kernel/libsyscall/sys_i386/setquota.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_setquota -#error "SYS_setquota not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setquota, setquota, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setsid.S b/src/kernel/libsyscall/sys_i386/setsid.S deleted file mode 100644 index 46d560ac0..000000000 --- a/src/kernel/libsyscall/sys_i386/setsid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_setsid -#error "SYS_setsid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setsid, setsid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setsockopt.S b/src/kernel/libsyscall/sys_i386/setsockopt.S deleted file mode 100644 index cae93ecf1..000000000 --- a/src/kernel/libsyscall/sys_i386/setsockopt.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_setsockopt -#error "SYS_setsockopt not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setsockopt, setsockopt, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setuid.S b/src/kernel/libsyscall/sys_i386/setuid.S deleted file mode 100644 index 8fa252f63..000000000 --- a/src/kernel/libsyscall/sys_i386/setuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setuid -#error "SYS_setuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setuid, setuid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/setxattr.S b/src/kernel/libsyscall/sys_i386/setxattr.S deleted file mode 100644 index 1ba7bbee9..000000000 --- a/src/kernel/libsyscall/sys_i386/setxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_setxattr -#error "SYS_setxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(setxattr, setxattr, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/shm_unlink.S b/src/kernel/libsyscall/sys_i386/shm_unlink.S deleted file mode 100644 index e6a0fc7c1..000000000 --- a/src/kernel/libsyscall/sys_i386/shm_unlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_shm_unlink -#error "SYS_shm_unlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(shm_unlink, shm_unlink, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/shmat.S b/src/kernel/libsyscall/sys_i386/shmat.S deleted file mode 100644 index 243ed72a6..000000000 --- a/src/kernel/libsyscall/sys_i386/shmat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_shmat -#error "SYS_shmat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(shmat, shmat, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/shmdt.S b/src/kernel/libsyscall/sys_i386/shmdt.S deleted file mode 100644 index 964098ef4..000000000 --- a/src/kernel/libsyscall/sys_i386/shmdt.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_shmdt -#error "SYS_shmdt not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(shmdt, shmdt, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/shmget.S b/src/kernel/libsyscall/sys_i386/shmget.S deleted file mode 100644 index b8311a4b3..000000000 --- a/src/kernel/libsyscall/sys_i386/shmget.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_shmget -#error "SYS_shmget not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(shmget, shmget, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/shutdown.S b/src/kernel/libsyscall/sys_i386/shutdown.S deleted file mode 100644 index 4c7af3041..000000000 --- a/src/kernel/libsyscall/sys_i386/shutdown.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_shutdown -#error "SYS_shutdown not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(shutdown, shutdown, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sigpending.S b/src/kernel/libsyscall/sys_i386/sigpending.S deleted file mode 100644 index b397443cb..000000000 --- a/src/kernel/libsyscall/sys_i386/sigpending.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sigpending -#error "SYS_sigpending not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(sigpending, sigpending, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sigprocmask.S b/src/kernel/libsyscall/sys_i386/sigprocmask.S deleted file mode 100644 index f72e5d301..000000000 --- a/src/kernel/libsyscall/sys_i386/sigprocmask.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_sigprocmask -#error "SYS_sigprocmask not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(sigprocmask, sigprocmask, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/socket.S b/src/kernel/libsyscall/sys_i386/socket.S deleted file mode 100644 index 6d4e72bd7..000000000 --- a/src/kernel/libsyscall/sys_i386/socket.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_socket -#error "SYS_socket not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(socket, socket, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/socket_delegate.S b/src/kernel/libsyscall/sys_i386/socket_delegate.S deleted file mode 100644 index 3a2bb893e..000000000 --- a/src/kernel/libsyscall/sys_i386/socket_delegate.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_socket_delegate -#error "SYS_socket_delegate not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(socket_delegate, socket_delegate, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/stat.S b/src/kernel/libsyscall/sys_i386/stat.S deleted file mode 100644 index bd3779aee..000000000 --- a/src/kernel/libsyscall/sys_i386/stat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_stat -#error "SYS_stat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(stat, stat, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/stat64.S b/src/kernel/libsyscall/sys_i386/stat64.S deleted file mode 100644 index b16fcc3ba..000000000 --- a/src/kernel/libsyscall/sys_i386/stat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_stat64 -#error "SYS_stat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(stat64, stat64, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl stat$INODE64 - stat$INODE64 = stat64 -#endif - diff --git a/src/kernel/libsyscall/sys_i386/statfs.S b/src/kernel/libsyscall/sys_i386/statfs.S deleted file mode 100644 index 916a27aad..000000000 --- a/src/kernel/libsyscall/sys_i386/statfs.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_statfs -#error "SYS_statfs not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(statfs, statfs, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/statfs64.S b/src/kernel/libsyscall/sys_i386/statfs64.S deleted file mode 100644 index 472c7a286..000000000 --- a/src/kernel/libsyscall/sys_i386/statfs64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_statfs64 -#error "SYS_statfs64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(statfs64, statfs64, 2, cerror_nocancel) -#endif - -#if defined(__i386__) - .globl statfs$INODE64 - statfs$INODE64 = statfs64 -#endif - diff --git a/src/kernel/libsyscall/sys_i386/stubs.list b/src/kernel/libsyscall/sys_i386/stubs.list deleted file mode 100644 index a7510155b..000000000 --- a/src/kernel/libsyscall/sys_i386/stubs.list +++ /dev/null @@ -1,388 +0,0 @@ -sys-i386/____old_semwait_signal_nocancel.s -sys-i386/____sigwait_nocancel.s -sys-i386/__accept.s -sys-i386/__accept_nocancel.s -sys-i386/__access_extended.s -sys-i386/__aio_suspend_nocancel.s -sys-i386/__bind.s -sys-i386/__bsdthread_create.s -sys-i386/__bsdthread_ctl.s -sys-i386/__bsdthread_register.s -sys-i386/__bsdthread_terminate.s -sys-i386/__chmod.s -sys-i386/__chmod_extended.s -sys-i386/__chud.s -sys-i386/__close_nocancel.s -sys-i386/__coalition.s -sys-i386/__coalition_info.s -sys-i386/__connect.s -sys-i386/__connect_nocancel.s -sys-i386/__copyfile.s -sys-i386/__csrctl.s -sys-i386/__delete.s -sys-i386/__disable_threadsignal.s -sys-i386/__exit.s -sys-i386/__fchmod.s -sys-i386/__fchmod_extended.s -sys-i386/__fcntl.s -sys-i386/__fcntl_nocancel.s -sys-i386/__fork.s -sys-i386/__fsgetpath.s -sys-i386/__fstat64_extended.s -sys-i386/__fstat_extended.s -sys-i386/__fsync_nocancel.s -sys-i386/__getattrlist.s -sys-i386/__getdirentries64.s -sys-i386/__gethostuuid.s -sys-i386/__getlcid.s -sys-i386/__getlogin.s -sys-i386/__getpeername.s -sys-i386/__getpid.s -sys-i386/__getrlimit.s -sys-i386/__getsgroups.s -sys-i386/__getsockname.s -sys-i386/__gettid.s -sys-i386/__gettimeofday.s -sys-i386/__getwgroups.s -sys-i386/__guarded_open_dprotected_np.s -sys-i386/__guarded_open_np.s -sys-i386/__identitysvc.s -sys-i386/__initgroups.s -sys-i386/__ioctl.s -sys-i386/__iopolicysys.s -sys-i386/__kdebug_trace.s -sys-i386/__kill.s -sys-i386/__lchown.s -sys-i386/__listen.s -sys-i386/__lseek.s -sys-i386/__lstat64_extended.s -sys-i386/__lstat_extended.s -sys-i386/__mac_execve.s -sys-i386/__mac_get_fd.s -sys-i386/__mac_get_file.s -sys-i386/__mac_get_lcid.s -sys-i386/__mac_get_lctx.s -sys-i386/__mac_get_link.s -sys-i386/__mac_get_mount.s -sys-i386/__mac_get_pid.s -sys-i386/__mac_get_proc.s -sys-i386/__mac_getfsstat.s -sys-i386/__mac_mount.s -sys-i386/__mac_set_fd.s -sys-i386/__mac_set_file.s -sys-i386/__mac_set_lctx.s -sys-i386/__mac_set_link.s -sys-i386/__mac_set_proc.s -sys-i386/__mac_syscall.s -sys-i386/__mkdir_extended.s -sys-i386/__mkfifo_extended.s -sys-i386/__mmap.s -sys-i386/__mprotect.s -sys-i386/__msgctl.s -sys-i386/__msgrcv_nocancel.s -sys-i386/__msgsnd_nocancel.s -sys-i386/__msgsys.s -sys-i386/__msync.s -sys-i386/__msync_nocancel.s -sys-i386/__munmap.s -sys-i386/__old_semwait_signal.s -sys-i386/__open.s -sys-i386/__open_dprotected_np.s -sys-i386/__open_extended.s -sys-i386/__open_nocancel.s -sys-i386/__openat.s -sys-i386/__openat_nocancel.s -sys-i386/__pipe.s -sys-i386/__poll_nocancel.s -sys-i386/__posix_spawn.s -sys-i386/__pread_nocancel.s -sys-i386/__proc_info.s -sys-i386/__process_policy.s -sys-i386/__psynch_cvbroad.s -sys-i386/__psynch_cvclrprepost.s -sys-i386/__psynch_cvsignal.s -sys-i386/__psynch_cvwait.s -sys-i386/__psynch_mutexdrop.s -sys-i386/__psynch_mutexwait.s -sys-i386/__psynch_rw_downgrade.s -sys-i386/__psynch_rw_longrdlock.s -sys-i386/__psynch_rw_rdlock.s -sys-i386/__psynch_rw_unlock.s -sys-i386/__psynch_rw_unlock2.s -sys-i386/__psynch_rw_upgrade.s -sys-i386/__psynch_rw_wrlock.s -sys-i386/__psynch_rw_yieldwrlock.s -sys-i386/__pthread_canceled.s -sys-i386/__pthread_chdir.s -sys-i386/__pthread_fchdir.s -sys-i386/__pthread_kill.s -sys-i386/__pthread_markcancel.s -sys-i386/__pthread_sigmask.s -sys-i386/__ptrace.s -sys-i386/__pwrite_nocancel.s -sys-i386/__read_nocancel.s -sys-i386/__readv_nocancel.s -sys-i386/__recvfrom.s -sys-i386/__recvfrom_nocancel.s -sys-i386/__recvmsg.s -sys-i386/__recvmsg_nocancel.s -sys-i386/__rename.s -sys-i386/__rename_ext.s -sys-i386/__renameat.s -sys-i386/__rmdir.s -sys-i386/__select.s -sys-i386/__select_nocancel.s -sys-i386/__sem_open.s -sys-i386/__sem_wait_nocancel.s -sys-i386/__semctl.s -sys-i386/__semsys.s -sys-i386/__semwait_signal.s -sys-i386/__semwait_signal_nocancel.s -sys-i386/__sendmsg.s -sys-i386/__sendmsg_nocancel.s -sys-i386/__sendto.s -sys-i386/__sendto_nocancel.s -sys-i386/__setattrlist.s -sys-i386/__setlcid.s -sys-i386/__setlogin.s -sys-i386/__setpriority.s -sys-i386/__setregid.s -sys-i386/__setreuid.s -sys-i386/__setrlimit.s -sys-i386/__setsgroups.s -sys-i386/__settid.s -sys-i386/__settid_with_pid.s -sys-i386/__settimeofday.s -sys-i386/__setwgroups.s -sys-i386/__sfi_ctl.s -sys-i386/__sfi_pidctl.s -sys-i386/__shared_region_check_np.s -sys-i386/__shared_region_map_and_slide_np.s -sys-i386/__shm_open.s -sys-i386/__shmctl.s -sys-i386/__shmsys.s -sys-i386/__sigaction.s -sys-i386/__sigaltstack.s -sys-i386/__sigreturn.s -sys-i386/__sigsuspend.s -sys-i386/__sigsuspend_nocancel.s -sys-i386/__sigwait.s -sys-i386/__socketpair.s -sys-i386/__stack_snapshot.s -sys-i386/__stat64_extended.s -sys-i386/__stat_extended.s -sys-i386/__syscall.s -sys-i386/__sysctl.s -sys-i386/__sysctlbyname.s -sys-i386/__telemetry.s -sys-i386/__thread_selfid.s -sys-i386/__thread_selfusage.s -sys-i386/__umask_extended.s -sys-i386/__unlink.s -sys-i386/__unlinkat.s -sys-i386/__vfork.s -sys-i386/__wait4.s -sys-i386/__wait4_nocancel.s -sys-i386/__waitid_nocancel.s -sys-i386/__workq_kernreturn.s -sys-i386/__workq_open.s -sys-i386/__write_nocancel.s -sys-i386/__writev_nocancel.s -sys-i386/access.s -sys-i386/acct.s -sys-i386/adjtime.s -sys-i386/aio_cancel.s -sys-i386/aio_error.s -sys-i386/aio_fsync.s -sys-i386/aio_read.s -sys-i386/aio_return.s -sys-i386/aio_suspend.s -sys-i386/aio_write.s -sys-i386/audit.s -sys-i386/audit_session_join.s -sys-i386/audit_session_port.s -sys-i386/audit_session_self.s -sys-i386/auditctl.s -sys-i386/auditon.s -sys-i386/change_fdguard_np.s -sys-i386/chdir.s -sys-i386/chflags.s -sys-i386/chown.s -sys-i386/chroot.s -sys-i386/close.s -sys-i386/connectx.s -sys-i386/csops.s -sys-i386/csops_audittoken.s -sys-i386/custom.s -sys-i386/disconnectx.s -sys-i386/dup.s -sys-i386/dup2.s -sys-i386/exchangedata.s -sys-i386/execve.s -sys-i386/faccessat.s -sys-i386/fchdir.s -sys-i386/fchflags.s -sys-i386/fchmodat.s -sys-i386/fchown.s -sys-i386/fchownat.s -sys-i386/fdatasync.s -sys-i386/ffsctl.s -sys-i386/fgetattrlist.s -sys-i386/fgetxattr.s -sys-i386/fhopen.s -sys-i386/fileport_makefd.s -sys-i386/fileport_makeport.s -sys-i386/flistxattr.s -sys-i386/flock.s -sys-i386/fpathconf.s -sys-i386/fremovexattr.s -sys-i386/fsctl.s -sys-i386/fsetattrlist.s -sys-i386/fsetxattr.s -sys-i386/fstat.s -sys-i386/fstat64.s -sys-i386/fstatat.s -sys-i386/fstatat64.s -sys-i386/fstatfs.s -sys-i386/fstatfs64.s -sys-i386/fsync.s -sys-i386/ftruncate.s -sys-i386/futimes.s -sys-i386/getattrlistat.s -sys-i386/getattrlistbulk.s -sys-i386/getaudit_addr.s -sys-i386/getauid.s -sys-i386/getdirentries.s -sys-i386/getdirentriesattr.s -sys-i386/getdtablesize.s -sys-i386/getegid.s -sys-i386/geteuid.s -sys-i386/getfh.s -sys-i386/getfsstat.s -sys-i386/getfsstat64.s -sys-i386/getgid.s -sys-i386/getgroups.s -sys-i386/getitimer.s -sys-i386/getpgid.s -sys-i386/getpgrp.s -sys-i386/getppid.s -sys-i386/getpriority.s -sys-i386/getrusage.s -sys-i386/getsid.s -sys-i386/getsockopt.s -sys-i386/getuid.s -sys-i386/getxattr.s -sys-i386/guarded_close_np.s -sys-i386/guarded_kqueue_np.s -sys-i386/guarded_pwrite_np.s -sys-i386/guarded_write_np.s -sys-i386/guarded_writev_np.s -sys-i386/issetugid.s -sys-i386/kas_info.s -sys-i386/kevent.s -sys-i386/kevent64.s -sys-i386/kqueue.s -sys-i386/ledger.s -sys-i386/link.s -sys-i386/linkat.s -sys-i386/lio_listio.s -sys-i386/listxattr.s -sys-i386/lstat.s -sys-i386/lstat64.s -sys-i386/madvise.s -sys-i386/memorystatus_control.s -sys-i386/memorystatus_get_level.s -sys-i386/mincore.s -sys-i386/minherit.s -sys-i386/mkdir.s -sys-i386/mkdirat.s -sys-i386/mkfifo.s -sys-i386/mknod.s -sys-i386/mlock.s -sys-i386/mlockall.s -sys-i386/modwatch.s -sys-i386/mount.s -sys-i386/mremap_encrypted.s -sys-i386/msgget.s -sys-i386/msgrcv.s -sys-i386/msgsnd.s -sys-i386/munlock.s -sys-i386/munlockall.s -sys-i386/necp_match_policy.s -sys-i386/nfsclnt.s -sys-i386/nfssvc.s -sys-i386/openbyid_np.s -sys-i386/pathconf.s -sys-i386/peeloff.s -sys-i386/pid_resume.s -sys-i386/pid_suspend.s -sys-i386/poll.s -sys-i386/pread.s -sys-i386/proc_rlimit_control.s -sys-i386/proc_trace_log.s -sys-i386/proc_uuid_policy.s -sys-i386/pwrite.s -sys-i386/quota.s -sys-i386/quotactl.s -sys-i386/read.s -sys-i386/readlink.s -sys-i386/readlinkat.s -sys-i386/readv.s -sys-i386/reboot.s -sys-i386/recvmsg_x.s -sys-i386/removexattr.s -sys-i386/revoke.s -sys-i386/searchfs.s -sys-i386/sem_close.s -sys-i386/sem_post.s -sys-i386/sem_trywait.s -sys-i386/sem_unlink.s -sys-i386/sem_wait.s -sys-i386/semget.s -sys-i386/semop.s -sys-i386/sendfile.s -sys-i386/sendmsg_x.s -sys-i386/setaudit_addr.s -sys-i386/setauid.s -sys-i386/setegid.s -sys-i386/seteuid.s -sys-i386/setgid.s -sys-i386/setgroups.s -sys-i386/setitimer.s -sys-i386/setpgid.s -sys-i386/setprivexec.s -sys-i386/setquota.s -sys-i386/setsid.s -sys-i386/setsockopt.s -sys-i386/setuid.s -sys-i386/setxattr.s -sys-i386/shm_unlink.s -sys-i386/shmat.s -sys-i386/shmdt.s -sys-i386/shmget.s -sys-i386/shutdown.s -sys-i386/sigpending.s -sys-i386/sigprocmask.s -sys-i386/socket.s -sys-i386/socket_delegate.s -sys-i386/stat.s -sys-i386/stat64.s -sys-i386/statfs.s -sys-i386/statfs64.s -sys-i386/swapon.s -sys-i386/symlink.s -sys-i386/symlinkat.s -sys-i386/sync.s -sys-i386/system_override.s -sys-i386/truncate.s -sys-i386/umask.s -sys-i386/undelete.s -sys-i386/unmount.s -sys-i386/utimes.s -sys-i386/vfs_purge.s -sys-i386/vm_pressure_monitor.s -sys-i386/waitevent.s -sys-i386/waitid.s -sys-i386/watchevent.s -sys-i386/write.s -sys-i386/writev.s diff --git a/src/kernel/libsyscall/sys_i386/swapon.S b/src/kernel/libsyscall/sys_i386/swapon.S deleted file mode 100644 index b88a2a6e1..000000000 --- a/src/kernel/libsyscall/sys_i386/swapon.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_swapon -#error "SYS_swapon not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(swapon, swapon, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/symlink.S b/src/kernel/libsyscall/sys_i386/symlink.S deleted file mode 100644 index 52536a85b..000000000 --- a/src/kernel/libsyscall/sys_i386/symlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_symlink -#error "SYS_symlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(symlink, symlink, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/symlinkat.S b/src/kernel/libsyscall/sys_i386/symlinkat.S deleted file mode 100644 index c2afbd58f..000000000 --- a/src/kernel/libsyscall/sys_i386/symlinkat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_symlinkat -#error "SYS_symlinkat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(symlinkat, symlinkat, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/sync.S b/src/kernel/libsyscall/sys_i386/sync.S deleted file mode 100644 index 580ba1aaf..000000000 --- a/src/kernel/libsyscall/sys_i386/sync.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_sync -#error "SYS_sync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(sync, sync, 0, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/system_override.S b/src/kernel/libsyscall/sys_i386/system_override.S deleted file mode 100644 index 7b3bf7bc4..000000000 --- a/src/kernel/libsyscall/sys_i386/system_override.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_system_override -#error "SYS_system_override not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(system_override, system_override, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/truncate.S b/src/kernel/libsyscall/sys_i386/truncate.S deleted file mode 100644 index 696610c57..000000000 --- a/src/kernel/libsyscall/sys_i386/truncate.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_truncate -#error "SYS_truncate not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(truncate, truncate, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/umask.S b/src/kernel/libsyscall/sys_i386/umask.S deleted file mode 100644 index 77c886825..000000000 --- a/src/kernel/libsyscall/sys_i386/umask.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_umask -#error "SYS_umask not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(umask, umask, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/undelete.S b/src/kernel/libsyscall/sys_i386/undelete.S deleted file mode 100644 index 26030d90a..000000000 --- a/src/kernel/libsyscall/sys_i386/undelete.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_undelete -#error "SYS_undelete not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(undelete, undelete, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/unmount.S b/src/kernel/libsyscall/sys_i386/unmount.S deleted file mode 100644 index 7802b0619..000000000 --- a/src/kernel/libsyscall/sys_i386/unmount.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_unmount -#error "SYS_unmount not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(unmount, unmount, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/utimes.S b/src/kernel/libsyscall/sys_i386/utimes.S deleted file mode 100644 index 9348c082a..000000000 --- a/src/kernel/libsyscall/sys_i386/utimes.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_utimes -#error "SYS_utimes not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(utimes, utimes, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/vfs_purge.S b/src/kernel/libsyscall/sys_i386/vfs_purge.S deleted file mode 100644 index fff651bb3..000000000 --- a/src/kernel/libsyscall/sys_i386/vfs_purge.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_vfs_purge -#error "SYS_vfs_purge not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(vfs_purge, vfs_purge, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/vm_pressure_monitor.S b/src/kernel/libsyscall/sys_i386/vm_pressure_monitor.S deleted file mode 100644 index be6992315..000000000 --- a/src/kernel/libsyscall/sys_i386/vm_pressure_monitor.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_vm_pressure_monitor -#error "SYS_vm_pressure_monitor not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(vm_pressure_monitor, vm_pressure_monitor, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/waitevent.S b/src/kernel/libsyscall/sys_i386/waitevent.S deleted file mode 100644 index 69d3d6296..000000000 --- a/src/kernel/libsyscall/sys_i386/waitevent.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_waitevent -#error "SYS_waitevent not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(waitevent, waitevent, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/waitid.S b/src/kernel/libsyscall/sys_i386/waitid.S deleted file mode 100644 index 3bd582802..000000000 --- a/src/kernel/libsyscall/sys_i386/waitid.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_waitid -#error "SYS_waitid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__waitid, waitid, 1, cerror) -#endif - - -#if defined(__i386__) - .globl waitid$UNIX2003 - waitid$UNIX2003 = __waitid -#endif - diff --git a/src/kernel/libsyscall/sys_i386/watchevent.S b/src/kernel/libsyscall/sys_i386/watchevent.S deleted file mode 100644 index a5fee9852..000000000 --- a/src/kernel/libsyscall/sys_i386/watchevent.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_watchevent -#error "SYS_watchevent not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(watchevent, watchevent, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_i386/write.S b/src/kernel/libsyscall/sys_i386/write.S deleted file mode 100644 index 6021d344e..000000000 --- a/src/kernel/libsyscall/sys_i386/write.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_write -#error "SYS_write not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__write, write, 1, cerror) -#endif - - -#if defined(__i386__) - .globl write$UNIX2003 - write$UNIX2003 = __write -#endif - diff --git a/src/kernel/libsyscall/sys_i386/writev.S b/src/kernel/libsyscall/sys_i386/writev.S deleted file mode 100644 index c02975fd3..000000000 --- a/src/kernel/libsyscall/sys_i386/writev.S +++ /dev/null @@ -1,17 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_writev -#error "SYS_writev not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__i386__) -__SYSCALL2(__writev, writev, 1, cerror) -#endif - - -#if defined(__i386__) - .globl writev$UNIX2003 - writev$UNIX2003 = __writev -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/SYS.h b/src/kernel/libsyscall/sys_x86-64/SYS.h deleted file mode 100644 index 6b8fdbb86..000000000 --- a/src/kernel/libsyscall/sys_x86-64/SYS.h +++ /dev/null @@ -1,213 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2011 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: SYS.h - * - * Definition of the user side of the UNIX system call interface - * for M98K. - * - * Errors are flagged by the location of the trap return (ie., which - * instruction is executed upon rfi): - * - * SC PC + 4: Error (typically branch to cerror()) - * SC PC + 8: Success - * - * HISTORY - * 18-Nov-92 Ben Fathi (benf@next.com) - * Ported to m98k. - * - * 9-Jan-92 Peter King (king@next.com) - * Created. - */ - -#include - -/* Binary compatibility stubs for syscalls that no longer exist */ - -#ifndef SYS_setquota -#define SYS_setquota 148 -#endif -#ifndef SYS_quota -#define SYS_quota 149 -#endif - -#if defined(__i386__) - -#include -#include - -/* - * We have two entry points. int's is used for syscalls which need to preserve - * %ecx across the call, or return a 64-bit value in %eax:%edx. sysenter is used - * for the majority of syscalls which just return a value in %eax. - */ - -#ifndef DARLING -#define UNIX_SYSCALL_SYSENTER call __sysenter_trap -#else -#define UNIX_SYSCALL_SYSENTER call __darling_bsd_syscall -#endif - -#define UNIX_SYSCALL(name, nargs) \ - .globl tramp_cerror ;\ -LEAF(_##name, 0) ;\ - movl $ SYS_##name, %eax ;\ - UNIX_SYSCALL_SYSENTER ;\ - jnb 2f ;\ - BRANCH_EXTERN(tramp_cerror) ;\ -2: - -#define UNIX_SYSCALL_INT(name, nargs) \ - .globl tramp_cerror ;\ -LEAF(_##name, 0) ;\ - movl $ SYS_##name, %eax ;\ - UNIX_SYSCALL_TRAP ;\ - jnb 2f ;\ - BRANCH_EXTERN(tramp_cerror) ;\ -2: - -#if defined(__SYSCALL_32BIT_ARG_BYTES) && ((__SYSCALL_32BIT_ARG_BYTES >= 4) && (__SYSCALL_32BIT_ARG_BYTES <= 20)) -#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ - movl $(SYS_##name | (__SYSCALL_32BIT_ARG_BYTES << I386_SYSCALL_ARG_BYTES_SHIFT)), %eax ;\ - UNIX_SYSCALL_SYSENTER ;\ - jnb 2f ;\ - BRANCH_EXTERN(tramp_##cerror) ;\ -2: -#else /* __SYSCALL_32BIT_ARG_BYTES < 4 || > 20 */ -#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ - movl $ SYS_##name, %eax ;\ - UNIX_SYSCALL_SYSENTER ;\ - jnb 2f ;\ - BRANCH_EXTERN(tramp_##cerror) ;\ -2: -#endif - -#define UNIX_SYSCALL_INT_NONAME(name, nargs) \ - .globl tramp_cerror_nocancel ;\ - movl $ SYS_##name, %eax ;\ - UNIX_SYSCALL_TRAP ;\ - jnb 2f ;\ - BRANCH_EXTERN(tramp_cerror_nocancel) ;\ -2: - -#define PSEUDO(pseudo, name, nargs, cerror) \ -LEAF(pseudo, 0) ;\ - UNIX_SYSCALL_NONAME(name, nargs, cerror) - -#define PSEUDO_INT(pseudo, name, nargs) \ -LEAF(pseudo, 0) ;\ - UNIX_SYSCALL_INT_NONAME(name, nargs) - -#define __SYSCALL2(pseudo, name, nargs, cerror) \ - PSEUDO(pseudo, name, nargs, cerror) ;\ - ret - -#define __SYSCALL(pseudo, name, nargs) \ - PSEUDO(pseudo, name, nargs, cerror) ;\ - ret - -#define __SYSCALL_INT(pseudo, name, nargs) \ - PSEUDO_INT(pseudo, name, nargs) ;\ - ret - -#elif defined(__x86_64__) - -#include -#include - -#ifdef DARLING - -#define UNIX_SYSCALL(name, nargs) \ - .globl cerror ;\ -LEAF(_#name, 0) ;\ - movl $ SYS_##name, %eax ;\ - call __darling_bsd_syscall ;\ - cmpq $-4095, %rax ;\ - jb 2f ;\ - movq %rax, %rdi ;\ - negq %rdi ;\ - BRANCH_EXTERN(_cerror) ;\ -2: - -#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ - .globl cerror ;\ - movl $ SYS_##name, %eax ;\ - call __darling_bsd_syscall ;\ - cmpq $-4095, %rax ;\ - jb 2f ;\ - movq %rax, %rdi ;\ - negq %rdi ;\ - BRANCH_EXTERN(_##cerror) ;\ -2: - - -#else - -#define UNIX_SYSCALL_SYSCALL \ - movq %rcx, %r10 ;\ - syscall - -#define UNIX_SYSCALL(name, nargs) \ - .globl cerror ;\ -LEAF(_##name, 0) ;\ - movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ - UNIX_SYSCALL_SYSCALL ;\ - jnb 2f ;\ - movq %rax, %rdi ;\ - BRANCH_EXTERN(_cerror) ;\ -2: - -#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \ - .globl cerror ;\ - movl $ SYSCALL_CONSTRUCT_UNIX(SYS_##name), %eax ;\ - UNIX_SYSCALL_SYSCALL ;\ - jnb 2f ;\ - movq %rax, %rdi ;\ - BRANCH_EXTERN(_##cerror) ;\ -2: - -#endif // DARLING - -#define PSEUDO(pseudo, name, nargs, cerror) \ -LEAF(pseudo, 0) ;\ - UNIX_SYSCALL_NONAME(name, nargs, cerror) - -#define __SYSCALL2(pseudo, name, nargs, cerror) \ - PSEUDO(pseudo, name, nargs, cerror) ;\ - ret - -#define __SYSCALL(pseudo, name, nargs) \ - PSEUDO(pseudo, name, nargs, cerror) ;\ - ret - -#else -#error Unsupported architecture -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_____old_semwait_signal_nocancel.S b/src/kernel/libsyscall/sys_x86-64/_____old_semwait_signal_nocancel.S deleted file mode 100644 index 35e761dc2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_____old_semwait_signal_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS___old_semwait_signal_nocancel -#error "SYS___old_semwait_signal_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_____old_semwait_signal_nocancel, __old_semwait_signal_nocancel, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_____sigwait_nocancel.S b/src/kernel/libsyscall/sys_x86-64/_____sigwait_nocancel.S deleted file mode 100644 index 7db68cc0c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_____sigwait_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___sigwait_nocancel -#error "SYS___sigwait_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_____sigwait_nocancel, __sigwait_nocancel, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___accept.S b/src/kernel/libsyscall/sys_x86-64/___accept.S deleted file mode 100644 index b067802cb..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___accept.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_accept -#error "SYS_accept not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___accept, accept, 3, cerror) -#endif - -#if defined(__x86_64__) - .globl _accept - .set _accept, ___accept -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___accept_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___accept_nocancel.S deleted file mode 100644 index 8b287705e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___accept_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_accept_nocancel -#error "SYS_accept_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___accept_nocancel, accept_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _accept$NOCANCEL - .set _accept$NOCANCEL, ___accept_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___access_extended.S b/src/kernel/libsyscall/sys_x86-64/___access_extended.S deleted file mode 100644 index 9ed0215b0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___access_extended.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_access_extended -#error "SYS_access_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___access_extended, access_extended, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _accessx_np - .set _accessx_np, ___access_extended -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___aio_suspend_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___aio_suspend_nocancel.S deleted file mode 100644 index 8af75b52c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___aio_suspend_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_aio_suspend_nocancel -#error "SYS_aio_suspend_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___aio_suspend_nocancel, aio_suspend_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _aio_suspend$NOCANCEL - .set _aio_suspend$NOCANCEL, ___aio_suspend_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___bind.S b/src/kernel/libsyscall/sys_x86-64/___bind.S deleted file mode 100644 index 04aaf1e63..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___bind.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_bind -#error "SYS_bind not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___bind, bind, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _bind - .set _bind, ___bind -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___bsdthread_create.S b/src/kernel/libsyscall/sys_x86-64/___bsdthread_create.S deleted file mode 100644 index 81ab10c82..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___bsdthread_create.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_bsdthread_create -#error "SYS_bsdthread_create not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___bsdthread_create, bsdthread_create, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___bsdthread_ctl.S b/src/kernel/libsyscall/sys_x86-64/___bsdthread_ctl.S deleted file mode 100644 index 2301903eb..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___bsdthread_ctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_bsdthread_ctl -#error "SYS_bsdthread_ctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___bsdthread_ctl, bsdthread_ctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___bsdthread_register.S b/src/kernel/libsyscall/sys_x86-64/___bsdthread_register.S deleted file mode 100644 index 4f7a244c8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___bsdthread_register.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_bsdthread_register -#error "SYS_bsdthread_register not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___bsdthread_register, bsdthread_register, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___bsdthread_terminate.S b/src/kernel/libsyscall/sys_x86-64/___bsdthread_terminate.S deleted file mode 100644 index 7088590df..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___bsdthread_terminate.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_bsdthread_terminate -#error "SYS_bsdthread_terminate not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___bsdthread_terminate, bsdthread_terminate, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___chmod.S b/src/kernel/libsyscall/sys_x86-64/___chmod.S deleted file mode 100644 index 8224c55e4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___chmod.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_chmod -#error "SYS_chmod not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___chmod, chmod, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___chmod_extended.S b/src/kernel/libsyscall/sys_x86-64/___chmod_extended.S deleted file mode 100644 index 45d2ae2cb..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___chmod_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_chmod_extended -#error "SYS_chmod_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___chmod_extended, chmod_extended, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___close_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___close_nocancel.S deleted file mode 100644 index 1f8bb8e2a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___close_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_close_nocancel -#error "SYS_close_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___close_nocancel, close_nocancel, 1, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _close$NOCANCEL - .set _close$NOCANCEL, ___close_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___coalition.S b/src/kernel/libsyscall/sys_x86-64/___coalition.S deleted file mode 100644 index 2ad2ac486..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___coalition.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_coalition -#error "SYS_coalition not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___coalition, coalition, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___coalition_info.S b/src/kernel/libsyscall/sys_x86-64/___coalition_info.S deleted file mode 100644 index f838d91bc..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___coalition_info.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_coalition_info -#error "SYS_coalition_info not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___coalition_info, coalition_info, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___connect.S b/src/kernel/libsyscall/sys_x86-64/___connect.S deleted file mode 100644 index 0a34cb9b0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___connect.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_connect -#error "SYS_connect not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___connect, connect, 3, cerror) -#endif - -#if defined(__x86_64__) - .globl _connect - .set _connect, ___connect -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___connect_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___connect_nocancel.S deleted file mode 100644 index fbbc9f027..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___connect_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_connect_nocancel -#error "SYS_connect_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___connect_nocancel, connect_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _connect$NOCANCEL - .set _connect$NOCANCEL, ___connect_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___copyfile.S b/src/kernel/libsyscall/sys_x86-64/___copyfile.S deleted file mode 100644 index 124a253e8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___copyfile.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_copyfile -#error "SYS_copyfile not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___copyfile, copyfile, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___csrctl.S b/src/kernel/libsyscall/sys_x86-64/___csrctl.S deleted file mode 100644 index 13b0aaac2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___csrctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_csrctl -#error "SYS_csrctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___csrctl, csrctl, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___delete.S b/src/kernel/libsyscall/sys_x86-64/___delete.S deleted file mode 100644 index 991912038..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___delete.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_delete -#error "SYS_delete not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___delete, delete, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___disable_threadsignal.S b/src/kernel/libsyscall/sys_x86-64/___disable_threadsignal.S deleted file mode 100644 index a2a3a8d57..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___disable_threadsignal.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___disable_threadsignal -#error "SYS___disable_threadsignal not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___disable_threadsignal, __disable_threadsignal, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___exit.S b/src/kernel/libsyscall/sys_x86-64/___exit.S deleted file mode 100644 index 7c69cc6d1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___exit.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_exit -#error "SYS_exit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___exit, exit, 1, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl __exit - .set __exit, ___exit -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___fchmod.S b/src/kernel/libsyscall/sys_x86-64/___fchmod.S deleted file mode 100644 index 4adfcb79c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___fchmod.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fchmod -#error "SYS_fchmod not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___fchmod, fchmod, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___fchmod_extended.S b/src/kernel/libsyscall/sys_x86-64/___fchmod_extended.S deleted file mode 100644 index a3115a921..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___fchmod_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fchmod_extended -#error "SYS_fchmod_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___fchmod_extended, fchmod_extended, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___fcntl.S b/src/kernel/libsyscall/sys_x86-64/___fcntl.S deleted file mode 100644 index 5f7df46e4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___fcntl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_fcntl -#error "SYS_fcntl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___fcntl, fcntl, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___fcntl_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___fcntl_nocancel.S deleted file mode 100644 index 463f9724f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___fcntl_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_fcntl_nocancel -#error "SYS_fcntl_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___fcntl_nocancel, fcntl_nocancel, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___fork.S b/src/kernel/libsyscall/sys_x86-64/___fork.S deleted file mode 100644 index 4e26ec7c2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___fork.S +++ /dev/null @@ -1,117 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2010 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: libc/ppc/sys/fork.s - * - * HISTORY - * 18-Nov-92 Ben Fathi (benf@next.com) - * Created from M88K sources - * - * 11-Jan-92 Peter King (king@next.com) - * Created from M68K sources - */ - -/* - * All of the asm stubs in this file have been adjusted so the pre/post - * fork handlers and dyld fixup are done in C inside Libc. As such, Libc - * expects the __fork asm to fix up the return code to be -1, 0 or pid - * and errno if needed. - */ - -#include "SYS.h" - -#if defined(__i386__) - -LEAF(___fork, 0) - subl $28, %esp // Align the stack, with 16 bytes of extra padding that we'll need - - movl $ SYS_fork,%eax; // code for fork -> eax - UNIX_SYSCALL_TRAP // do the system call - jnc L1 // jump if CF==0 - - CALL_EXTERN(tramp_cerror) - movl $-1,%eax - addl $28, %esp // restore the stack - ret - -L1: - orl %edx,%edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - - //child here... - xorl %eax,%eax // zero eax - REG_TO_EXTERN(%eax, __current_pid); -L2: - addl $28, %esp // restore the stack - // parent ends up here skipping child portion - ret - -#elif defined(__x86_64__) - -LEAF(___fork, 0) - subq $24, %rsp // Align the stack, plus room for local storage - -#ifndef DARLING - movl $ SYSCALL_CONSTRUCT_UNIX(SYS_fork),%eax; // code for fork -> rax - UNIX_SYSCALL_TRAP // do the system call - jnc L1 // jump if CF==0 -#else - movl $ SYS_fork, %eax - call __darling_bsd_syscall - cmpq $0, %rax - jnb L1 -#endif - movq %rax, %rdi - CALL_EXTERN(_cerror) - movq $-1, %rax - addq $24, %rsp // restore the stack - ret - -L1: -#ifndef DARLING - orl %edx,%edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child -#else - testl %eax, %eax - jnz L2 -#endif - - //child here... - xorq %rax, %rax - PICIFY(__current_pid) - movl %eax,(%r11) -L2: - // parent ends up here skipping child portion - addq $24, %rsp // restore the stack - ret - -#else -#error Unsupported architecture -#endif diff --git a/src/kernel/libsyscall/sys_x86-64/___fsgetpath.S b/src/kernel/libsyscall/sys_x86-64/___fsgetpath.S deleted file mode 100644 index 41a694b5b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___fsgetpath.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fsgetpath -#error "SYS_fsgetpath not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___fsgetpath, fsgetpath, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___fstat64_extended.S b/src/kernel/libsyscall/sys_x86-64/___fstat64_extended.S deleted file mode 100644 index 3dbbc54ef..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___fstat64_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fstat64_extended -#error "SYS_fstat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___fstat64_extended, fstat64_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___fstat_extended.S b/src/kernel/libsyscall/sys_x86-64/___fstat_extended.S deleted file mode 100644 index b919b5c38..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___fstat_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fstat_extended -#error "SYS_fstat_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___fstat_extended, fstat_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___fsync_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___fsync_nocancel.S deleted file mode 100644 index bdd8472c9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___fsync_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fsync_nocancel -#error "SYS_fsync_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___fsync_nocancel, fsync_nocancel, 1, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _fsync$NOCANCEL - .set _fsync$NOCANCEL, ___fsync_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___getattrlist.S b/src/kernel/libsyscall/sys_x86-64/___getattrlist.S deleted file mode 100644 index 8374c43d3..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___getattrlist.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_getattrlist -#error "SYS_getattrlist not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___getattrlist, getattrlist, 5, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _getattrlist - .set _getattrlist, ___getattrlist -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___getdirentries64.S b/src/kernel/libsyscall/sys_x86-64/___getdirentries64.S deleted file mode 100644 index 80d6a6ad8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___getdirentries64.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_getdirentries64 -#error "SYS_getdirentries64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___getdirentries64, getdirentries64, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___gethostuuid.S b/src/kernel/libsyscall/sys_x86-64/___gethostuuid.S deleted file mode 100644 index eaa088294..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___gethostuuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_gethostuuid -#error "SYS_gethostuuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___gethostuuid, gethostuuid, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___getlogin.S b/src/kernel/libsyscall/sys_x86-64/___getlogin.S deleted file mode 100644 index 8c8c018e1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___getlogin.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getlogin -#error "SYS_getlogin not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___getlogin, getlogin, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___getpeername.S b/src/kernel/libsyscall/sys_x86-64/___getpeername.S deleted file mode 100644 index dfc705359..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___getpeername.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_getpeername -#error "SYS_getpeername not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___getpeername, getpeername, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _getpeername - .set _getpeername, ___getpeername -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___getpid.S b/src/kernel/libsyscall/sys_x86-64/___getpid.S deleted file mode 100644 index f3e75802b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___getpid.S +++ /dev/null @@ -1,110 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include "SYS.h" - -#if defined(__i386__) - - .data - .globl __current_pid - .private_extern __current_pid -L__current_pid_addr: - __current_pid: - .long 0 - -#if defined(__DYNAMIC__) -#define GET_CURRENT_PID \ - call 0f ; \ -0: ; \ - popl %ecx ; \ - leal L__current_pid_addr-0b(%ecx), %ecx - -#define __current_pid (%ecx) - -#else -#define GET_CURRENT_PID -#endif - -/* - * If __current_pid is > 0, return it, else make syscall. - * If __current_pid is 0, cache result of syscall. - */ -TEXT -LEAF(___getpid, 0) - GET_CURRENT_PID - movl __current_pid, %eax - testl %eax, %eax - jle 1f - ret -1: - UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) - movl %eax, %edx - xorl %eax, %eax - GET_CURRENT_PID - lock - cmpxchgl %edx, __current_pid - movl %edx, %eax - ret - -#elif defined(__x86_64__) - - .data - .globl __current_pid - .private_extern __current_pid -__current_pid: - .long 0 - -/* - * If __current_pid is > 0, return it, else make syscall. - * If __current_pid is 0, cache result of syscall. - */ -TEXT -LEAF(___getpid, 0) - movl __current_pid(%rip), %eax - testl %eax, %eax - jle 1f - ret -1: - UNIX_SYSCALL_NONAME(getpid, 0, cerror_nocancel) - movl %eax, %edx - xorl %eax, %eax - leaq __current_pid(%rip), %rcx - lock - cmpxchgl %edx, (%rcx) - movl %edx, %eax - ret - -#else -#error Unsupported architecture -#endif -#if defined(__x86_64__) - .globl _getpid - .set _getpid, ___getpid -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___getrlimit.S b/src/kernel/libsyscall/sys_x86-64/___getrlimit.S deleted file mode 100644 index f19e881fd..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___getrlimit.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getrlimit -#error "SYS_getrlimit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___getrlimit, getrlimit, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___getsgroups.S b/src/kernel/libsyscall/sys_x86-64/___getsgroups.S deleted file mode 100644 index d3a25d571..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___getsgroups.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getsgroups -#error "SYS_getsgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___getsgroups, getsgroups, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _getsgroups_np - .set _getsgroups_np, ___getsgroups -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___getsockname.S b/src/kernel/libsyscall/sys_x86-64/___getsockname.S deleted file mode 100644 index 8b98c8361..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___getsockname.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_getsockname -#error "SYS_getsockname not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___getsockname, getsockname, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _getsockname - .set _getsockname, ___getsockname -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___gettid.S b/src/kernel/libsyscall/sys_x86-64/___gettid.S deleted file mode 100644 index dc8394035..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___gettid.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_gettid -#error "SYS_gettid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___gettid, gettid, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _pthread_getugid_np - .set _pthread_getugid_np, ___gettid -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___getwgroups.S b/src/kernel/libsyscall/sys_x86-64/___getwgroups.S deleted file mode 100644 index d93e7ed87..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___getwgroups.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getwgroups -#error "SYS_getwgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___getwgroups, getwgroups, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _getwgroups_np - .set _getwgroups_np, ___getwgroups -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___guarded_open_dprotected_np.S b/src/kernel/libsyscall/sys_x86-64/___guarded_open_dprotected_np.S deleted file mode 100644 index 58df04b77..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___guarded_open_dprotected_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_guarded_open_dprotected_np -#error "SYS_guarded_open_dprotected_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___guarded_open_dprotected_np, guarded_open_dprotected_np, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___guarded_open_np.S b/src/kernel/libsyscall/sys_x86-64/___guarded_open_np.S deleted file mode 100644 index fa0868336..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___guarded_open_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_guarded_open_np -#error "SYS_guarded_open_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___guarded_open_np, guarded_open_np, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___identitysvc.S b/src/kernel/libsyscall/sys_x86-64/___identitysvc.S deleted file mode 100644 index fdbc8bfac..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___identitysvc.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_identitysvc -#error "SYS_identitysvc not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___identitysvc, identitysvc, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___initgroups.S b/src/kernel/libsyscall/sys_x86-64/___initgroups.S deleted file mode 100644 index 7ad04d07a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___initgroups.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_initgroups -#error "SYS_initgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___initgroups, initgroups, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___ioctl.S b/src/kernel/libsyscall/sys_x86-64/___ioctl.S deleted file mode 100644 index 2c518a375..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___ioctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_ioctl -#error "SYS_ioctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___ioctl, ioctl, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___iopolicysys.S b/src/kernel/libsyscall/sys_x86-64/___iopolicysys.S deleted file mode 100644 index 1fe60fcd4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___iopolicysys.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_iopolicysys -#error "SYS_iopolicysys not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___iopolicysys, iopolicysys, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___kdebug_trace.S b/src/kernel/libsyscall/sys_x86-64/___kdebug_trace.S deleted file mode 100644 index f10a62d86..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___kdebug_trace.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_kdebug_trace -#error "SYS_kdebug_trace not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___kdebug_trace, kdebug_trace, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___kdebug_trace64.S b/src/kernel/libsyscall/sys_x86-64/___kdebug_trace64.S deleted file mode 100644 index ffc23d7b9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___kdebug_trace64.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 36 -#include "SYS.h" - -#ifndef SYS_kdebug_trace64 -#error "SYS_kdebug_trace64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___kdebug_trace64, kdebug_trace64, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___kdebug_trace_string.S b/src/kernel/libsyscall/sys_x86-64/___kdebug_trace_string.S deleted file mode 100644 index 4f4595d78..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___kdebug_trace_string.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_kdebug_trace_string -#error "SYS_kdebug_trace_string not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___kdebug_trace_string, kdebug_trace_string, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___kill.S b/src/kernel/libsyscall/sys_x86-64/___kill.S deleted file mode 100644 index 2ba63bb86..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___kill.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_kill -#error "SYS_kill not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___kill, kill, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___lchown.S b/src/kernel/libsyscall/sys_x86-64/___lchown.S deleted file mode 100644 index 9e768e1b6..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___lchown.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_lchown -#error "SYS_lchown not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___lchown, lchown, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _lchown - .set _lchown, ___lchown -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___listen.S b/src/kernel/libsyscall/sys_x86-64/___listen.S deleted file mode 100644 index d186717a5..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___listen.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_listen -#error "SYS_listen not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___listen, listen, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _listen - .set _listen, ___listen -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___lseek.S b/src/kernel/libsyscall/sys_x86-64/___lseek.S deleted file mode 100644 index fbaf70d08..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___lseek.S +++ /dev/null @@ -1,47 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include "SYS.h" - -#if defined(__x86_64__) - -__SYSCALL(___lseek, lseek, 3) - -#elif defined(__i386__) - -__SYSCALL_INT(___lseek, lseek, 3) - -#else -#error Unsupported architecture -#endif -#if defined(__x86_64__) - .globl _lseek - .set _lseek, ___lseek -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___lstat64_extended.S b/src/kernel/libsyscall/sys_x86-64/___lstat64_extended.S deleted file mode 100644 index 5241a62d9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___lstat64_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_lstat64_extended -#error "SYS_lstat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___lstat64_extended, lstat64_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___lstat_extended.S b/src/kernel/libsyscall/sys_x86-64/___lstat_extended.S deleted file mode 100644 index 461103d96..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___lstat_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_lstat_extended -#error "SYS_lstat_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___lstat_extended, lstat_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_execve.S b/src/kernel/libsyscall/sys_x86-64/___mac_execve.S deleted file mode 100644 index 770ce3110..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_execve.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS___mac_execve -#error "SYS___mac_execve not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_execve, __mac_execve, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl ___sandbox_me - .set ___sandbox_me, ___mac_execve -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_get_fd.S b/src/kernel/libsyscall/sys_x86-64/___mac_get_fd.S deleted file mode 100644 index d510ee38a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_get_fd.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_fd -#error "SYS___mac_get_fd not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_get_fd, __mac_get_fd, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_get_file.S b/src/kernel/libsyscall/sys_x86-64/___mac_get_file.S deleted file mode 100644 index a9f9bb53b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_get_file.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_file -#error "SYS___mac_get_file not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_get_file, __mac_get_file, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_get_link.S b/src/kernel/libsyscall/sys_x86-64/___mac_get_link.S deleted file mode 100644 index a66529475..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_get_link.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_link -#error "SYS___mac_get_link not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_get_link, __mac_get_link, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_get_mount.S b/src/kernel/libsyscall/sys_x86-64/___mac_get_mount.S deleted file mode 100644 index 5550ee9ea..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_get_mount.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_mount -#error "SYS___mac_get_mount not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_get_mount, __mac_get_mount, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_get_pid.S b/src/kernel/libsyscall/sys_x86-64/___mac_get_pid.S deleted file mode 100644 index 2ef2d82a9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_get_pid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_get_pid -#error "SYS___mac_get_pid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_get_pid, __mac_get_pid, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_get_proc.S b/src/kernel/libsyscall/sys_x86-64/___mac_get_proc.S deleted file mode 100644 index 03e1a643b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_get_proc.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___mac_get_proc -#error "SYS___mac_get_proc not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_get_proc, __mac_get_proc, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_getfsstat.S b/src/kernel/libsyscall/sys_x86-64/___mac_getfsstat.S deleted file mode 100644 index bad0027d8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_getfsstat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS___mac_getfsstat -#error "SYS___mac_getfsstat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_getfsstat, __mac_getfsstat, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_mount.S b/src/kernel/libsyscall/sys_x86-64/___mac_mount.S deleted file mode 100644 index 1bff23cb6..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_mount.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS___mac_mount -#error "SYS___mac_mount not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_mount, __mac_mount, 5, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl ___sandbox_mm - .set ___sandbox_mm, ___mac_mount -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_set_fd.S b/src/kernel/libsyscall/sys_x86-64/___mac_set_fd.S deleted file mode 100644 index 56746bad5..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_set_fd.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_set_fd -#error "SYS___mac_set_fd not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_set_fd, __mac_set_fd, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_set_file.S b/src/kernel/libsyscall/sys_x86-64/___mac_set_file.S deleted file mode 100644 index f7a3cd231..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_set_file.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_set_file -#error "SYS___mac_set_file not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_set_file, __mac_set_file, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_set_link.S b/src/kernel/libsyscall/sys_x86-64/___mac_set_link.S deleted file mode 100644 index 3ff645a04..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_set_link.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___mac_set_link -#error "SYS___mac_set_link not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_set_link, __mac_set_link, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_set_proc.S b/src/kernel/libsyscall/sys_x86-64/___mac_set_proc.S deleted file mode 100644 index 6ad3bcc85..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_set_proc.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___mac_set_proc -#error "SYS___mac_set_proc not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_set_proc, __mac_set_proc, 1, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl ___sandbox_msp - .set ___sandbox_msp, ___mac_set_proc -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mac_syscall.S b/src/kernel/libsyscall/sys_x86-64/___mac_syscall.S deleted file mode 100644 index 755eb7323..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mac_syscall.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS___mac_syscall -#error "SYS___mac_syscall not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mac_syscall, __mac_syscall, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl ___sandbox_ms - .set ___sandbox_ms, ___mac_syscall -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___microstackshot.S b/src/kernel/libsyscall/sys_x86-64/___microstackshot.S deleted file mode 100644 index cb7e944fc..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___microstackshot.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_microstackshot -#error "SYS_microstackshot not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___microstackshot, microstackshot, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mkdir_extended.S b/src/kernel/libsyscall/sys_x86-64/___mkdir_extended.S deleted file mode 100644 index dfa126986..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mkdir_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_mkdir_extended -#error "SYS_mkdir_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mkdir_extended, mkdir_extended, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mkfifo_extended.S b/src/kernel/libsyscall/sys_x86-64/___mkfifo_extended.S deleted file mode 100644 index 84a216cda..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mkfifo_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_mkfifo_extended -#error "SYS_mkfifo_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mkfifo_extended, mkfifo_extended, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mmap.S b/src/kernel/libsyscall/sys_x86-64/___mmap.S deleted file mode 100644 index a3d159865..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mmap.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_mmap -#error "SYS_mmap not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mmap, mmap, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___mprotect.S b/src/kernel/libsyscall/sys_x86-64/___mprotect.S deleted file mode 100644 index c79c77548..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___mprotect.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_mprotect -#error "SYS_mprotect not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___mprotect, mprotect, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _mprotect - .set _mprotect, ___mprotect -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___msgctl.S b/src/kernel/libsyscall/sys_x86-64/___msgctl.S deleted file mode 100644 index f24b1b8ed..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___msgctl.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_msgctl -#error "SYS_msgctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___msgctl, msgctl, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _msgctl - .set _msgctl, ___msgctl -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___msgrcv_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___msgrcv_nocancel.S deleted file mode 100644 index d0e6b2e08..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___msgrcv_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_msgrcv_nocancel -#error "SYS_msgrcv_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___msgrcv_nocancel, msgrcv_nocancel, 5, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _msgrcv$NOCANCEL - .set _msgrcv$NOCANCEL, ___msgrcv_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___msgsnd_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___msgsnd_nocancel.S deleted file mode 100644 index d124666d6..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___msgsnd_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_msgsnd_nocancel -#error "SYS_msgsnd_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___msgsnd_nocancel, msgsnd_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _msgsnd$NOCANCEL - .set _msgsnd$NOCANCEL, ___msgsnd_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___msgsys.S b/src/kernel/libsyscall/sys_x86-64/___msgsys.S deleted file mode 100644 index 486d5de88..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___msgsys.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_msgsys -#error "SYS_msgsys not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___msgsys, msgsys, 5, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _msgsys - .set _msgsys, ___msgsys -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___msync.S b/src/kernel/libsyscall/sys_x86-64/___msync.S deleted file mode 100644 index 629e1559c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___msync.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_msync -#error "SYS_msync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___msync, msync, 3, cerror) -#endif - -#if defined(__x86_64__) - .globl _msync - .set _msync, ___msync -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___msync_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___msync_nocancel.S deleted file mode 100644 index 550a7238b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___msync_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_msync_nocancel -#error "SYS_msync_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___msync_nocancel, msync_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _msync$NOCANCEL - .set _msync$NOCANCEL, ___msync_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___munmap.S b/src/kernel/libsyscall/sys_x86-64/___munmap.S deleted file mode 100644 index f6d140a06..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___munmap.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_munmap -#error "SYS_munmap not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___munmap, munmap, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___old_semwait_signal.S b/src/kernel/libsyscall/sys_x86-64/___old_semwait_signal.S deleted file mode 100644 index 847296124..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___old_semwait_signal.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS___old_semwait_signal -#error "SYS___old_semwait_signal not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___old_semwait_signal, __old_semwait_signal, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___open.S b/src/kernel/libsyscall/sys_x86-64/___open.S deleted file mode 100644 index bddc6f30a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___open.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_open -#error "SYS_open not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___open, open, 3, cerror) -#endif - -#if defined(__x86_64__) - .globl _open - .set _open, ___open -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___open_dprotected_np.S b/src/kernel/libsyscall/sys_x86-64/___open_dprotected_np.S deleted file mode 100644 index df6ff9fcd..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___open_dprotected_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_open_dprotected_np -#error "SYS_open_dprotected_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___open_dprotected_np, open_dprotected_np, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___open_extended.S b/src/kernel/libsyscall/sys_x86-64/___open_extended.S deleted file mode 100644 index 474369e09..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___open_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_open_extended -#error "SYS_open_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___open_extended, open_extended, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___open_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___open_nocancel.S deleted file mode 100644 index 0aeab816a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___open_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_open_nocancel -#error "SYS_open_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___open_nocancel, open_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _open$NOCANCEL - .set _open$NOCANCEL, ___open_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___openat.S b/src/kernel/libsyscall/sys_x86-64/___openat.S deleted file mode 100644 index b6d7a3272..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___openat.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_openat -#error "SYS_openat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___openat, openat, 4, cerror) -#endif - -#if defined(__x86_64__) - .globl _openat - .set _openat, ___openat -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___openat_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___openat_nocancel.S deleted file mode 100644 index e5b8eaf65..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___openat_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_openat_nocancel -#error "SYS_openat_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___openat_nocancel, openat_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _openat$NOCANCEL - .set _openat$NOCANCEL, ___openat_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___persona.S b/src/kernel/libsyscall/sys_x86-64/___persona.S deleted file mode 100644 index 166a6d55d..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___persona.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_persona -#error "SYS_persona not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___persona, persona, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pipe.S b/src/kernel/libsyscall/sys_x86-64/___pipe.S deleted file mode 100644 index d97802407..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pipe.S +++ /dev/null @@ -1,57 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ - -#include "SYS.h" - -#if defined(__i386__) - -PSEUDO_INT(___pipe, pipe, 0) - movl 4(%esp),%ecx - movl %eax,(%ecx) - movl %edx,4(%ecx) - xorl %eax,%eax - ret - -#elif defined(__x86_64__) - -PSEUDO(___pipe, pipe, 0, cerror_nocancel) - movl %eax, (%rdi) - movl %edx, 4(%rdi) - xorl %eax, %eax - ret - -#else -#error Unsupported architecture -#endif -#if defined(__x86_64__) - .globl _pipe - .set _pipe, ___pipe -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___poll_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___poll_nocancel.S deleted file mode 100644 index ebc2f55b4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___poll_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_poll_nocancel -#error "SYS_poll_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___poll_nocancel, poll_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _poll$NOCANCEL - .set _poll$NOCANCEL, ___poll_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___posix_spawn.S b/src/kernel/libsyscall/sys_x86-64/___posix_spawn.S deleted file mode 100644 index b44b0b78b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___posix_spawn.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_posix_spawn -#error "SYS_posix_spawn not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___posix_spawn, posix_spawn, 5, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pread_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___pread_nocancel.S deleted file mode 100644 index f0f7f2f1b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pread_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_pread_nocancel -#error "SYS_pread_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pread_nocancel, pread_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _pread$NOCANCEL - .set _pread$NOCANCEL, ___pread_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___proc_info.S b/src/kernel/libsyscall/sys_x86-64/___proc_info.S deleted file mode 100644 index e22465c32..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___proc_info.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_proc_info -#error "SYS_proc_info not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___proc_info, proc_info, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___process_policy.S b/src/kernel/libsyscall/sys_x86-64/___process_policy.S deleted file mode 100644 index 5a9e11d1b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___process_policy.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 32 -#include "SYS.h" - -#ifndef SYS_process_policy -#error "SYS_process_policy not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___process_policy, process_policy, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pselect.S b/src/kernel/libsyscall/sys_x86-64/___pselect.S deleted file mode 100644 index 711cbbb26..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pselect.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_pselect -#error "SYS_pselect not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pselect, pselect, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pselect_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___pselect_nocancel.S deleted file mode 100644 index 1d253f536..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pselect_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_pselect_nocancel -#error "SYS_pselect_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pselect_nocancel, pselect_nocancel, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_cvbroad.S b/src/kernel/libsyscall/sys_x86-64/___psynch_cvbroad.S deleted file mode 100644 index 782d8f265..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_cvbroad.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 44 -#include "SYS.h" - -#ifndef SYS_psynch_cvbroad -#error "SYS_psynch_cvbroad not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_cvbroad, psynch_cvbroad, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_cvclrprepost.S b/src/kernel/libsyscall/sys_x86-64/___psynch_cvclrprepost.S deleted file mode 100644 index 8313d3a15..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_cvclrprepost.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_psynch_cvclrprepost -#error "SYS_psynch_cvclrprepost not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_cvclrprepost, psynch_cvclrprepost, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_cvsignal.S b/src/kernel/libsyscall/sys_x86-64/___psynch_cvsignal.S deleted file mode 100644 index 1d7a6ee71..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_cvsignal.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 44 -#include "SYS.h" - -#ifndef SYS_psynch_cvsignal -#error "SYS_psynch_cvsignal not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_cvsignal, psynch_cvsignal, 8, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_cvwait.S b/src/kernel/libsyscall/sys_x86-64/___psynch_cvwait.S deleted file mode 100644 index cab17a3de..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_cvwait.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 44 -#include "SYS.h" - -#ifndef SYS_psynch_cvwait -#error "SYS_psynch_cvwait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_cvwait, psynch_cvwait, 8, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_mutexdrop.S b/src/kernel/libsyscall/sys_x86-64/___psynch_mutexdrop.S deleted file mode 100644 index 0712412bf..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_mutexdrop.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_psynch_mutexdrop -#error "SYS_psynch_mutexdrop not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_mutexdrop, psynch_mutexdrop, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_mutexwait.S b/src/kernel/libsyscall/sys_x86-64/___psynch_mutexwait.S deleted file mode 100644 index e6b6703ee..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_mutexwait.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_psynch_mutexwait -#error "SYS_psynch_mutexwait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_mutexwait, psynch_mutexwait, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_downgrade.S b/src/kernel/libsyscall/sys_x86-64/___psynch_rw_downgrade.S deleted file mode 100644 index 88183e6ca..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_downgrade.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_downgrade -#error "SYS_psynch_rw_downgrade not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_rw_downgrade, psynch_rw_downgrade, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_longrdlock.S b/src/kernel/libsyscall/sys_x86-64/___psynch_rw_longrdlock.S deleted file mode 100644 index 9c7a716c4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_longrdlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_longrdlock -#error "SYS_psynch_rw_longrdlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_rw_longrdlock, psynch_rw_longrdlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_rdlock.S b/src/kernel/libsyscall/sys_x86-64/___psynch_rw_rdlock.S deleted file mode 100644 index 966ed6309..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_rdlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_rdlock -#error "SYS_psynch_rw_rdlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_rw_rdlock, psynch_rw_rdlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_unlock.S b/src/kernel/libsyscall/sys_x86-64/___psynch_rw_unlock.S deleted file mode 100644 index d3ecb5df2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_unlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_unlock -#error "SYS_psynch_rw_unlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_rw_unlock, psynch_rw_unlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_unlock2.S b/src/kernel/libsyscall/sys_x86-64/___psynch_rw_unlock2.S deleted file mode 100644 index 3bd0e98ea..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_unlock2.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_unlock2 -#error "SYS_psynch_rw_unlock2 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_rw_unlock2, psynch_rw_unlock2, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_upgrade.S b/src/kernel/libsyscall/sys_x86-64/___psynch_rw_upgrade.S deleted file mode 100644 index ee2d4362f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_upgrade.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_upgrade -#error "SYS_psynch_rw_upgrade not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_rw_upgrade, psynch_rw_upgrade, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_wrlock.S b/src/kernel/libsyscall/sys_x86-64/___psynch_rw_wrlock.S deleted file mode 100644 index e55b535bd..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_wrlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_wrlock -#error "SYS_psynch_rw_wrlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_rw_wrlock, psynch_rw_wrlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_yieldwrlock.S b/src/kernel/libsyscall/sys_x86-64/___psynch_rw_yieldwrlock.S deleted file mode 100644 index 4f405af5f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___psynch_rw_yieldwrlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_psynch_rw_yieldwrlock -#error "SYS_psynch_rw_yieldwrlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___psynch_rw_yieldwrlock, psynch_rw_yieldwrlock, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pthread_canceled.S b/src/kernel/libsyscall/sys_x86-64/___pthread_canceled.S deleted file mode 100644 index 26f2daca3..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pthread_canceled.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___pthread_canceled -#error "SYS___pthread_canceled not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pthread_canceled, __pthread_canceled, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pthread_chdir.S b/src/kernel/libsyscall/sys_x86-64/___pthread_chdir.S deleted file mode 100644 index 73b4f56cc..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pthread_chdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___pthread_chdir -#error "SYS___pthread_chdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pthread_chdir, __pthread_chdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pthread_fchdir.S b/src/kernel/libsyscall/sys_x86-64/___pthread_fchdir.S deleted file mode 100644 index ae47d3ad2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pthread_fchdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___pthread_fchdir -#error "SYS___pthread_fchdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pthread_fchdir, __pthread_fchdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pthread_kill.S b/src/kernel/libsyscall/sys_x86-64/___pthread_kill.S deleted file mode 100644 index 4fba578fe..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pthread_kill.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___pthread_kill -#error "SYS___pthread_kill not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pthread_kill, __pthread_kill, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pthread_markcancel.S b/src/kernel/libsyscall/sys_x86-64/___pthread_markcancel.S deleted file mode 100644 index 70e236473..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pthread_markcancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS___pthread_markcancel -#error "SYS___pthread_markcancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pthread_markcancel, __pthread_markcancel, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pthread_sigmask.S b/src/kernel/libsyscall/sys_x86-64/___pthread_sigmask.S deleted file mode 100644 index 0fabccb0e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pthread_sigmask.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS___pthread_sigmask -#error "SYS___pthread_sigmask not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pthread_sigmask, __pthread_sigmask, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___ptrace.S b/src/kernel/libsyscall/sys_x86-64/___ptrace.S deleted file mode 100644 index 69220b3a0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___ptrace.S +++ /dev/null @@ -1,61 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ - -#include "SYS.h" - -#if defined(__i386__) - - .globl _errno - -LEAF(___ptrace, 0) - xorl %eax,%eax - REG_TO_EXTERN(%eax,_errno) - UNIX_SYSCALL_NONAME(ptrace, 4, cerror) - ret - -#elif defined(__x86_64__) - - .globl _errno - -LEAF(___ptrace, 0) - xorq %rax,%rax - PICIFY(_errno) - movl %eax,(%r11) - UNIX_SYSCALL_NONAME(ptrace, 4, cerror) - ret - -#else -#error Unsupported architecture -#endif -#if defined(__x86_64__) - .globl _ptrace - .set _ptrace, ___ptrace -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___pwrite_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___pwrite_nocancel.S deleted file mode 100644 index 3c0161067..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___pwrite_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_pwrite_nocancel -#error "SYS_pwrite_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___pwrite_nocancel, pwrite_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _pwrite$NOCANCEL - .set _pwrite$NOCANCEL, ___pwrite_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___read_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___read_nocancel.S deleted file mode 100644 index 67243abb4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___read_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_read_nocancel -#error "SYS_read_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___read_nocancel, read_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _read$NOCANCEL - .set _read$NOCANCEL, ___read_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___readv_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___readv_nocancel.S deleted file mode 100644 index 6fa04fa88..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___readv_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_readv_nocancel -#error "SYS_readv_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___readv_nocancel, readv_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _readv$NOCANCEL - .set _readv$NOCANCEL, ___readv_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___recvfrom.S b/src/kernel/libsyscall/sys_x86-64/___recvfrom.S deleted file mode 100644 index 52b3e8901..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___recvfrom.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_recvfrom -#error "SYS_recvfrom not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___recvfrom, recvfrom, 6, cerror) -#endif - -#if defined(__x86_64__) - .globl _recvfrom - .set _recvfrom, ___recvfrom -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___recvfrom_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___recvfrom_nocancel.S deleted file mode 100644 index 49b0f2006..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___recvfrom_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_recvfrom_nocancel -#error "SYS_recvfrom_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___recvfrom_nocancel, recvfrom_nocancel, 6, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _recvfrom$NOCANCEL - .set _recvfrom$NOCANCEL, ___recvfrom_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___recvmsg.S b/src/kernel/libsyscall/sys_x86-64/___recvmsg.S deleted file mode 100644 index c70a89908..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___recvmsg.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_recvmsg -#error "SYS_recvmsg not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___recvmsg, recvmsg, 3, cerror) -#endif - -#if defined(__x86_64__) - .globl _recvmsg - .set _recvmsg, ___recvmsg -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___recvmsg_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___recvmsg_nocancel.S deleted file mode 100644 index 2c42cbafe..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___recvmsg_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_recvmsg_nocancel -#error "SYS_recvmsg_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___recvmsg_nocancel, recvmsg_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _recvmsg$NOCANCEL - .set _recvmsg$NOCANCEL, ___recvmsg_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___rename.S b/src/kernel/libsyscall/sys_x86-64/___rename.S deleted file mode 100644 index 0293f7418..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___rename.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_rename -#error "SYS_rename not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___rename, rename, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___renameat.S b/src/kernel/libsyscall/sys_x86-64/___renameat.S deleted file mode 100644 index 589167607..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___renameat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_renameat -#error "SYS_renameat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___renameat, renameat, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___rmdir.S b/src/kernel/libsyscall/sys_x86-64/___rmdir.S deleted file mode 100644 index 37bef72f8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___rmdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_rmdir -#error "SYS_rmdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___rmdir, rmdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___select.S b/src/kernel/libsyscall/sys_x86-64/___select.S deleted file mode 100644 index 1a255ba04..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___select.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_select -#error "SYS_select not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___select, select, 5, cerror) -#endif - -#if defined(__x86_64__) - .globl _select$DARWIN_EXTSN - .set _select$DARWIN_EXTSN, ___select -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___select_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___select_nocancel.S deleted file mode 100644 index 76838bd90..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___select_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_select_nocancel -#error "SYS_select_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___select_nocancel, select_nocancel, 5, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _select$DARWIN_EXTSN$NOCANCEL - .set _select$DARWIN_EXTSN$NOCANCEL, ___select_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sem_open.S b/src/kernel/libsyscall/sys_x86-64/___sem_open.S deleted file mode 100644 index fa891e3eb..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sem_open.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_sem_open -#error "SYS_sem_open not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sem_open, sem_open, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _sem_open - .set _sem_open, ___sem_open -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sem_wait_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___sem_wait_nocancel.S deleted file mode 100644 index f5cc61b1e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sem_wait_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_wait_nocancel -#error "SYS_sem_wait_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sem_wait_nocancel, sem_wait_nocancel, 1, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _sem_wait$NOCANCEL - .set _sem_wait$NOCANCEL, ___sem_wait_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___semctl.S b/src/kernel/libsyscall/sys_x86-64/___semctl.S deleted file mode 100644 index eb0570fd7..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___semctl.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_semctl -#error "SYS_semctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___semctl, semctl, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _semctl - .set _semctl, ___semctl -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___semsys.S b/src/kernel/libsyscall/sys_x86-64/___semsys.S deleted file mode 100644 index 83bac2282..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___semsys.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_semsys -#error "SYS_semsys not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___semsys, semsys, 5, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _semsys - .set _semsys, ___semsys -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___semwait_signal.S b/src/kernel/libsyscall/sys_x86-64/___semwait_signal.S deleted file mode 100644 index fc691c81e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___semwait_signal.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS___semwait_signal -#error "SYS___semwait_signal not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___semwait_signal, __semwait_signal, 6, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___semwait_signal_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___semwait_signal_nocancel.S deleted file mode 100644 index 59340e27e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___semwait_signal_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS___semwait_signal_nocancel -#error "SYS___semwait_signal_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___semwait_signal_nocancel, __semwait_signal_nocancel, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sendmsg.S b/src/kernel/libsyscall/sys_x86-64/___sendmsg.S deleted file mode 100644 index ab1d5edee..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sendmsg.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_sendmsg -#error "SYS_sendmsg not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sendmsg, sendmsg, 3, cerror) -#endif - -#if defined(__x86_64__) - .globl _sendmsg - .set _sendmsg, ___sendmsg -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sendmsg_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___sendmsg_nocancel.S deleted file mode 100644 index 5866455b0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sendmsg_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_sendmsg_nocancel -#error "SYS_sendmsg_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sendmsg_nocancel, sendmsg_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _sendmsg$NOCANCEL - .set _sendmsg$NOCANCEL, ___sendmsg_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sendto.S b/src/kernel/libsyscall/sys_x86-64/___sendto.S deleted file mode 100644 index e6fbdf600..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sendto.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_sendto -#error "SYS_sendto not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sendto, sendto, 6, cerror) -#endif - -#if defined(__x86_64__) - .globl _sendto - .set _sendto, ___sendto -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sendto_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___sendto_nocancel.S deleted file mode 100644 index 9408dff1e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sendto_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_sendto_nocancel -#error "SYS_sendto_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sendto_nocancel, sendto_nocancel, 6, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _sendto$NOCANCEL - .set _sendto$NOCANCEL, ___sendto_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___setattrlist.S b/src/kernel/libsyscall/sys_x86-64/___setattrlist.S deleted file mode 100644 index d5a97ffae..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___setattrlist.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_setattrlist -#error "SYS_setattrlist not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___setattrlist, setattrlist, 5, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _setattrlist - .set _setattrlist, ___setattrlist -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___setlogin.S b/src/kernel/libsyscall/sys_x86-64/___setlogin.S deleted file mode 100644 index bded93611..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___setlogin.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setlogin -#error "SYS_setlogin not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___setlogin, setlogin, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___setpriority.S b/src/kernel/libsyscall/sys_x86-64/___setpriority.S deleted file mode 100644 index f8c8062d2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___setpriority.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_setpriority -#error "SYS_setpriority not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___setpriority, setpriority, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___setregid.S b/src/kernel/libsyscall/sys_x86-64/___setregid.S deleted file mode 100644 index a4757cd2c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___setregid.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setregid -#error "SYS_setregid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___setregid, setregid, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _setregid - .set _setregid, ___setregid -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___setreuid.S b/src/kernel/libsyscall/sys_x86-64/___setreuid.S deleted file mode 100644 index 5acf97e4e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___setreuid.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setreuid -#error "SYS_setreuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___setreuid, setreuid, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _setreuid - .set _setreuid, ___setreuid -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___setrlimit.S b/src/kernel/libsyscall/sys_x86-64/___setrlimit.S deleted file mode 100644 index 67acf1544..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___setrlimit.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setrlimit -#error "SYS_setrlimit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___setrlimit, setrlimit, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___setsgroups.S b/src/kernel/libsyscall/sys_x86-64/___setsgroups.S deleted file mode 100644 index 6ca1bb779..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___setsgroups.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setsgroups -#error "SYS_setsgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___setsgroups, setsgroups, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _setsgroups_np - .set _setsgroups_np, ___setsgroups -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___settid.S b/src/kernel/libsyscall/sys_x86-64/___settid.S deleted file mode 100644 index 3be52108f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___settid.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_settid -#error "SYS_settid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___settid, settid, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _pthread_setugid_np - .set _pthread_setugid_np, ___settid -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___settid_with_pid.S b/src/kernel/libsyscall/sys_x86-64/___settid_with_pid.S deleted file mode 100644 index 1cab72d8b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___settid_with_pid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_settid_with_pid -#error "SYS_settid_with_pid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___settid_with_pid, settid_with_pid, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___settimeofday.S b/src/kernel/libsyscall/sys_x86-64/___settimeofday.S deleted file mode 100644 index 84dc1f537..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___settimeofday.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_settimeofday -#error "SYS_settimeofday not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___settimeofday, settimeofday, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___setwgroups.S b/src/kernel/libsyscall/sys_x86-64/___setwgroups.S deleted file mode 100644 index f55bf5355..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___setwgroups.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setwgroups -#error "SYS_setwgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___setwgroups, setwgroups, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _setwgroups_np - .set _setwgroups_np, ___setwgroups -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sfi_ctl.S b/src/kernel/libsyscall/sys_x86-64/___sfi_ctl.S deleted file mode 100644 index 85e90768e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sfi_ctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_sfi_ctl -#error "SYS_sfi_ctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sfi_ctl, sfi_ctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sfi_pidctl.S b/src/kernel/libsyscall/sys_x86-64/___sfi_pidctl.S deleted file mode 100644 index ce338d9b2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sfi_pidctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_sfi_pidctl -#error "SYS_sfi_pidctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sfi_pidctl, sfi_pidctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___shared_region_check_np.S b/src/kernel/libsyscall/sys_x86-64/___shared_region_check_np.S deleted file mode 100644 index 1c4978c99..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___shared_region_check_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_shared_region_check_np -#error "SYS_shared_region_check_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___shared_region_check_np, shared_region_check_np, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___shared_region_map_and_slide_np.S b/src/kernel/libsyscall/sys_x86-64/___shared_region_map_and_slide_np.S deleted file mode 100644 index a4b9df074..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___shared_region_map_and_slide_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_shared_region_map_and_slide_np -#error "SYS_shared_region_map_and_slide_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___shared_region_map_and_slide_np, shared_region_map_and_slide_np, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___shm_open.S b/src/kernel/libsyscall/sys_x86-64/___shm_open.S deleted file mode 100644 index 895cdeecd..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___shm_open.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_shm_open -#error "SYS_shm_open not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___shm_open, shm_open, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _shm_open - .set _shm_open, ___shm_open -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___shmctl.S b/src/kernel/libsyscall/sys_x86-64/___shmctl.S deleted file mode 100644 index 978a5a9a9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___shmctl.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_shmctl -#error "SYS_shmctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___shmctl, shmctl, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _shmctl - .set _shmctl, ___shmctl -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___shmsys.S b/src/kernel/libsyscall/sys_x86-64/___shmsys.S deleted file mode 100644 index 5608e2a02..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___shmsys.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_shmsys -#error "SYS_shmsys not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___shmsys, shmsys, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _shmsys - .set _shmsys, ___shmsys -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sigaction.S b/src/kernel/libsyscall/sys_x86-64/___sigaction.S deleted file mode 100644 index a42c13cf1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sigaction.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_sigaction -#error "SYS_sigaction not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sigaction, sigaction, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sigaltstack.S b/src/kernel/libsyscall/sys_x86-64/___sigaltstack.S deleted file mode 100644 index a8edf9110..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sigaltstack.S +++ /dev/null @@ -1,42 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include "SYS.h" - -#if defined(__x86_64__) - -__SYSCALL(___sigaltstack, sigaltstack, 3) - -#elif defined(__i386__) - -__SYSCALL_INT(___sigaltstack, sigaltstack, 3) - -#else -#error Unsupported architecture -#endif diff --git a/src/kernel/libsyscall/sys_x86-64/___sigsuspend.S b/src/kernel/libsyscall/sys_x86-64/___sigsuspend.S deleted file mode 100644 index ae50456a9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sigsuspend.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sigsuspend -#error "SYS_sigsuspend not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sigsuspend, sigsuspend, 1, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sigsuspend_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___sigsuspend_nocancel.S deleted file mode 100644 index ea56ae30f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sigsuspend_nocancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sigsuspend_nocancel -#error "SYS_sigsuspend_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sigsuspend_nocancel, sigsuspend_nocancel, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sigwait.S b/src/kernel/libsyscall/sys_x86-64/___sigwait.S deleted file mode 100644 index a118dd619..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sigwait.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS___sigwait -#error "SYS___sigwait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sigwait, __sigwait, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___socketpair.S b/src/kernel/libsyscall/sys_x86-64/___socketpair.S deleted file mode 100644 index 95d6120f9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___socketpair.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_socketpair -#error "SYS_socketpair not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___socketpair, socketpair, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _socketpair - .set _socketpair, ___socketpair -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___stack_snapshot_with_config.S b/src/kernel/libsyscall/sys_x86-64/___stack_snapshot_with_config.S deleted file mode 100644 index 97f01f8d3..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___stack_snapshot_with_config.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_stack_snapshot_with_config -#error "SYS_stack_snapshot_with_config not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___stack_snapshot_with_config, stack_snapshot_with_config, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___stat64_extended.S b/src/kernel/libsyscall/sys_x86-64/___stat64_extended.S deleted file mode 100644 index 7e56090ea..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___stat64_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_stat64_extended -#error "SYS_stat64_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___stat64_extended, stat64_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___stat_extended.S b/src/kernel/libsyscall/sys_x86-64/___stat_extended.S deleted file mode 100644 index 8b1530e71..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___stat_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_stat_extended -#error "SYS_stat_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___stat_extended, stat_extended, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___syscall.S b/src/kernel/libsyscall/sys_x86-64/___syscall.S deleted file mode 100644 index 2b08a01f3..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___syscall.S +++ /dev/null @@ -1,61 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ - -#include "SYS.h" - -#if defined(__i386__) - -LEAF(___syscall, 0) - popl %ecx // ret addr - popl %eax // syscall number - pushl %ecx - UNIX_SYSCALL_TRAP - movl (%esp),%edx // add one element to stack so - pushl %ecx // caller "pop" will work - jnb 2f - BRANCH_EXTERN(tramp_cerror) -2: -END(___syscall) - -#elif defined(__x86_64__) - -// For x86-64, the kernel slides the argument list for us. -// The number of arguments here is variable, but our macros ignore -// that value anyway. -__SYSCALL(___syscall, syscall, 0); - -#else -#error Unsupported architecture -#endif -#if defined(__x86_64__) - .globl _syscall - .set _syscall, ___syscall -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sysctl.S b/src/kernel/libsyscall/sys_x86-64/___sysctl.S deleted file mode 100644 index ba6b32d8e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sysctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_sysctl -#error "SYS_sysctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sysctl, sysctl, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___sysctlbyname.S b/src/kernel/libsyscall/sys_x86-64/___sysctlbyname.S deleted file mode 100644 index a4a3b6627..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___sysctlbyname.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_sysctlbyname -#error "SYS_sysctlbyname not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___sysctlbyname, sysctlbyname, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___telemetry.S b/src/kernel/libsyscall/sys_x86-64/___telemetry.S deleted file mode 100644 index 6aef7cc4f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___telemetry.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 48 -#include "SYS.h" - -#ifndef SYS_telemetry -#error "SYS_telemetry not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___telemetry, telemetry, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___umask_extended.S b/src/kernel/libsyscall/sys_x86-64/___umask_extended.S deleted file mode 100644 index 09e2b6434..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___umask_extended.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_umask_extended -#error "SYS_umask_extended not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___umask_extended, umask_extended, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___unlink.S b/src/kernel/libsyscall/sys_x86-64/___unlink.S deleted file mode 100644 index bc5537611..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___unlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_unlink -#error "SYS_unlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___unlink, unlink, 1, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___unlinkat.S b/src/kernel/libsyscall/sys_x86-64/___unlinkat.S deleted file mode 100644 index 0bc52bf63..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___unlinkat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_unlinkat -#error "SYS_unlinkat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___unlinkat, unlinkat, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___vfork.S b/src/kernel/libsyscall/sys_x86-64/___vfork.S deleted file mode 100644 index a63e8a568..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___vfork.S +++ /dev/null @@ -1,152 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. - * - * File: libc/ppc/sys/vfork.s - * - * HISTORY - * 23-Jun-1998 Umesh Vaishampayan (umeshv@apple.com) - * Created from fork.s - * - */ - -#include "SYS.h" - -#if defined(__i386__) - -#if defined(__DYNAMIC__) -#define GET_CURRENT_PID PICIFY(__current_pid) - - NON_LAZY_STUB(__current_pid) -#define __current_pid (%edx) -#else -#define GET_CURRENT_PID -#endif - -/* - * If __current_pid >= 0, we want to put a -1 in there - * otherwise we just decrement it - */ - -LEAF(___vfork, 0) - GET_CURRENT_PID - movl __current_pid, %eax -0: - xorl %ecx, %ecx - testl %eax, %eax - cmovs %eax, %ecx - decl %ecx - lock - cmpxchgl %ecx, __current_pid - jne 0b - popl %ecx - movl $(SYS_vfork), %eax // code for vfork -> eax - UNIX_SYSCALL_TRAP // do the system call - jnb L1 // jump if CF==0 - GET_CURRENT_PID - lock - incl __current_pid - pushl %ecx - BRANCH_EXTERN(tramp_cerror) - -L1: - testl %edx, %edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child - xorl %eax, %eax // zero eax - jmp *%ecx - -L2: - GET_CURRENT_PID - lock - incl __current_pid - jmp *%ecx - -#elif defined(__x86_64__) - -/* - * If __current_pid >= 0, we want to put a -1 in there - * otherwise we just decrement it - */ - -LEAF(___vfork, 0) - movq __current_pid@GOTPCREL(%rip), %rax - movl (%rax), %eax -0: - xorl %ecx, %ecx - testl %eax, %eax - cmovs %eax, %ecx - subl $1, %ecx - movq __current_pid@GOTPCREL(%rip), %rdx - lock - cmpxchgl %ecx, (%rdx) - jne 0b - //popq %rdi // return address in %rdi -#ifndef DARLING - movq $ SYSCALL_CONSTRUCT_UNIX(SYS_vfork), %rax // code for vfork -> rax - UNIX_SYSCALL_TRAP // do the system call - jnb L1 // jump if CF==0 - pushq %rdi // put return address back on stack for cerror -#else - movl $ SYS_vfork, %eax - call __darling_bsd_syscall - cmpq $0, %rax - jnb L1 -#endif - movq __current_pid@GOTPCREL(%rip), %rcx - lock - addq $1, (%rcx) - movq %rax, %rdi - BRANCH_EXTERN(_cerror) - -L1: -#ifndef DARLING - testl %edx, %edx // CF=OF=0, ZF set if zero result - jz L2 // parent, since r1 == 0 in parent, 1 in child -#else - testl %eax, %eax - jnz L2 -#endif - xorq %rax, %rax // zero rax - jmp *%rdi - -L2: - movq __current_pid@GOTPCREL(%rip), %rdx - lock - addq $1, (%rdx) - //jmp *%rdi - ret - -#else -#error Unsupported architecture -#endif -#if defined(__x86_64__) - .globl _vfork - .set _vfork, ___vfork -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___wait4.S b/src/kernel/libsyscall/sys_x86-64/___wait4.S deleted file mode 100644 index 0cc7f53f1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___wait4.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_wait4 -#error "SYS_wait4 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___wait4, wait4, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___wait4_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___wait4_nocancel.S deleted file mode 100644 index 8ec333c5e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___wait4_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_wait4_nocancel -#error "SYS_wait4_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___wait4_nocancel, wait4_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _wait4 - .set _wait4, ___wait4_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___waitid_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___waitid_nocancel.S deleted file mode 100644 index 914c4b048..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___waitid_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_waitid_nocancel -#error "SYS_waitid_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___waitid_nocancel, waitid_nocancel, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _waitid$NOCANCEL - .set _waitid$NOCANCEL, ___waitid_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___work_interval_ctl.S b/src/kernel/libsyscall/sys_x86-64/___work_interval_ctl.S deleted file mode 100644 index 7aeec9eb1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___work_interval_ctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_work_interval_ctl -#error "SYS_work_interval_ctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___work_interval_ctl, work_interval_ctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___workq_kernreturn.S b/src/kernel/libsyscall/sys_x86-64/___workq_kernreturn.S deleted file mode 100644 index 5cd827fce..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___workq_kernreturn.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_workq_kernreturn -#error "SYS_workq_kernreturn not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___workq_kernreturn, workq_kernreturn, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___workq_open.S b/src/kernel/libsyscall/sys_x86-64/___workq_open.S deleted file mode 100644 index 3bae9c38c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___workq_open.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_workq_open -#error "SYS_workq_open not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___workq_open, workq_open, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___write_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___write_nocancel.S deleted file mode 100644 index b48b40065..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___write_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_write_nocancel -#error "SYS_write_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___write_nocancel, write_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _write$NOCANCEL - .set _write$NOCANCEL, ___write_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/___writev_nocancel.S b/src/kernel/libsyscall/sys_x86-64/___writev_nocancel.S deleted file mode 100644 index e41588851..000000000 --- a/src/kernel/libsyscall/sys_x86-64/___writev_nocancel.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_writev_nocancel -#error "SYS_writev_nocancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(___writev_nocancel, writev_nocancel, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _writev$NOCANCEL - .set _writev$NOCANCEL, ___writev_nocancel -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_access.S b/src/kernel/libsyscall/sys_x86-64/_access.S deleted file mode 100644 index 95d299741..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_access.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_access -#error "SYS_access not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_access, access, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_acct.S b/src/kernel/libsyscall/sys_x86-64/_acct.S deleted file mode 100644 index 3cf44b5aa..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_acct.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_acct -#error "SYS_acct not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_acct, acct, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_adjtime.S b/src/kernel/libsyscall/sys_x86-64/_adjtime.S deleted file mode 100644 index d51a4a04f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_adjtime.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_adjtime -#error "SYS_adjtime not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_adjtime, adjtime, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_aio_cancel.S b/src/kernel/libsyscall/sys_x86-64/_aio_cancel.S deleted file mode 100644 index fd8056623..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_aio_cancel.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_aio_cancel -#error "SYS_aio_cancel not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_aio_cancel, aio_cancel, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_aio_error.S b/src/kernel/libsyscall/sys_x86-64/_aio_error.S deleted file mode 100644 index 750989925..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_aio_error.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_aio_error -#error "SYS_aio_error not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_aio_error, aio_error, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_aio_fsync.S b/src/kernel/libsyscall/sys_x86-64/_aio_fsync.S deleted file mode 100644 index 33e5ab215..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_aio_fsync.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_aio_fsync -#error "SYS_aio_fsync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_aio_fsync, aio_fsync, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_aio_read.S b/src/kernel/libsyscall/sys_x86-64/_aio_read.S deleted file mode 100644 index 3a0d58a01..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_aio_read.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_aio_read -#error "SYS_aio_read not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_aio_read, aio_read, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_aio_return.S b/src/kernel/libsyscall/sys_x86-64/_aio_return.S deleted file mode 100644 index b6f7b5503..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_aio_return.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_aio_return -#error "SYS_aio_return not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_aio_return, aio_return, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_aio_suspend.S b/src/kernel/libsyscall/sys_x86-64/_aio_suspend.S deleted file mode 100644 index a296fbbd0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_aio_suspend.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_aio_suspend -#error "SYS_aio_suspend not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_aio_suspend, aio_suspend, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_aio_write.S b/src/kernel/libsyscall/sys_x86-64/_aio_write.S deleted file mode 100644 index 23ceb8cef..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_aio_write.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_aio_write -#error "SYS_aio_write not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_aio_write, aio_write, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_audit.S b/src/kernel/libsyscall/sys_x86-64/_audit.S deleted file mode 100644 index 3fd1f1de5..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_audit.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_audit -#error "SYS_audit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_audit, audit, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_audit_session_join.S b/src/kernel/libsyscall/sys_x86-64/_audit_session_join.S deleted file mode 100644 index 50abb9836..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_audit_session_join.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_audit_session_join -#error "SYS_audit_session_join not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_audit_session_join, audit_session_join, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_audit_session_port.S b/src/kernel/libsyscall/sys_x86-64/_audit_session_port.S deleted file mode 100644 index a9f2186b7..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_audit_session_port.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_audit_session_port -#error "SYS_audit_session_port not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_audit_session_port, audit_session_port, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_audit_session_self.S b/src/kernel/libsyscall/sys_x86-64/_audit_session_self.S deleted file mode 100644 index 98374af2f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_audit_session_self.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_audit_session_self -#error "SYS_audit_session_self not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_audit_session_self, audit_session_self, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_auditctl.S b/src/kernel/libsyscall/sys_x86-64/_auditctl.S deleted file mode 100644 index 9a5563abf..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_auditctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_auditctl -#error "SYS_auditctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_auditctl, auditctl, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_auditon.S b/src/kernel/libsyscall/sys_x86-64/_auditon.S deleted file mode 100644 index 6df4030e1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_auditon.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_auditon -#error "SYS_auditon not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_auditon, auditon, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_change_fdguard_np.S b/src/kernel/libsyscall/sys_x86-64/_change_fdguard_np.S deleted file mode 100644 index 4b7f6d9c0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_change_fdguard_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_change_fdguard_np -#error "SYS_change_fdguard_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_change_fdguard_np, change_fdguard_np, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_chdir.S b/src/kernel/libsyscall/sys_x86-64/_chdir.S deleted file mode 100644 index 7ffd228fa..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_chdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_chdir -#error "SYS_chdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_chdir, chdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_chflags.S b/src/kernel/libsyscall/sys_x86-64/_chflags.S deleted file mode 100644 index bb7503d0f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_chflags.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_chflags -#error "SYS_chflags not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_chflags, chflags, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_chown.S b/src/kernel/libsyscall/sys_x86-64/_chown.S deleted file mode 100644 index f1366a173..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_chown.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_chown -#error "SYS_chown not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_chown, chown, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_chroot.S b/src/kernel/libsyscall/sys_x86-64/_chroot.S deleted file mode 100644 index e58809271..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_chroot.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_chroot -#error "SYS_chroot not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_chroot, chroot, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_close.S b/src/kernel/libsyscall/sys_x86-64/_close.S deleted file mode 100644 index ef0ca830f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_close.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_close -#error "SYS_close not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_close, close, 1, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_connectx.S b/src/kernel/libsyscall/sys_x86-64/_connectx.S deleted file mode 100644 index e65b4e182..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_connectx.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 32 -#include "SYS.h" - -#ifndef SYS_connectx -#error "SYS_connectx not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_connectx, connectx, 8, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_csops.S b/src/kernel/libsyscall/sys_x86-64/_csops.S deleted file mode 100644 index 7daa0905f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_csops.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_csops -#error "SYS_csops not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_csops, csops, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_csops_audittoken.S b/src/kernel/libsyscall/sys_x86-64/_csops_audittoken.S deleted file mode 100644 index 34f7798fa..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_csops_audittoken.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_csops_audittoken -#error "SYS_csops_audittoken not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_csops_audittoken, csops_audittoken, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_disconnectx.S b/src/kernel/libsyscall/sys_x86-64/_disconnectx.S deleted file mode 100644 index addad8acc..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_disconnectx.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_disconnectx -#error "SYS_disconnectx not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_disconnectx, disconnectx, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_dup.S b/src/kernel/libsyscall/sys_x86-64/_dup.S deleted file mode 100644 index 2779515cb..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_dup.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_dup -#error "SYS_dup not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_dup, dup, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_dup2.S b/src/kernel/libsyscall/sys_x86-64/_dup2.S deleted file mode 100644 index 8e08ac0c3..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_dup2.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_dup2 -#error "SYS_dup2 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_dup2, dup2, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_exchangedata.S b/src/kernel/libsyscall/sys_x86-64/_exchangedata.S deleted file mode 100644 index b4809ebe3..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_exchangedata.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_exchangedata -#error "SYS_exchangedata not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_exchangedata, exchangedata, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_execve.S b/src/kernel/libsyscall/sys_x86-64/_execve.S deleted file mode 100644 index 8bf57bc45..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_execve.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_execve -#error "SYS_execve not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_execve, execve, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_faccessat.S b/src/kernel/libsyscall/sys_x86-64/_faccessat.S deleted file mode 100644 index 176823fe9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_faccessat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_faccessat -#error "SYS_faccessat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_faccessat, faccessat, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fchdir.S b/src/kernel/libsyscall/sys_x86-64/_fchdir.S deleted file mode 100644 index 4f601ba8f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fchdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fchdir -#error "SYS_fchdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fchdir, fchdir, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fchflags.S b/src/kernel/libsyscall/sys_x86-64/_fchflags.S deleted file mode 100644 index 3b70a1098..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fchflags.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fchflags -#error "SYS_fchflags not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fchflags, fchflags, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fchmodat.S b/src/kernel/libsyscall/sys_x86-64/_fchmodat.S deleted file mode 100644 index 3cb0a8568..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fchmodat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fchmodat -#error "SYS_fchmodat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fchmodat, fchmodat, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fchown.S b/src/kernel/libsyscall/sys_x86-64/_fchown.S deleted file mode 100644 index 823211d4f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fchown.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_fchown -#error "SYS_fchown not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fchown, fchown, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fchownat.S b/src/kernel/libsyscall/sys_x86-64/_fchownat.S deleted file mode 100644 index 73603e971..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fchownat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fchownat -#error "SYS_fchownat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fchownat, fchownat, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fdatasync.S b/src/kernel/libsyscall/sys_x86-64/_fdatasync.S deleted file mode 100644 index 7c0e412c9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fdatasync.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fdatasync -#error "SYS_fdatasync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fdatasync, fdatasync, 1, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_ffsctl.S b/src/kernel/libsyscall/sys_x86-64/_ffsctl.S deleted file mode 100644 index df5e3a1dd..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_ffsctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_ffsctl -#error "SYS_ffsctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_ffsctl, ffsctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fgetattrlist.S b/src/kernel/libsyscall/sys_x86-64/_fgetattrlist.S deleted file mode 100644 index 43f56d270..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fgetattrlist.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fgetattrlist -#error "SYS_fgetattrlist not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fgetattrlist, fgetattrlist, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fgetxattr.S b/src/kernel/libsyscall/sys_x86-64/_fgetxattr.S deleted file mode 100644 index ee87a7367..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fgetxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_fgetxattr -#error "SYS_fgetxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fgetxattr, fgetxattr, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fhopen.S b/src/kernel/libsyscall/sys_x86-64/_fhopen.S deleted file mode 100644 index 7c6eb63e7..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fhopen.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fhopen -#error "SYS_fhopen not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fhopen, fhopen, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fileport_makefd.S b/src/kernel/libsyscall/sys_x86-64/_fileport_makefd.S deleted file mode 100644 index cc91a3db2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fileport_makefd.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fileport_makefd -#error "SYS_fileport_makefd not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fileport_makefd, fileport_makefd, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fileport_makeport.S b/src/kernel/libsyscall/sys_x86-64/_fileport_makeport.S deleted file mode 100644 index 652cecf8d..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fileport_makeport.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fileport_makeport -#error "SYS_fileport_makeport not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fileport_makeport, fileport_makeport, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_flistxattr.S b/src/kernel/libsyscall/sys_x86-64/_flistxattr.S deleted file mode 100644 index 13251bae5..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_flistxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_flistxattr -#error "SYS_flistxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_flistxattr, flistxattr, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_flock.S b/src/kernel/libsyscall/sys_x86-64/_flock.S deleted file mode 100644 index b67565b14..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_flock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_flock -#error "SYS_flock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_flock, flock, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fpathconf.S b/src/kernel/libsyscall/sys_x86-64/_fpathconf.S deleted file mode 100644 index b70a6d4d8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fpathconf.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fpathconf -#error "SYS_fpathconf not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fpathconf, fpathconf, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fremovexattr.S b/src/kernel/libsyscall/sys_x86-64/_fremovexattr.S deleted file mode 100644 index 38aac00ed..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fremovexattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_fremovexattr -#error "SYS_fremovexattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fremovexattr, fremovexattr, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fsctl.S b/src/kernel/libsyscall/sys_x86-64/_fsctl.S deleted file mode 100644 index 94c672493..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fsctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fsctl -#error "SYS_fsctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fsctl, fsctl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fsetattrlist.S b/src/kernel/libsyscall/sys_x86-64/_fsetattrlist.S deleted file mode 100644 index 0487d52d9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fsetattrlist.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_fsetattrlist -#error "SYS_fsetattrlist not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fsetattrlist, fsetattrlist, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fsetxattr.S b/src/kernel/libsyscall/sys_x86-64/_fsetxattr.S deleted file mode 100644 index 2bb8fc132..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fsetxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_fsetxattr -#error "SYS_fsetxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fsetxattr, fsetxattr, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fstat.S b/src/kernel/libsyscall/sys_x86-64/_fstat.S deleted file mode 100644 index 0a0db5528..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fstat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fstat -#error "SYS_fstat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fstat, fstat, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fstat64.S b/src/kernel/libsyscall/sys_x86-64/_fstat64.S deleted file mode 100644 index 9e21432be..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fstat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fstat64 -#error "SYS_fstat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fstat64, fstat64, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _fstat$INODE64 - .set _fstat$INODE64, _fstat64 -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fstatat.S b/src/kernel/libsyscall/sys_x86-64/_fstatat.S deleted file mode 100644 index 1885f0105..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fstatat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fstatat -#error "SYS_fstatat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fstatat, fstatat, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fstatat64.S b/src/kernel/libsyscall/sys_x86-64/_fstatat64.S deleted file mode 100644 index 0245117f2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fstatat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_fstatat64 -#error "SYS_fstatat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fstatat64, fstatat64, 4, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _fstatat$INODE64 - .set _fstatat$INODE64, _fstatat64 -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fstatfs.S b/src/kernel/libsyscall/sys_x86-64/_fstatfs.S deleted file mode 100644 index 48cd391cc..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fstatfs.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fstatfs -#error "SYS_fstatfs not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fstatfs, fstatfs, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fstatfs64.S b/src/kernel/libsyscall/sys_x86-64/_fstatfs64.S deleted file mode 100644 index 4b5fcfce8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fstatfs64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_fstatfs64 -#error "SYS_fstatfs64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fstatfs64, fstatfs64, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _fstatfs$INODE64 - .set _fstatfs$INODE64, _fstatfs64 -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_fsync.S b/src/kernel/libsyscall/sys_x86-64/_fsync.S deleted file mode 100644 index f03c5db19..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_fsync.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_fsync -#error "SYS_fsync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_fsync, fsync, 1, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_ftruncate.S b/src/kernel/libsyscall/sys_x86-64/_ftruncate.S deleted file mode 100644 index 960cc1960..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_ftruncate.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_ftruncate -#error "SYS_ftruncate not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_ftruncate, ftruncate, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_futimes.S b/src/kernel/libsyscall/sys_x86-64/_futimes.S deleted file mode 100644 index 67dab3413..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_futimes.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_futimes -#error "SYS_futimes not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_futimes, futimes, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getattrlistat.S b/src/kernel/libsyscall/sys_x86-64/_getattrlistat.S deleted file mode 100644 index ac6fedeca..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getattrlistat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_getattrlistat -#error "SYS_getattrlistat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getattrlistat, getattrlistat, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getattrlistbulk.S b/src/kernel/libsyscall/sys_x86-64/_getattrlistbulk.S deleted file mode 100644 index 035b2dee3..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getattrlistbulk.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_getattrlistbulk -#error "SYS_getattrlistbulk not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getattrlistbulk, getattrlistbulk, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getaudit_addr.S b/src/kernel/libsyscall/sys_x86-64/_getaudit_addr.S deleted file mode 100644 index 9e000352b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getaudit_addr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getaudit_addr -#error "SYS_getaudit_addr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getaudit_addr, getaudit_addr, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getauid.S b/src/kernel/libsyscall/sys_x86-64/_getauid.S deleted file mode 100644 index cbb631a8a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getauid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_getauid -#error "SYS_getauid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getauid, getauid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getdirentries.S b/src/kernel/libsyscall/sys_x86-64/_getdirentries.S deleted file mode 100644 index 50f132ac0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getdirentries.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_getdirentries -#error "SYS_getdirentries not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getdirentries, getdirentries, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getdirentriesattr.S b/src/kernel/libsyscall/sys_x86-64/_getdirentriesattr.S deleted file mode 100644 index 0d4fd5da4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getdirentriesattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 32 -#include "SYS.h" - -#ifndef SYS_getdirentriesattr -#error "SYS_getdirentriesattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getdirentriesattr, getdirentriesattr, 8, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getdtablesize.S b/src/kernel/libsyscall/sys_x86-64/_getdtablesize.S deleted file mode 100644 index c8b5049a4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getdtablesize.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getdtablesize -#error "SYS_getdtablesize not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getdtablesize, getdtablesize, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getegid.S b/src/kernel/libsyscall/sys_x86-64/_getegid.S deleted file mode 100644 index de85526bf..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getegid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getegid -#error "SYS_getegid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getegid, getegid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_geteuid.S b/src/kernel/libsyscall/sys_x86-64/_geteuid.S deleted file mode 100644 index ff2759203..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_geteuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_geteuid -#error "SYS_geteuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_geteuid, geteuid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getfh.S b/src/kernel/libsyscall/sys_x86-64/_getfh.S deleted file mode 100644 index 8996f8792..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getfh.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getfh -#error "SYS_getfh not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getfh, getfh, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getfsstat.S b/src/kernel/libsyscall/sys_x86-64/_getfsstat.S deleted file mode 100644 index fb1f4e23b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getfsstat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_getfsstat -#error "SYS_getfsstat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getfsstat, getfsstat, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getfsstat64.S b/src/kernel/libsyscall/sys_x86-64/_getfsstat64.S deleted file mode 100644 index c9ba9540b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getfsstat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_getfsstat64 -#error "SYS_getfsstat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getfsstat64, getfsstat64, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _getfsstat$INODE64 - .set _getfsstat$INODE64, _getfsstat64 -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getgid.S b/src/kernel/libsyscall/sys_x86-64/_getgid.S deleted file mode 100644 index 11bb8879e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getgid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getgid -#error "SYS_getgid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getgid, getgid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getgroups.S b/src/kernel/libsyscall/sys_x86-64/_getgroups.S deleted file mode 100644 index ec643cb86..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getgroups.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getgroups -#error "SYS_getgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getgroups, getgroups, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getitimer.S b/src/kernel/libsyscall/sys_x86-64/_getitimer.S deleted file mode 100644 index 8a1fc064c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getitimer.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getitimer -#error "SYS_getitimer not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getitimer, getitimer, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getpgid.S b/src/kernel/libsyscall/sys_x86-64/_getpgid.S deleted file mode 100644 index 8aab8067f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getpgid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_getpgid -#error "SYS_getpgid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getpgid, getpgid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getpgrp.S b/src/kernel/libsyscall/sys_x86-64/_getpgrp.S deleted file mode 100644 index 064e4012f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getpgrp.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getpgrp -#error "SYS_getpgrp not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getpgrp, getpgrp, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getppid.S b/src/kernel/libsyscall/sys_x86-64/_getppid.S deleted file mode 100644 index f46524d20..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getppid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getppid -#error "SYS_getppid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getppid, getppid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getpriority.S b/src/kernel/libsyscall/sys_x86-64/_getpriority.S deleted file mode 100644 index 90f521214..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getpriority.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getpriority -#error "SYS_getpriority not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getpriority, getpriority, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getrusage.S b/src/kernel/libsyscall/sys_x86-64/_getrusage.S deleted file mode 100644 index d662b3c35..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getrusage.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_getrusage -#error "SYS_getrusage not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getrusage, getrusage, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getsid.S b/src/kernel/libsyscall/sys_x86-64/_getsid.S deleted file mode 100644 index 8c521830a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getsid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_getsid -#error "SYS_getsid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getsid, getsid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getsockopt.S b/src/kernel/libsyscall/sys_x86-64/_getsockopt.S deleted file mode 100644 index 4d7caf70e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getsockopt.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_getsockopt -#error "SYS_getsockopt not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getsockopt, getsockopt, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getuid.S b/src/kernel/libsyscall/sys_x86-64/_getuid.S deleted file mode 100644 index a9ba97b92..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_getuid -#error "SYS_getuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getuid, getuid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_getxattr.S b/src/kernel/libsyscall/sys_x86-64/_getxattr.S deleted file mode 100644 index 549b1abf8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_getxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_getxattr -#error "SYS_getxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_getxattr, getxattr, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_grab_pgo_data.S b/src/kernel/libsyscall/sys_x86-64/_grab_pgo_data.S deleted file mode 100644 index ecf5c5e4f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_grab_pgo_data.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_grab_pgo_data -#error "SYS_grab_pgo_data not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_grab_pgo_data, grab_pgo_data, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_guarded_close_np.S b/src/kernel/libsyscall/sys_x86-64/_guarded_close_np.S deleted file mode 100644 index 5a9f64e0a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_guarded_close_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_guarded_close_np -#error "SYS_guarded_close_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_guarded_close_np, guarded_close_np, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_guarded_kqueue_np.S b/src/kernel/libsyscall/sys_x86-64/_guarded_kqueue_np.S deleted file mode 100644 index 1b1a08a73..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_guarded_kqueue_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_guarded_kqueue_np -#error "SYS_guarded_kqueue_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_guarded_kqueue_np, guarded_kqueue_np, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_guarded_pwrite_np.S b/src/kernel/libsyscall/sys_x86-64/_guarded_pwrite_np.S deleted file mode 100644 index 79f1dfabd..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_guarded_pwrite_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_guarded_pwrite_np -#error "SYS_guarded_pwrite_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_guarded_pwrite_np, guarded_pwrite_np, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_guarded_write_np.S b/src/kernel/libsyscall/sys_x86-64/_guarded_write_np.S deleted file mode 100644 index 885bf189e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_guarded_write_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_guarded_write_np -#error "SYS_guarded_write_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_guarded_write_np, guarded_write_np, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_guarded_writev_np.S b/src/kernel/libsyscall/sys_x86-64/_guarded_writev_np.S deleted file mode 100644 index bb0fb6ba5..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_guarded_writev_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_guarded_writev_np -#error "SYS_guarded_writev_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_guarded_writev_np, guarded_writev_np, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_issetugid.S b/src/kernel/libsyscall/sys_x86-64/_issetugid.S deleted file mode 100644 index 4b5e59c51..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_issetugid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_issetugid -#error "SYS_issetugid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_issetugid, issetugid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_kas_info.S b/src/kernel/libsyscall/sys_x86-64/_kas_info.S deleted file mode 100644 index 8b1c6a2f9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_kas_info.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_kas_info -#error "SYS_kas_info not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_kas_info, kas_info, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_kevent.S b/src/kernel/libsyscall/sys_x86-64/_kevent.S deleted file mode 100644 index be9233895..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_kevent.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_kevent -#error "SYS_kevent not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_kevent, kevent, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_kevent64.S b/src/kernel/libsyscall/sys_x86-64/_kevent64.S deleted file mode 100644 index 754114e99..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_kevent64.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_kevent64 -#error "SYS_kevent64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_kevent64, kevent64, 7, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_kevent_qos.S b/src/kernel/libsyscall/sys_x86-64/_kevent_qos.S deleted file mode 100644 index 6a5a2c9fa..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_kevent_qos.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 32 -#include "SYS.h" - -#ifndef SYS_kevent_qos -#error "SYS_kevent_qos not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_kevent_qos, kevent_qos, 8, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_kqueue.S b/src/kernel/libsyscall/sys_x86-64/_kqueue.S deleted file mode 100644 index 789e84dda..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_kqueue.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_kqueue -#error "SYS_kqueue not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_kqueue, kqueue, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_ledger.S b/src/kernel/libsyscall/sys_x86-64/_ledger.S deleted file mode 100644 index e3f8ba5f1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_ledger.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_ledger -#error "SYS_ledger not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_ledger, ledger, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_link.S b/src/kernel/libsyscall/sys_x86-64/_link.S deleted file mode 100644 index 2eae426f9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_link.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_link -#error "SYS_link not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_link, link, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_linkat.S b/src/kernel/libsyscall/sys_x86-64/_linkat.S deleted file mode 100644 index 53ee2f9ba..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_linkat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_linkat -#error "SYS_linkat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_linkat, linkat, 5, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_lio_listio.S b/src/kernel/libsyscall/sys_x86-64/_lio_listio.S deleted file mode 100644 index 87431af0d..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_lio_listio.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_lio_listio -#error "SYS_lio_listio not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_lio_listio, lio_listio, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_listxattr.S b/src/kernel/libsyscall/sys_x86-64/_listxattr.S deleted file mode 100644 index 63781b9f0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_listxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_listxattr -#error "SYS_listxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_listxattr, listxattr, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_lstat.S b/src/kernel/libsyscall/sys_x86-64/_lstat.S deleted file mode 100644 index 9ff7145be..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_lstat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_lstat -#error "SYS_lstat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_lstat, lstat, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_lstat64.S b/src/kernel/libsyscall/sys_x86-64/_lstat64.S deleted file mode 100644 index 23b8c8c1f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_lstat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_lstat64 -#error "SYS_lstat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_lstat64, lstat64, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _lstat$INODE64 - .set _lstat$INODE64, _lstat64 -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_madvise.S b/src/kernel/libsyscall/sys_x86-64/_madvise.S deleted file mode 100644 index fbeacd6dd..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_madvise.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_madvise -#error "SYS_madvise not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_madvise, madvise, 3, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _posix_madvise - .set _posix_madvise, _madvise -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_memorystatus_control.S b/src/kernel/libsyscall/sys_x86-64/_memorystatus_control.S deleted file mode 100644 index dd1fe72bd..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_memorystatus_control.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_memorystatus_control -#error "SYS_memorystatus_control not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_memorystatus_control, memorystatus_control, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_memorystatus_get_level.S b/src/kernel/libsyscall/sys_x86-64/_memorystatus_get_level.S deleted file mode 100644 index 5ee7eda62..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_memorystatus_get_level.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_memorystatus_get_level -#error "SYS_memorystatus_get_level not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_memorystatus_get_level, memorystatus_get_level, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_mincore.S b/src/kernel/libsyscall/sys_x86-64/_mincore.S deleted file mode 100644 index bbd08adc9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_mincore.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_mincore -#error "SYS_mincore not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_mincore, mincore, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_minherit.S b/src/kernel/libsyscall/sys_x86-64/_minherit.S deleted file mode 100644 index e8a1b2234..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_minherit.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_minherit -#error "SYS_minherit not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_minherit, minherit, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_mkdir.S b/src/kernel/libsyscall/sys_x86-64/_mkdir.S deleted file mode 100644 index 1b5bd423c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_mkdir.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_mkdir -#error "SYS_mkdir not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_mkdir, mkdir, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_mkdirat.S b/src/kernel/libsyscall/sys_x86-64/_mkdirat.S deleted file mode 100644 index 27cf8cc47..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_mkdirat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_mkdirat -#error "SYS_mkdirat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_mkdirat, mkdirat, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_mkfifo.S b/src/kernel/libsyscall/sys_x86-64/_mkfifo.S deleted file mode 100644 index bcad8b2b7..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_mkfifo.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_mkfifo -#error "SYS_mkfifo not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_mkfifo, mkfifo, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_mknod.S b/src/kernel/libsyscall/sys_x86-64/_mknod.S deleted file mode 100644 index 0008f14b4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_mknod.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_mknod -#error "SYS_mknod not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_mknod, mknod, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_mlock.S b/src/kernel/libsyscall/sys_x86-64/_mlock.S deleted file mode 100644 index cef4cd1be..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_mlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_mlock -#error "SYS_mlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_mlock, mlock, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_mlockall.S b/src/kernel/libsyscall/sys_x86-64/_mlockall.S deleted file mode 100644 index 39578920b..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_mlockall.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_mlockall -#error "SYS_mlockall not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_mlockall, mlockall, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_modwatch.S b/src/kernel/libsyscall/sys_x86-64/_modwatch.S deleted file mode 100644 index f8e944844..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_modwatch.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_modwatch -#error "SYS_modwatch not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_modwatch, modwatch, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_mount.S b/src/kernel/libsyscall/sys_x86-64/_mount.S deleted file mode 100644 index 8e8c8e25d..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_mount.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_mount -#error "SYS_mount not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_mount, mount, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_mremap_encrypted.S b/src/kernel/libsyscall/sys_x86-64/_mremap_encrypted.S deleted file mode 100644 index 0988c8d42..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_mremap_encrypted.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_mremap_encrypted -#error "SYS_mremap_encrypted not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_mremap_encrypted, mremap_encrypted, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_msgget.S b/src/kernel/libsyscall/sys_x86-64/_msgget.S deleted file mode 100644 index 69939f607..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_msgget.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_msgget -#error "SYS_msgget not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_msgget, msgget, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_msgrcv.S b/src/kernel/libsyscall/sys_x86-64/_msgrcv.S deleted file mode 100644 index 25d4049bb..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_msgrcv.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_msgrcv -#error "SYS_msgrcv not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_msgrcv, msgrcv, 5, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_msgsnd.S b/src/kernel/libsyscall/sys_x86-64/_msgsnd.S deleted file mode 100644 index 1bac99ab5..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_msgsnd.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_msgsnd -#error "SYS_msgsnd not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_msgsnd, msgsnd, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_munlock.S b/src/kernel/libsyscall/sys_x86-64/_munlock.S deleted file mode 100644 index 61e0830ee..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_munlock.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_munlock -#error "SYS_munlock not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_munlock, munlock, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_munlockall.S b/src/kernel/libsyscall/sys_x86-64/_munlockall.S deleted file mode 100644 index d925dbfed..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_munlockall.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_munlockall -#error "SYS_munlockall not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_munlockall, munlockall, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_necp_match_policy.S b/src/kernel/libsyscall/sys_x86-64/_necp_match_policy.S deleted file mode 100644 index 8a2e3a4bc..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_necp_match_policy.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_necp_match_policy -#error "SYS_necp_match_policy not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_necp_match_policy, necp_match_policy, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_netagent_trigger.S b/src/kernel/libsyscall/sys_x86-64/_netagent_trigger.S deleted file mode 100644 index 220ce72a1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_netagent_trigger.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_netagent_trigger -#error "SYS_netagent_trigger not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_netagent_trigger, netagent_trigger, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_nfsclnt.S b/src/kernel/libsyscall/sys_x86-64/_nfsclnt.S deleted file mode 100644 index 20055c0cf..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_nfsclnt.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_nfsclnt -#error "SYS_nfsclnt not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_nfsclnt, nfsclnt, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_nfssvc.S b/src/kernel/libsyscall/sys_x86-64/_nfssvc.S deleted file mode 100644 index db5ebf6b7..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_nfssvc.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_nfssvc -#error "SYS_nfssvc not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_nfssvc, nfssvc, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_openbyid_np.S b/src/kernel/libsyscall/sys_x86-64/_openbyid_np.S deleted file mode 100644 index f063cf143..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_openbyid_np.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_openbyid_np -#error "SYS_openbyid_np not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_openbyid_np, openbyid_np, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_pathconf.S b/src/kernel/libsyscall/sys_x86-64/_pathconf.S deleted file mode 100644 index 8623a7124..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_pathconf.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_pathconf -#error "SYS_pathconf not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_pathconf, pathconf, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_peeloff.S b/src/kernel/libsyscall/sys_x86-64/_peeloff.S deleted file mode 100644 index 6356c93d0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_peeloff.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_peeloff -#error "SYS_peeloff not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_peeloff, peeloff, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_pid_resume.S b/src/kernel/libsyscall/sys_x86-64/_pid_resume.S deleted file mode 100644 index 207fa339a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_pid_resume.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_pid_resume -#error "SYS_pid_resume not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_pid_resume, pid_resume, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_pid_suspend.S b/src/kernel/libsyscall/sys_x86-64/_pid_suspend.S deleted file mode 100644 index b16a896be..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_pid_suspend.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_pid_suspend -#error "SYS_pid_suspend not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_pid_suspend, pid_suspend, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_poll.S b/src/kernel/libsyscall/sys_x86-64/_poll.S deleted file mode 100644 index 2bb93afb4..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_poll.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_poll -#error "SYS_poll not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_poll, poll, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_pread.S b/src/kernel/libsyscall/sys_x86-64/_pread.S deleted file mode 100644 index c27cabe16..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_pread.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_pread -#error "SYS_pread not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_pread, pread, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_proc_rlimit_control.S b/src/kernel/libsyscall/sys_x86-64/_proc_rlimit_control.S deleted file mode 100644 index e0da064bf..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_proc_rlimit_control.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_proc_rlimit_control -#error "SYS_proc_rlimit_control not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_proc_rlimit_control, proc_rlimit_control, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_proc_trace_log.S b/src/kernel/libsyscall/sys_x86-64/_proc_trace_log.S deleted file mode 100644 index 9bc495714..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_proc_trace_log.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_proc_trace_log -#error "SYS_proc_trace_log not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_proc_trace_log, proc_trace_log, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_proc_uuid_policy.S b/src/kernel/libsyscall/sys_x86-64/_proc_uuid_policy.S deleted file mode 100644 index 63b68b900..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_proc_uuid_policy.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_proc_uuid_policy -#error "SYS_proc_uuid_policy not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_proc_uuid_policy, proc_uuid_policy, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_pwrite.S b/src/kernel/libsyscall/sys_x86-64/_pwrite.S deleted file mode 100644 index 4b1ae8ae2..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_pwrite.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_pwrite -#error "SYS_pwrite not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_pwrite, pwrite, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_quotactl.S b/src/kernel/libsyscall/sys_x86-64/_quotactl.S deleted file mode 100644 index 900b10195..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_quotactl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_quotactl -#error "SYS_quotactl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_quotactl, quotactl, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_read.S b/src/kernel/libsyscall/sys_x86-64/_read.S deleted file mode 100644 index cef425a2a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_read.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_read -#error "SYS_read not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_read, read, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_readlink.S b/src/kernel/libsyscall/sys_x86-64/_readlink.S deleted file mode 100644 index a22f12f2f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_readlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_readlink -#error "SYS_readlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_readlink, readlink, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_readlinkat.S b/src/kernel/libsyscall/sys_x86-64/_readlinkat.S deleted file mode 100644 index 897337d5a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_readlinkat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_readlinkat -#error "SYS_readlinkat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_readlinkat, readlinkat, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_readv.S b/src/kernel/libsyscall/sys_x86-64/_readv.S deleted file mode 100644 index c4b82656f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_readv.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_readv -#error "SYS_readv not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_readv, readv, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_reboot.S b/src/kernel/libsyscall/sys_x86-64/_reboot.S deleted file mode 100644 index ec8179b07..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_reboot.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_reboot -#error "SYS_reboot not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_reboot, reboot, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_recvmsg_x.S b/src/kernel/libsyscall/sys_x86-64/_recvmsg_x.S deleted file mode 100644 index 31f378051..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_recvmsg_x.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_recvmsg_x -#error "SYS_recvmsg_x not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_recvmsg_x, recvmsg_x, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_removexattr.S b/src/kernel/libsyscall/sys_x86-64/_removexattr.S deleted file mode 100644 index fad8f2660..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_removexattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_removexattr -#error "SYS_removexattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_removexattr, removexattr, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_revoke.S b/src/kernel/libsyscall/sys_x86-64/_revoke.S deleted file mode 100644 index fe2b22edc..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_revoke.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_revoke -#error "SYS_revoke not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_revoke, revoke, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_searchfs.S b/src/kernel/libsyscall/sys_x86-64/_searchfs.S deleted file mode 100644 index 823beb79c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_searchfs.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_searchfs -#error "SYS_searchfs not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_searchfs, searchfs, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sem_close.S b/src/kernel/libsyscall/sys_x86-64/_sem_close.S deleted file mode 100644 index 1b337949a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sem_close.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_close -#error "SYS_sem_close not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sem_close, sem_close, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sem_post.S b/src/kernel/libsyscall/sys_x86-64/_sem_post.S deleted file mode 100644 index b87edcfb9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sem_post.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_post -#error "SYS_sem_post not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sem_post, sem_post, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sem_trywait.S b/src/kernel/libsyscall/sys_x86-64/_sem_trywait.S deleted file mode 100644 index 4c2fad7b3..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sem_trywait.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_trywait -#error "SYS_sem_trywait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sem_trywait, sem_trywait, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sem_unlink.S b/src/kernel/libsyscall/sys_x86-64/_sem_unlink.S deleted file mode 100644 index 617dae966..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sem_unlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_unlink -#error "SYS_sem_unlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sem_unlink, sem_unlink, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sem_wait.S b/src/kernel/libsyscall/sys_x86-64/_sem_wait.S deleted file mode 100644 index ada7dad57..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sem_wait.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sem_wait -#error "SYS_sem_wait not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sem_wait, sem_wait, 1, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_semget.S b/src/kernel/libsyscall/sys_x86-64/_semget.S deleted file mode 100644 index e9eaf1d60..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_semget.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_semget -#error "SYS_semget not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_semget, semget, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_semop.S b/src/kernel/libsyscall/sys_x86-64/_semop.S deleted file mode 100644 index 283f5384d..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_semop.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_semop -#error "SYS_semop not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_semop, semop, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sendfile.S b/src/kernel/libsyscall/sys_x86-64/_sendfile.S deleted file mode 100644 index 4d2279924..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sendfile.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 28 -#include "SYS.h" - -#ifndef SYS_sendfile -#error "SYS_sendfile not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sendfile, sendfile, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sendmsg_x.S b/src/kernel/libsyscall/sys_x86-64/_sendmsg_x.S deleted file mode 100644 index 81d83e2e5..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sendmsg_x.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_sendmsg_x -#error "SYS_sendmsg_x not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sendmsg_x, sendmsg_x, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setaudit_addr.S b/src/kernel/libsyscall/sys_x86-64/_setaudit_addr.S deleted file mode 100644 index 9c10eafec..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setaudit_addr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setaudit_addr -#error "SYS_setaudit_addr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setaudit_addr, setaudit_addr, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setauid.S b/src/kernel/libsyscall/sys_x86-64/_setauid.S deleted file mode 100644 index 91fe07da8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setauid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setauid -#error "SYS_setauid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setauid, setauid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setegid.S b/src/kernel/libsyscall/sys_x86-64/_setegid.S deleted file mode 100644 index 6d220e5ea..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setegid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setegid -#error "SYS_setegid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setegid, setegid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_seteuid.S b/src/kernel/libsyscall/sys_x86-64/_seteuid.S deleted file mode 100644 index e512e235c..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_seteuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_seteuid -#error "SYS_seteuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_seteuid, seteuid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setgid.S b/src/kernel/libsyscall/sys_x86-64/_setgid.S deleted file mode 100644 index 260c20453..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setgid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setgid -#error "SYS_setgid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setgid, setgid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setgroups.S b/src/kernel/libsyscall/sys_x86-64/_setgroups.S deleted file mode 100644 index 959d02aa1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setgroups.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setgroups -#error "SYS_setgroups not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setgroups, setgroups, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setitimer.S b/src/kernel/libsyscall/sys_x86-64/_setitimer.S deleted file mode 100644 index 01cd5b14e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setitimer.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_setitimer -#error "SYS_setitimer not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setitimer, setitimer, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setpgid.S b/src/kernel/libsyscall/sys_x86-64/_setpgid.S deleted file mode 100644 index e25c6974e..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setpgid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_setpgid -#error "SYS_setpgid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setpgid, setpgid, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setprivexec.S b/src/kernel/libsyscall/sys_x86-64/_setprivexec.S deleted file mode 100644 index 03fb1d90d..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setprivexec.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setprivexec -#error "SYS_setprivexec not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setprivexec, setprivexec, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setsid.S b/src/kernel/libsyscall/sys_x86-64/_setsid.S deleted file mode 100644 index a362e16d1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setsid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_setsid -#error "SYS_setsid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setsid, setsid, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setsockopt.S b/src/kernel/libsyscall/sys_x86-64/_setsockopt.S deleted file mode 100644 index 27b5c76bb..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setsockopt.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 20 -#include "SYS.h" - -#ifndef SYS_setsockopt -#error "SYS_setsockopt not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setsockopt, setsockopt, 5, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setuid.S b/src/kernel/libsyscall/sys_x86-64/_setuid.S deleted file mode 100644 index ae9e09023..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setuid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_setuid -#error "SYS_setuid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setuid, setuid, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_setxattr.S b/src/kernel/libsyscall/sys_x86-64/_setxattr.S deleted file mode 100644 index b2050791d..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_setxattr.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 24 -#include "SYS.h" - -#ifndef SYS_setxattr -#error "SYS_setxattr not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_setxattr, setxattr, 6, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_shm_unlink.S b/src/kernel/libsyscall/sys_x86-64/_shm_unlink.S deleted file mode 100644 index 77142b6d9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_shm_unlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_shm_unlink -#error "SYS_shm_unlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_shm_unlink, shm_unlink, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_shmat.S b/src/kernel/libsyscall/sys_x86-64/_shmat.S deleted file mode 100644 index 1259b0397..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_shmat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_shmat -#error "SYS_shmat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_shmat, shmat, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_shmdt.S b/src/kernel/libsyscall/sys_x86-64/_shmdt.S deleted file mode 100644 index bbf6b65db..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_shmdt.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_shmdt -#error "SYS_shmdt not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_shmdt, shmdt, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_shmget.S b/src/kernel/libsyscall/sys_x86-64/_shmget.S deleted file mode 100644 index 2c1c26b37..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_shmget.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_shmget -#error "SYS_shmget not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_shmget, shmget, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_shutdown.S b/src/kernel/libsyscall/sys_x86-64/_shutdown.S deleted file mode 100644 index 7ae075c30..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_shutdown.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_shutdown -#error "SYS_shutdown not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_shutdown, shutdown, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sigpending.S b/src/kernel/libsyscall/sys_x86-64/_sigpending.S deleted file mode 100644 index 02d597aef..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sigpending.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_sigpending -#error "SYS_sigpending not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sigpending, sigpending, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sigprocmask.S b/src/kernel/libsyscall/sys_x86-64/_sigprocmask.S deleted file mode 100644 index 2508f29e3..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sigprocmask.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_sigprocmask -#error "SYS_sigprocmask not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sigprocmask, sigprocmask, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_socket.S b/src/kernel/libsyscall/sys_x86-64/_socket.S deleted file mode 100644 index 1ac5a79c5..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_socket.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_socket -#error "SYS_socket not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_socket, socket, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_socket_delegate.S b/src/kernel/libsyscall/sys_x86-64/_socket_delegate.S deleted file mode 100644 index 93cac6314..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_socket_delegate.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_socket_delegate -#error "SYS_socket_delegate not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_socket_delegate, socket_delegate, 4, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_stat.S b/src/kernel/libsyscall/sys_x86-64/_stat.S deleted file mode 100644 index 45df7f88f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_stat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_stat -#error "SYS_stat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_stat, stat, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_stat64.S b/src/kernel/libsyscall/sys_x86-64/_stat64.S deleted file mode 100644 index 7306503d5..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_stat64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_stat64 -#error "SYS_stat64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_stat64, stat64, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _stat$INODE64 - .set _stat$INODE64, _stat64 -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_statfs.S b/src/kernel/libsyscall/sys_x86-64/_statfs.S deleted file mode 100644 index 780b8bc41..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_statfs.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_statfs -#error "SYS_statfs not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_statfs, statfs, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_statfs64.S b/src/kernel/libsyscall/sys_x86-64/_statfs64.S deleted file mode 100644 index bc566f3a7..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_statfs64.S +++ /dev/null @@ -1,16 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_statfs64 -#error "SYS_statfs64 not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_statfs64, statfs64, 2, cerror_nocancel) -#endif - -#if defined(__x86_64__) - .globl _statfs$INODE64 - .set _statfs$INODE64, _statfs64 -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_swapon.S b/src/kernel/libsyscall/sys_x86-64/_swapon.S deleted file mode 100644 index 861f63c05..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_swapon.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_swapon -#error "SYS_swapon not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_swapon, swapon, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_symlink.S b/src/kernel/libsyscall/sys_x86-64/_symlink.S deleted file mode 100644 index 5c7cc7dd8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_symlink.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_symlink -#error "SYS_symlink not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_symlink, symlink, 2, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_symlinkat.S b/src/kernel/libsyscall/sys_x86-64/_symlinkat.S deleted file mode 100644 index 44f7e50de..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_symlinkat.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_symlinkat -#error "SYS_symlinkat not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_symlinkat, symlinkat, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_sync.S b/src/kernel/libsyscall/sys_x86-64/_sync.S deleted file mode 100644 index cb8346157..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_sync.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_sync -#error "SYS_sync not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_sync, sync, 0, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_system_override.S b/src/kernel/libsyscall/sys_x86-64/_system_override.S deleted file mode 100644 index c9d1aefe8..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_system_override.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_system_override -#error "SYS_system_override not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_system_override, system_override, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_truncate.S b/src/kernel/libsyscall/sys_x86-64/_truncate.S deleted file mode 100644 index b45aac823..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_truncate.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_truncate -#error "SYS_truncate not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_truncate, truncate, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_umask.S b/src/kernel/libsyscall/sys_x86-64/_umask.S deleted file mode 100644 index 2d3a506e9..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_umask.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_umask -#error "SYS_umask not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_umask, umask, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_undelete.S b/src/kernel/libsyscall/sys_x86-64/_undelete.S deleted file mode 100644 index c824e5ad1..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_undelete.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_undelete -#error "SYS_undelete not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_undelete, undelete, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_unmount.S b/src/kernel/libsyscall/sys_x86-64/_unmount.S deleted file mode 100644 index 20b77e53f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_unmount.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_unmount -#error "SYS_unmount not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_unmount, unmount, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_usrctl.S b/src/kernel/libsyscall/sys_x86-64/_usrctl.S deleted file mode 100644 index fe440acf0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_usrctl.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 4 -#include "SYS.h" - -#ifndef SYS_usrctl -#error "SYS_usrctl not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_usrctl, usrctl, 1, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_utimes.S b/src/kernel/libsyscall/sys_x86-64/_utimes.S deleted file mode 100644 index e7c0ab72d..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_utimes.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_utimes -#error "SYS_utimes not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_utimes, utimes, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_vfs_purge.S b/src/kernel/libsyscall/sys_x86-64/_vfs_purge.S deleted file mode 100644 index 302cb6767..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_vfs_purge.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 0 -#include "SYS.h" - -#ifndef SYS_vfs_purge -#error "SYS_vfs_purge not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_vfs_purge, vfs_purge, 0, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_vm_pressure_monitor.S b/src/kernel/libsyscall/sys_x86-64/_vm_pressure_monitor.S deleted file mode 100644 index 787bc3bc0..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_vm_pressure_monitor.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_vm_pressure_monitor -#error "SYS_vm_pressure_monitor not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_vm_pressure_monitor, vm_pressure_monitor, 3, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_waitevent.S b/src/kernel/libsyscall/sys_x86-64/_waitevent.S deleted file mode 100644 index ebe03fb1a..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_waitevent.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_waitevent -#error "SYS_waitevent not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_waitevent, waitevent, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_waitid.S b/src/kernel/libsyscall/sys_x86-64/_waitid.S deleted file mode 100644 index 53d27b80f..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_waitid.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 16 -#include "SYS.h" - -#ifndef SYS_waitid -#error "SYS_waitid not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_waitid, waitid, 4, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_watchevent.S b/src/kernel/libsyscall/sys_x86-64/_watchevent.S deleted file mode 100644 index cb0f103da..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_watchevent.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 8 -#include "SYS.h" - -#ifndef SYS_watchevent -#error "SYS_watchevent not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_watchevent, watchevent, 2, cerror_nocancel) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_write.S b/src/kernel/libsyscall/sys_x86-64/_write.S deleted file mode 100644 index c2ab9cf48..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_write.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_write -#error "SYS_write not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_write, write, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/_writev.S b/src/kernel/libsyscall/sys_x86-64/_writev.S deleted file mode 100644 index b8a878dac..000000000 --- a/src/kernel/libsyscall/sys_x86-64/_writev.S +++ /dev/null @@ -1,11 +0,0 @@ -#define __SYSCALL_32BIT_ARG_BYTES 12 -#include "SYS.h" - -#ifndef SYS_writev -#error "SYS_writev not defined. The header files libsyscall is building against do not match syscalls.master." -#endif - -#if defined(__x86_64__) -__SYSCALL2(_writev, writev, 3, cerror) -#endif - diff --git a/src/kernel/libsyscall/sys_x86-64/custom.S b/src/kernel/libsyscall/sys_x86-64/custom.S deleted file mode 100644 index 7c0004688..000000000 --- a/src/kernel/libsyscall/sys_x86-64/custom.S +++ /dev/null @@ -1,108 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999-2011 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - */ - -#include "SYS.h" - -#if defined(__i386__) - -/* - * i386 needs custom assembly to transform the return from syscalls - * into a proper stack for a function call out to cerror{,_nocancel}. - */ - -LABEL(tramp_cerror) - mov %esp, %edx - andl $0xfffffff0, %esp - subl $16, %esp - movl %edx, 4(%esp) - movl %eax, (%esp) - CALL_EXTERN(_cerror) - movl 4(%esp), %esp - ret - -LABEL(tramp_cerror_nocancel) - mov %esp, %edx - andl $0xfffffff0, %esp - subl $16, %esp - movl %edx, 4(%esp) - movl %eax, (%esp) - CALL_EXTERN(_cerror_nocancel) - movl 4(%esp), %esp - ret - -LABEL(__sysenter_trap) - popl %edx - movl %esp, %ecx - sysenter - - .globl _i386_get_ldt - ALIGN -_i386_get_ldt: - movl $6,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - jmp _tramp_cerror -2: ret - - - .globl _i386_set_ldt - ALIGN -_i386_set_ldt: - movl $5,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - jmp _tramp_cerror -2: ret - -#elif defined(__x86_64__) - - .globl _i386_get_ldt - ALIGN -_i386_get_ldt: - movl $6,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - movq %rax, %rdi - jmp _cerror -2: ret - - - .globl _i386_set_ldt - ALIGN -_i386_set_ldt: - movl $5,%eax - MACHDEP_SYSCALL_TRAP - jnb 2f - movq %rax, %rdi - jmp _cerror -2: ret - -#endif diff --git a/src/kernel/libsyscall/sys_x86-64/stubs.list b/src/kernel/libsyscall/sys_x86-64/stubs.list deleted file mode 100644 index 60bcd7800..000000000 --- a/src/kernel/libsyscall/sys_x86-64/stubs.list +++ /dev/null @@ -1,395 +0,0 @@ -sys_x86-64/_____old_semwait_signal_nocancel.s -sys_x86-64/_____sigwait_nocancel.s -sys_x86-64/___accept.s -sys_x86-64/___accept_nocancel.s -sys_x86-64/___access_extended.s -sys_x86-64/___aio_suspend_nocancel.s -sys_x86-64/___bind.s -sys_x86-64/___bsdthread_create.s -sys_x86-64/___bsdthread_ctl.s -sys_x86-64/___bsdthread_register.s -sys_x86-64/___bsdthread_terminate.s -sys_x86-64/___chmod.s -sys_x86-64/___chmod_extended.s -sys_x86-64/___chud.s -sys_x86-64/___close_nocancel.s -sys_x86-64/___coalition.s -sys_x86-64/___coalition_info.s -sys_x86-64/___connect.s -sys_x86-64/___connect_nocancel.s -sys_x86-64/___copyfile.s -sys_x86-64/___csrctl.s -sys_x86-64/___delete.s -sys_x86-64/___disable_threadsignal.s -sys_x86-64/___exit.s -sys_x86-64/___fchmod.s -sys_x86-64/___fchmod_extended.s -sys_x86-64/___fcntl.s -sys_x86-64/___fcntl_nocancel.s -sys_x86-64/___fork.s -sys_x86-64/___fsgetpath.s -sys_x86-64/___fstat64_extended.s -sys_x86-64/___fstat_extended.s -sys_x86-64/___fsync_nocancel.s -sys_x86-64/___getattrlist.s -sys_x86-64/___getdirentries64.s -sys_x86-64/___gethostuuid.s -sys_x86-64/___getlogin.s -sys_x86-64/___getpeername.s -sys_x86-64/___getpid.s -sys_x86-64/___getrlimit.s -sys_x86-64/___getsgroups.s -sys_x86-64/___getsockname.s -sys_x86-64/___gettid.s -sys_x86-64/___gettimeofday.s -sys_x86-64/___getwgroups.s -sys_x86-64/___guarded_open_dprotected_np.s -sys_x86-64/___guarded_open_np.s -sys_x86-64/___identitysvc.s -sys_x86-64/___initgroups.s -sys_x86-64/___ioctl.s -sys_x86-64/___iopolicysys.s -sys_x86-64/___kdebug_trace.s -sys_x86-64/___kdebug_trace64.s -sys_x86-64/___kdebug_trace_string.s -sys_x86-64/___kill.s -sys_x86-64/___lchown.s -sys_x86-64/___listen.s -sys_x86-64/___lseek.s -sys_x86-64/___lstat64_extended.s -sys_x86-64/___lstat_extended.s -sys_x86-64/___mac_execve.s -sys_x86-64/___mac_get_fd.s -sys_x86-64/___mac_get_file.s -sys_x86-64/___mac_get_link.s -sys_x86-64/___mac_get_mount.s -sys_x86-64/___mac_get_pid.s -sys_x86-64/___mac_get_proc.s -sys_x86-64/___mac_getfsstat.s -sys_x86-64/___mac_mount.s -sys_x86-64/___mac_set_fd.s -sys_x86-64/___mac_set_file.s -sys_x86-64/___mac_set_link.s -sys_x86-64/___mac_set_proc.s -sys_x86-64/___mac_syscall.s -sys_x86-64/___microstackshot.s -sys_x86-64/___mkdir_extended.s -sys_x86-64/___mkfifo_extended.s -sys_x86-64/___mmap.s -sys_x86-64/___mprotect.s -sys_x86-64/___msgctl.s -sys_x86-64/___msgrcv_nocancel.s -sys_x86-64/___msgsnd_nocancel.s -sys_x86-64/___msgsys.s -sys_x86-64/___msync.s -sys_x86-64/___msync_nocancel.s -sys_x86-64/___munmap.s -sys_x86-64/___old_semwait_signal.s -sys_x86-64/___open.s -sys_x86-64/___open_dprotected_np.s -sys_x86-64/___open_extended.s -sys_x86-64/___open_nocancel.s -sys_x86-64/___openat.s -sys_x86-64/___openat_nocancel.s -sys_x86-64/___persona.s -sys_x86-64/___pipe.s -sys_x86-64/___poll_nocancel.s -sys_x86-64/___posix_spawn.s -sys_x86-64/___pread_nocancel.s -sys_x86-64/___proc_info.s -sys_x86-64/___process_policy.s -sys_x86-64/___pselect.s -sys_x86-64/___pselect_nocancel.s -sys_x86-64/___psynch_cvbroad.s -sys_x86-64/___psynch_cvclrprepost.s -sys_x86-64/___psynch_cvsignal.s -sys_x86-64/___psynch_cvwait.s -sys_x86-64/___psynch_mutexdrop.s -sys_x86-64/___psynch_mutexwait.s -sys_x86-64/___psynch_rw_downgrade.s -sys_x86-64/___psynch_rw_longrdlock.s -sys_x86-64/___psynch_rw_rdlock.s -sys_x86-64/___psynch_rw_unlock.s -sys_x86-64/___psynch_rw_unlock2.s -sys_x86-64/___psynch_rw_upgrade.s -sys_x86-64/___psynch_rw_wrlock.s -sys_x86-64/___psynch_rw_yieldwrlock.s -sys_x86-64/___pthread_canceled.s -sys_x86-64/___pthread_chdir.s -sys_x86-64/___pthread_fchdir.s -sys_x86-64/___pthread_kill.s -sys_x86-64/___pthread_markcancel.s -sys_x86-64/___pthread_sigmask.s -sys_x86-64/___ptrace.s -sys_x86-64/___pwrite_nocancel.s -sys_x86-64/___read_nocancel.s -sys_x86-64/___readv_nocancel.s -sys_x86-64/___recvfrom.s -sys_x86-64/___recvfrom_nocancel.s -sys_x86-64/___recvmsg.s -sys_x86-64/___recvmsg_nocancel.s -sys_x86-64/___rename.s -sys_x86-64/___rename_ext.s -sys_x86-64/___renameat.s -sys_x86-64/___rmdir.s -sys_x86-64/___select.s -sys_x86-64/___select_nocancel.s -sys_x86-64/___sem_open.s -sys_x86-64/___sem_wait_nocancel.s -sys_x86-64/___semctl.s -sys_x86-64/___semsys.s -sys_x86-64/___semwait_signal.s -sys_x86-64/___semwait_signal_nocancel.s -sys_x86-64/___sendmsg.s -sys_x86-64/___sendmsg_nocancel.s -sys_x86-64/___sendto.s -sys_x86-64/___sendto_nocancel.s -sys_x86-64/___setattrlist.s -sys_x86-64/___setlogin.s -sys_x86-64/___setpriority.s -sys_x86-64/___setregid.s -sys_x86-64/___setreuid.s -sys_x86-64/___setrlimit.s -sys_x86-64/___setsgroups.s -sys_x86-64/___settid.s -sys_x86-64/___settid_with_pid.s -sys_x86-64/___settimeofday.s -sys_x86-64/___setwgroups.s -sys_x86-64/___sfi_ctl.s -sys_x86-64/___sfi_pidctl.s -sys_x86-64/___shared_region_check_np.s -sys_x86-64/___shared_region_map_and_slide_np.s -sys_x86-64/___shm_open.s -sys_x86-64/___shmctl.s -sys_x86-64/___shmsys.s -sys_x86-64/___sigaction.s -sys_x86-64/___sigaltstack.s -sys_x86-64/___sigreturn.s -sys_x86-64/___sigsuspend.s -sys_x86-64/___sigsuspend_nocancel.s -sys_x86-64/___sigwait.s -sys_x86-64/___socketpair.s -sys_x86-64/___stack_snapshot.s -sys_x86-64/___stack_snapshot_with_config.s -sys_x86-64/___stat64_extended.s -sys_x86-64/___stat_extended.s -sys_x86-64/___syscall.s -sys_x86-64/___sysctl.s -sys_x86-64/___sysctlbyname.s -sys_x86-64/___telemetry.s -sys_x86-64/___thread_selfid.s -sys_x86-64/___thread_selfusage.s -sys_x86-64/___umask_extended.s -sys_x86-64/___unlink.s -sys_x86-64/___unlinkat.s -sys_x86-64/___vfork.s -sys_x86-64/___wait4.s -sys_x86-64/___wait4_nocancel.s -sys_x86-64/___waitid_nocancel.s -sys_x86-64/___work_interval_ctl.s -sys_x86-64/___workq_kernreturn.s -sys_x86-64/___workq_open.s -sys_x86-64/___write_nocancel.s -sys_x86-64/___writev_nocancel.s -sys_x86-64/_access.s -sys_x86-64/_acct.s -sys_x86-64/_adjtime.s -sys_x86-64/_aio_cancel.s -sys_x86-64/_aio_error.s -sys_x86-64/_aio_fsync.s -sys_x86-64/_aio_read.s -sys_x86-64/_aio_return.s -sys_x86-64/_aio_suspend.s -sys_x86-64/_aio_write.s -sys_x86-64/_audit.s -sys_x86-64/_audit_session_join.s -sys_x86-64/_audit_session_port.s -sys_x86-64/_audit_session_self.s -sys_x86-64/_auditctl.s -sys_x86-64/_auditon.s -sys_x86-64/_change_fdguard_np.s -sys_x86-64/_chdir.s -sys_x86-64/_chflags.s -sys_x86-64/_chown.s -sys_x86-64/_chroot.s -sys_x86-64/_close.s -sys_x86-64/_connectx.s -sys_x86-64/_csops.s -sys_x86-64/_csops_audittoken.s -sys_x86-64/_disconnectx.s -sys_x86-64/_dup.s -sys_x86-64/_dup2.s -sys_x86-64/_exchangedata.s -sys_x86-64/_execve.s -sys_x86-64/_faccessat.s -sys_x86-64/_fchdir.s -sys_x86-64/_fchflags.s -sys_x86-64/_fchmodat.s -sys_x86-64/_fchown.s -sys_x86-64/_fchownat.s -sys_x86-64/_fdatasync.s -sys_x86-64/_ffsctl.s -sys_x86-64/_fgetattrlist.s -sys_x86-64/_fgetxattr.s -sys_x86-64/_fhopen.s -sys_x86-64/_fileport_makefd.s -sys_x86-64/_fileport_makeport.s -sys_x86-64/_flistxattr.s -sys_x86-64/_flock.s -sys_x86-64/_fpathconf.s -sys_x86-64/_fremovexattr.s -sys_x86-64/_fsctl.s -sys_x86-64/_fsetattrlist.s -sys_x86-64/_fsetxattr.s -sys_x86-64/_fstat.s -sys_x86-64/_fstat64.s -sys_x86-64/_fstatat.s -sys_x86-64/_fstatat64.s -sys_x86-64/_fstatfs.s -sys_x86-64/_fstatfs64.s -sys_x86-64/_fsync.s -sys_x86-64/_ftruncate.s -sys_x86-64/_futimes.s -sys_x86-64/_getattrlistat.s -sys_x86-64/_getattrlistbulk.s -sys_x86-64/_getaudit_addr.s -sys_x86-64/_getauid.s -sys_x86-64/_getdirentries.s -sys_x86-64/_getdirentriesattr.s -sys_x86-64/_getdtablesize.s -sys_x86-64/_getegid.s -sys_x86-64/_geteuid.s -sys_x86-64/_getfh.s -sys_x86-64/_getfsstat.s -sys_x86-64/_getfsstat64.s -sys_x86-64/_getgid.s -sys_x86-64/_getgroups.s -sys_x86-64/_getitimer.s -sys_x86-64/_getpgid.s -sys_x86-64/_getpgrp.s -sys_x86-64/_getppid.s -sys_x86-64/_getpriority.s -sys_x86-64/_getrusage.s -sys_x86-64/_getsid.s -sys_x86-64/_getsockopt.s -sys_x86-64/_getuid.s -sys_x86-64/_getxattr.s -sys_x86-64/_grab_pgo_data.s -sys_x86-64/_guarded_close_np.s -sys_x86-64/_guarded_kqueue_np.s -sys_x86-64/_guarded_pwrite_np.s -sys_x86-64/_guarded_write_np.s -sys_x86-64/_guarded_writev_np.s -sys_x86-64/_issetugid.s -sys_x86-64/_kas_info.s -sys_x86-64/_kevent.s -sys_x86-64/_kevent64.s -sys_x86-64/_kevent_qos.s -sys_x86-64/_kqueue.s -sys_x86-64/_ledger.s -sys_x86-64/_link.s -sys_x86-64/_linkat.s -sys_x86-64/_lio_listio.s -sys_x86-64/_listxattr.s -sys_x86-64/_lstat.s -sys_x86-64/_lstat64.s -sys_x86-64/_madvise.s -sys_x86-64/_memorystatus_control.s -sys_x86-64/_memorystatus_get_level.s -sys_x86-64/_mincore.s -sys_x86-64/_minherit.s -sys_x86-64/_mkdir.s -sys_x86-64/_mkdirat.s -sys_x86-64/_mkfifo.s -sys_x86-64/_mknod.s -sys_x86-64/_mlock.s -sys_x86-64/_mlockall.s -sys_x86-64/_modwatch.s -sys_x86-64/_mount.s -sys_x86-64/_mremap_encrypted.s -sys_x86-64/_msgget.s -sys_x86-64/_msgrcv.s -sys_x86-64/_msgsnd.s -sys_x86-64/_munlock.s -sys_x86-64/_munlockall.s -sys_x86-64/_necp_match_policy.s -sys_x86-64/_netagent_trigger.s -sys_x86-64/_nfsclnt.s -sys_x86-64/_nfssvc.s -sys_x86-64/_openbyid_np.s -sys_x86-64/_pathconf.s -sys_x86-64/_peeloff.s -sys_x86-64/_pid_resume.s -sys_x86-64/_pid_suspend.s -sys_x86-64/_poll.s -sys_x86-64/_pread.s -sys_x86-64/_proc_rlimit_control.s -sys_x86-64/_proc_trace_log.s -sys_x86-64/_proc_uuid_policy.s -sys_x86-64/_pwrite.s -sys_x86-64/_quota.s -sys_x86-64/_quotactl.s -sys_x86-64/_read.s -sys_x86-64/_readlink.s -sys_x86-64/_readlinkat.s -sys_x86-64/_readv.s -sys_x86-64/_reboot.s -sys_x86-64/_recvmsg_x.s -sys_x86-64/_removexattr.s -sys_x86-64/_revoke.s -sys_x86-64/_searchfs.s -sys_x86-64/_sem_close.s -sys_x86-64/_sem_post.s -sys_x86-64/_sem_trywait.s -sys_x86-64/_sem_unlink.s -sys_x86-64/_sem_wait.s -sys_x86-64/_semget.s -sys_x86-64/_semop.s -sys_x86-64/_sendfile.s -sys_x86-64/_sendmsg_x.s -sys_x86-64/_setaudit_addr.s -sys_x86-64/_setauid.s -sys_x86-64/_setegid.s -sys_x86-64/_seteuid.s -sys_x86-64/_setgid.s -sys_x86-64/_setgroups.s -sys_x86-64/_setitimer.s -sys_x86-64/_setpgid.s -sys_x86-64/_setprivexec.s -sys_x86-64/_setquota.s -sys_x86-64/_setsid.s -sys_x86-64/_setsockopt.s -sys_x86-64/_setuid.s -sys_x86-64/_setxattr.s -sys_x86-64/_shm_unlink.s -sys_x86-64/_shmat.s -sys_x86-64/_shmdt.s -sys_x86-64/_shmget.s -sys_x86-64/_shutdown.s -sys_x86-64/_sigpending.s -sys_x86-64/_sigprocmask.s -sys_x86-64/_socket.s -sys_x86-64/_socket_delegate.s -sys_x86-64/_stat.s -sys_x86-64/_stat64.s -sys_x86-64/_statfs.s -sys_x86-64/_statfs64.s -sys_x86-64/_swapon.s -sys_x86-64/_symlink.s -sys_x86-64/_symlinkat.s -sys_x86-64/_sync.s -sys_x86-64/_system_override.s -sys_x86-64/_truncate.s -sys_x86-64/_umask.s -sys_x86-64/_undelete.s -sys_x86-64/_unmount.s -sys_x86-64/_usrctl.s -sys_x86-64/_utimes.s -sys_x86-64/_vfs_purge.s -sys_x86-64/_vm_pressure_monitor.s -sys_x86-64/_waitevent.s -sys_x86-64/_waitid.s -sys_x86-64/_watchevent.s -sys_x86-64/_write.s -sys_x86-64/_writev.s -sys_x86-64/custom.s diff --git a/src/kernel/libsyscall/wrappers/__commpage_gettimeofday.c b/src/kernel/libsyscall/wrappers/__commpage_gettimeofday.c index 0bc34b4ab..4967a2f8d 100644 --- a/src/kernel/libsyscall/wrappers/__commpage_gettimeofday.c +++ b/src/kernel/libsyscall/wrappers/__commpage_gettimeofday.c @@ -21,3 +21,59 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include +#include +#include + +int __commpage_gettimeofday(struct timeval *); + +__attribute__((visibility("hidden"))) +int __commpage_gettimeofday_internal(struct timeval *tp, uint64_t *tbr_out); + +#if defined(__x86_64__) || defined(__i386__) + +// XXX: must be kept in sync with __commpage_gettimeofday.s +int +__commpage_gettimeofday_internal(struct timeval *tp, uint64_t *tbr_out) +{ + volatile uint32_t *gtod_generation_p = _COMM_PAGE_GTOD_GENERATION; + volatile uint64_t *gtod_sec_base_p = _COMM_PAGE_GTOD_SEC_BASE; + volatile uint64_t *gtod_ns_base_p = _COMM_PAGE_GTOD_NS_BASE; + + uint64_t tbr, gen, tod_secs, tod_nsecs, elapsed; + while(1) { + gen = *gtod_generation_p; + tbr = mach_absolute_time(); + tod_secs = *gtod_sec_base_p; + tod_nsecs = *gtod_ns_base_p; + uint64_t gen2 = *gtod_generation_p; + if(__builtin_expect(gen, gen2) == gen2) + break; + } + if (gen == 0) return KERN_FAILURE; + elapsed = tbr - tod_nsecs; + + unsigned long secs; + uint32_t nsec; +#if defined(__x86_64__) + secs = elapsed/NSEC_PER_SEC; + nsec = elapsed % NSEC_PER_SEC; +#elif defined(__i386__) + uint32_t secs1, secs2; + secs1 = elapsed >> 32; + secs2 = elapsed; + __asm__ ( + "divl %4" + : "=a" (secs), "=d" (nsec) + : "0" (secs2), "1" (secs1), "rm" (NSEC_PER_SEC) + ); +#endif /* __i386 or __x86_64__ */ + tp->tv_sec = tod_secs + secs; + tp->tv_usec = nsec / NSEC_PER_USEC; + + if (tbr_out) *tbr_out = tbr; + + return KERN_SUCCESS; +} + +#endif diff --git a/src/kernel/libsyscall/wrappers/_libc_funcptr.c b/src/kernel/libsyscall/wrappers/_libc_funcptr.c index fb59f2f3c..63eb09ca6 100644 --- a/src/kernel/libsyscall/wrappers/_libc_funcptr.c +++ b/src/kernel/libsyscall/wrappers/_libc_funcptr.c @@ -30,7 +30,6 @@ extern _libkernel_functions_t _libkernel_functions; extern void mig_os_release(void* ptr); -#ifndef VARIANT_DYLD __attribute__((visibility("hidden"))) void * malloc(size_t size) @@ -61,22 +60,17 @@ reallocf(void *ptr, size_t size) free(ptr); return (nptr); } -#endif __attribute__((visibility("hidden"))) void _pthread_exit_if_canceled(int error) { -#ifndef VARIANT_DYLD - _libkernel_functions->_pthread_exit_if_canceled(error); -#endif + return _libkernel_functions->_pthread_exit_if_canceled(error); } -#ifndef VARIANT_DYLD __attribute__((visibility("hidden"))) void _pthread_set_self(void *ptr __attribute__((__unused__))) {} -#endif __attribute__((visibility("hidden"))) void diff --git a/src/kernel/libsyscall/wrappers/_libkernel_init.c b/src/kernel/libsyscall/wrappers/_libkernel_init.c index 1f6cc6064..903749424 100644 --- a/src/kernel/libsyscall/wrappers/_libkernel_init.c +++ b/src/kernel/libsyscall/wrappers/_libkernel_init.c @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2010 Apple Inc. All rights reserved. * @@ -31,23 +30,23 @@ #include extern int mach_init(void); -extern void mach_driver_init(void); -/* dlsym() funcptr is for legacy support in exc_catcher */ -void* (*_dlsym)(void*, const char*) __attribute__((visibility("hidden"))); +__attribute__((visibility("hidden"))) +struct elf_calls* _elfcalls; + extern int strncmp(const char *s1, const char *s2, __SIZE_TYPE__ n); extern unsigned long long __simple_atoi16(const char* str, const char** endp); -__attribute__((visibility("hidden"))) -_libkernel_functions_t _libkernel_functions; +/* dlsym() funcptr is for legacy support in exc_catcher */ +void* (*_dlsym)(void*, const char*) __attribute__((visibility("hidden"))); __attribute__((visibility("hidden"))) -struct elf_calls* _elfcalls; +_libkernel_functions_t _libkernel_functions; void __libkernel_init(_libkernel_functions_t fns, const char *envp[] __attribute__((unused)), - const char *apple[], + const char *apple[] __attribute__((unused)), const struct ProgramVars *vars __attribute__((unused))) { int i; @@ -64,6 +63,6 @@ __libkernel_init(_libkernel_functions_t fns, _elfcalls = (struct elf_calls*) table; } } - + mach_init(); } diff --git a/src/kernel/libsyscall/wrappers/cancelable/fcntl-base.c b/src/kernel/libsyscall/wrappers/cancelable/fcntl-base.c index 728dc07b6..bf6395112 100644 --- a/src/kernel/libsyscall/wrappers/cancelable/fcntl-base.c +++ b/src/kernel/libsyscall/wrappers/cancelable/fcntl-base.c @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2004, 2006 Apple Computer, Inc. All rights reserved. * @@ -22,7 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ #include -#include int __FCNTL(int, int, void *); @@ -42,9 +40,15 @@ fcntl(int fd, int cmd, ...) va_start(ap, cmd); switch(cmd) { case F_GETLK: + case F_GETLKPID: case F_SETLK: case F_SETLKW: case F_SETLKWTIMEOUT: + case F_OFD_GETLK: + case F_OFD_GETLKPID: + case F_OFD_SETLK: + case F_OFD_SETLKW: + case F_OFD_SETLKWTIMEOUT: case F_PREALLOCATE: case F_SETSIZE: case F_RDADVISE: @@ -58,8 +62,11 @@ fcntl(int fd, int cmd, ...) case F_UNLINKFROM: case F_ADDSIGS: case F_ADDFILESIGS: + case F_ADDFILESIGS_FOR_DYLD_SIM: + case F_ADDFILESIGS_RETURN: case F_FINDSIGS: case F_TRANSCODEKEY: + case F_CHECK_LV: arg = va_arg(ap, void *); break; default: diff --git a/src/kernel/libsyscall/wrappers/cancelable/pselect-darwinext-cancel.c b/src/kernel/libsyscall/wrappers/cancelable/pselect-darwinext-cancel.c new file mode 100644 index 000000000..54ea91375 --- /dev/null +++ b/src/kernel/libsyscall/wrappers/cancelable/pselect-darwinext-cancel.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#define VARIANT_CANCELABLE +#define VARIANT_DARWIN_EXTSN + +#include "../select-base.c" diff --git a/src/kernel/libsyscall/wrappers/cancelable/pselect-darwinext.c b/src/kernel/libsyscall/wrappers/cancelable/pselect-darwinext.c new file mode 100644 index 000000000..4bfb1b756 --- /dev/null +++ b/src/kernel/libsyscall/wrappers/cancelable/pselect-darwinext.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#undef __DARWIN_NON_CANCELABLE +#define __DARWIN_NON_CANCELABLE 1 +#define VARIANT_DARWIN_EXTSN + +#include "../select-base.c" diff --git a/src/kernel/libsyscall/wrappers/clonefile.c b/src/kernel/libsyscall/wrappers/clonefile.c new file mode 100644 index 000000000..33b6beabd --- /dev/null +++ b/src/kernel/libsyscall/wrappers/clonefile.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +int +clonefile(const char *old, const char *new, uint32_t flags) +{ + return (clonefileat(AT_FDCWD, old, AT_FDCWD, new, flags)); +} diff --git a/src/kernel/libsyscall/wrappers/csr.c b/src/kernel/libsyscall/wrappers/csr.c index 2870bf97f..c5944c507 100644 --- a/src/kernel/libsyscall/wrappers/csr.c +++ b/src/kernel/libsyscall/wrappers/csr.c @@ -29,15 +29,10 @@ int __csrctl(csr_op_t op, void *buffer, size_t size); int csr_check(csr_config_t mask) { - return __csrctl(CSR_OP_CHECK, &mask, sizeof(csr_config_t)); + return __csrctl(CSR_SYSCALL_CHECK, &mask, sizeof(csr_config_t)); } int csr_get_active_config(csr_config_t *config) { - return __csrctl(CSR_OP_GET_ACTIVE_CONFIG, config, sizeof(csr_config_t)); -} - -int csr_get_pending_config(csr_config_t *config) -{ - return __csrctl(CSR_OP_GET_PENDING_CONFIG, config, sizeof(csr_config_t)); + return __csrctl(CSR_SYSCALL_GET_ACTIVE_CONFIG, config, sizeof(csr_config_t)); } diff --git a/src/kernel/libsyscall/wrappers/fs_snapshot.c b/src/kernel/libsyscall/wrappers/fs_snapshot.c new file mode 100644 index 000000000..10aed0453 --- /dev/null +++ b/src/kernel/libsyscall/wrappers/fs_snapshot.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include + +extern int __fs_snapshot(uint32_t, int, const char *, const char *, void *, + uint32_t); + +int +fs_snapshot_create(int dirfd, const char *name, uint32_t flags) +{ + return __fs_snapshot(SNAPSHOT_OP_CREATE, dirfd, name, NULL, NULL, flags); +} + +int +fs_snapshot_list(int dirfd, struct attrlist *alist, void *attrbuf, size_t bufsize, + uint32_t flags) +{ + if (flags != 0) { + errno = EINVAL; + return (-1); + } + + return (getattrlistbulk(dirfd, alist, attrbuf, bufsize, + FSOPT_LIST_SNAPSHOT)); +} + +int +fs_snapshot_delete(int dirfd, const char *name, uint32_t flags) +{ + return __fs_snapshot(SNAPSHOT_OP_DELETE, dirfd, name, NULL, NULL, flags); +} + +int +fs_snapshot_rename(int dirfd, const char *old, const char *new, uint32_t flags) +{ + return __fs_snapshot(SNAPSHOT_OP_RENAME, dirfd, old, new, NULL, flags); +} + +int +fs_snapshot_revert(int dirfd, const char *name, uint32_t flags) +{ + return __fs_snapshot(SNAPSHOT_OP_REVERT, dirfd, name, NULL, NULL, flags); +} + +/* + * XXX Temporary hack to do what mount_apfs(8) does. This will be removed and + * replaced with a VFS_IOCTL based implementation in the kernel. + */ +#include +#include "strings.h" + +#ifndef SNAPSHOT_OP_MOUNT +#define SNAPSHOT_OP_MOUNT 0x4 +#endif + +#define FS_MOUNT_SNAPSHOT 2 +#define MAX_SNAPSHOT_NAMELEN 256 + +struct fs_mount_options { + uint32_t fs_flags; + uint8_t _padding_[2]; +}; + +struct fs_mount_args { + char *specdev; + struct fs_mount_options options; + uint16_t mode; + uint16_t _padding_[3]; + union { + struct { // FS_MOUNT_SNAPSHOT + dev_t snap_fsys; + char snap_name[MAX_SNAPSHOT_NAMELEN]; + }; + struct { // APFS_MOUNT_FOR_CONVERSION + }; + }; +}; + +int +fs_snapshot_mount(int dirfd, const char *dir, const char *snapshot, + uint32_t flags) +{ + struct stat st; + struct fs_mount_args mnt_args; + + mnt_args.specdev = NULL; + mnt_args.mode = FS_MOUNT_SNAPSHOT; + if (fstat(dirfd, &st) == -1) + return (-1); + + mnt_args.snap_fsys = st.st_dev; + strlcpy(mnt_args.snap_name, snapshot, sizeof(mnt_args.snap_name)); + return (__fs_snapshot(SNAPSHOT_OP_MOUNT, dirfd, snapshot, dir, + (void *)&mnt_args, flags)); +} diff --git a/src/kernel/libsyscall/wrappers/ioctl.c b/src/kernel/libsyscall/wrappers/ioctl.c index a181fdde6..eced7e7e1 100644 --- a/src/kernel/libsyscall/wrappers/ioctl.c +++ b/src/kernel/libsyscall/wrappers/ioctl.c @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. * @@ -24,11 +23,7 @@ #if defined(__LP64__) || defined(__arm__) -#ifdef DARLING -# define ioctl __real_ioctl -#endif - -//#include +#include #include int __ioctl(int, unsigned long, void *); @@ -38,8 +33,14 @@ int __ioctl(int, unsigned long, void *); * This is for LP64 only. */ int -ioctl(int d, unsigned long request, void* arg) +ioctl(int d, unsigned long request, ...) { + va_list ap; + void *arg; + + va_start(ap, request); + arg = va_arg(ap, void *); + va_end(ap); return (__ioctl(d, request, arg)); } diff --git a/src/kernel/libsyscall/wrappers/kdebug_trace.c b/src/kernel/libsyscall/wrappers/kdebug_trace.c new file mode 100644 index 000000000..8234f4582 --- /dev/null +++ b/src/kernel/libsyscall/wrappers/kdebug_trace.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int __kdebug_typefilter(void** addr, size_t* size); +extern int __kdebug_trace64(uint32_t code, uint64_t arg1, uint64_t arg2, + uint64_t arg3, uint64_t arg4); +extern uint64_t __kdebug_trace_string(uint32_t debugid, uint64_t str_id, + const char *str); + +static int kdebug_signpost_internal(uint32_t debugid, uintptr_t arg1, + uintptr_t arg2, uintptr_t arg3, uintptr_t arg4); + +/* + * GENERAL API DESIGN NOTE! + * + * Trace API's are expected to avoid performing checks until tracing has + * been enabled. This includes checks that might cause error codes to be + * returned. + * + * Trace invocations via wrapper and syscall must have the same behavior. + * + * Note that the userspace API is chosing to optimize fastpath, non-error + * performance by eliding validation of each debugid. This means that error + * cases which could have been caught in userspace will make a syscall + * before returning with the correct error code. This tradeoff in performance + * is intentional. + */ + +void * +kdebug_typefilter(void) +{ + static void* typefilter; + + /* We expect kdebug_typefilter_bitmap to be valid (the if is not executed) */ + if (__builtin_expect(!typefilter, 0)) { + // Map the typefilter if it can be mapped. + void* ptr = NULL; + size_t ptr_size = 0; + + if (__kdebug_typefilter(&ptr, &ptr_size) == 0) { + void* old_value = NULL; + if (ptr && !atomic_compare_exchange_strong((void* _Atomic volatile *)&typefilter, &old_value, ptr)) { + mach_vm_deallocate(mach_task_self(), (mach_vm_offset_t)ptr, KDBG_TYPEFILTER_BITMAP_SIZE); + } + } + } + + return typefilter; +} + +bool +kdebug_is_enabled(uint32_t debugid) +{ + uint32_t state = *((volatile uint32_t *)(uintptr_t)(_COMM_PAGE_KDEBUG_ENABLE)); + + if (state == 0) { + return FALSE; + } + + if ((state & KDEBUG_COMMPAGE_ENABLE_TYPEFILTER) > 0) { + /* + * Typefilter rules... + * + * If no typefilter is available (even if due to error), + * debugids are allowed. + * + * The typefilter will always allow DBG_TRACE; this is a kernel + * invariant. There is no need for an explicit check here. + * + * NOTE: The typefilter will always allow DBG_TRACE, but + * it is not legal to inject DBG_TRACE via kdebug_trace. + * Attempts to do so will not be detected here, but will be + * detected in the kernel, and an error will be returned. Per + * the API design note at the top of this file, this is a + * deliberate choice. + */ + uint8_t* typefilter = kdebug_typefilter(); + if (typefilter && isset(typefilter, KDBG_EXTRACT_CSC(debugid)) == 0) { + return FALSE; + } + } + + return TRUE; +} + +int +kdebug_trace(uint32_t debugid, uint64_t arg1, uint64_t arg2, uint64_t arg3, + uint64_t arg4) +{ + if (!kdebug_is_enabled(debugid)) { + return 0; + } + + return __kdebug_trace64(debugid, arg1, arg2, arg3, arg4); +} + +uint64_t +kdebug_trace_string(uint32_t debugid, uint64_t str_id, const char *str) +{ + if (!kdebug_is_enabled(debugid)) { + return 0; + } + + if ((int64_t)str_id == -1) { + errno = EINVAL; + return (uint64_t)-1; + } + + if (str_id == 0 && str == NULL) { + errno = EINVAL; + return (uint64_t)-1; + } + + return __kdebug_trace_string(debugid, str_id, str); +} + +static int +kdebug_signpost_internal(uint32_t debugid, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) +{ + if (KDBG_EXTRACT_CSC(debugid) != 0) { + errno = EINVAL; + return -1; + } + + debugid |= APPSDBG_CODE(DBG_APP_SIGNPOST, 0); + + return kdebug_trace(debugid, arg1, arg2, arg3, arg4); +} + +int +kdebug_signpost(uint32_t code, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) +{ + return kdebug_signpost_internal(code << KDBG_CODE_OFFSET, arg1, arg2, arg3, arg4); +} + +int +kdebug_signpost_start(uint32_t code, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) +{ + return kdebug_signpost_internal((code << KDBG_CODE_OFFSET) | DBG_FUNC_START, arg1, arg2, arg3, arg4); +} + +int +kdebug_signpost_end(uint32_t code, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) +{ + return kdebug_signpost_internal((code << KDBG_CODE_OFFSET) | DBG_FUNC_END, arg1, arg2, arg3, arg4); +} diff --git a/src/kernel/libsyscall/wrappers/libproc/libproc.c b/src/kernel/libsyscall/wrappers/libproc/libproc.c index 2f47dcaf4..e46dbe0c5 100644 --- a/src/kernel/libsyscall/wrappers/libproc/libproc.c +++ b/src/kernel/libsyscall/wrappers/libproc/libproc.c @@ -26,10 +26,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include "libproc_internal.h" @@ -113,6 +115,17 @@ proc_pidoriginatorinfo(int flavor, void *buffer, int buffersize) return(retval); } +int +proc_listcoalitions(int flavor, int coaltype, void *buffer, int buffersize) +{ + int retval; + + if ((retval = __proc_info(PROC_INFO_CALL_LISTCOALITIONS, flavor, coaltype, 0, buffer, buffersize)) == -1) + return 0; + + return retval; +} + int proc_pid_rusage(int pid, int flavor, rusage_info_t *buffer) { @@ -349,11 +362,21 @@ proc_terminate(pid_t pid, int *sig) return 0; } +/* + * XXX the _fatal() variant both checks for an existing monitor + * (with important policy effects on first party background apps) + * and validates inputs. + */ int proc_set_cpumon_params(pid_t pid, int percentage, int interval) { proc_policy_cpuusage_attr_t attr; + /* no argument validation ... + * task_set_cpuusage() ignores 0 values and squashes negative + * values into uint32_t. + */ + attr.ppattr_cpu_attr = PROC_POLICY_RSRCACT_NOTIFY_EXC; attr.ppattr_cpu_percentage = percentage; attr.ppattr_cpu_attr_interval = (uint64_t)interval; @@ -397,6 +420,16 @@ proc_set_cpumon_defaults(pid_t pid) PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0)); } +int +proc_resume_cpumon(pid_t pid) +{ + return __process_policy(PROC_POLICY_SCOPE_PROCESS, + PROC_POLICY_ACTION_ENABLE, + PROC_POLICY_RESOURCE_USAGE, + PROC_POLICY_RUSAGE_CPU, + NULL, pid, 0); +} + int proc_disable_cpumon(pid_t pid) { @@ -436,6 +469,10 @@ proc_set_cpumon_params_fatal(pid_t pid, int percentage, int interval) * already active. If either the percentage or the * interval is nonzero, then CPU monitoring is * already in use for this process. + * + * XXX: need set...() and set..fatal() to behave similarly. + * Currently, this check prevents 1st party apps (which get a + * default non-fatal monitor) not to get a fatal monitor. */ (void)proc_get_cpumon_params(pid, ¤t_percentage, ¤t_interval); if (current_percentage || current_interval) @@ -517,6 +554,84 @@ proc_disable_wakemon(pid_t pid) return (proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, ¶ms)); } +int +proc_list_uptrs(int pid, uint64_t *buf, uint32_t bufsz) +{ + int i, j; + int nfds, nkns; + int count = 0; + int knote_max = 4096; /* arbitrary starting point */ + + /* if buffer is empty, this call simply counts the knotes */ + if (bufsz > 0 && buf == NULL) { + errno = EFAULT; + return -1; + } + + /* get the list of FDs for this process */ + struct proc_fdinfo fdlist[OPEN_MAX+1]; + nfds = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, &fdlist[1], OPEN_MAX*sizeof(struct proc_fdinfo)); + if (nfds < 0 || nfds > OPEN_MAX) { + return -1; + } + + /* Add FD -1, the implicit workq kqueue */ + fdlist[0].proc_fd = -1; + fdlist[0].proc_fdtype = PROX_FDTYPE_KQUEUE; + nfds++; + + struct kevent_extinfo *kqext = malloc(knote_max * sizeof(struct kevent_extinfo)); + if (!kqext) { + errno = ENOMEM; + return -1; + } + + for (i = 0; i < nfds; i++) { + if (fdlist[i].proc_fdtype != PROX_FDTYPE_KQUEUE) { + continue; + } + + again: + nkns = __proc_info(PROC_INFO_CALL_PIDFDINFO, pid, PROC_PIDFDKQUEUE_EXTINFO, + (uint64_t)fdlist[i].proc_fd, kqext, knote_max * sizeof(struct kevent_extinfo)); + if (nkns < 0) { + if (errno == EBADF) { + /* the FD table can change after enumerating the FDs */ + errno = EAGAIN; + } + free(kqext); + return -1; + } + + if (nkns > knote_max) { + /* there are more knotes than we requested - try again with a + * larger buffer */ + free(kqext); + knote_max = nkns + 32; /* small margin in case of extra knotes */ + kqext = malloc(knote_max * sizeof(struct kevent_extinfo)); + if (!kqext) { + errno = ENOMEM; + return -1; + } + goto again; + } + + for (j = 0; j < nkns; j++) { + if (kqext[j].kqext_kev.udata == 0) { + continue; + } + + if (bufsz >= sizeof(uint64_t)) { + *buf++ = kqext[j].kqext_kev.udata; + bufsz -= sizeof(uint64_t); + } + count++; + } + } + + free(kqext); + return count; +} diff --git a/src/kernel/libsyscall/wrappers/libproc/libproc.h b/src/kernel/libsyscall/wrappers/libproc/libproc.h index 9e98f1760..27633ffa4 100644 --- a/src/kernel/libsyscall/wrappers/libproc/libproc.h +++ b/src/kernel/libsyscall/wrappers/libproc/libproc.h @@ -126,6 +126,20 @@ int proc_clear_dirty(pid_t pid, uint32_t flags); int proc_terminate(pid_t pid, int *sig); +#ifdef PRIVATE +/* + * Enumerate potential userspace pointers embedded in kernel data structures. + * Currently inspects kqueues only. + * + * NOTE: returned "pointers" are opaque user-supplied values and thus not + * guaranteed to address valid objects or be pointers at all. + * + * Returns the number of pointers found (which may exceed buffersize), or -1 on + * failure and errno set appropriately. + */ +int proc_list_uptrs(pid_t pid, uint64_t *buffer, uint32_t buffersize); +#endif /* PRIVATE */ + __END_DECLS #endif /*_LIBPROC_H_ */ diff --git a/src/kernel/libsyscall/wrappers/libproc/libproc_internal.h b/src/kernel/libsyscall/wrappers/libproc/libproc_internal.h index 39be79194..d8fc8f1f9 100644 --- a/src/kernel/libsyscall/wrappers/libproc/libproc_internal.h +++ b/src/kernel/libsyscall/wrappers/libproc/libproc_internal.h @@ -26,8 +26,8 @@ #include #include -#include #include +#include __BEGIN_DECLS @@ -78,24 +78,29 @@ int proc_denap_assertion_begin_with_msg(mach_msg_header_t *msg, /* drop a de-nap assertion */ int proc_denap_assertion_complete(uint64_t assertion_handle); +/* ongoing percent-over-time CPU monitor */ +int proc_set_cpumon_defaults(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); int proc_set_cpumon_params(pid_t pid, int percentage, int interval) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); +int proc_set_cpumon_params_fatal(pid_t pid, int percentage, int interval) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); + int proc_get_cpumon_params(pid_t pid, int *percentage, int *interval) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); -int proc_set_cpumon_defaults(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); +int proc_resume_cpumon(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0); int proc_disable_cpumon(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); +/* ongoing wakes/second monitor */ +int proc_set_wakemon_defaults(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); int proc_set_wakemon_params(pid_t pid, int rate_hz, int flags) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); int proc_get_wakemon_params(pid_t pid, int *rate_hz, int *flags) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); -int proc_set_wakemon_defaults(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); int proc_disable_wakemon(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); -int proc_set_cpumon_params_fatal(pid_t pid, int percentage, int interval) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); - /* request trace buffer collection */ int proc_trace_log(pid_t pid, uint64_t uniqueid) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); /* proc_info call to get the originator information */ int proc_pidoriginatorinfo(int flavor, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); +int proc_listcoalitions(int flavor, int coaltype, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_8_3); + #if !TARGET_IPHONE_SIMULATOR #define PROC_SUPPRESS_SUCCESS (0) diff --git a/src/kernel/libsyscall/wrappers/mach_boottime.c b/src/kernel/libsyscall/wrappers/mach_boottime.c new file mode 100644 index 000000000..23b22f93b --- /dev/null +++ b/src/kernel/libsyscall/wrappers/mach_boottime.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include + +uint64_t +mach_boottime_usec(void) +{ + return *(uint64_t*)_COMM_PAGE_BOOTTIME_USEC; +} diff --git a/src/kernel/libsyscall/wrappers/mach_continuous_time.c b/src/kernel/libsyscall/wrappers/mach_continuous_time.c new file mode 100644 index 000000000..4f20664f8 --- /dev/null +++ b/src/kernel/libsyscall/wrappers/mach_continuous_time.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include +#include +#include + +__attribute__((visibility("hidden"))) +uint64_t +_mach_continuous_time_base(void) +{ +#if !defined(__x86_64__) && !defined(__arm64__) + // Deal with the lack of 64-bit loads on arm32 (see mach_approximate_time.s) + while(1) { + volatile uint64_t *base_ptr = (volatile uint64_t*)_COMM_PAGE_CONT_TIMEBASE; + uint64_t read1, read2; + read1 = *base_ptr; +#if defined(__i386__) + __asm__ volatile("lfence" ::: "memory"); +#else +#error "unsupported arch" +#endif + read2 = *base_ptr; + + if(__builtin_expect((read1 == read2), 1)) + return read1; + } +#else // 64-bit + return *(volatile uint64_t*)_COMM_PAGE_CONT_TIMEBASE; +#endif // 64-bit +} + + +__attribute__((visibility("hidden"))) +kern_return_t +_mach_continuous_time(uint64_t* absolute_time, uint64_t* cont_time) +{ + volatile uint64_t *base_ptr = (volatile uint64_t*)_COMM_PAGE_CONT_TIMEBASE; + volatile uint64_t read1, read2; + volatile uint64_t absolute; + + do { + read1 = *base_ptr; + absolute = mach_absolute_time(); + read2 = *base_ptr; + } while (__builtin_expect((read1 != read2), 0)); + + if (absolute_time) *absolute_time = absolute; + if (cont_time) *cont_time = absolute + read1; + + return KERN_SUCCESS; +} + +uint64_t +mach_continuous_time(void) +{ + uint64_t cont_time; + _mach_continuous_time(NULL, &cont_time); + return cont_time; +} + +uint64_t +mach_continuous_approximate_time(void) +{ + /* + * No retry loop here because if we use a slightly too old timebase that's + * okay, we are approximate time anyway. + */ + volatile register uint64_t time_base = _mach_continuous_time_base(); + return time_base + mach_approximate_time(); +} diff --git a/src/kernel/libsyscall/wrappers/mach_get_times.c b/src/kernel/libsyscall/wrappers/mach_get_times.c new file mode 100644 index 000000000..37ddfa9fd --- /dev/null +++ b/src/kernel/libsyscall/wrappers/mach_get_times.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include +#include +#include +#include + +// From __commpage_gettimeofday.c +extern int __commpage_gettimeofday_internal(struct timeval *tp, uint64_t *tbr_out); +extern kern_return_t _mach_continuous_time(uint64_t* absolute_time, uint64_t* cont_time); +// From mach_continuous_time.c +extern uint64_t _mach_continuous_time_base(void); +// Underlying syscall stub +extern int __gettimeofday_with_mach(struct timeval *, struct timezone *, uint64_t *); + +kern_return_t +mach_get_times(uint64_t* absolute_time, uint64_t* cont_time, struct timespec *tp) { + if (tp == NULL) { + return _mach_continuous_time(absolute_time, cont_time); + } + + uint64_t continuous_time_base_prior = -1, continuous_time_base_post = -1; + uint64_t tbr; + struct timeval tv; + + do { + /* + * We need to capture the result of gettimeofday without our continuous + * time base changing. Once we have that, and the value for absolute + * time that was used to compute the timespec, we can just add the base + * to get the accompanying continuous time. + */ + continuous_time_base_prior = _mach_continuous_time_base(); + + /* + * This call has the necessary memory barriers for this retry loop, + * since it is implemented with a retry loop of its own. + */ + if (__commpage_gettimeofday_internal(&tv, &tbr)) { + tbr = 0; + if (__gettimeofday_with_mach(&tv, NULL, &tbr) < 0) { + return KERN_FAILURE; + } else if (tbr == 0) { + // On an old kernel, likely chroot'ed. (remove next year) + tbr = mach_absolute_time(); + } + } + + continuous_time_base_post = _mach_continuous_time_base(); + } while (__builtin_expect(continuous_time_base_prior != continuous_time_base_post, 0)); + + if (absolute_time) *absolute_time = tbr; + if (cont_time) *cont_time = continuous_time_base_prior + tbr; + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * NSEC_PER_USEC; + + return KERN_SUCCESS; +} diff --git a/src/kernel/libsyscall/wrappers/mach_timebase_info.c b/src/kernel/libsyscall/wrappers/mach_timebase_info.c new file mode 100644 index 000000000..80cd559ad --- /dev/null +++ b/src/kernel/libsyscall/wrappers/mach_timebase_info.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include + +extern kern_return_t +mach_timebase_info_trap(mach_timebase_info_t info); + +kern_return_t +mach_timebase_info(mach_timebase_info_t info){ + static mach_timebase_info_data_t cached_info; + + /* + * This is racy, but because it is safe to initialize twice we avoid a + * barrier in the fast path by risking double initialization. + */ + if (cached_info.numer == 0 || cached_info.denom == 0){ + kern_return_t kr = mach_timebase_info_trap(&cached_info); + if (kr != KERN_SUCCESS) return kr; + } + + info->numer = cached_info.numer; + info->denom = cached_info.denom; + + return KERN_SUCCESS; +} diff --git a/src/kernel/libsyscall/wrappers/persona.c b/src/kernel/libsyscall/wrappers/persona.c new file mode 100644 index 000000000..e167cc38f --- /dev/null +++ b/src/kernel/libsyscall/wrappers/persona.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include +#include +#include + +#include "strings.h" + +/* syscall entry point */ +int __persona(uint32_t operation, uint32_t flags, struct kpersona_info *info, uid_t *id, size_t *idlen); + +int kpersona_alloc(struct kpersona_info *info, uid_t *id) +{ + size_t idlen = 1; + return __persona(PERSONA_OP_ALLOC, 0, info, id, &idlen); +} + +int kpersona_dealloc(uid_t id) +{ + size_t idlen = 1; + return __persona(PERSONA_OP_DEALLOC, 0, NULL, &id, &idlen); +} + +int kpersona_get(uid_t *id) +{ + /* persona is a process-static identifier: cache it in a global */ + static uid_t p_id = PERSONA_ID_NONE; + if (p_id == PERSONA_ID_NONE) { + int ret = 0; + size_t idlen = 1; + ret = __persona(PERSONA_OP_GET, 0, NULL, &p_id, &idlen); + if (ret != 0) + return ret; + } + *id = p_id; + return 0; +} + +int kpersona_info(uid_t id, struct kpersona_info *info) +{ + size_t idlen = 1; + return __persona(PERSONA_OP_INFO, 0, info, &id, &idlen); +} + +int kpersona_pidinfo(pid_t pid, struct kpersona_info *info) +{ + size_t idlen = 1; + uid_t id = (uid_t)pid; + return __persona(PERSONA_OP_PIDINFO, 0, info, &id, &idlen); +} + +int kpersona_find(const char *name, uid_t uid, uid_t *id, size_t *idlen) +{ + int ret; + struct kpersona_info kinfo; + kinfo.persona_info_version = PERSONA_INFO_V1; + kinfo.persona_id = uid; + kinfo.persona_type = 0; + kinfo.persona_gid = 0; + kinfo.persona_ngroups = 0; + kinfo.persona_groups[0] = 0; + kinfo.persona_name[0] = 0; + if (name) + strlcpy(kinfo.persona_name, name, sizeof(kinfo.persona_name)); + ret = __persona(PERSONA_OP_FIND, 0, &kinfo, id, idlen); + if (ret < 0) + return ret; + return (int)(*idlen); +} diff --git a/src/kernel/libsyscall/wrappers/quota_obsolete.c b/src/kernel/libsyscall/wrappers/quota_obsolete.c new file mode 100644 index 000000000..435339b2c --- /dev/null +++ b/src/kernel/libsyscall/wrappers/quota_obsolete.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include + +/* + * system call stubs are no longer generated for these from + * syscalls.master. Instead, provide simple stubs here. + */ + +extern int quota(void); +extern int setquota(void); + +int quota(void) +{ + return kill(getpid(), SIGSYS); +} + +int setquota(void) +{ + return kill(getpid(), SIGSYS); +} diff --git a/src/kernel/libsyscall/wrappers/rename_ext.c b/src/kernel/libsyscall/wrappers/rename_ext.c deleted file mode 100644 index 8c7762139..000000000 --- a/src/kernel/libsyscall/wrappers/rename_ext.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2014 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - #include - -/* - * XXXXX REMOVE AND REPLACE the definition of VFS_RENAME_FLAGS_MASK below with - * appropriate header file if/when defined in a header file. - */ -#define VFS_RENAME_FLAGS_MASK 0x00000001 - -void __inc_remove_counter(void); -int __rename_ext(const char *old, const char *new, int flags); - -int -rename_ext(const char *old, const char *new, unsigned int flags) -{ - if (!(flags & VFS_RENAME_FLAGS_MASK)) { - errno = EINVAL; - return -1; - } - - int res = __rename_ext(old, new, flags & VFS_RENAME_FLAGS_MASK); - if (res == 0) __inc_remove_counter(); - return res; -} diff --git a/src/kernel/libsyscall/wrappers/renamex.c b/src/kernel/libsyscall/wrappers/renamex.c new file mode 100644 index 000000000..8bdfdcd0d --- /dev/null +++ b/src/kernel/libsyscall/wrappers/renamex.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include + +void __inc_remove_counter(void); +int __renameatx_np(int oldfd, const char *old, int newfd, const char *new, unsigned int flags); + +int +renameatx_np(int oldfd, const char *old, int newfd, const char *new, unsigned int flags) +{ + int res = __renameatx_np(oldfd, old, newfd, new, flags); + if (res == 0) __inc_remove_counter(); + return res; +} + +int +renamex_np(const char *old, const char *new, unsigned int flags) +{ + return renameatx_np(AT_FDCWD, old, AT_FDCWD, new, flags); +} + +// Deprecated +int +rename_ext(const char *old, const char *new, unsigned int flags) +{ + return renamex_np(old, new, flags); +} diff --git a/src/kernel/libsyscall/wrappers/select-base.c b/src/kernel/libsyscall/wrappers/select-base.c index 09f8816f6..f688d6f36 100644 --- a/src/kernel/libsyscall/wrappers/select-base.c +++ b/src/kernel/libsyscall/wrappers/select-base.c @@ -26,24 +26,37 @@ #define __DARWIN_NON_CANCELABLE 0 #endif /* __LP64__ && (VARIANT_CANCELABLE || VARIANT_PRE1050) */ +#if defined(VARIANT_DARWIN_EXTSN) +#define _DARWIN_C_SOURCE +#define _DARWIN_UNLIMITED_SELECT +#endif + #include +#include +#include #include "_errno.h" #if defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050) +#if !defined(VARIANT_DARWIN_EXTSN) extern int __select(int, fd_set * __restrict, fd_set * __restrict, fd_set * __restrict, struct timeval * __restrict); +#endif +int __pselect(int, fd_set * __restrict, fd_set * __restrict, + fd_set * __restrict, const struct timespec * __restrict, const sigset_t * __restrict); #else /* !VARIANT_CANCELABLE && !VARIANT_PRE1050 */ +#if !defined(VARIANT_DARWIN_EXTSN) int __select_nocancel(int, fd_set * __restrict, fd_set * __restrict, fd_set * __restrict, struct timeval * __restrict); +#endif +int __pselect_nocancel(int, fd_set * __restrict, fd_set * __restrict, + fd_set * __restrict, const struct timespec * __restrict, const sigset_t * __restrict); #endif /* VARIANT_CANCELABLE || VARIANT_PRE1050 */ +#if !defined(VARIANT_DARWIN_EXTSN) /* - * select stub, return error if nfds > FD_SETSIZE - * add pthread cancelability - * mandated for conformance. - * - * This is only for (non DARWINEXTSN) UNIX03 (both cancelable and - * non-cancelable) and for legacy + * select() implementation for 1050 and legacy (cancelable and non-cancelable) + * variants. The darwin extension variants (both cancelable & non-cancelable) are + * mapped directly to the syscall stub. */ int select(int nfds, fd_set * __restrict readfds, fd_set * __restrict writefds, @@ -55,7 +68,6 @@ select(int nfds, fd_set * __restrict readfds, fd_set * __restrict writefds, #endif /* VARIANT_LEGACY || VARIANT_PRE1050 */ ) { - #if defined(VARIANT_LEGACY) || defined(VARIANT_PRE1050) struct timeval tb, *timeout; @@ -66,17 +78,111 @@ select(int nfds, fd_set * __restrict readfds, fd_set * __restrict writefds, tb.tv_sec = 0; tb.tv_usec = 10000; timeout = &tb; - } else + } else { timeout = intimeout; + } #else /* !VARIANT_LEGACY && !VARIANT_PRE1050 */ if (nfds > FD_SETSIZE) { errno = EINVAL; return -1; } -#endif /* VARIANT_LEGACY || VARIANT_PRE1050 */ +#endif + #if defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050) return __select(nfds, readfds, writefds, exceptfds, timeout); #else /* !VARIANT_CANCELABLE && !VARIANT_PRE1050 */ return __select_nocancel(nfds, readfds, writefds, exceptfds, timeout); #endif /* VARIANT_CANCELABLE || VARIANT_PRE1050 */ } +#endif /* !defined(VARIANT_DARWIN_EXTSN) */ + + +/* + * User-space emulation of pselect() syscall for B&I + * TODO: remove when B&I move to xnu with native pselect() + */ +extern int __pthread_sigmask(int, const sigset_t *, sigset_t *); +static int +_pselect_emulated(int count, fd_set * __restrict rfds, fd_set * __restrict wfds, + fd_set * __restrict efds, const struct timespec * __restrict timo, + const sigset_t * __restrict mask) +{ + sigset_t omask; + struct timeval tvtimo, *tvp; + int rv, sverrno; + + if (timo) { + tvtimo.tv_sec = timo->tv_sec; + tvtimo.tv_usec = (__darwin_suseconds_t)(timo->tv_nsec / 1000); + tvp = &tvtimo; + } else { + tvp = 0; + } + + if (mask != 0) { + rv = __pthread_sigmask(SIG_SETMASK, mask, &omask); + if (rv != 0) + return rv; + } + + rv = select(count, rfds, wfds, efds, tvp); + if (mask != 0) { + sverrno = errno; + __pthread_sigmask(SIG_SETMASK, &omask, (sigset_t *)0); + errno = sverrno; + } + + return rv; +} + +/* + * pselect() implementation for all variants. Unlike select(), we implement the + * darwin extension variants here to catch cases where xnu doesn't implement + * pselect and we need to emulate. + */ +int +pselect(int nfds, fd_set * __restrict readfds, fd_set * __restrict writefds, + fd_set * __restrict exceptfds, const struct timespec * __restrict +#if defined(VARIANT_LEGACY) || defined(VARIANT_PRE1050) + intimeout, +#else /* !VARIANT_LEGACY && !VARIANT_PRE1050 */ + timeout, +#endif /* VARIANT_LEGACY || VARIANT_PRE1050 */ + const sigset_t * __restrict sigmask) +{ + int ret; +#if defined(VARIANT_LEGACY) || defined(VARIANT_PRE1050) + struct timespec tb; + const struct timespec *timeout; + + /* + * Legacy select behavior is minimum 10 msec when tv_usec is non-zero + */ + if (intimeout && intimeout->tv_sec == 0 && intimeout->tv_nsec > 0 && intimeout->tv_nsec < 10000000L) { + tb.tv_sec = 0; + tb.tv_nsec = 10000000L; + timeout = &tb; + } else { + timeout = intimeout; + } +#elif defined(VARIANT_DARWIN_EXTSN) +#else + /* 1050 variant */ + if (nfds > FD_SETSIZE) { + errno = EINVAL; + return -1; + } +#endif + +#if defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050) + ret = __pselect(nfds, readfds, writefds, exceptfds, timeout, sigmask); +#else /* !VARIANT_CANCELABLE && !VARIANT_PRE1050 */ + ret = __pselect_nocancel(nfds, readfds, writefds, exceptfds, timeout, sigmask); +#endif /* VARIANT_CANCELABLE || VARIANT_PRE1050 */ + + if (ret == -1 && errno == ENOSYS) { + ret = _pselect_emulated(nfds, readfds, writefds, exceptfds, timeout, sigmask); + } + + return ret; +} diff --git a/src/kernel/libsyscall/wrappers/spawn/posix_spawn.c b/src/kernel/libsyscall/wrappers/spawn/posix_spawn.c index d3bec4ede..be3e94cea 100644 --- a/src/kernel/libsyscall/wrappers/spawn/posix_spawn.c +++ b/src/kernel/libsyscall/wrappers/spawn/posix_spawn.c @@ -38,7 +38,8 @@ #include #include #include - +#include /* for COALITION_TYPE_MAX */ +#include /* * posix_spawnattr_init @@ -112,7 +113,6 @@ posix_spawnattr_init(posix_spawnattr_t *attr) (*psattrp)->short_padding = 0; (*psattrp)->flags_padding = 0; - (*psattrp)->int_padding = 0; /* Default is no new apptype requested */ (*psattrp)->psa_apptype = POSIX_SPAWN_PROCESS_TYPE_DEFAULT; @@ -120,7 +120,8 @@ posix_spawnattr_init(posix_spawnattr_t *attr) /* Jetsam related */ (*psattrp)->psa_jetsam_flags = 0; (*psattrp)->psa_priority = -1; - (*psattrp)->psa_high_water_mark = -1; + (*psattrp)->psa_memlimit_active = -1; + (*psattrp)->psa_memlimit_inactive = -1; /* Default is no CPU usage monitor active. */ (*psattrp)->psa_cpumonitor_percent = 0; @@ -129,11 +130,26 @@ posix_spawnattr_init(posix_spawnattr_t *attr) /* Default is no MAC policy extensions. */ (*psattrp)->psa_mac_extensions = NULL; - /* Default is to inherit parent's coalition */ - (*psattrp)->psa_coalitionid = 0; + /* Default is to inherit parent's coalition(s) */ + (*psattrp)->psa_coalition_info = NULL; + + (*psattrp)->psa_persona_info = NULL; + + /* + * old coalition field + * For backwards compatibility reasons, we set this to 1 + * which is the first valid coalition id. This will allow + * newer user space code to properly spawn processes on + * older kernels + * (they will just all end up in the same coalition). + */ + (*psattrp)->psa_reserved = 1; /* Default is no new clamp */ (*psattrp)->psa_qos_clamp = POSIX_SPAWN_PROC_CLAMP_NONE; + + /* Default is no change to role */ + (*psattrp)->psa_darwin_role = POSIX_SPAWN_DARWIN_ROLE_NONE; } return (err); @@ -161,6 +177,8 @@ posix_spawnattr_init(posix_spawnattr_t *attr) * EINVAL The value specified by attr is invalid. */ static int posix_spawn_destroyportactions_np(posix_spawnattr_t *); +static int posix_spawn_destroycoalition_info_np(posix_spawnattr_t *); +static int posix_spawn_destroypersona_info_np(posix_spawnattr_t *); int posix_spawnattr_destroy(posix_spawnattr_t *attr) @@ -172,6 +190,8 @@ posix_spawnattr_destroy(posix_spawnattr_t *attr) psattr = *(_posix_spawnattr_t *)attr; posix_spawn_destroyportactions_np(attr); + posix_spawn_destroycoalition_info_np(attr); + posix_spawn_destroypersona_info_np(attr); free(psattr); *attr = NULL; @@ -736,6 +756,52 @@ posix_spawn_destroyportactions_np(posix_spawnattr_t *attr) return 0; } +/* + * posix_spawn_destroycoalition_info_np + * Description: clean up coalition_info struct in posix_spawnattr_t attr + */ +static int +posix_spawn_destroycoalition_info_np(posix_spawnattr_t *attr) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_coalition_info *coal_info; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + coal_info = psattr->psa_coalition_info; + if (coal_info == NULL) + return EINVAL; + + psattr->psa_coalition_info = NULL; + free(coal_info); + return 0; +} + +/* + * posix_spawn_destroypersona_info_np + * Description: clean up persona_info struct in posix_spawnattr_t attr + */ +static int +posix_spawn_destroypersona_info_np(posix_spawnattr_t *attr) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + persona = psattr->psa_persona_info; + if (persona == NULL) + return EINVAL; + + psattr->psa_persona_info = NULL; + free(persona); + return 0; +} + /* * posix_spawn_appendportaction_np * Description: append a port action, grow the array if necessary @@ -1266,6 +1332,43 @@ posix_spawnattr_getcpumonitor(posix_spawnattr_t * __restrict attr, } +/* + * posix_spawnattr_setjetsam_ext + * + * Description: Set jetsam attributes for the spawn attribute object + * referred to by 'attr'. + * + * Parameters: flags The flags value to set + * priority Relative jetsam priority + * memlimit_active Value in megabytes; memory footprint + * above this level while process is + * active may result in termination. + * memlimit_inactive Value in megabytes; memory footprint + * above this level while process is + * inactive may result in termination. + * + * Returns: 0 Success + */ +int +posix_spawnattr_setjetsam_ext(posix_spawnattr_t * __restrict attr, + short flags, int priority, int memlimit_active, int memlimit_inactive) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + + psattr->psa_jetsam_flags = flags; + psattr->psa_jetsam_flags |= POSIX_SPAWN_JETSAM_SET; + psattr->psa_priority = priority; + psattr->psa_memlimit_active = memlimit_active; + psattr->psa_memlimit_inactive = memlimit_inactive; + + return (0); +} + /* * posix_spawnattr_set_importancewatch_port_np @@ -1390,16 +1493,31 @@ posix_spawnattr_setmacpolicyinfo_np(posix_spawnattr_t * __restrict attr, return 0; } -int posix_spawnattr_setcoalition_np(const posix_spawnattr_t * __restrict attr, uint64_t coalitionid) +int posix_spawnattr_setcoalition_np(const posix_spawnattr_t * __restrict attr, + uint64_t coalitionid, int type, int role) { _posix_spawnattr_t psattr; + struct _posix_spawn_coalition_info *coal_info; if (attr == NULL || *attr == NULL) { return EINVAL; } + if (type < 0 || type > COALITION_TYPE_MAX) + return EINVAL; psattr = *(_posix_spawnattr_t *)attr; - psattr->psa_coalitionid = coalitionid; + + coal_info = psattr->psa_coalition_info; + if (!coal_info) { + coal_info = (struct _posix_spawn_coalition_info *)malloc(sizeof(*coal_info)); + if (!coal_info) + return ENOMEM; + memset(coal_info, 0, sizeof(*coal_info)); + psattr->psa_coalition_info = coal_info; + } + + coal_info->psci_info[type].psci_id = coalitionid; + coal_info->psci_info[type].psci_role = role; return 0; } @@ -1437,6 +1555,152 @@ posix_spawnattr_get_qos_clamp_np(const posix_spawnattr_t * __restrict attr, uint return (0); } +int posix_spawnattr_set_darwin_role_np(const posix_spawnattr_t * __restrict attr, uint64_t darwin_role) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) { + return EINVAL; + } + + psattr = *(_posix_spawnattr_t *)attr; + psattr->psa_darwin_role = darwin_role; + + return 0; +} + +int +posix_spawnattr_get_darwin_role_np(const posix_spawnattr_t * __restrict attr, uint64_t * __restrict darwin_rolep) +{ + _posix_spawnattr_t psattr; + + if (attr == NULL || *attr == NULL) { + return EINVAL; + } + + psattr = *(_posix_spawnattr_t *)attr; + *darwin_rolep = psattr->psa_darwin_role; + + return (0); +} + + +int +posix_spawnattr_set_persona_np(const posix_spawnattr_t * __restrict attr, uid_t persona_id, uint32_t flags) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + if (flags & ~POSIX_SPAWN_PERSONA_ALL_FLAGS) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + + persona = psattr->psa_persona_info; + if (!persona) { + persona = (struct _posix_spawn_persona_info *)malloc(sizeof(*persona)); + if (!persona) + return ENOMEM; + persona->pspi_uid = 0; + persona->pspi_gid = 0; + persona->pspi_ngroups = 0; + persona->pspi_groups[0] = 0; + + psattr->psa_persona_info = persona; + } + + persona->pspi_id = persona_id; + persona->pspi_flags = flags; + + return 0; +} + +int +posix_spawnattr_set_persona_uid_np(const posix_spawnattr_t * __restrict attr, uid_t uid) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + persona = psattr->psa_persona_info; + if (!persona) + return EINVAL; + + if (!(persona->pspi_flags & (POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE | POSIX_SPAWN_PERSONA_FLAGS_VERIFY))) + return EINVAL; + + persona->pspi_uid = uid; + + persona->pspi_flags |= POSIX_SPAWN_PERSONA_UID; + + return 0; +} + +int +posix_spawnattr_set_persona_gid_np(const posix_spawnattr_t * __restrict attr, gid_t gid) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + persona = psattr->psa_persona_info; + if (!persona) + return EINVAL; + + if (!(persona->pspi_flags & (POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE | POSIX_SPAWN_PERSONA_FLAGS_VERIFY))) + return EINVAL; + + persona->pspi_gid = gid; + + persona->pspi_flags |= POSIX_SPAWN_PERSONA_GID; + + return 0; +} + +int +posix_spawnattr_set_persona_groups_np(const posix_spawnattr_t * __restrict attr, int ngroups, gid_t *gidarray, uid_t gmuid) +{ + _posix_spawnattr_t psattr; + struct _posix_spawn_persona_info *persona; + + if (attr == NULL || *attr == NULL) + return EINVAL; + + if (gidarray == NULL) + return EINVAL; + + if (ngroups > NGROUPS) + return EINVAL; + + psattr = *(_posix_spawnattr_t *)attr; + persona = psattr->psa_persona_info; + if (!persona) + return EINVAL; + + if (!(persona->pspi_flags & (POSIX_SPAWN_PERSONA_FLAGS_OVERRIDE | POSIX_SPAWN_PERSONA_FLAGS_VERIFY))) + return EINVAL; + + persona->pspi_ngroups = ngroups; + for (int i = 0; i < ngroups; i++) + persona->pspi_groups[i] = gidarray[i]; + + persona->pspi_gmuid = gmuid; + + persona->pspi_flags |= POSIX_SPAWN_PERSONA_GROUPS; + + return 0; +} + + /* * posix_spawn @@ -1511,6 +1775,14 @@ posix_spawn(pid_t * __restrict pid, const char * __restrict path, ad.mac_extensions_size = PS_MAC_EXTENSIONS_SIZE( ad.mac_extensions->psmx_count); } + if (psattr->psa_coalition_info != NULL) { + ad.coal_info_size = sizeof(struct _posix_spawn_coalition_info); + ad.coal_info = psattr->psa_coalition_info; + } + if (psattr->psa_persona_info != NULL) { + ad.persona_info_size = sizeof(struct _posix_spawn_persona_info); + ad.persona_info = psattr->psa_persona_info; + } } if (file_actions != NULL && *file_actions != NULL) { _posix_spawn_file_actions_t psactsp = diff --git a/src/kernel/libsyscall/wrappers/spawn/spawn.h b/src/kernel/libsyscall/wrappers/spawn/spawn.h index 53b4ecb86..663dd3ca5 100644 --- a/src/kernel/libsyscall/wrappers/spawn/spawn.h +++ b/src/kernel/libsyscall/wrappers/spawn/spawn.h @@ -29,9 +29,9 @@ * [SPN] Support for _POSIX_SPAWN */ -#include +#include #include <_types.h> -#include /* shared types */ +#include /* shared types */ #include @@ -56,38 +56,72 @@ __BEGIN_DECLS * gcc under c99 mode won't compile "[ __restrict]" by itself. As a workaround, * a dummy argument name is added. */ + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn(pid_t * __restrict, const char * __restrict, const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, char *const __argv[ __restrict], char *const __envp[ __restrict]) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnp(pid_t * __restrict, const char * __restrict, const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, char *const __argv[ __restrict], char *const __envp[ __restrict]) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_addopen( posix_spawn_file_actions_t * __restrict, int, const char * __restrict, int, mode_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_init(posix_spawn_file_actions_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_destroy(posix_spawnattr_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict, sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getflags(const posix_spawnattr_t * __restrict, short * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict, pid_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict, sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_init(posix_spawnattr_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict, const sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setflags(posix_spawnattr_t *, short) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict, const sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); @@ -115,17 +149,28 @@ __END_DECLS __BEGIN_DECLS +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_getbinpref_np(const posix_spawnattr_t * __restrict, size_t, cpu_type_t *__restrict, size_t *__restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setauditsessionport_np(posix_spawnattr_t *__restrict, mach_port_t) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict, size_t, cpu_type_t *__restrict, size_t *__restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setexceptionports_np(posix_spawnattr_t *__restrict, exception_mask_t, mach_port_t, exception_behavior_t, thread_state_flavor_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawnattr_setspecialport_np(posix_spawnattr_t *__restrict, mach_port_t, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int posix_spawn_file_actions_addinherit_np(posix_spawn_file_actions_t *, int) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); diff --git a/src/kernel/libsyscall/wrappers/spawn/spawn_private.h b/src/kernel/libsyscall/wrappers/spawn/spawn_private.h index 10a1b544c..ec7f50fb6 100644 --- a/src/kernel/libsyscall/wrappers/spawn/spawn_private.h +++ b/src/kernel/libsyscall/wrappers/spawn/spawn_private.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -40,6 +41,9 @@ int posix_spawnattr_getcpumonitor(posix_spawnattr_t * __restrict, uint64_t *, ui int posix_spawnattr_setcpumonitor_default(posix_spawnattr_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0); +int posix_spawnattr_setjetsam_ext(posix_spawnattr_t * __restrict attr, + short flags, int priority, int memlimit_active, int memlimit_inactive) __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); + #define POSIX_SPAWN_IMPORTANCE_PORT_COUNT 32 int posix_spawnattr_set_importancewatch_port_np(posix_spawnattr_t * __restrict attr, int count, mach_port_t portarray[]) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0); @@ -48,9 +52,17 @@ int posix_spawnattr_set_importancewatch_port_np(posix_spawnattr_t * __restrict a int posix_spawnattr_getmacpolicyinfo_np(const posix_spawnattr_t * __restrict, const char *, void **, size_t *) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); int posix_spawnattr_setmacpolicyinfo_np(posix_spawnattr_t * __restrict, const char *, void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); -int posix_spawnattr_setcoalition_np(const posix_spawnattr_t * __restrict, uint64_t) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); +int posix_spawnattr_setcoalition_np(const posix_spawnattr_t * __restrict, uint64_t, int, int) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); int posix_spawnattr_set_qos_clamp_np(const posix_spawnattr_t * __restrict, uint64_t) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); int posix_spawnattr_get_qos_clamp_np(const posix_spawnattr_t * __restrict, uint64_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); +int posix_spawnattr_set_darwin_role_np(const posix_spawnattr_t * __restrict, uint64_t) __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); +int posix_spawnattr_get_darwin_role_np(const posix_spawnattr_t * __restrict, uint64_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); + +int posix_spawnattr_set_persona_np(const posix_spawnattr_t * __restrict, uid_t, uint32_t) __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); +int posix_spawnattr_set_persona_uid_np(const posix_spawnattr_t * __restrict, uid_t) __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); +int posix_spawnattr_set_persona_gid_np(const posix_spawnattr_t * __restrict, gid_t) __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); +int posix_spawnattr_set_persona_groups_np(const posix_spawnattr_t * __restrict, int, gid_t *, uid_t) __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); + #endif /* !defined _SPAWN_PRIVATE_H_*/ diff --git a/src/kernel/libsyscall/wrappers/stackshot.c b/src/kernel/libsyscall/wrappers/stackshot.c new file mode 100644 index 000000000..0e065edd2 --- /dev/null +++ b/src/kernel/libsyscall/wrappers/stackshot.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2014 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include +#include +#include +#include + +/* + * System call entry point + */ +int __stack_snapshot_with_config(int stackshot_config_version, user_addr_t stackshot_config, size_t stackshot_config_size); + +/* + * stackshot_config_create: create and initialize the arguments for a stackshot + * + * Outputs: NULL if malloc fails + * a pointer to a new stackshot_config_t on success + */ +stackshot_config_t * +stackshot_config_create(void) +{ + stackshot_config_t *s_config; + + s_config = malloc(sizeof(stackshot_config_t)); + if (s_config == NULL) { + return NULL; + } + + s_config->sc_pid = -1; + s_config->sc_flags = 0; + s_config->sc_delta_timestamp = 0; + s_config->sc_buffer = 0; + s_config->sc_size = 0; + + return s_config; +} + +/* + * stackshot_config_set_pid: set the PID to be traced + * + * Inputs: stackshot_config - a pointer to the stackshot_config_t we want to update + * pid - process id of process to be traced, or -1 for the entire system + * + * Outputs: EINVAL if the passed stackshot_config pointer is NULL + * 0 on success + */ +int +stackshot_config_set_pid(stackshot_config_t *stackshot_config, int pid) +{ + stackshot_config_t *s_config; + + if (stackshot_config == NULL) { + return EINVAL; + } + + s_config = (stackshot_config_t *) stackshot_config; + s_config->sc_pid = pid; + + return 0; +} + +/* + * stackshot_config_set_flags: set the flags to be passed for the stackshot + * + * Inputs: stackshot_config - a pointer to the stackshot_config_t we want to update + * flags - flags to pass to stackshot + * + * Outputs: EINVAL if the passed stackshot_config pointer is NULL + * 0 on success + */ +int +stackshot_config_set_flags(stackshot_config_t *stackshot_config, uint32_t flags) +{ + stackshot_config_t *s_config; + + if (stackshot_config == NULL) { + return EINVAL; + } + + s_config = (stackshot_config_t *) stackshot_config; + s_config->sc_flags = flags; + + return 0; +} + +/* + * stackshot_capture_with_config: take a stackshot with the provided config + * + * Inputs: stackshot_config - a pointer to the stackshot_config_t we want to use + * + * Outputs: EINVAL if the passed stackshot_config pointer is NULL, a caller is trying + * to reuse a config without deallocating its buffer or if there is a + * problem with the arguments + * EFAULT if there was a problem with accessing the arguments from the kernel + * EPERM if the caller is not privileged + * ENOTSUP if the caller is passing a stackshot config version that is not + * supported by the kernel (indicates libsyscall:kernel mismatch), + * or if the caller is requesting unsupported flags + * ENOMEM if the kernel is unable to allocate memory + * ENOSPC if the caller doesn't have enough space in their address space for + * the kernel to remap the buffer + * ENOENT if the caller is requesting an existing buffer that doesn't exist + * or the target PID isn't found + * 0 on success + */ +int +stackshot_capture_with_config(stackshot_config_t *stackshot_config) +{ + int ret; + stackshot_config_t *s_config; + + if (stackshot_config == NULL) { + return EINVAL; + } + + s_config = (stackshot_config_t *) stackshot_config; + if (s_config->sc_buffer != 0) { + return EINVAL; + } + + s_config->sc_out_buffer_addr = &s_config->sc_buffer; + s_config->sc_out_size_addr = &s_config->sc_size; + ret = __stack_snapshot_with_config(STACKSHOT_CONFIG_TYPE, s_config, sizeof(stackshot_config_t)); + + if (ret != 0) { + ret = errno; + s_config->sc_buffer = 0; + s_config->sc_size = 0; + } + + return ret; +} + +/* + * stackshot_config_get_stackshot_buffer: get a pointer to the buffer containing the stackshot + * + * Inputs: stackshot_config - a pointer to a stackshot_config_t + * + * Outputs: NULL if the passed stackshot_config is NULL or if its buffer is NULL + * a pointer to the buffer containing the stackshot on success + */ +void * +stackshot_config_get_stackshot_buffer(stackshot_config_t *stackshot_config) +{ + stackshot_config_t *s_config; + + if (stackshot_config == NULL) { + return NULL; + } + s_config = (stackshot_config_t *) stackshot_config; + + return ((void *)s_config->sc_buffer); +} + +/* + * stackshot_config_get_stackshot_size: get the size of the stackshot buffer + * + * Inputs: stackshot_config - a pointer to a stackshot_config_t + * + * Outputs: -1 if the passed stackshot config is NULL or there is no buffer + * the length of the stackshot buffer on success + */ +uint32_t +stackshot_config_get_stackshot_size(stackshot_config_t * stackshot_config) +{ + if (stackshot_config == NULL || (void *)stackshot_config->sc_buffer == NULL) { + return -1; + } + + return stackshot_config->sc_size; +} + +/* + * stackshot_config_set_size_hint: set the size of the stackshot buffer + * + * Inputs: stackshot_config - a pointer to a stackshot_config_t + * suggested_size - hint for size allocation of stackshot + * + * Outputs: -1 if the passed stackshot config is NULL or there is existing stackshot buffer set. + * the length of the stackshot buffer on success. + */ +int +stackshot_config_set_size_hint(stackshot_config_t *stackshot_config, uint32_t suggested_size) +{ + if (stackshot_config == NULL || (void *)stackshot_config->sc_buffer != NULL) { + return -1; + } + + stackshot_config->sc_size = suggested_size; + + return 0; +} + +/* + * stackshot_config_set_delta_timestamp: set the timestamp to use as the basis for the delta stackshot + * + * This timestamp will be used along with STACKSHOT_COLLECT_DELTA_SNAPSHOT flag to collect delta stackshots + * + * Inputs: stackshot_config - a pointer to a stackshot_config_t + * delta_timestamp - timestamp in MachAbsoluteTime units to be used as the basis for a delta stackshot + * + * Outputs: -1 if the passed stackshot config is NULL or there is existing stackshot buffer set. + * 0 on success + */ +int +stackshot_config_set_delta_timestamp(stackshot_config_t *stackshot_config, uint64_t delta_timestamp) +{ + if (stackshot_config == NULL || (void *)stackshot_config->sc_buffer != NULL) { + return -1; + } + + stackshot_config->sc_delta_timestamp = delta_timestamp; + + return 0; +} + + +/* + * stackshot_config_dealloc_buffer: dealloc the stackshot buffer and reset the size so that a + * stackshot_config_t can be used again + * + * Inputs: stackshot_config - a pointer to a stackshot_config_t + * + * Outputs: EINVAL if the passed stackshot_config is NULL or if its buffer is NULL + * 0 otherwise + */ +int +stackshot_config_dealloc_buffer(stackshot_config_t *stackshot_config) +{ + stackshot_config_t *s_config; + + if (stackshot_config == NULL) { + return EINVAL; + } + s_config = (stackshot_config_t *) stackshot_config; + + if (s_config->sc_size && s_config->sc_buffer) { + mach_vm_deallocate(mach_task_self(), (mach_vm_offset_t)s_config->sc_buffer, (mach_vm_size_t)s_config->sc_size); + } + + s_config->sc_buffer = 0; + s_config->sc_size = 0; + + return 0; +} + +/* + * stackshot_config_dealloc: dealloc the stackshot buffer and the stackshot config + * + * Inputs: stackshot_config - a pointer to a stackshot_config_t + * + * Outputs: EINVAL if the passed stackshot_cofnig is NULL + * 0 otherwise + */ +int +stackshot_config_dealloc(stackshot_config_t *stackshot_config) +{ + stackshot_config_t *s_config; + + if (stackshot_config == NULL) { + return EINVAL; + } + s_config = (stackshot_config_t *) stackshot_config; + + if (s_config->sc_size && s_config->sc_buffer) { + mach_vm_deallocate(mach_task_self(), (mach_vm_offset_t)s_config->sc_buffer, (mach_vm_size_t)s_config->sc_size); + } + + s_config->sc_buffer = 0; + s_config->sc_size = 0; + + free(s_config); + return 0; +} diff --git a/src/kernel/libsyscall/wrappers/string/memset.c b/src/kernel/libsyscall/wrappers/string/memset.c index 3ae3c7717..cab6587d6 100644 --- a/src/kernel/libsyscall/wrappers/string/memset.c +++ b/src/kernel/libsyscall/wrappers/string/memset.c @@ -36,6 +36,8 @@ #define wsize sizeof(u_int) #define wmask (wsize - 1) +// n.b. this must be compiled with -fno-builtin or it might get optimized into +// a recursive call to bzero. __attribute__((visibility("hidden"))) void bzero(void *dst0, size_t length) diff --git a/src/kernel/libsyscall/wrappers/terminate_with_reason.c b/src/kernel/libsyscall/wrappers/terminate_with_reason.c new file mode 100644 index 000000000..05fdb7848 --- /dev/null +++ b/src/kernel/libsyscall/wrappers/terminate_with_reason.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include +#include +#include + +/* System call entry points */ +int __terminate_with_payload(int pid, uint32_t reason_namespace, uint64_t reason_code, + void *payload, uint32_t payload_size, const char *reason_string, + uint64_t reason_flags); + +void __abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, + void *payload, uint32_t payload_size, const char *reason_string, + uint64_t reason_flags); + +static void abort_with_payload_wrapper_internal(uint32_t reason_namespace, uint64_t reason_code, + void *payload, uint32_t payload_size, const char *reason_string, + uint64_t reason_flags) __attribute__((noreturn)); + +/* System call wrappers */ +int +terminate_with_reason(int pid, uint32_t reason_namespace, uint64_t reason_code, + const char *reason_string, uint64_t reason_flags) +{ + return __terminate_with_payload(pid, reason_namespace, reason_code, 0, 0, + reason_string, reason_flags); +} + +int +terminate_with_payload(int pid, uint32_t reason_namespace, uint64_t reason_code, + void *payload, uint32_t payload_size, + const char *reason_string, uint64_t reason_flags) +{ + return __terminate_with_payload(pid, reason_namespace, reason_code, payload, + payload_size, reason_string, reason_flags); +} + +static void abort_with_payload_wrapper_internal(uint32_t reason_namespace, uint64_t reason_code, + void *payload, uint32_t payload_size, const char *reason_string, + uint64_t reason_flags) +{ + sigset_t unmask_signal; + + /* Try to unmask SIGABRT before trapping to the kernel */ + sigemptyset(&unmask_signal); + sigaddset(&unmask_signal, SIGABRT); + sigprocmask(SIG_UNBLOCK, &unmask_signal, NULL); + + __abort_with_payload(reason_namespace, reason_code, payload, payload_size, + reason_string, reason_flags); + + /* If sending a SIGABRT failed, we try to fall back to SIGKILL */ + terminate_with_payload(getpid(), reason_namespace, reason_code, payload, payload_size, + reason_string, reason_flags); + + /* Last resort, let's use SIGTRAP (SIGILL on i386) */ + sigemptyset(&unmask_signal); + sigaddset(&unmask_signal, SIGTRAP); + sigaddset(&unmask_signal, SIGILL); + sigprocmask(SIG_UNBLOCK, &unmask_signal, NULL); + + __builtin_trap(); +} + +void +abort_with_reason(uint32_t reason_namespace, uint64_t reason_code, const char *reason_string, + uint64_t reason_flags) +{ + abort_with_payload_wrapper_internal(reason_namespace, reason_code, 0, 0, reason_string, reason_flags); +} + +void +abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, void *payload, + uint32_t payload_size, const char *reason_string, + uint64_t reason_flags) +{ + abort_with_payload_wrapper_internal(reason_namespace, reason_code, payload, payload_size, + reason_string, reason_flags); +} + diff --git a/src/kernel/libsyscall/wrappers/thread_register_state.c b/src/kernel/libsyscall/wrappers/thread_register_state.c new file mode 100644 index 000000000..2fa478328 --- /dev/null +++ b/src/kernel/libsyscall/wrappers/thread_register_state.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#include + +kern_return_t +thread_get_register_pointer_values(thread_t thread, uintptr_t *sp, size_t *length, uintptr_t *values) +{ + if (!length) return KERN_INVALID_ARGUMENT; + if (*length > 0 && values == NULL) return KERN_INVALID_ARGUMENT; + + size_t in_length = *length; + size_t out_length = 0; + +#if defined(__i386__) + i386_thread_state_t state = {}; + thread_state_flavor_t flavor = x86_THREAD_STATE32; + mach_msg_type_number_t count = i386_THREAD_STATE_COUNT; +#elif defined(__x86_64__) + x86_thread_state64_t state = {}; + thread_state_flavor_t flavor = x86_THREAD_STATE64; + mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; +#else +#error thread_get_register_pointer_values not defined for this architecture +#endif + + kern_return_t ret = thread_get_state(thread, flavor, (thread_state_t)&state, &count); + if (ret != KERN_SUCCESS){ + return ret; + } + + // If the provided pointer value is > PAGE_SIZE, add it to the output array + // if there's available space. (Values between 0 and PAGE_SIZE are the NULL page + // and not valid pointers.) +#define push_register_value(p) do { \ + if ((uintptr_t)p > PAGE_SIZE) { \ + if (out_length < in_length && values) \ + values[out_length] = p; \ + out_length++; \ + } } while (0) + +#if defined(__i386__) + if (sp) *sp = state.__esp; + + push_register_value(state.__eip); + + push_register_value(state.__eax); + push_register_value(state.__ebx); + push_register_value(state.__ecx); + push_register_value(state.__edx); + push_register_value(state.__edi); + push_register_value(state.__esi); + push_register_value(state.__ebp); +#elif defined(__x86_64__) + if (sp) *sp = state.__rsp - 128 /* redzone */; + + push_register_value(state.__rip); + + push_register_value(state.__rax); + push_register_value(state.__rbx); + push_register_value(state.__rcx); + push_register_value(state.__rdx); + push_register_value(state.__rdi); + push_register_value(state.__rbp); + push_register_value(state.__r8); + push_register_value(state.__r9); + push_register_value(state.__r10); + push_register_value(state.__r11); + push_register_value(state.__r12); + push_register_value(state.__r13); + push_register_value(state.__r14); + push_register_value(state.__r15); +#else +#error thread_get_register_pointer_values not defined for this architecture +#endif + + *length = out_length; + + if (in_length == 0 || out_length > in_length){ + return KERN_INSUFFICIENT_BUFFER_SIZE; + } + + return KERN_SUCCESS; +} diff --git a/src/kernel/libsyscall/wrappers/work_interval.c b/src/kernel/libsyscall/wrappers/work_interval.c new file mode 100644 index 000000000..29dd2ad61 --- /dev/null +++ b/src/kernel/libsyscall/wrappers/work_interval.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include +#include +#include +#include + +struct work_interval { + uint64_t thread_id; + uint64_t work_interval_id; +}; + +extern uint64_t __thread_selfid(void); + +/* Create a new work interval handle (currently for the current thread only). Flags is unused */ +int +work_interval_create(work_interval_t *interval_handle, uint32_t flags __unused) +{ + int ret; + uint64_t work_interval_id; + work_interval_t handle; + + ret = __work_interval_ctl(WORK_INTERVAL_OPERATION_CREATE, 0, &work_interval_id, sizeof(work_interval_id)); + if (ret == -1) { + return ret; + } + + handle = malloc(sizeof(*handle)); + if (handle == NULL) { + errno = ENOMEM; + return -1; + } + + handle->thread_id = __thread_selfid(); + handle->work_interval_id = work_interval_id; + + *interval_handle = handle; + return 0; +} + +int +work_interval_notify(work_interval_t interval_handle, uint64_t start, uint64_t finish, uint64_t deadline, uint64_t next_start, uint32_t flags) +{ + int ret; + uint64_t work_interval_id; + struct work_interval_notification notification = { + .start = start, + .finish = finish, + .deadline = deadline, + .next_start = next_start, + .flags = flags, + .unused1 = 0 + }; + + if (interval_handle == NULL) { + errno = EINVAL; + return -1; + } + + work_interval_id = interval_handle->work_interval_id; + + ret = __work_interval_ctl(WORK_INTERVAL_OPERATION_NOTIFY, work_interval_id, ¬ification, sizeof(notification)); + return ret; +} + +int +work_interval_notify_simple(work_interval_t interval_handle, uint64_t start, uint64_t deadline, uint64_t next_start) +{ + return work_interval_notify(interval_handle, start, mach_absolute_time(), deadline, next_start, 0); +} + +int +work_interval_destroy(work_interval_t interval_handle) +{ + int ret, saved_errno; + uint64_t work_interval_id; + + if (interval_handle == NULL) { + errno = EINVAL; + return -1; + } + + work_interval_id = interval_handle->work_interval_id; + + ret = __work_interval_ctl(WORK_INTERVAL_OPERATION_DESTROY, work_interval_id, NULL, 0); + saved_errno = errno; + free(interval_handle); + errno = saved_errno; + + return ret; +} diff --git a/src/kernel/libsyscall/xcodescripts/syscalls.master b/src/kernel/libsyscall/xcodescripts/syscalls.master index faf5af9d4..7c2bd0f69 100644 --- a/src/kernel/libsyscall/xcodescripts/syscalls.master +++ b/src/kernel/libsyscall/xcodescripts/syscalls.master @@ -31,9 +31,6 @@ ; N.B.: makesyscalls.sh and createsyscalls.pl must be updated to account ; for any new argument types. -; If you add a new syscall number to the end of this file, you need to -; increment the value of NUM_SYSENT in bsd/sys/sysent.h. - #include #include #include @@ -113,7 +110,7 @@ 60 AUE_UMASK ALL { int umask(int newmask); } 61 AUE_CHROOT ALL { int chroot(user_addr_t path); } 62 AUE_NULL ALL { int nosys(void); } { old fstat } -63 AUE_NULL ALL { int nosys(void); } { used internally, reserved } +63 AUE_NULL ALL { int nosys(void); } { used internally and reserved } 64 AUE_NULL ALL { int nosys(void); } { old getpagesize } 65 AUE_MSYNC ALL { int msync(caddr_t addr, size_t len, int flags) NO_SYSCALL_STUB; } 66 AUE_VFORK ALL { int vfork(void); } @@ -182,7 +179,7 @@ 114 AUE_NULL ALL { int nosys(void); } #endif /* SOCKETS */ 115 AUE_NULL ALL { int nosys(void); } { old vtrace } -116 AUE_GETTIMEOFDAY ALL { int gettimeofday(struct timeval *tp, struct timezone *tzp) NO_SYSCALL_STUB; } +116 AUE_GETTIMEOFDAY ALL { int gettimeofday(struct timeval *tp, struct timezone *tzp, uint64_t *mach_absolute_time) NO_SYSCALL_STUB; } 117 AUE_GETRUSAGE ALL { int getrusage(int who, struct rusage *rusage); } #if SOCKETS 118 AUE_GETSOCKOPT ALL { int getsockopt(int s, int level, int name, caddr_t val, socklen_t *avalsize); } @@ -265,7 +262,7 @@ 174 AUE_NULL ALL { int nosys(void); } { old getdents } 175 AUE_NULL ALL { int nosys(void); } { old gc_control } 176 AUE_NULL ALL { int nosys(void); } { old add_profil } -177 AUE_NULL ALL { int nosys(void); } +177 AUE_KDEBUGTRACE ALL { int kdebug_typefilter(void** addr, size_t* size) NO_SYSCALL_STUB; } 178 AUE_KDEBUGTRACE ALL { uint64_t kdebug_trace_string(uint32_t debugid, uint64_t str_id, const char *str) NO_SYSCALL_STUB; } 179 AUE_KDEBUGTRACE ALL { int kdebug_trace64(uint32_t code, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) NO_SYSCALL_STUB; } 180 AUE_KDEBUGTRACE ALL { int kdebug_trace(uint32_t code, u_long arg1, u_long arg2, u_long arg3, u_long arg4) NO_SYSCALL_STUB; } @@ -273,7 +270,7 @@ 182 AUE_SETEGID ALL { int setegid(gid_t egid); } 183 AUE_SETEUID ALL { int seteuid(uid_t euid); } 184 AUE_SIGRETURN ALL { int sigreturn(struct ucontext *uctx, int infostyle) NO_SYSCALL_STUB; } -185 AUE_CHUD ALL { int chud(uint64_t code, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) NO_SYSCALL_STUB; } +185 AUE_NULL ALL { int enosys(void); } { old chud } 186 AUE_NULL ALL { int nosys(void); } 187 AUE_FDATASYNC ALL { int fdatasync(int fd); } 188 AUE_STAT ALL { int stat(user_addr_t path, user_addr_t ub); } @@ -281,12 +278,12 @@ 190 AUE_LSTAT ALL { int lstat(user_addr_t path, user_addr_t ub); } 191 AUE_PATHCONF ALL { int pathconf(char *path, int name); } 192 AUE_FPATHCONF ALL { int fpathconf(int fd, int name); } -193 AUE_NULL ALL { int nosys(void); } +193 AUE_NULL ALL { int nosys(void); } { old getfsstat } 194 AUE_GETRLIMIT ALL { int getrlimit(u_int which, struct rlimit *rlp) NO_SYSCALL_STUB; } 195 AUE_SETRLIMIT ALL { int setrlimit(u_int which, struct rlimit *rlp) NO_SYSCALL_STUB; } 196 AUE_GETDIRENTRIES ALL { int getdirentries(int fd, char *buf, u_int count, long *basep); } 197 AUE_MMAP ALL { user_addr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos) NO_SYSCALL_STUB; } -198 AUE_NULL ALL { int nosys(void); } { __syscall } +198 AUE_NULL ALL { int nosys(void); } { old __syscall } 199 AUE_LSEEK ALL { off_t lseek(int fd, off_t offset, int whence); } 200 AUE_TRUNCATE ALL { int truncate(char *path, off_t length); } 201 AUE_FTRUNCATE ALL { int ftruncate(int fd, off_t length); } @@ -317,14 +314,14 @@ ; 216-> 219 used to be mkcomplex and {f,l}statv variants. They are gone now. 216 AUE_NULL ALL { int open_dprotected_np(user_addr_t path, int flags, int class, int dpflags, int mode) NO_SYSCALL_STUB; } -217 AUE_NULL ALL { int nosys(void); } -218 AUE_NULL ALL { int nosys(void); } -219 AUE_NULL ALL { int nosys(void); } +217 AUE_NULL ALL { int nosys(void); } { old statv } +218 AUE_NULL ALL { int nosys(void); } { old lstatv } +219 AUE_NULL ALL { int nosys(void); } { old fstatv } 220 AUE_GETATTRLIST ALL { int getattrlist(const char *path, struct attrlist *alist, void *attributeBuffer, size_t bufferSize, u_long options) NO_SYSCALL_STUB; } 221 AUE_SETATTRLIST ALL { int setattrlist(const char *path, struct attrlist *alist, void *attributeBuffer, size_t bufferSize, u_long options) NO_SYSCALL_STUB; } 222 AUE_GETDIRENTRIESATTR ALL { int getdirentriesattr(int fd, struct attrlist *alist, void *buffer, size_t buffersize, u_long *count, u_long *basep, u_long *newstate, u_long options); } 223 AUE_EXCHANGEDATA ALL { int exchangedata(const char *path1, const char *path2, u_long options); } -224 AUE_NULL ALL { int nosys(void); } { old checkuseraccess / fsgetpath (which moved to 427) } +224 AUE_NULL ALL { int nosys(void); } { old checkuseraccess or fsgetpath } 225 AUE_SEARCHFS ALL { int searchfs(const char *path, struct fssearchblock *searchblock, uint32_t *nummatches, uint32_t scriptcode, uint32_t options, struct searchstate *state); } 226 AUE_DELETE ALL { int delete(user_addr_t path) NO_SYSCALL_STUB; } { private delete (Carbon semantics) } 227 AUE_COPYFILE ALL { int copyfile(char *from, char *to, int mode, int flags) NO_SYSCALL_STUB; } @@ -380,7 +377,7 @@ 254 AUE_SEMCTL ALL { int semctl(int semid, int semnum, int cmd, semun_t arg) NO_SYSCALL_STUB; } 255 AUE_SEMGET ALL { int semget(key_t key, int nsems, int semflg); } 256 AUE_SEMOP ALL { int semop(int semid, struct sembuf *sops, int nsops); } -257 AUE_NULL ALL { int nosys(void); } +257 AUE_NULL ALL { int nosys(void); } { old semconfig } #else 254 AUE_NULL ALL { int nosys(void); } 255 AUE_NULL ALL { int nosys(void); } @@ -547,7 +544,7 @@ 362 AUE_KQUEUE ALL { int kqueue(void); } 363 AUE_NULL ALL { int kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); } 364 AUE_LCHOWN ALL { int lchown(user_addr_t path, uid_t owner, gid_t group) NO_SYSCALL_STUB; } -365 AUE_STACKSNAPSHOT ALL { int stack_snapshot(pid_t pid, user_addr_t tracebuf, uint32_t tracebuf_size, uint32_t flags, uint32_t dispatch_offset) NO_SYSCALL_STUB; } +365 AUE_NULL ALL { int nosys(void); } { old stack_snapshot } #if CONFIG_WORKQUEUE 366 AUE_NULL ALL { int bsdthread_register(user_addr_t threadstart, user_addr_t wqthread, uint32_t flags, user_addr_t stack_addr_hint, user_addr_t targetconc_ptr, uint32_t dispatchqueue_offset, uint32_t tsd_offset) NO_SYSCALL_STUB; } 367 AUE_WORKQOPEN ALL { int workq_open(void) NO_SYSCALL_STUB; } @@ -661,7 +658,7 @@ 425 AUE_MAC_GET_MOUNT ALL { int nosys(void); } #endif 426 AUE_MAC_GETFSSTAT ALL { int __mac_getfsstat(user_addr_t buf, int bufsize, user_addr_t mac, int macsize, int flags); } -427 AUE_FSGETPATH ALL { user_ssize_t fsgetpath(user_addr_t buf, size_t bufsize, user_addr_t fsid, uint64_t objid) NO_SYSCALL_STUB; } { private fsgetpath (File Manager SPI) } +427 AUE_FSGETPATH ALL { user_ssize_t fsgetpath(user_addr_t buf, size_t bufsize, user_addr_t fsid, uint64_t objid); } { private fsgetpath (File Manager SPI) } 428 AUE_NULL ALL { mach_port_name_t audit_session_self(void); } 429 AUE_NULL ALL { int audit_session_join(mach_port_name_t port); } 430 AUE_NULL ALL { int fileport_makeport(int fd, user_addr_t portnamep); } @@ -719,12 +716,12 @@ 459 AUE_NULL ALL { int enosys(void); } #endif /* COALITIONS */ #if NECP -460 AUE_NULL ALL { int necp_match_policy(uint8_t *parameters, size_t parameters_size, struct necp_aggregate_result *returned_result); } +460 AUE_NECP ALL { int necp_match_policy(uint8_t *parameters, size_t parameters_size, struct necp_aggregate_result *returned_result); } #else 460 AUE_NULL ALL { int nosys(void); } #endif /* NECP */ 461 AUE_GETATTRLISTBULK ALL { int getattrlistbulk(int dirfd, struct attrlist *alist, void *attributeBuffer, size_t bufferSize, uint64_t options); } -462 AUE_NULL ALL { int enosys(void); } /* PLACEHOLDER for CLONEFILE */ +462 AUE_CLONEFILEAT ALL { int clonefileat(int src_dirfd, user_addr_t src, int dst_dirfd, user_addr_t dst, uint32_t flags); } 463 AUE_OPENAT_RWTC ALL { int openat(int fd, user_addr_t path, int flags, int mode) NO_SYSCALL_STUB; } 464 AUE_OPENAT_RWTC ALL { int openat_nocancel(int fd, user_addr_t path, int flags, int mode) NO_SYSCALL_STUB; } 465 AUE_RENAMEAT ALL { int renameat(int fromfd, char *from, int tofd, char *to) NO_SYSCALL_STUB; } @@ -759,18 +756,14 @@ 485 AUE_NULL ALL { user_ssize_t guarded_write_np(int fd, const guardid_t *guard, user_addr_t cbuf, user_size_t nbyte); } 486 AUE_PWRITE ALL { user_ssize_t guarded_pwrite_np(int fd, const guardid_t *guard, user_addr_t buf, user_size_t nbyte, off_t offset); } 487 AUE_WRITEV ALL { user_ssize_t guarded_writev_np(int fd, const guardid_t *guard, struct iovec *iovp, int iovcnt); } -#if CONFIG_SECLUDED_RENAME -488 AUE_RENAME ALL { int rename_ext(char *from, char *to, u_int flags) NO_SYSCALL_STUB; } -#else -488 AUE_NULL ALL { int enosys(void); } -#endif +488 AUE_RENAMEAT ALL { int renameatx_np(int fromfd, char *from, int tofd, char *to, u_int flags) NO_SYSCALL_STUB; } #if CONFIG_CODE_DECRYPTION 489 AUE_MPROTECT ALL { int mremap_encrypted(caddr_t addr, size_t len, uint32_t cryptid, uint32_t cputype, uint32_t cpusubtype); } #else 489 AUE_NULL ALL { int enosys(void); } #endif #if NETWORKING -490 AUE_NULL ALL { int netagent_trigger(uuid_t agent_uuid, size_t agent_uuidlen); } +490 AUE_NETAGENT ALL { int netagent_trigger(uuid_t agent_uuid, size_t agent_uuidlen); } #else 490 AUE_NULL ALL { int nosys(void); } #endif /* NETWORKING */ @@ -788,6 +781,33 @@ #endif 495 AUE_NULL ALL { int enosys(void); } 496 AUE_NULL ALL { int enosys(void); } -497 AUE_NULL ALL { int enosys(void); } +497 AUE_NULL ALL { int enosys(void); } 498 AUE_NULL ALL { int enosys(void); } 499 AUE_NULL ALL { int work_interval_ctl(uint32_t operation, uint64_t work_interval_id, void *arg, size_t len) NO_SYSCALL_STUB; } +500 AUE_NULL ALL { int getentropy(void *buffer, size_t size); } +#if NECP +501 AUE_NECP ALL { int necp_open(int flags); } } +502 AUE_NECP ALL { int necp_client_action(int necp_fd, uint32_t action, uuid_t client_id, size_t client_id_len, uint8_t *buffer, size_t buffer_size); } +#else +501 AUE_NULL ALL { int enosys(void); } +502 AUE_NULL ALL { int enosys(void); } +#endif /* NECP */ +503 AUE_NULL ALL { int enosys(void); } +504 AUE_NULL ALL { int enosys(void); } +505 AUE_NULL ALL { int enosys(void); } +506 AUE_NULL ALL { int enosys(void); } +507 AUE_NULL ALL { int enosys(void); } +508 AUE_NULL ALL { int enosys(void); } +509 AUE_NULL ALL { int enosys(void); } +510 AUE_NULL ALL { int enosys(void); } +511 AUE_NULL ALL { int enosys(void); } +512 AUE_NULL ALL { int enosys(void); } +513 AUE_NULL ALL { int enosys(void); } +514 AUE_NULL ALL { int enosys(void); } +515 AUE_NULL ALL { int ulock_wait(uint32_t operation, void *addr, uint64_t value, uint32_t timeout) NO_SYSCALL_STUB; } +516 AUE_NULL ALL { int ulock_wake(uint32_t operation, void *addr, uint64_t wake_value) NO_SYSCALL_STUB; } +517 AUE_FCLONEFILEAT ALL { int fclonefileat(int src_fd, int dst_dirfd, user_addr_t dst, uint32_t flags); } +518 AUE_NULL ALL { int fs_snapshot(uint32_t op, int dirfd, user_addr_t name1, user_addr_t name2, user_addr_t data, uint32_t flags) NO_SYSCALL_STUB; } +519 AUE_NULL ALL { int enosys(void); } +520 AUE_KILL ALL { int terminate_with_payload(int pid, uint32_t reason_namespace, uint64_t reason_code, void *payload, uint32_t payload_size, const char *reason_string, uint64_t reason_flags) NO_SYSCALL_STUB; } +521 AUE_EXIT ALL { void abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, void *payload, uint32_t payload_size, const char *reason_string, uint64_t reason_flags) NO_SYSCALL_STUB; } diff --git a/src/kernel/mach_server/client/CMakeLists.txt b/src/kernel/mach_server/client/CMakeLists.txt index 10b67d5a0..02d035066 100644 --- a/src/kernel/mach_server/client/CMakeLists.txt +++ b/src/kernel/mach_server/client/CMakeLists.txt @@ -1,9 +1,10 @@ project(mach_server_client) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -nostdinc") -include_directories("${DARLING_TOP_DIRECTORY}/platform-include") -include_directories("${DARLING_TOP_DIRECTORY}/src/libc/include") -include_directories("${DARLING_TOP_DIRECTORY}/src/kernel/emulation/linux/ext") +include_directories("${CMAKE_SOURCE_DIR}/platform-include") +include_directories("${CMAKE_SOURCE_DIR}/src/libc/include") +include_directories("${CMAKE_SOURCE_DIR}/src/kernel/emulation/linux/ext") +include_directories("${CMAKE_SOURCE_DIR}/src/kernel/libsyscall/wrappers") set(mach_server_client_sources mach_traps.c @@ -14,3 +15,5 @@ set(mach_server_client_sources add_library(mach_server_client OBJECT ${mach_server_client_sources}) add_library(mach_server_client_dyld OBJECT ${mach_server_client_sources}) set_target_properties(mach_server_client_dyld PROPERTIES COMPILE_FLAGS "-DVARIANT_DYLD") +make_fat(mach_server_client) +make_fat(mach_server_client_dyld) diff --git a/src/kernel/mach_server/client/mach_time.c b/src/kernel/mach_server/client/mach_time.c index 0b9ad23df..48d9a9ea6 100644 --- a/src/kernel/mach_server/client/mach_time.c +++ b/src/kernel/mach_server/client/mach_time.c @@ -7,7 +7,7 @@ # define NSEC_PER_SEC 1000000000ull #endif -kern_return_t mach_timebase_info( +kern_return_t mach_timebase_info_trap( mach_timebase_info_t info) { info->numer = NSEC_PER_SEC; diff --git a/src/launchd/liblaunch/CMakeLists.txt b/src/launchd/liblaunch/CMakeLists.txt index aee92ee20..e84201ac1 100644 --- a/src/launchd/liblaunch/CMakeLists.txt +++ b/src/launchd/liblaunch/CMakeLists.txt @@ -4,13 +4,19 @@ cmake_minimum_required(VERSION 2.4.0) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../external/libdispatch/) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../external/libdispatch/private) -include_directories(${DARLING_TOP_DIRECTORY}/platform-include) +include_directories(${CMAKE_SOURCE_DIR}/platform-include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src/) -include_directories(${DARLING_TOP_DIRECTORY}/src/libc/darwin) +include_directories(${CMAKE_SOURCE_DIR}/src/libc/darwin) +include_directories(${CMAKE_SOURCE_DIR}/src/libc/locale) +include_directories(${CMAKE_SOURCE_DIR}/src/libc/locale/FreeBSD) +include_directories(${CMAKE_SOURCE_DIR}/src/libc/stdtime/FreeBSD) +include_directories(${CMAKE_SOURCE_DIR}/src/libmalloc/include) +include_directories(${CMAKE_SOURCE_DIR}/src/kernel/libsyscall/wrappers/libproc) +include_directories(${CMAKE_SOURCE_DIR}/src/kernel/libsyscall/wrappers) include_directories(${CMAKE_CURRENT_BINARY_DIR}) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fblocks -nostdinc -include ${DARLING_TOP_DIRECTORY}/kernel-include/sys/fileport.h -ggdb") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fblocks -nostdinc -include ${CMAKE_SOURCE_DIR}/kernel-include/sys/fileport.h -ggdb") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib -Wl,-flat_namespace -Wl,-undefined,suppress") mig(job.defs) diff --git a/src/libc/.gitignore b/src/libc/.gitignore new file mode 100644 index 000000000..12645b6c9 --- /dev/null +++ b/src/libc/.gitignore @@ -0,0 +1,11 @@ +*~ +build/ +.DS_Store +*.xcodeproj/*.mode* +*.xcodeproj/*.pbxuser +*.xcodeproj/*.perspectivev3 + +# /Libc.xcodeproj/ +/Libc.xcodeproj/project.xcworkspace +/Libc.xcodeproj/xcuserdata +/Libc.xcodeproj/xcshareddata diff --git a/src/libc/.upstream_base_commits b/src/libc/.upstream_base_commits new file mode 100644 index 000000000..e5121036b --- /dev/null +++ b/src/libc/.upstream_base_commits @@ -0,0 +1,47 @@ +#freebsd = https://github.com/freebsd/freebsd.git +#openbsd = https://github.com/robertbachmann/openbsd-libc.git +gen/FreeBSD/basename.c freebsd lib/libc/gen/basename.c 26f49abeef12bd43e9671edee6df7b9905c97a47 +gen/FreeBSD/basename.3 freebsd lib/libc/gen/basename.3 26f49abeef12bd43e9671edee6df7b9905c97a47 +gen/FreeBSD/clock.3 freebsd lib/libc/gen/clock.3 5b882020081a138285227631c46a406c08e17bc8 +gen/FreeBSD/ctermid.3 freebsd lib/libc/gen/ctermid.3 5b882020081a138285227631c46a406c08e17bc8 +gen/FreeBSD/getbsize.c freebsd lib/libc/gen/getbsize.c 5b882020081a138285227631c46a406c08e17bc8 +gen/FreeBSD/raise3 freebsd lib/libc/gen/raise.3 6b42c90c1ff5f7c35431eced41b6213401521d3d +gen/FreeBSD/readpassphrase.c freebsd lib/libc/gen/readpassphrase.c 1f19a8fc755a14865a5a5b67d5fa895c4b7cf622 +gen/FreeBSD/readpassphrase.3 freebsd lib/libc/gen/readpassphrase.3 e0a2d4f15ed9e93fcb62544ed65f7a98e2339c3b +gen/FreeBSD/times.3 freebsd lib/libc/gen/times.3 5b882020081a138285227631c46a406c08e17bc8 +gen/FreeBSD/unvis.c freebsd contrib/libc-vis/unvis.c 9e3e4b88576d01efe1f56469cac79e116bb62c67 +gen/FreeBSD/unvis.3 freebsd contrib/libc-vis/unvis.3 9e3e4b88576d01efe1f56469cac79e116bb62c67 +gen/FreeBSD/usleep.3 freebsd lib/libc/gen/usleep.3 5b882020081a138285227631c46a406c08e17bc8 +gen/FreeBSD/vis.c freebsd contrib/libc-vis/unvis.c 9e3e4b88576d01efe1f56469cac79e116bb62c67 +gen/FreeBSD/vis.3 freebsd contrib/libc-vis/unvis.3 9e3e4b88576d01efe1f56469cac79e116bb62c67 +gen/FreeBSD/vis.h freebsd contrib/libc-vis/unvis.3 9e3e4b88576d01efe1f56469cac79e116bb62c67 +gen/fts.c openbsd gen/fts.c 2a32c97c979d267fa99a362943265700bfcac5fd +include/readpassphrase.h freebsd include/readpassphrase.h e0a2d4f15ed9e93fcb62544ed65f7a98e2339c3b +locale/FreeBSD/ascii.c freebsd lib/libc/locale/ascii.c 93e484e00e1e2dc498a7f4c45c0019e43b8ec5b2 +locale/FreeBSD/isspecial.3 freebsd freebsd/lib/libc/locale/isspecial.3 5b882020081a138285227631c46a406c08e17bc8 +locale/FreeBSD/none.c freebsd lib/libc/locale/ascii.c 93e484e00e1e2dc498a7f4c45c0019e43b8ec5b2 +locale/FreeBSD/setlocale.3 freebsd lib/libc/locale/setlocale.3 2131182e401759b74104a541a3b43cf2ee6a7434 +man/FreeBSD/environ.7 freebsd share/man/man7/environ.7 5b882020081a138285227631c46a406c08e17bc8 +net/FreeBSD/linkaddr.c freebsd lib/libc/net/linkaddr.c 9240f72512c0357636b2e19554d6141ee21edc5f +stdio/FreeBSD/mktemp.3 freebsd lib/libc/stdio/mktemp.3 2895e1352cf3788606924d800c3a5c589520ea00 +stdio/FreeBSD/mktemp.c freebsd lib/libc/stdio/mktemp.c 2895e1352cf3788606924d800c3a5c589520ea00 +stdio/FreeBSD/printf.3 freebsd lib/libc/stdio/printf.3 cfc3df2b8f708ce8494d9d556e3472a5c8c21b8a +stdio/FreeBSD/wprintf.3 freebsd lib/libc/stdio/wprintf.3 5b882020081a138285227631c46a406c08e17bc8 +stdlib/FreeBSD/getenv.3 freebsd lib/libc/stdlib/getenv.3 3eb0ea4663f0ae19c4983e80963a121463224508 +stdlib/FreeBSD/getopt_long.3 freebsd lib/libc/stdlib/getopt_long.3 5b882020081a138285227631c46a406c08e17bc8 +stdlib/FreeBSD/reallocf.c freebsd lib/libc/stdlib/reallocf.c 3dc97c4341b6c5a0163c12badc7f50628cecf4e6 +stdtime/FreeBSD/strptime.c freebsd lib/libc/stdtime/strptime.c 52d53d171566c2cd975d2db86a291e516d34d9fe +stdtime/FreeBSD/strptime.3 freebsd lib/libc/stdtime/strptime.3 52d53d171566c2cd975d2db86a291e516d34d9fe +string/FreeBSD/bcmp.3 freebsd lib/libc/string/bcmp.3 408f4a1ab49f89368c80edb4485895658fc81598 +string/FreeBSD/memcmp.3 freebsd lib/libc/string/memcmp.3 3eb0ea4663f0ae19c4983e80963a121463224508 +string/FreeBSD/strcpy.3 freebsd lib/libc/string/strcpy.3 cfc3df2b8f708ce8494d9d556e3472a5c8c21b8a +string/FreeBSD/strpbrk.3 freebsd lib/libc/string/strpbrk.3 5b882020081a138285227631c46a406c08e17bc8 +string/FreeBSD/strspn.3 freebsd lib/libc/string/strspn.3 5b882020081a138285227631c46a406c08e17bc8 +string/FreeBSD/strstr.3 freebsd lib/libc/string/strstr.3 cfc3df2b8f708ce8494d9d556e3472a5c8c21b8a +string/FreeBSD/timingsafe_bcmp.3 freebsd lib/libc/string/timingsafe_bcmp.3 408f4a1ab49f89368c80edb4485895658fc81598 +string/FreeBSD/timingsafe_bcmp.c freebsd lib/libc/string/timingsafe_bcmp.c 408f4a1ab49f89368c80edb4485895658fc81598 +tests/netbsd_getcwd.c freebsd contrib/netbsd-tests/lib/libc/gen/t_getcwd.c 6f5b3c1fa3e9554a26cbf6401366ff8b0f0506fe +tests/netbsd_getenv_thread.c freebsd contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c 3f09b8d0af642c2aeb96a4d667cefb7fe3bce443 +tests/netbsd_stat.c freebsd contrib/netbsd-tests/lib/libc/sys/t_stat.c 6f5b3c1fa3e9554a26cbf6401366ff8b0f0506fe +tests/netbsd_strptime.c freebsd contrib/netbsd-tests/lib/libc/time/t_strptime.c 52d53d171566c2cd975d2db86a291e516d34d9fe +tests/netbsd_vis.c freebsd contrib/netbsd-tests/lib/libc/gen/t_vis.c 52d53d171566c2cd975d2db86a291e516d34d9fe diff --git a/src/libc/CMakeLists.txt b/src/libc/CMakeLists.txt index 989b85879..3d22780f4 100644 --- a/src/libc/CMakeLists.txt +++ b/src/libc/CMakeLists.txt @@ -6,20 +6,11 @@ if(COMMAND cmake_policy) cmake_policy(SET CMP0018 NEW) endif(COMMAND cmake_policy) - -# -DHAVE_STDINT_H=1 -I libc/include -I platform-include/ -I kernel-include/ -I -# libc/locale/ -I libc/locale/FreeBSD/ -I libc/stdtime/FreeBSD -I -# platform-include/pthread/ -I libc/fbsdcompat -I libc/pthreads -nostdinc -# -DTARGET_CPU_X86_64=1 -DTARGET_OS_MAC=1 - add_definitions(-DTARGET_OS_MAC=1) add_definitions(-DHAVE_STDINT_H=1) -add_definitions(-D__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=1080) +add_definitions(-D__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=1090) add_definitions(-D__LIBC__ -D__DARWIN_UNIX03=1 -D__DARWIN_64_BIT_INO_T=1 -D__DARWIN_NON_CANCELABLE=1 -D__DARWIN_VERS_1050=1) -#add_definitions("'-D__weak_reference(sym,alias)=__asm__(\".weak \" \\\#alias );__asm__(\".equ \" \\\#alias \", \" \\\#sym)'") -#add_definitions("'-D__weak_reference(sym,alias)='") add_definitions("'-D__warn_references(name,warning)='") -#add_definitions(-Ddladdr=__darwin_dladdr) add_definitions(-DBUILDING_LIBC -DPRIVATE) # Hide warnings that get spammed @@ -38,8 +29,8 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -O0") # development flags set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib -Wl,-bind_at_load -Wl,-flat_namespace -Wl,-undefined,suppress") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/fbsdcompat") -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/pthreads") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/darwin") +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/derived") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../libmalloc/src") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/locale") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/gen") @@ -48,6 +39,7 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/NetBSD") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/stdtime/FreeBSD") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../external/libdispatch") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../external/libdispatch/private") +include_directories("${CMAKE_SOURCE_DIR}/src/kernel/libsyscall/wrappers") add_subdirectory(db) # produces libc-db add_subdirectory(compat-43) # produces libc-compat @@ -65,39 +57,74 @@ add_subdirectory(stdlib) add_subdirectory(stdio) add_subdirectory(secure) add_subdirectory(regex) -add_subdirectory(pthreads) add_subdirectory(posix1e) add_subdirectory(nls) add_subdirectory(net) add_subdirectory(locale) -add_subdirectory(threads) -add_subdirectory(platform) - -# The following generate libc-hwplat -if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686") - add_subdirectory(i386) - - # Pre-UNIX2003 variants - set(extra_objs - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - ) -endif() - -if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86.64") - add_subdirectory(x86_64) -endif() - add_subdirectory(darwin) +add_subdirectory(i386) +add_subdirectory(x86_64) + +set_property ( + TARGET + libc-stdio_legacy + libc-compat_legacy + libc-stdlib_legacy + libc-stdtime_legacy + libc-gen_legacy + libc-string_legacy + libc-gdtoa_legacy + libc-regex_legacy + libc-locale_legacy + libc-net_legacy + libc-i386 + APPEND_STRING PROPERTY COMPILE_FLAGS + " -arch i386" +) +set_property ( + TARGET + libc-x86_64 + APPEND_STRING PROPERTY COMPILE_FLAGS + " -arch x86_64" +) + +#set_property ( +# TARGET +make_fat( + libc-db + libc-compat + libc-compat_cancelable + libc-emulated + libc-gdtoa + libc-gen + libc-gen_pre1050 + libc-gen_cancelable + libc-gen_noinode64 + libc-gen_extsn + libc-gmon + libc-os + libc-uuid + libc-util + libc-string + libc-stdtime + libc-sys + libc-sys_noinode64 + libc-stdlib + libc-stdlib_extsn + libc-stdlib_cancelable + libc-stdio + libc-stdio_extsn + libc-secure + libc-regex + libc-posix1e + libc-nls + libc-net + libc-net_cancelable + libc-locale +) +# APPEND_STRING PROPERTY COMPILE_FLAGS +# " -arch x86_64 -arch i386" +#) set(DYLIB_INSTALL_NAME "/usr/lib/system/libsystem_c.dylib") add_darling_library(system_c SHARED @@ -111,7 +138,6 @@ add_darling_library(system_c SHARED $ $ $ - $ $ $ $ @@ -127,20 +153,28 @@ add_darling_library(system_c SHARED $ $ $ - $ - $ $ $ $ $ $ - $ - $ + $ + $ $ $ - $ - ${extra_objs}) + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ +) target_link_libraries(system_c system_kernel system_m macho system_malloc) +make_fat(system_c) install(TARGETS system_c DESTINATION libexec/darling/usr/lib/system) @@ -148,12 +182,11 @@ set(CMAKE_AR "${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/ar/x86_64-ap set(CMAKE_RANLIB "${CMAKE_BINARY_DIR}/src/external/cctools-port/cctools/misc/ranlib") add_library(libc_static STATIC $ - $ $ $ $ - $ - $ + $ + $ $ $ $ @@ -161,11 +194,7 @@ add_library(libc_static STATIC $ $ $ - $ - platform/OSAtomic.c) + ) add_dependencies(libc_static ranlib x86_64-apple-darwin11-ar) set_target_properties(libc_static PROPERTIES COMPILE_FLAGS "-ffunction-sections") -# TODO: see ./xcodescripts/variants.xcconfig - -#SET_TARGET_PROPERTIES(system_c PROPERTIES LINKER_LANGUAGE C) diff --git a/src/libc/Libc.xcodeproj/project.pbxproj b/src/libc/Libc.xcodeproj/project.pbxproj index 987a2e088..adda4b87c 100644 --- a/src/libc/Libc.xcodeproj/project.pbxproj +++ b/src/libc/Libc.xcodeproj/project.pbxproj @@ -6,15 +6,60 @@ objectVersion = 46; objects = { +/* Begin PBXAggregateTarget section */ + 925E7FE619E8945900AC7889 /* Libc_tests */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 925E7FF919E8945A00AC7889 /* Build configuration list for PBXAggregateTarget "Libc_tests" */; + buildPhases = ( + ); + dependencies = ( + 928F25D51BEAD2AE007B13C7 /* PBXTargetDependency */, + ); + name = Libc_tests; + productName = Libc_tests; + }; +/* End PBXAggregateTarget section */ + /* Begin PBXBuildFile section */ - 3F2208E814358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; }; - 3F2208E914358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; }; - 3F2208EA14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; }; - 3F2208EB14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; }; - 3F2208EC14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; }; - 3F2208ED14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; }; - 3F2208EE14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; }; - 3F2208EF14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; }; + 147CDFD91B7C232100831EC6 /* clock_gettime.c in Sources */ = {isa = PBXBuildFile; fileRef = 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */; }; + 147CDFDA1B7C232900831EC6 /* clock_gettime.c in Sources */ = {isa = PBXBuildFile; fileRef = 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */; }; + 147CDFDB1B7C232A00831EC6 /* clock_gettime.c in Sources */ = {isa = PBXBuildFile; fileRef = 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */; }; + 147CDFDC1B7C232F00831EC6 /* clock_gettime.c in Sources */ = {isa = PBXBuildFile; fileRef = 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */; }; + 147CDFDD1B7C233000831EC6 /* clock_gettime.c in Sources */ = {isa = PBXBuildFile; fileRef = 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */; }; + 147CDFDE1B7C233100831EC6 /* clock_gettime.c in Sources */ = {isa = PBXBuildFile; fileRef = 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */; }; + 147CDFDF1B7C233100831EC6 /* clock_gettime.c in Sources */ = {isa = PBXBuildFile; fileRef = 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */; }; + 147CDFE01B7C233200831EC6 /* clock_gettime.c in Sources */ = {isa = PBXBuildFile; fileRef = 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */; }; + 147CDFE11B7C233300831EC6 /* clock_gettime.c in Sources */ = {isa = PBXBuildFile; fileRef = 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */; }; + 2DF67CDE184F9CBE00B83A3D /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + 2DF67CDF184F9CBE00B83A3D /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + 2DF67CE0184F9CBE00B83A3D /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + 2DF67CE1184F9CBE00B83A3D /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + 2DF67CE2184F9CBE00B83A3D /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + 2DF67CE3184F9CBE00B83A3D /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + 2DF67CE4184F9CBE00B83A3D /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + 2DF67CE5184F9CBE00B83A3D /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + 2DF67CE6184F9CBE00B83A3D /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + 3F169A3E1643B7BA0029E851 /* memccpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F169A3C1643B7BA0029E851 /* memccpy_chk.c */; }; + 3F18DE21162A732C008B15AC /* memset_s.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F18DE20162A732C008B15AC /* memset_s.c */; }; + 3F267F38163FC8880089A0A6 /* rb.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F267F36163FC8880089A0A6 /* rb.c */; }; + 3F34A15D1C4AA80B000D4A82 /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; + 3F51210416C317FD00AFB431 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; + 3F51210516C317FD00AFB431 /* memccpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F169A3C1643B7BA0029E851 /* memccpy_chk.c */; }; + 3F51210616C317FD00AFB431 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; + 3F51210716C317FD00AFB431 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; + 3F51210816C317FD00AFB431 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; + 3F51210916C317FD00AFB431 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; + 3F51210A16C317FD00AFB431 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; + 3F51210B16C317FD00AFB431 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; + 3F51210C16C317FD00AFB431 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; + 3F51210D16C317FD00AFB431 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; + 3F51210E16C317FD00AFB431 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; + 3F51210F16C317FD00AFB431 /* strlcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3081643AB4300D37078 /* strlcat_chk.c */; }; + 3F51211016C317FD00AFB431 /* strlcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3091643AB4300D37078 /* strlcpy_chk.c */; }; + 3F51211116C317FD00AFB431 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; + 3F51211216C317FD00AFB431 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; + 3F51211316C317FD00AFB431 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; + 3F51211416C317FD00AFB431 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; 3F76864713E91CBC00C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; }; 3F76864913E91CE800C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; }; 3F76864A13E91D3700C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; }; @@ -23,6 +68,8 @@ 3F76864D13E91D5500C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; }; 3F76864E13E91D5D00C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; }; 3F76864F13E91D6700C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; }; + 3FA8F3251643AB8100D37078 /* strlcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3081643AB4300D37078 /* strlcat_chk.c */; }; + 3FA8F3261643AB8100D37078 /* strlcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3091643AB4300D37078 /* strlcpy_chk.c */; }; 3FB7E1B5146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; }; 3FB7E1B6146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; }; 3FB7E1B7146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; }; @@ -30,16 +77,30 @@ 3FB7E1B9146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; }; 3FB7E1BA146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; }; 3FB7E1BB146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; }; + 3FD14574171D42B300B7BAF5 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FD14572171D42B300B7BAF5 /* bcopy.c */; settings = {COMPILER_FLAGS = "-momit-leaf-frame-pointer"; }; }; + 3FD14575171D42B300B7BAF5 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FD14572171D42B300B7BAF5 /* bcopy.c */; settings = {COMPILER_FLAGS = "-momit-leaf-frame-pointer"; }; }; + 3FD14576171D42B300B7BAF5 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FD14572171D42B300B7BAF5 /* bcopy.c */; settings = {COMPILER_FLAGS = "-momit-leaf-frame-pointer"; }; }; 3FD4D48E1472F4B200075CCE /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; }; + 4B2C64A315519BC300342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; + 4B2C64A415519BC400342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; + 4B2C64A515519BC600342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; + 4B2C64A615519BC600342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; + 4B2C64A715519BC700342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; + 4B2C64A815519BC700342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; + 4B2C64A915519BC800342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; + 4B2C64AA15519BCB00342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; + 4B2C64BA1551B03700342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; 6310518713D4D966004F7BA8 /* strcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518613D4D966004F7BA8 /* strcpy.c */; }; 6310518A13D4D9E9004F7BA8 /* strcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518613D4D966004F7BA8 /* strcpy.c */; }; 6310518C13D4DABD004F7BA8 /* strlcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518B13D4DABD004F7BA8 /* strlcpy.c */; }; 6310518D13D4DABD004F7BA8 /* strlcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518B13D4DABD004F7BA8 /* strlcpy.c */; }; 6310518F13D4DAEA004F7BA8 /* strncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518E13D4DAEA004F7BA8 /* strncpy.c */; }; 6310519013D4DAEA004F7BA8 /* strncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518E13D4DAEA004F7BA8 /* strncpy.c */; }; - 634C4C3813BCEADC008CA66D /* memset_pattern_Swift.s in Sources */ = {isa = PBXBuildFile; fileRef = 634C4C3713BCEADC008CA66D /* memset_pattern_Swift.s */; }; - 6358199113B53DD800CDF61C /* bzero_Swift.s in Sources */ = {isa = PBXBuildFile; fileRef = 6358199013B53DD800CDF61C /* bzero_Swift.s */; }; - 6358199313B53ECC00CDF61C /* bcopy_Swift.s in Sources */ = {isa = PBXBuildFile; fileRef = 6358199213B53ECB00CDF61C /* bcopy_Swift.s */; }; + 63505E3B1548525D00B637D7 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 63505E3A1548525D00B637D7 /* strnlen.s */; }; + 63505E3C1548525D00B637D7 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 63505E3A1548525D00B637D7 /* strnlen.s */; }; + 63505E3D1548525D00B637D7 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 63505E3A1548525D00B637D7 /* strnlen.s */; }; + 639D126A15595DDE00D0403A /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 639D126615595DDE00D0403A /* strnlen.s */; }; + 639D126C15595DDE00D0403A /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 639D126615595DDE00D0403A /* strnlen.s */; }; 63D4060613DDEDF10094DD56 /* stpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060513DDEDF10094DD56 /* stpcpy.c */; }; 63D4060813DDEDFF0094DD56 /* stpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060513DDEDF10094DD56 /* stpcpy.c */; }; 63D4060A13DDEEA20094DD56 /* stpncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060913DDEEA10094DD56 /* stpncpy.c */; }; @@ -50,6 +111,16 @@ 63D4061113DDF4340094DD56 /* strncat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060F13DDF4340094DD56 /* strncat.c */; }; 63D4061313DDF6A30094DD56 /* strlcat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4061213DDF6A20094DD56 /* strlcat.c */; }; 63D4061413DDF6A30094DD56 /* strlcat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4061213DDF6A20094DD56 /* strlcat.c */; }; + 928BD1001D76072200EC01FC /* timingsafe_bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */; }; + 928BD1011D76072200EC01FC /* timingsafe_bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */; }; + 928BD1021D76072C00EC01FC /* timingsafe_bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */; }; + 928BD1031D76073300EC01FC /* timingsafe_bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */; }; + 928BD1041D76073400EC01FC /* timingsafe_bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */; }; + 928BD1051D76073400EC01FC /* timingsafe_bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */; }; + 928BD1061D76073500EC01FC /* timingsafe_bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */; }; + 928BD1071D76073600EC01FC /* timingsafe_bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */; }; + 928BD1081D76073600EC01FC /* timingsafe_bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */; }; + 92ABC7E91D375FC2000DF880 /* compatibility_hacks.c in Sources */ = {isa = PBXBuildFile; fileRef = 92ABC7E81D375FC2000DF880 /* compatibility_hacks.c */; }; B10BC41C14338AEB005E4366 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = B122F2B11432B95B00AF95D0 /* regcomp.c */; settings = {COMPILER_FLAGS = "-DHAVE_CONFIG_H -I$(SRCROOT)/regex/TRE -I$(SRCROOT)/regex/FreeBSD"; }; }; B122F2C71432B95B00AF95D0 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = B122F2B11432B95B00AF95D0 /* regcomp.c */; }; B122F2C91432B95B00AF95D0 /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = B122F2B21432B95B00AF95D0 /* regexec.c */; }; @@ -60,6 +131,20 @@ B122F2D31432B95B00AF95D0 /* tre-mem.c in Sources */ = {isa = PBXBuildFile; fileRef = B122F2BB1432B95B00AF95D0 /* tre-mem.c */; }; B122F2D51432B95B00AF95D0 /* tre-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = B122F2BD1432B95B00AF95D0 /* tre-parse.c */; }; B122F2D71432B95B00AF95D0 /* tre-stack.c in Sources */ = {isa = PBXBuildFile; fileRef = B122F2BF1432B95B00AF95D0 /* tre-stack.c */; }; + B12613F8158818EC0077E3CC /* xprintf_errno.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613EE158818EC0077E3CC /* xprintf_errno.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; }; + B12613F9158818EC0077E3CC /* xprintf_float.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613EF158818EC0077E3CC /* xprintf_float.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; }; + B12613FA158818EC0077E3CC /* xprintf_hexdump.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F0158818EC0077E3CC /* xprintf_hexdump.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; }; + B12613FB158818EC0077E3CC /* xprintf_int.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F1158818EC0077E3CC /* xprintf_int.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; }; + B12613FC158818EC0077E3CC /* xprintf_quote.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F3158818EC0077E3CC /* xprintf_quote.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; }; + B12613FD158818EC0077E3CC /* xprintf_str.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F4158818EC0077E3CC /* xprintf_str.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; }; + B12613FE158818EC0077E3CC /* xprintf_time.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F5158818EC0077E3CC /* xprintf_time.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; }; + B12613FF158818EC0077E3CC /* xprintf_vis.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F6158818EC0077E3CC /* xprintf_vis.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; }; + B1261400158818EC0077E3CC /* xprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F7158818EC0077E3CC /* xprintf.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; }; + B126140515881A000077E3CC /* xprintf_comp.c in Sources */ = {isa = PBXBuildFile; fileRef = B126140215881A000077E3CC /* xprintf_comp.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio/FreeBSD"; }; }; + B126140615881A000077E3CC /* xprintf_domain.c in Sources */ = {isa = PBXBuildFile; fileRef = B126140315881A000077E3CC /* xprintf_domain.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio/FreeBSD"; }; }; + B17726CD185A9AD600668DCA /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; + B1795373158B0E35008990E8 /* xprintf_all_in_one.c in Sources */ = {isa = PBXBuildFile; fileRef = B1795371158B0E35008990E8 /* xprintf_all_in_one.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio/FreeBSD"; }; }; + B1795374158B0E35008990E8 /* xprintf_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = B1795372158B0E35008990E8 /* xprintf_exec.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio/FreeBSD"; }; }; B19C645C1450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; }; B19C645D1450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; }; B19C645E1450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; }; @@ -68,9 +153,600 @@ B19C64611450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; }; B19C64621450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; }; B19C64631450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; }; - B1E96442157E722200FCCEE7 /* printf-pos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA3138D9E990028D27C /* printf-pos.c */; }; - B1E9645F157E722200FCCEE7 /* vfprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEA138D9E990028D27C /* vfprintf.c */; }; - B1E96461157E722200FCCEE7 /* vfwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEE138D9E9A0028D27C /* vfwprintf.c */; }; + C0E343921C582ECB00E749C2 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53819138D9E990028D27C /* mcount.s */; }; + C0E343931C582ECB00E749C2 /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383D138D9E990028D27C /* strcpy.s */; }; + C0E343941C582ECB00E749C2 /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383E138D9E990028D27C /* strlcat.s */; }; + C0E343951C582ECB00E749C2 /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383F138D9E990028D27C /* strlcpy.s */; }; + C0E343961C582ECB00E749C2 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53840138D9E990028D27C /* strlen.s */; }; + C0E343971C582ECB00E749C2 /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53842138D9E990028D27C /* strncpy.s */; }; + C0E343981C582ECB00E749C2 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CF138D9E980028D27C /* strlen.s */; }; + C0E343991C582ECB00E749C2 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D2138D9E980028D27C /* strnlen.s */; }; + C0E3439A1C582ECB00E749C2 /* strstr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D3138D9E980028D27C /* strstr.s */; }; + C0E3439B1C582ECB00E749C2 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF9138D9E9A0028D27C /* mcount.s */; }; + C0E3439C1C582ECB00E749C2 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C0E3439D1C582ECB00E749C2 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C0E3439E1C582ECB00E749C2 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C0E3439F1C582ECB00E749C2 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C0E343A01C582ECB00E749C2 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; + C0E343A11C582ECB00E749C2 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; }; + C0E343A21C582ECB00E749C2 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; + C0E343A31C582ECB00E749C2 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; + C0E343A41C582ECB00E749C2 /* killpg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53601138D9E980028D27C /* killpg.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_KILLPG"; }; }; + C0E343A51C582ECB00E749C2 /* sethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53603138D9E980028D27C /* sethostid.c */; }; + C0E343A61C582ECB00E749C2 /* setpgrp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53604138D9E980028D27C /* setpgrp.c */; }; + C0E343A71C582ECB00E749C2 /* setrgid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53606138D9E980028D27C /* setrgid.c */; }; + C0E343A81C582ECB00E749C2 /* setruid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53608138D9E980028D27C /* setruid.c */; }; + C0E343A91C582ECB00E749C2 /* setregid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360A138D9E980028D27C /* setregid.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SETREGID"; }; }; + C0E343AA1C582ECB00E749C2 /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SETREUID"; }; }; + C0E343AB1C582ECB00E749C2 /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; + C0E343AC1C582ECB00E749C2 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; }; + C0E343AD1C582ECB00E749C2 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; + C0E343AE1C582ECB00E749C2 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; + C0E343AF1C582ECB00E749C2 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; }; + C0E343B01C582ECB00E749C2 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; }; + C0E343B11C582ECB00E749C2 /* bt_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53622138D9E980028D27C /* bt_debug.c */; }; + C0E343B21C582ECB00E749C2 /* bt_delete.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53623138D9E980028D27C /* bt_delete.c */; }; + C0E343B31C582ECB00E749C2 /* bt_get.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53624138D9E980028D27C /* bt_get.c */; }; + C0E343B41C582ECB00E749C2 /* bt_open.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53625138D9E980028D27C /* bt_open.c */; }; + C0E343B51C582ECB00E749C2 /* bt_overflow.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53626138D9E980028D27C /* bt_overflow.c */; }; + C0E343B61C582ECB00E749C2 /* bt_page.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53628138D9E980028D27C /* bt_page.c */; }; + C0E343B71C582ECB00E749C2 /* bt_put.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53629138D9E980028D27C /* bt_put.c */; }; + C0E343B81C582ECB00E749C2 /* bt_search.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362A138D9E980028D27C /* bt_search.c */; }; + C0E343B91C582ECB00E749C2 /* bt_seq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362B138D9E980028D27C /* bt_seq.c */; }; + C0E343BA1C582ECB00E749C2 /* bt_split.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362D138D9E980028D27C /* bt_split.c */; }; + C0E343BB1C582ECB00E749C2 /* bt_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362F138D9E980028D27C /* bt_utils.c */; }; + C0E343BC1C582ECB00E749C2 /* db.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53636138D9E980028D27C /* db.c */; }; + C0E343BD1C582ECB00E749C2 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5363B138D9E980028D27C /* hash.c */; }; + C0E343BE1C582ECB00E749C2 /* hash_bigkey.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5363F138D9E980028D27C /* hash_bigkey.c */; }; + C0E343BF1C582ECB00E749C2 /* hash_buf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53641138D9E980028D27C /* hash_buf.c */; }; + C0E343C01C582ECB00E749C2 /* hash_func.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53643138D9E980028D27C /* hash_func.c */; }; + C0E343C11C582ECB00E749C2 /* hash_log2.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53645138D9E980028D27C /* hash_log2.c */; }; + C0E343C21C582ECB00E749C2 /* hash_page.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53647138D9E980028D27C /* hash_page.c */; }; + C0E343C31C582ECB00E749C2 /* ndbm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53649138D9E980028D27C /* ndbm.c */; }; + C0E343C41C582ECB00E749C2 /* mpool.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5365A138D9E980028D27C /* mpool.c */; }; + C0E343C51C582ECB00E749C2 /* rec_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53661138D9E980028D27C /* rec_close.c */; }; + C0E343C61C582ECB00E749C2 /* rec_delete.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53662138D9E980028D27C /* rec_delete.c */; }; + C0E343C71C582ECB00E749C2 /* rec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53663138D9E980028D27C /* rec_get.c */; }; + C0E343C81C582ECB00E749C2 /* rec_open.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53664138D9E980028D27C /* rec_open.c */; }; + C0E343C91C582ECB00E749C2 /* rec_put.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53665138D9E980028D27C /* rec_put.c */; }; + C0E343CA1C582ECB00E749C2 /* rec_search.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53666138D9E980028D27C /* rec_search.c */; }; + C0E343CB1C582ECB00E749C2 /* rec_seq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53667138D9E980028D27C /* rec_seq.c */; }; + C0E343CC1C582ECB00E749C2 /* rec_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53668138D9E980028D27C /* rec_utils.c */; }; + C0E343CD1C582ECB00E749C2 /* brk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5366E138D9E980028D27C /* brk.c */; }; + C0E343CE1C582ECB00E749C2 /* bsd_signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53670138D9E980028D27C /* bsd_signal.c */; }; + C0E343CF1C582ECB00E749C2 /* lchflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53672138D9E980028D27C /* lchflags.c */; }; + C0E343D01C582ECB00E749C2 /* lchmod.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53674138D9E980028D27C /* lchmod.c */; }; + C0E343D11C582ECB00E749C2 /* lutimes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53676138D9E980028D27C /* lutimes.c */; }; + C0E343D21C582ECB00E749C2 /* statvfs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53679138D9E980028D27C /* statvfs.c */; }; + C0E343D31C582ECB00E749C2 /* tcgetsid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5367B138D9E980028D27C /* tcgetsid.c */; }; + C0E343D41C582ECB00E749C2 /* _ldbl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5368E138D9E980028D27C /* _ldbl_util.c */; }; + C0E343D51C582ECB00E749C2 /* _hdtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53691138D9E980028D27C /* _hdtoa.c */; }; + C0E343D61C582ECB00E749C2 /* _ldtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53693138D9E980028D27C /* _ldtoa.c */; }; + C0E343D71C582ECB00E749C2 /* gdtoa-dmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53695138D9E980028D27C /* gdtoa-dmisc.c */; }; + C0E343D81C582ECB00E749C2 /* gdtoa-dtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53696138D9E980028D27C /* gdtoa-dtoa.c */; }; + C0E343D91C582ECB00E749C2 /* gdtoa-gdtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53697138D9E980028D27C /* gdtoa-gdtoa.c */; }; + C0E343DA1C582ECB00E749C2 /* gdtoa-gethex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53698138D9E980028D27C /* gdtoa-gethex.c */; }; + C0E343DB1C582ECB00E749C2 /* gdtoa-gmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369A138D9E980028D27C /* gdtoa-gmisc.c */; }; + C0E343DC1C582ECB00E749C2 /* gdtoa-hd_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369B138D9E980028D27C /* gdtoa-hd_init.c */; }; + C0E343DD1C582ECB00E749C2 /* gdtoa-hexnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369C138D9E980028D27C /* gdtoa-hexnan.c */; }; + C0E343DE1C582ECB00E749C2 /* gdtoa-misc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369E138D9E980028D27C /* gdtoa-misc.c */; }; + C0E343DF1C582ECB00E749C2 /* gdtoa-smisc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A0138D9E980028D27C /* gdtoa-smisc.c */; }; + C0E343E01C582ECB00E749C2 /* gdtoa-strtod.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A1138D9E980028D27C /* gdtoa-strtod.c */; }; + C0E343E11C582ECB00E749C2 /* gdtoa-strtodg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A3138D9E980028D27C /* gdtoa-strtodg.c */; }; + C0E343E21C582ECB00E749C2 /* gdtoa-strtof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A5138D9E980028D27C /* gdtoa-strtof.c */; }; + C0E343E31C582ECB00E749C2 /* gdtoa-strtoIg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A7138D9E980028D27C /* gdtoa-strtoIg.c */; }; + C0E343E41C582ECB00E749C2 /* gdtoa-strtopdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A8138D9E980028D27C /* gdtoa-strtopdd.c */; }; + C0E343E51C582ECB00E749C2 /* gdtoa-strtopx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AA138D9E980028D27C /* gdtoa-strtopx.c */; }; + C0E343E61C582ECB00E749C2 /* gdtoa-strtord.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AC138D9E980028D27C /* gdtoa-strtord.c */; }; + C0E343E71C582ECB00E749C2 /* gdtoa-sum.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AE138D9E980028D27C /* gdtoa-sum.c */; }; + C0E343E81C582ECB00E749C2 /* gdtoa-ulp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AF138D9E980028D27C /* gdtoa-ulp.c */; }; + C0E343E91C582ECB00E749C2 /* glue.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B5138D9E980028D27C /* glue.c */; }; + C0E343EA1C582ECB00E749C2 /* machdep_ldisd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B6138D9E980028D27C /* machdep_ldisd.c */; }; + C0E343EB1C582ECB00E749C2 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; }; + C0E343EC1C582ECB00E749C2 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; + C0E343ED1C582ECB00E749C2 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; + C0E343EE1C582ECB00E749C2 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; }; + C0E343EF1C582ECB00E749C2 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; + C0E343F01C582ECB00E749C2 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_CONFSTR"; }; }; + C0E343F11C582ECB00E749C2 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY"; }; }; + C0E343F21C582ECB00E749C2 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; + C0E343F31C582ECB00E749C2 /* disklabel.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E1138D9E990028D27C /* disklabel.c */; }; + C0E343F41C582ECB00E749C2 /* errlst.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E2138D9E990028D27C /* errlst.c */; }; + C0E343F51C582ECB00E749C2 /* filesec.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E4138D9E990028D27C /* filesec.c */; }; + C0E343F61C582ECB00E749C2 /* _rand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E6138D9E990028D27C /* _rand48.c */; }; + C0E343F71C582ECB00E749C2 /* alarm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536EA138D9E990028D27C /* alarm.c */; }; + C0E343F81C582ECB00E749C2 /* arc4random.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536EC138D9E990028D27C /* arc4random.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E343F91C582ECB00E749C2 /* assert.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536EE138D9E990028D27C /* assert.c */; }; + C0E343FA1C582ECB00E749C2 /* basename.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536F2138D9E990028D27C /* basename.c */; }; + C0E343FB1C582ECB00E749C2 /* clock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536F5138D9E990028D27C /* clock.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CLOCK"; }; }; + C0E343FC1C582ECB00E749C2 /* closedir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536F6138D9E990028D27C /* closedir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CLOSEDIR -include gen/__dirent.h"; }; }; + C0E343FD1C582ECB00E749C2 /* ctermid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536FA138D9E990028D27C /* ctermid.c */; }; + C0E343FE1C582ECB00E749C2 /* daemon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536FD138D9E990028D27C /* daemon.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E343FF1C582ECB00E749C2 /* dirname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53701138D9E990028D27C /* dirname.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E344001C582ECB00E749C2 /* drand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53703138D9E990028D27C /* drand48.c */; }; + C0E344011C582ECB00E749C2 /* erand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53705138D9E990028D27C /* erand48.c */; }; + C0E344021C582ECB00E749C2 /* err.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53709138D9E990028D27C /* err.c */; }; + C0E344031C582ECB00E749C2 /* exec.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5370D138D9E990028D27C /* exec.c */; }; + C0E344041C582ECB00E749C2 /* fmtcheck.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53710138D9E990028D27C /* fmtcheck.c */; }; + C0E344051C582ECB00E749C2 /* fmtmsg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53712138D9E990028D27C /* fmtmsg.c */; }; + C0E344061C582ECB00E749C2 /* fnmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53716138D9E990028D27C /* fnmatch.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FNMATCH"; }; }; + C0E344071C582ECB00E749C2 /* ftok.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5371A138D9E990028D27C /* ftok.c */; }; + C0E344081C582ECB00E749C2 /* getbsize.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5371C138D9E990028D27C /* getbsize.c */; }; + C0E344091C582ECB00E749C2 /* getcap.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5371E138D9E990028D27C /* getcap.c */; }; + C0E3440A1C582ECB00E749C2 /* getcwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53722138D9E990028D27C /* getcwd.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E3440B1C582ECB00E749C2 /* gethostname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53726138D9E990028D27C /* gethostname.c */; }; + C0E3440C1C582ECB00E749C2 /* getlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53728138D9E990028D27C /* getlogin.c */; }; + C0E3440D1C582ECB00E749C2 /* getmntinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5372C138D9E990028D27C /* getmntinfo.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E3440E1C582ECB00E749C2 /* getpagesize.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5372F138D9E990028D27C /* getpagesize.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E3440F1C582ECB00E749C2 /* getpeereid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53732138D9E990028D27C /* getpeereid.c */; }; + C0E344101C582ECB00E749C2 /* getprogname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53735138D9E990028D27C /* getprogname.c */; }; + C0E344111C582ECB00E749C2 /* glob.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53739138D9E990028D27C /* glob.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_GLOB"; }; }; + C0E344121C582ECB00E749C2 /* isatty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5373B138D9E990028D27C /* isatty.c */; }; + C0E344131C582ECB00E749C2 /* jrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5373D138D9E990028D27C /* jrand48.c */; }; + C0E344141C582ECB00E749C2 /* lcong48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5373F138D9E990028D27C /* lcong48.c */; }; + C0E344151C582ECB00E749C2 /* lockf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53743138D9E990028D27C /* lockf.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_LOCKF"; }; }; + C0E344161C582ECB00E749C2 /* lrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53745138D9E990028D27C /* lrand48.c */; }; + C0E344171C582ECB00E749C2 /* mrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53749138D9E990028D27C /* mrand48.c */; }; + C0E344181C582ECB00E749C2 /* nice.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374C138D9E990028D27C /* nice.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_NICE"; }; }; + C0E344191C582ECB00E749C2 /* nrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374E138D9E990028D27C /* nrand48.c */; }; + C0E3441A1C582ECB00E749C2 /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS___OPENDIR2 -DLIBC_ALIAS_OPENDIR -include gen/__dirent.h"; }; }; + C0E3441B1C582ECB00E749C2 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; }; + C0E3441C1C582ECB00E749C2 /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; }; + C0E3441D1C582ECB00E749C2 /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; + C0E3441E1C582ECB00E749C2 /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; + C0E3441F1C582ECB00E749C2 /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; + C0E344201C582ECB00E749C2 /* readpassphrase.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53769138D9E990028D27C /* readpassphrase.c */; }; + C0E344211C582ECB00E749C2 /* rewinddir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5376B138D9E990028D27C /* rewinddir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_REWINDDIR -include gen/__dirent.h"; }; }; + C0E344221C582ECB00E749C2 /* scandir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5376E138D9E990028D27C /* scandir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; + C0E344231C582ECB00E749C2 /* seed48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53771138D9E990028D27C /* seed48.c */; }; + C0E344241C582ECB00E749C2 /* seekdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53773138D9E990028D27C /* seekdir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SEEKDIR -include gen/__dirent.h"; }; }; + C0E344251C582ECB00E749C2 /* sethostname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53774138D9E990028D27C /* sethostname.c */; }; + C0E344261C582ECB00E749C2 /* setmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53776138D9E990028D27C /* setmode.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SETMODE"; }; }; + C0E344271C582ECB00E749C2 /* setprogname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53778138D9E990028D27C /* setprogname.c */; }; + C0E344281C582ECB00E749C2 /* siginterrupt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377C138D9E990028D27C /* siginterrupt.c */; }; + C0E344291C582ECB00E749C2 /* siglist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377D138D9E990028D27C /* siglist.c */; }; + C0E3442A1C582ECB00E749C2 /* signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53781138D9E990028D27C /* signal.c */; }; + C0E3442B1C582ECB00E749C2 /* sleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53787138D9E990028D27C /* sleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SLEEP"; }; }; + C0E3442C1C582ECB00E749C2 /* srand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53789138D9E990028D27C /* srand48.c */; }; + C0E3442D1C582ECB00E749C2 /* stringlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378C138D9E990028D27C /* stringlist.c */; }; + C0E3442E1C582ECB00E749C2 /* sysconf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378E138D9E990028D27C /* sysconf.c */; }; + C0E3442F1C582ECB00E749C2 /* sysctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53792138D9E990028D27C /* sysctl.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E344301C582ECB00E749C2 /* sysctlbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53794138D9E990028D27C /* sysctlbyname.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E344311C582ECB00E749C2 /* sysctlnametomib.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53795138D9E990028D27C /* sysctlnametomib.c */; }; + C0E344321C582ECB00E749C2 /* telldir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53796138D9E990028D27C /* telldir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS__SEEKDIR -DLIBC_ALIAS_TELLDIR -include gen/__dirent.h"; }; }; + C0E344331C582ECB00E749C2 /* termios.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5379A138D9E990028D27C /* termios.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TCDRAIN"; }; }; + C0E344341C582ECB00E749C2 /* time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5379E138D9E990028D27C /* time.c */; }; + C0E344351C582ECB00E749C2 /* times.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A2138D9E990028D27C /* times.c */; }; + C0E344361C582ECB00E749C2 /* timezone.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A4138D9E990028D27C /* timezone.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E344371C582ECB00E749C2 /* ttyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A7138D9E990028D27C /* ttyname.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TTYNAME_R"; }; }; + C0E344381C582ECB00E749C2 /* ttyslot.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A9138D9E990028D27C /* ttyslot.c */; }; + C0E344391C582ECB00E749C2 /* ualarm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537AC138D9E990028D27C /* ualarm.c */; }; + C0E3443A1C582ECB00E749C2 /* ulimit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B0138D9E990028D27C /* ulimit.c */; }; + C0E3443B1C582ECB00E749C2 /* unvis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B2138D9E990028D27C /* unvis.c */; }; + C0E3443C1C582ECB00E749C2 /* usleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B6138D9E990028D27C /* usleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_USLEEP"; }; }; + C0E3443D1C582ECB00E749C2 /* utime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BA138D9E990028D27C /* utime.c */; }; + C0E3443E1C582ECB00E749C2 /* vis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BC138D9E990028D27C /* vis.c */; }; + C0E3443F1C582ECB00E749C2 /* wait.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BE138D9E990028D27C /* wait.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAIT"; }; }; + C0E344401C582ECB00E749C2 /* wait3.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C0138D9E990028D27C /* wait3.c */; }; + C0E344411C582ECB00E749C2 /* waitpid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C1138D9E990028D27C /* waitpid.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAITPID"; }; }; + C0E344421C582ECB00E749C2 /* fts.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C4138D9E990028D27C /* fts.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTS_CHILDREN -DLIBC_ALIAS_FTS_CLOSE -DLIBC_ALIAS_FTS_OPEN -DLIBC_ALIAS_FTS_OPEN_B -DLIBC_ALIAS_FTS_READ -DLIBC_ALIAS_FTS_SET"; }; }; + C0E344431C582ECB00E749C2 /* get_compat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C6138D9E990028D27C /* get_compat.c */; }; + C0E344441C582ECB00E749C2 /* getloadavg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CA138D9E990028D27C /* getloadavg.c */; }; + C0E344451C582ECB00E749C2 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; + C0E344461C582ECB00E749C2 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; + C0E344471C582ECB00E749C2 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; + C0E344481C582ECB00E749C2 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; }; + C0E344491C582ECB00E749C2 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; + C0E3444A1C582ECB00E749C2 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW"; }; }; + C0E3444B1C582ECB00E749C2 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; + C0E3444C1C582ECB00E749C2 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; }; + C0E3444D1C582ECB00E749C2 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; + C0E3444E1C582ECB00E749C2 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; + C0E3444F1C582ECB00E749C2 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; + C0E344501C582ECB00E749C2 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; + C0E344511C582ECB00E749C2 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; + C0E344521C582ECB00E749C2 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; + C0E344531C582ECB00E749C2 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; + C0E344541C582ECB00E749C2 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; + C0E344551C582ECB00E749C2 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; }; + C0E344561C582ECB00E749C2 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; }; + C0E344571C582ECB00E749C2 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; }; + C0E344581C582ECB00E749C2 /* collate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5390B138D9E990028D27C /* collate.c */; }; + C0E344591C582ECB00E749C2 /* collcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5390F138D9E990028D27C /* collcmp.c */; }; + C0E3445A1C582ECB00E749C2 /* euc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53916138D9E990028D27C /* euc.c */; }; + C0E3445B1C582ECB00E749C2 /* fix_grouping.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53918138D9E990028D27C /* fix_grouping.c */; }; + C0E3445C1C582ECB00E749C2 /* gb18030.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5391B138D9E990028D27C /* gb18030.c */; }; + C0E3445D1C582ECB00E749C2 /* gb2312.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5391E138D9E990028D27C /* gb2312.c */; }; + C0E3445E1C582ECB00E749C2 /* gbk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53921138D9E990028D27C /* gbk.c */; }; + C0E3445F1C582ECB00E749C2 /* ldpart.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53946138D9E990028D27C /* ldpart.c */; }; + C0E344601C582ECB00E749C2 /* lmessages.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5394A138D9E990028D27C /* lmessages.c */; }; + C0E344611C582ECB00E749C2 /* lmonetary.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5394E138D9E990028D27C /* lmonetary.c */; }; + C0E344621C582ECB00E749C2 /* lnumeric.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53952138D9E990028D27C /* lnumeric.c */; }; + C0E344631C582ECB00E749C2 /* localeconv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53958138D9E990028D27C /* localeconv.c */; }; + C0E344641C582ECB00E749C2 /* mblen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5395C138D9E990028D27C /* mblen.c */; }; + C0E344651C582ECB00E749C2 /* mbrlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53962138D9E990028D27C /* mbrlen.c */; }; + C0E344661C582ECB00E749C2 /* mbrtowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53966138D9E990028D27C /* mbrtowc.c */; }; + C0E344671C582ECB00E749C2 /* mbsinit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5396A138D9E990028D27C /* mbsinit.c */; }; + C0E344681C582ECB00E749C2 /* mbsnrtowcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5396C138D9E990028D27C /* mbsnrtowcs.c */; }; + C0E344691C582ECB00E749C2 /* mbsrtowcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53970138D9E990028D27C /* mbsrtowcs.c */; }; + C0E3446A1C582ECB00E749C2 /* mbstowcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53974138D9E990028D27C /* mbstowcs.c */; }; + C0E3446B1C582ECB00E749C2 /* mbtowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53978138D9E990028D27C /* mbtowc.c */; }; + C0E3446C1C582ECB00E749C2 /* mskanji.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5397B138D9E990028D27C /* mskanji.c */; }; + C0E3446D1C582ECB00E749C2 /* nextwctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53980138D9E990028D27C /* nextwctype.c */; }; + C0E3446E1C582ECB00E749C2 /* nl_langinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53984138D9E990028D27C /* nl_langinfo.c */; }; + C0E3446F1C582ECB00E749C2 /* nomacros.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53986138D9E990028D27C /* nomacros.c */; }; + C0E344701C582ECB00E749C2 /* none.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53987138D9E990028D27C /* none.c */; }; + C0E344711C582ECB00E749C2 /* rune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53989138D9E990028D27C /* rune.c */; }; + C0E344721C582ECB00E749C2 /* runetype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5398B138D9E990028D27C /* runetype.c */; }; + C0E344731C582ECB00E749C2 /* setlocale.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5398F138D9E990028D27C /* setlocale.c */; }; + C0E344741C582ECB00E749C2 /* debug_private.c in Sources */ = {isa = PBXBuildFile; fileRef = 2DF67CDD184F9CBE00B83A3D /* debug_private.c */; }; + C0E344751C582ECB00E749C2 /* setrunelocale.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53993138D9E990028D27C /* setrunelocale.c */; }; + C0E344761C582ECB00E749C2 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53995138D9E990028D27C /* table.c */; }; + C0E344771C582ECB00E749C2 /* tolower.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5399A138D9E990028D27C /* tolower.c */; }; + C0E344781C582ECB00E749C2 /* toupper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5399E138D9E990028D27C /* toupper.c */; }; + C0E344791C582ECB00E749C2 /* utf2.c in Sources */ = {isa = PBXBuildFile; fileRef = C9FA32F8138E4A5C0089A94B /* utf2.c */; }; + C0E3447A1C582ECB00E749C2 /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539A6138D9E990028D27C /* utf8.c */; }; + C0E3447B1C582ECB00E749C2 /* wcrtomb.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539AA138D9E990028D27C /* wcrtomb.c */; }; + C0E3447C1C582ECB00E749C2 /* wcsftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539AE138D9E990028D27C /* wcsftime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WCSFTIME -DLIBC_ALIAS_WCSFTIME_L"; }; }; + C0E3447D1C582ECB00E749C2 /* wcsnrtombs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539B0138D9E990028D27C /* wcsnrtombs.c */; }; + C0E3447E1C582ECB00E749C2 /* wcsrtombs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539B4138D9E990028D27C /* wcsrtombs.c */; }; + C0E3447F1C582ECB00E749C2 /* wcstod.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539B8138D9E990028D27C /* wcstod.c */; }; + C0E344801C582ECB00E749C2 /* wcstof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539BA138D9E990028D27C /* wcstof.c */; }; + C0E344811C582ECB00E749C2 /* wcstoimax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539BC138D9E990028D27C /* wcstoimax.c */; }; + C0E344821C582ECB00E749C2 /* wcstol.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C0138D9E990028D27C /* wcstol.c */; }; + C0E344831C582ECB00E749C2 /* wcstold.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C2138D9E990028D27C /* wcstold.c */; }; + C0E344841C582ECB00E749C2 /* wcstoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C4138D9E990028D27C /* wcstoll.c */; }; + C0E344851C582ECB00E749C2 /* wcstombs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C8138D9E990028D27C /* wcstombs.c */; }; + C0E344861C582ECB00E749C2 /* wcstoul.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539CA138D9E990028D27C /* wcstoul.c */; }; + C0E344871C582ECB00E749C2 /* wcstoull.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539CC138D9E990028D27C /* wcstoull.c */; }; + C0E344881C582ECB00E749C2 /* wcstoumax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539CE138D9E990028D27C /* wcstoumax.c */; }; + C0E344891C582ECB00E749C2 /* wctob.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539D0138D9E990028D27C /* wctob.c */; }; + C0E3448A1C582ECB00E749C2 /* wctomb.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539D4138D9E990028D27C /* wctomb.c */; }; + C0E3448B1C582ECB00E749C2 /* wctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539D8138D9E990028D27C /* wctrans.c */; }; + C0E3448C1C582ECB00E749C2 /* wctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539DC138D9E990028D27C /* wctype.c */; }; + C0E3448D1C582ECB00E749C2 /* wcwidth.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E0138D9E990028D27C /* wcwidth.c */; }; + C0E3448E1C582ECB00E749C2 /* frune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E3138D9E990028D27C /* frune.c */; }; + C0E3448F1C582ECB00E749C2 /* isctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E5138D9E990028D27C /* isctype.c */; }; + C0E344901C582ECB00E749C2 /* iswctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E7138D9E990028D27C /* iswctype.c */; }; + C0E344911C582ECB00E749C2 /* lconv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E8138D9E990028D27C /* lconv.c */; }; + C0E344921C582ECB00E749C2 /* mbrune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EB138D9E990028D27C /* mbrune.c */; }; + C0E344931C582ECB00E749C2 /* runedepreciated.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EF138D9E990028D27C /* runedepreciated.c */; }; + C0E344941C582ECB00E749C2 /* setinvalidrune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539F1138D9E990028D27C /* setinvalidrune.c */; }; + C0E344951C582ECB00E749C2 /* xlocale.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539F7138D9E990028D27C /* xlocale.c */; }; + C0E344961C582ECB00E749C2 /* addr2ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A16138D9E990028D27C /* addr2ascii.c */; }; + C0E344971C582ECB00E749C2 /* ascii2addr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A17138D9E990028D27C /* ascii2addr.c */; }; + C0E344981C582ECB00E749C2 /* inet_addr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A1A138D9E990028D27C /* inet_addr.c */; }; + C0E344991C582ECB00E749C2 /* inet_lnaof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A1C138D9E990028D27C /* inet_lnaof.c */; }; + C0E3449A1C582ECB00E749C2 /* inet_makeaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A1D138D9E990028D27C /* inet_makeaddr.c */; }; + C0E3449B1C582ECB00E749C2 /* inet_net_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A20138D9E990028D27C /* inet_net_ntop.c */; }; + C0E3449C1C582ECB00E749C2 /* inet_net_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A21138D9E990028D27C /* inet_net_pton.c */; }; + C0E3449D1C582ECB00E749C2 /* inet_neta.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A23138D9E990028D27C /* inet_neta.c */; }; + C0E3449E1C582ECB00E749C2 /* inet_netof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A24138D9E990028D27C /* inet_netof.c */; }; + C0E3449F1C582ECB00E749C2 /* inet_network.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A25138D9E990028D27C /* inet_network.c */; }; + C0E344A01C582ECB00E749C2 /* inet_ntoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A27138D9E990028D27C /* inet_ntoa.c */; }; + C0E344A11C582ECB00E749C2 /* linkaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2A138D9E990028D27C /* linkaddr.c */; }; + C0E344A21C582ECB00E749C2 /* nsap_addr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2B138D9E990028D27C /* nsap_addr.c */; }; + C0E344A31C582ECB00E749C2 /* recv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2D138D9E990028D27C /* recv.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_RECV"; }; }; + C0E344A41C582ECB00E749C2 /* send.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2F138D9E990028D27C /* send.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SEND"; }; }; + C0E344A51C582ECB00E749C2 /* sockatmark.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A33138D9E990028D27C /* sockatmark.c */; }; + C0E344A61C582ECB00E749C2 /* sourcefilter.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A36138D9E990028D27C /* sourcefilter.c */; }; + C0E344A71C582ECB00E749C2 /* msgcat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A3F138D9E990028D27C /* msgcat.c */; }; + C0E344A81C582ECB00E749C2 /* acl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A4C138D9E990028D27C /* acl.c */; }; + C0E344A91C582ECB00E749C2 /* acl_entry.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A59138D9E990028D27C /* acl_entry.c */; }; + C0E344AA1C582ECB00E749C2 /* acl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5A138D9E990028D27C /* acl_file.c */; }; + C0E344AB1C582ECB00E749C2 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; + C0E344AC1C582ECB00E749C2 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; + C0E344AD1C582ECB00E749C2 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; + C0E344AE1C582ECB00E749C2 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; + C0E344AF1C582ECB00E749C2 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; + C0E344B01C582ECB00E749C2 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; + C0E344B11C582ECB00E749C2 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; + C0E344B21C582ECB00E749C2 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; + C0E344B31C582ECB00E749C2 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; + C0E344B41C582ECB00E749C2 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; + C0E344B51C582ECB00E749C2 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; + C0E344B61C582ECB00E749C2 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; + C0E344B71C582ECB00E749C2 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; + C0E344B81C582ECB00E749C2 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; + C0E344B91C582ECB00E749C2 /* strlcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3081643AB4300D37078 /* strlcat_chk.c */; }; + C0E344BA1C582ECB00E749C2 /* strlcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3091643AB4300D37078 /* strlcpy_chk.c */; }; + C0E344BB1C582ECB00E749C2 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; + C0E344BC1C582ECB00E749C2 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; + C0E344BD1C582ECB00E749C2 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; + C0E344BE1C582ECB00E749C2 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; + C0E344BF1C582ECB00E749C2 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; }; + C0E344C01C582ECB00E749C2 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; }; + C0E344C11C582ECB00E749C2 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; }; + C0E344C21C582ECB00E749C2 /* dprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B33138D9E990028D27C /* dprintf.c */; }; + C0E344C31C582ECB00E749C2 /* fclose.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B36138D9E990028D27C /* fclose.c */; }; + C0E344C41C582ECB00E749C2 /* fdopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B38138D9E990028D27C /* fdopen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FDOPEN"; }; }; + C0E344C51C582ECB00E749C2 /* feof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B3A138D9E990028D27C /* feof.c */; }; + C0E344C61C582ECB00E749C2 /* ferror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B3C138D9E990028D27C /* ferror.c */; }; + C0E344C71C582ECB00E749C2 /* fflush.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B3E138D9E990028D27C /* fflush.c */; }; + C0E344C81C582ECB00E749C2 /* fgetc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B40138D9E990028D27C /* fgetc.c */; }; + C0E344C91C582ECB00E749C2 /* fgetln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B43138D9E990028D27C /* fgetln.c */; }; + C0E344CA1C582ECB00E749C2 /* fgetpos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B45138D9E990028D27C /* fgetpos.c */; }; + C0E344CB1C582ECB00E749C2 /* fgets.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B47138D9E990028D27C /* fgets.c */; }; + C0E344CC1C582ECB00E749C2 /* fgetwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B48138D9E990028D27C /* fgetwc.c */; }; + C0E344CD1C582ECB00E749C2 /* fgetwln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B4C138D9E990028D27C /* fgetwln.c */; }; + C0E344CE1C582ECB00E749C2 /* fgetws.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B50138D9E990028D27C /* fgetws.c */; }; + C0E344CF1C582ECB00E749C2 /* fileno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B52138D9E990028D27C /* fileno.c */; }; + C0E344D01C582ECB00E749C2 /* findfp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B53138D9E990028D27C /* findfp.c */; }; + C0E344D11C582ECB00E749C2 /* flags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B55138D9E990028D27C /* flags.c */; }; + C0E344D21C582ECB00E749C2 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FD14572171D42B300B7BAF5 /* bcopy.c */; settings = {COMPILER_FLAGS = "-momit-leaf-frame-pointer"; }; }; + C0E344D31C582ECB00E749C2 /* fopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B5C138D9E990028D27C /* fopen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FOPEN"; }; }; + C0E344D41C582ECB00E749C2 /* fprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B5E138D9E990028D27C /* fprintf.c */; }; + C0E344D51C582ECB00E749C2 /* fpurge.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B60138D9E990028D27C /* fpurge.c */; }; + C0E344D61C582ECB00E749C2 /* fputc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B61138D9E990028D27C /* fputc.c */; }; + C0E344D71C582ECB00E749C2 /* fputs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B64138D9E990028D27C /* fputs.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FPUTS"; }; }; + C0E344D81C582ECB00E749C2 /* fputwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B66138D9E990028D27C /* fputwc.c */; }; + C0E344D91C582ECB00E749C2 /* fputws.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B6A138D9E990028D27C /* fputws.c */; }; + C0E344DA1C582ECB00E749C2 /* fread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B6E138D9E990028D27C /* fread.c */; }; + C0E344DB1C582ECB00E749C2 /* freopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B70138D9E990028D27C /* freopen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FREOPEN"; }; }; + C0E344DC1C582ECB00E749C2 /* fscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B72138D9E990028D27C /* fscanf.c */; }; + C0E344DD1C582ECB00E749C2 /* fseek.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B76138D9E990028D27C /* fseek.c */; }; + C0E344DE1C582ECB00E749C2 /* fsetpos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B77138D9E990028D27C /* fsetpos.c */; }; + C0E344DF1C582ECB00E749C2 /* ftell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B78138D9E990028D27C /* ftell.c */; }; + C0E344E01C582ECB00E749C2 /* funopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B7B138D9E990028D27C /* funopen.c */; }; + C0E344E11C582ECB00E749C2 /* fvwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B7D138D9E990028D27C /* fvwrite.c */; }; + C0E344E21C582ECB00E749C2 /* fwalk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B7F138D9E990028D27C /* fwalk.c */; }; + C0E344E31C582ECB00E749C2 /* fwide.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B82138D9E990028D27C /* fwide.c */; }; + C0E344E41C582ECB00E749C2 /* fwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B83138D9E990028D27C /* fwprintf.c */; }; + C0E344E51C582ECB00E749C2 /* fwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B85138D9E990028D27C /* fwrite.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FWRITE"; }; }; + C0E344E61C582ECB00E749C2 /* fwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B87138D9E990028D27C /* fwscanf.c */; }; + C0E344E71C582ECB00E749C2 /* getc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B8B138D9E990028D27C /* getc.c */; }; + C0E344E81C582ECB00E749C2 /* getchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B8C138D9E990028D27C /* getchar.c */; }; + C0E344E91C582ECB00E749C2 /* getdelim.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B8D138D9E990028D27C /* getdelim.c */; }; + C0E344EA1C582ECB00E749C2 /* getline.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B90138D9E990028D27C /* getline.c */; }; + C0E344EB1C582ECB00E749C2 /* gets.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B91138D9E990028D27C /* gets.c */; }; + C0E344EC1C582ECB00E749C2 /* getw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B92138D9E990028D27C /* getw.c */; }; + C0E344ED1C582ECB00E749C2 /* getwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B95138D9E990028D27C /* getwc.c */; }; + C0E344EE1C582ECB00E749C2 /* getwchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B97138D9E990028D27C /* getwchar.c */; }; + C0E344EF1C582ECB00E749C2 /* makebuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B9C138D9E990028D27C /* makebuf.c */; }; + C0E344F01C582ECB00E749C2 /* mktemp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA0138D9E990028D27C /* mktemp.c */; }; + C0E344F11C582ECB00E749C2 /* perror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA2138D9E990028D27C /* perror.c */; }; + C0E344F21C582ECB00E749C2 /* printf-pos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA3138D9E990028D27C /* printf-pos.c */; }; + C0E344F31C582ECB00E749C2 /* printf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA7138D9E990028D27C /* printf.c */; }; + C0E344F41C582ECB00E749C2 /* putc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BAF138D9E990028D27C /* putc.c */; }; + C0E344F51C582ECB00E749C2 /* putchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB0138D9E990028D27C /* putchar.c */; }; + C0E344F61C582ECB00E749C2 /* puts.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB1138D9E990028D27C /* puts.c */; }; + C0E344F71C582ECB00E749C2 /* putw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB3138D9E990028D27C /* putw.c */; }; + C0E344F81C582ECB00E749C2 /* putwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB6138D9E990028D27C /* putwc.c */; }; + C0E344F91C582ECB00E749C2 /* putwchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB8138D9E990028D27C /* putwchar.c */; }; + C0E344FA1C582ECB00E749C2 /* refill.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BBA138D9E990028D27C /* refill.c */; }; + C0E344FB1C582ECB00E749C2 /* remove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BBE138D9E990028D27C /* remove.c */; }; + C0E344FC1C582ECB00E749C2 /* rewind.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BBF138D9E990028D27C /* rewind.c */; }; + C0E344FD1C582ECB00E749C2 /* rget.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC1138D9E990028D27C /* rget.c */; }; + C0E344FE1C582ECB00E749C2 /* scanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC4138D9E990028D27C /* scanf.c */; }; + C0E344FF1C582ECB00E749C2 /* setbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC8138D9E990028D27C /* setbuf.c */; }; + C0E345001C582ECB00E749C2 /* setbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC9138D9E990028D27C /* setbuffer.c */; }; + C0E345011C582ECB00E749C2 /* setvbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCA138D9E990028D27C /* setvbuf.c */; }; + C0E345021C582ECB00E749C2 /* snprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCB138D9E990028D27C /* snprintf.c */; }; + C0E345031C582ECB00E749C2 /* sprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCD138D9E990028D27C /* sprintf.c */; }; + C0E345041C582ECB00E749C2 /* sscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCF138D9E990028D27C /* sscanf.c */; }; + C0E345051C582ECB00E749C2 /* stdio.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD3138D9E990028D27C /* stdio.c */; }; + C0E345061C582ECB00E749C2 /* swprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD4138D9E990028D27C /* swprintf.c */; }; + C0E345071C582ECB00E749C2 /* swscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD6138D9E990028D27C /* swscanf.c */; }; + C0E345081C582ECB00E749C2 /* tempnam.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD8138D9E990028D27C /* tempnam.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TEMPNAM"; }; }; + C0E345091C582ECB00E749C2 /* tmpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BDA138D9E990028D27C /* tmpfile.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -D_DARWIN_UNLIMITED_STREAMS"; }; }; + C0E3450A1C582ECB00E749C2 /* tmpnam.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BDD138D9E990028D27C /* tmpnam.c */; }; + C0E3450B1C582ECB00E749C2 /* ungetc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE1138D9E990028D27C /* ungetc.c */; }; + C0E3450C1C582ECB00E749C2 /* ungetwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE4138D9E990028D27C /* ungetwc.c */; }; + C0E3450D1C582ECB00E749C2 /* vasprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE6138D9E990028D27C /* vasprintf.c */; }; + C0E3450E1C582ECB00E749C2 /* vdprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE8138D9E990028D27C /* vdprintf.c */; }; + C0E3450F1C582ECB00E749C2 /* vfprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEA138D9E990028D27C /* vfprintf.c */; }; + C0E345101C582ECB00E749C2 /* vfscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEC138D9E990028D27C /* vfscanf.c */; }; + C0E345111C582ECB00E749C2 /* vfwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEE138D9E9A0028D27C /* vfwprintf.c */; }; + C0E345121C582ECB00E749C2 /* vfwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF0138D9E9A0028D27C /* vfwscanf.c */; }; + C0E345131C582ECB00E749C2 /* vprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF2138D9E9A0028D27C /* vprintf.c */; }; + C0E345141C582ECB00E749C2 /* vscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF4138D9E9A0028D27C /* vscanf.c */; }; + C0E345151C582ECB00E749C2 /* vsnprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF6138D9E9A0028D27C /* vsnprintf.c */; }; + C0E345161C582ECB00E749C2 /* vsprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF8138D9E9A0028D27C /* vsprintf.c */; }; + C0E345171C582ECB00E749C2 /* vsscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BFA138D9E9A0028D27C /* vsscanf.c */; }; + C0E345181C582ECB00E749C2 /* vswprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BFC138D9E9A0028D27C /* vswprintf.c */; }; + C0E345191C582ECB00E749C2 /* vswscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BFE138D9E9A0028D27C /* vswscanf.c */; }; + C0E3451A1C582ECB00E749C2 /* vwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C00138D9E9A0028D27C /* vwprintf.c */; }; + C0E3451B1C582ECB00E749C2 /* vwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C02138D9E9A0028D27C /* vwscanf.c */; }; + C0E3451C1C582ECB00E749C2 /* wbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C04138D9E9A0028D27C /* wbuf.c */; }; + C0E3451D1C582ECB00E749C2 /* wprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C08138D9E9A0028D27C /* wprintf.c */; }; + C0E3451E1C582ECB00E749C2 /* wscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C0C138D9E9A0028D27C /* wscanf.c */; }; + C0E3451F1C582ECB00E749C2 /* wsetup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C0E138D9E9A0028D27C /* wsetup.c */; }; + C0E345201C582ECB00E749C2 /* a64l.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C18138D9E9A0028D27C /* a64l.c */; }; + C0E345211C582ECB00E749C2 /* _Exit_.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C1A138D9E9A0028D27C /* _Exit_.c */; }; + C0E345221C582ECB00E749C2 /* abort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C1D138D9E9A0028D27C /* abort.c */; }; + C0E345231C582ECB00E749C2 /* abs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C21138D9E9A0028D27C /* abs.c */; }; + C0E345241C582ECB00E749C2 /* atexit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C26138D9E9A0028D27C /* atexit.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E345251C582ECB00E749C2 /* atof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C2C138D9E9A0028D27C /* atof.c */; }; + C0E345261C582ECB00E749C2 /* atoi.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C30138D9E9A0028D27C /* atoi.c */; }; + C0E345271C582ECB00E749C2 /* atol.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C34138D9E9A0028D27C /* atol.c */; }; + C0E345281C582ECB00E749C2 /* atoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C36138D9E9A0028D27C /* atoll.c */; }; + C0E345291C582ECB00E749C2 /* bsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C3A138D9E9A0028D27C /* bsearch.c */; }; + C0E3452A1C582ECB00E749C2 /* div.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C3E138D9E9A0028D27C /* div.c */; }; + C0E3452B1C582ECB00E749C2 /* exit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C40138D9E9A0028D27C /* exit.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E3452C1C582ECB00E749C2 /* getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C44138D9E9A0028D27C /* getenv.c */; }; + C0E3452D1C582ECB00E749C2 /* getopt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C47138D9E9A0028D27C /* getopt.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_GETOPT"; }; }; + C0E3452E1C582ECB00E749C2 /* getopt_long.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C4A138D9E9A0028D27C /* getopt_long.c */; }; + C0E3452F1C582ECB00E749C2 /* getsubopt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C4D138D9E9A0028D27C /* getsubopt.c */; }; + C0E345301C582ECB00E749C2 /* hcreate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C4F138D9E9A0028D27C /* hcreate.c */; }; + C0E345311C582ECB00E749C2 /* heapsort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C50138D9E9A0028D27C /* heapsort.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E345321C582ECB00E749C2 /* heapsort_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94357138EC0C600FB7ACC /* heapsort_b.c */; }; + C0E345331C582ECB00E749C2 /* heapsort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94358138EC0C600FB7ACC /* heapsort_r.c */; }; + C0E345341C582ECB00E749C2 /* imaxabs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C54138D9E9A0028D27C /* imaxabs.c */; }; + C0E345351C582ECB00E749C2 /* imaxdiv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C57138D9E9A0028D27C /* imaxdiv.c */; }; + C0E345361C582ECB00E749C2 /* insque.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C5A138D9E9A0028D27C /* insque.c */; }; + C0E345371C582ECB00E749C2 /* labs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C5D138D9E9A0028D27C /* labs.c */; }; + C0E345381C582ECB00E749C2 /* ldiv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C60138D9E9A0028D27C /* ldiv.c */; }; + C0E345391C582ECB00E749C2 /* llabs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C63138D9E9A0028D27C /* llabs.c */; }; + C0E3453A1C582ECB00E749C2 /* lldiv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C66138D9E9A0028D27C /* lldiv.c */; }; + C0E3453B1C582ECB00E749C2 /* lsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C69138D9E9A0028D27C /* lsearch.c */; }; + C0E3453C1C582ECB00E749C2 /* merge.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C6C138D9E9A0028D27C /* merge.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E3453D1C582ECB00E749C2 /* putenv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C6F138D9E9A0028D27C /* putenv.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PUTENV"; }; }; + C0E3453E1C582ECB00E749C2 /* qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C73138D9E9A0028D27C /* qsort.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E3453F1C582ECB00E749C2 /* qsort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C75138D9E9A0028D27C /* qsort_r.c */; }; + C0E345401C582ECB00E749C2 /* radixsort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C78138D9E9A0028D27C /* radixsort.c */; }; + C0E345411C582ECB00E749C2 /* rand.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C7C138D9E9A0028D27C /* rand.c */; }; + C0E345421C582ECB00E749C2 /* random.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C7F138D9E9A0028D27C /* random.c */; }; + C0E345431C582ECB00E749C2 /* reallocf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C81138D9E9A0028D27C /* reallocf.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E345441C582ECB00E749C2 /* realpath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C84138D9E9A0028D27C /* realpath.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_REALPATH"; }; }; + C0E345451C582ECB00E749C2 /* remque.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C86138D9E9A0028D27C /* remque.c */; }; + C0E345461C582ECB00E749C2 /* setenv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C87138D9E9A0028D27C /* setenv.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_REALPATH"; }; }; + C0E345471C582ECB00E749C2 /* strhash.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C89138D9E9A0028D27C /* strhash.c */; }; + C0E345481C582ECB00E749C2 /* strtoimax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C8D138D9E9A0028D27C /* strtoimax.c */; }; + C0E345491C582ECB00E749C2 /* strtol.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C91138D9E9A0028D27C /* strtol.c */; }; + C0E3454A1C582ECB00E749C2 /* strtoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C93138D9E9A0028D27C /* strtoll.c */; }; + C0E3454B1C582ECB00E749C2 /* strtoq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C95138D9E9A0028D27C /* strtoq.c */; }; + C0E3454C1C582ECB00E749C2 /* strtoul.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C99138D9E9A0028D27C /* strtoul.c */; }; + C0E3454D1C582ECB00E749C2 /* strtoull.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C9B138D9E9A0028D27C /* strtoull.c */; }; + C0E3454E1C582ECB00E749C2 /* strtoumax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C9D138D9E9A0028D27C /* strtoumax.c */; }; + C0E3454F1C582ECB00E749C2 /* strtouq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C9F138D9E9A0028D27C /* strtouq.c */; }; + C0E345501C582ECB00E749C2 /* system.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA3138D9E9A0028D27C /* system.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SYSTEM"; }; }; + C0E345511C582ECB00E749C2 /* tdelete.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA5138D9E9A0028D27C /* tdelete.c */; }; + C0E345521C582ECB00E749C2 /* tfind.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA6138D9E9A0028D27C /* tfind.c */; }; + C0E345531C582ECB00E749C2 /* tsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA9138D9E9A0028D27C /* tsearch.c */; }; + C0E345541C582ECB00E749C2 /* twalk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CAA138D9E9A0028D27C /* twalk.c */; }; + C0E345551C582ECB00E749C2 /* grantpt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CAC138D9E9A0028D27C /* grantpt.c */; }; + C0E345561C582ECB00E749C2 /* l64a.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CAD138D9E9A0028D27C /* l64a.c */; }; + C0E345571C582ECB00E749C2 /* strfmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB2138D9E9A0028D27C /* strfmon.c */; }; + C0E345581C582ECB00E749C2 /* ecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB7138D9E9A0028D27C /* ecvt.c */; }; + C0E345591C582ECB00E749C2 /* gcvt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB9138D9E9A0028D27C /* gcvt.c */; }; + C0E3455A1C582ECB00E749C2 /* qsort_b-fbsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CBD138D9E9A0028D27C /* qsort_b-fbsd.c */; }; + C0E3455B1C582ECB00E749C2 /* asctime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CC2138D9E9A0028D27C /* asctime.c */; }; + C0E3455C1C582ECB00E749C2 /* difftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CC6138D9E9A0028D27C /* difftime.c */; }; + C0E3455D1C582ECB00E749C2 /* ftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CC9138D9E9A0028D27C /* ftime.c */; }; + C0E3455E1C582ECB00E749C2 /* localtime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CCA138D9E9A0028D27C /* localtime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_MKTIME"; }; }; + C0E3455F1C582ECB00E749C2 /* strftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CCF138D9E9A0028D27C /* strftime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRFTIME -DLIBC_ALIAS_STRFTIME_L"; }; }; + C0E345601C582ECB00E749C2 /* strptime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD3138D9E9A0028D27C /* strptime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRPTIME -DLIBC_ALIAS_STRPTIME_L"; }; }; + C0E345611C582ECB00E749C2 /* time32.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD6138D9E9A0028D27C /* time32.c */; }; + C0E345621C582ECB00E749C2 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; + C0E345631C582ECB00E749C2 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; settings = {COMPILER_FLAGS = "-D_DARWIN_UNLIMITED_STREAMS"; }; }; + C0E345641C582ECB00E749C2 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; + C0E345651C582ECB00E749C2 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; + C0E345661C582ECB00E749C2 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; + C0E345671C582ECB00E749C2 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; + C0E345681C582ECB00E749C2 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; + C0E345691C582ECB00E749C2 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; + C0E3456A1C582ECB00E749C2 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; + C0E3456B1C582ECB00E749C2 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; + C0E3456C1C582ECB00E749C2 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E3456D1C582ECB00E749C2 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRERROR"; }; }; + C0E3456E1C582ECB00E749C2 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; + C0E3456F1C582ECB00E749C2 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; + C0E345701C582ECB00E749C2 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; + C0E345711C582ECB00E749C2 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; + C0E345721C582ECB00E749C2 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; + C0E345731C582ECB00E749C2 /* strpbrk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D49138D9E9A0028D27C /* strpbrk.c */; }; + C0E345741C582ECB00E749C2 /* strrchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D4C138D9E9A0028D27C /* strrchr.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E345751C582ECB00E749C2 /* strsep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D4F138D9E9A0028D27C /* strsep.c */; }; + C0E345761C582ECB00E749C2 /* strsignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D50138D9E9A0028D27C /* strsignal.c */; }; + C0E345771C582ECB00E749C2 /* strspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D54138D9E9A0028D27C /* strspn.c */; }; + C0E345781C582ECB00E749C2 /* strstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D57138D9E9A0028D27C /* strstr.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C0E345791C582ECB00E749C2 /* strtok.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D5A138D9E9A0028D27C /* strtok.c */; }; + C0E3457A1C582ECB00E749C2 /* strxfrm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D5D138D9E9A0028D27C /* strxfrm.c */; }; + C0E3457B1C582ECB00E749C2 /* swab.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D61138D9E9A0028D27C /* swab.c */; }; + C0E3457C1C582ECB00E749C2 /* wcpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D63138D9E9A0028D27C /* wcpcpy.c */; }; + C0E3457D1C582ECB00E749C2 /* wcpncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D64138D9E9A0028D27C /* wcpncpy.c */; }; + C0E3457E1C582ECB00E749C2 /* wcscasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D65138D9E9A0028D27C /* wcscasecmp.c */; }; + C0E3457F1C582ECB00E749C2 /* wcscat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D67138D9E9A0028D27C /* wcscat.c */; }; + C0E345801C582ECB00E749C2 /* wcschr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D68138D9E9A0028D27C /* wcschr.c */; }; + C0E345811C582ECB00E749C2 /* wcscmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D69138D9E9A0028D27C /* wcscmp.c */; }; + C0E345821C582ECB00E749C2 /* wcscoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D6C138D9E9A0028D27C /* wcscoll.c */; }; + C0E345831C582ECB00E749C2 /* wcscpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D6E138D9E9A0028D27C /* wcscpy.c */; }; + C0E345841C582ECB00E749C2 /* wcscspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D6F138D9E9A0028D27C /* wcscspn.c */; }; + C0E345851C582ECB00E749C2 /* wcsdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D70138D9E9A0028D27C /* wcsdup.c */; }; + C0E345861C582ECB00E749C2 /* wcslcat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D71138D9E9A0028D27C /* wcslcat.c */; }; + C0E345871C582ECB00E749C2 /* wcslcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D72138D9E9A0028D27C /* wcslcpy.c */; }; + C0E345881C582ECB00E749C2 /* wcslen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D73138D9E9A0028D27C /* wcslen.c */; }; + C0E345891C582ECB00E749C2 /* wcsncasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D74138D9E9A0028D27C /* wcsncasecmp.c */; }; + C0E3458A1C582ECB00E749C2 /* wcsncat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D76138D9E9A0028D27C /* wcsncat.c */; }; + C0E3458B1C582ECB00E749C2 /* wcsncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D77138D9E9A0028D27C /* wcsncmp.c */; }; + C0E3458C1C582ECB00E749C2 /* wcsncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D78138D9E9A0028D27C /* wcsncpy.c */; }; + C0E3458D1C582ECB00E749C2 /* wcsnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D79138D9E9A0028D27C /* wcsnlen.c */; }; + C0E3458E1C582ECB00E749C2 /* wcspbrk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7A138D9E9A0028D27C /* wcspbrk.c */; }; + C0E3458F1C582ECB00E749C2 /* wcsrchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7B138D9E9A0028D27C /* wcsrchr.c */; }; + C0E345901C582ECB00E749C2 /* wcsspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7C138D9E9A0028D27C /* wcsspn.c */; }; + C0E345911C582ECB00E749C2 /* wcsstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7D138D9E9A0028D27C /* wcsstr.c */; }; + C0E345921C582ECB00E749C2 /* wcstok.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D80138D9E9A0028D27C /* wcstok.c */; }; + C0E345931C582ECB00E749C2 /* wcswidth.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D83138D9E9A0028D27C /* wcswidth.c */; }; + C0E345941C582ECB00E749C2 /* wcsxfrm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D87138D9E9A0028D27C /* wcsxfrm.c */; }; + C0E345951C582ECB00E749C2 /* wmemchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8B138D9E9A0028D27C /* wmemchr.c */; }; + C0E345961C582ECB00E749C2 /* wmemcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8C138D9E9A0028D27C /* wmemcmp.c */; }; + C0E345971C582ECB00E749C2 /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; }; + C0E345981C582ECB00E749C2 /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; }; + C0E345991C582ECB00E749C2 /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; + C0E3459A1C582ECB00E749C2 /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; + C0E3459B1C582ECB00E749C2 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; + C0E3459C1C582ECB00E749C2 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; + C0E3459D1C582ECB00E749C2 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; + C0E3459E1C582ECB00E749C2 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; + C0E3459F1C582ECB00E749C2 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; }; + C0E345A01C582ECB00E749C2 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; + C0E345A11C582ECB00E749C2 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_MSGCTL -DKERNEL"; }; }; + C0E345A21C582ECB00E749C2 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; }; + C0E345A31C582ECB00E749C2 /* openx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAB138D9E9A0028D27C /* openx_np.c */; }; + C0E345A41C582ECB00E749C2 /* OSMemoryNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAC138D9E9A0028D27C /* OSMemoryNotification.c */; }; + C0E345A51C582ECB00E749C2 /* OSThermalNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAD138D9E9A0028D27C /* OSThermalNotification.c */; }; + C0E345A61C582ECB00E749C2 /* posix_spawn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAE138D9E9A0028D27C /* posix_spawn.c */; }; + C0E345A71C582ECB00E749C2 /* semctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB2138D9E9A0028D27C /* semctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SEMCTL -DKERNEL"; }; }; + C0E345A81C582ECB00E749C2 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; + C0E345A91C582ECB00E749C2 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SHMCTL -DKERNEL"; }; }; + C0E345AA1C582ECB00E749C2 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; + C0E345AB1C582ECB00E749C2 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C0E345AC1C582ECB00E749C2 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; + C0E345AD1C582ECB00E749C2 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; + C0E345AE1C582ECB00E749C2 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; }; + C0E345AF1C582ECB00E749C2 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; + C0E345B01C582ECB00E749C2 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; + C0E345B11C582ECB00E749C2 /* logout.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCC138D9E9A0028D27C /* logout.c */; }; + C0E345B21C582ECB00E749C2 /* logwtmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCD138D9E9A0028D27C /* logwtmp.c */; }; + C0E345B31C582ECB00E749C2 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; }; + C0E345B41C582ECB00E749C2 /* opendev.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DD0138D9E9A0028D27C /* opendev.c */; }; + C0E345B51C582ECB00E749C2 /* pty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DD2138D9E9A0028D27C /* pty.c */; }; + C0E345B61C582ECB00E749C2 /* clear.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DD9138D9E9A0028D27C /* clear.c */; }; + C0E345B71C582ECB00E749C2 /* compare.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDA138D9E9A0028D27C /* compare.c */; }; + C0E345B81C582ECB00E749C2 /* copy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDB138D9E9A0028D27C /* copy.c */; }; + C0E345B91C582ECB00E749C2 /* gen_uuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDC138D9E9A0028D27C /* gen_uuid.c */; }; + C0E345BA1C582ECB00E749C2 /* isnull.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDE138D9E9A0028D27C /* isnull.c */; }; + C0E345BB1C582ECB00E749C2 /* pack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE0138D9E9A0028D27C /* pack.c */; }; + C0E345BC1C582ECB00E749C2 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; }; + C0E345BD1C582ECB00E749C2 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; }; + C0E345BE1C582ECB00E749C2 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; }; + C0E345BF1C582ECB00E749C2 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C0E345C01C582ECB00E749C2 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C0E345C11C582ECB00E749C2 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C0E345C21C582ECB00E749C2 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C0E345C31C582ECB00E749C2 /* scandir_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB350E138F769B0075BB52 /* scandir_b.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; + C0E345C41C582ECB00E749C2 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C921D3831395B7DD001CE070 /* init_cpu_capabilities.c */; }; + C0E345C51C582ECB00E749C2 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3841395B7DD001CE070 /* pthread_getspecific.s */; }; + C0E345C61C582ECB00E749C2 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3851395B7DD001CE070 /* pthread_self.s */; }; + C0E345C71C582ECB00E749C2 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3861395B7DD001CE070 /* pthread_set_self.s */; }; + C0E345C81C582ECB00E749C2 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3871395B7DD001CE070 /* start_wqthread.s */; }; + C0E345C91C582ECB00E749C2 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3881395B7DD001CE070 /* thread_start.s */; }; + C0E345CA1C582ECB00E749C2 /* strcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518613D4D966004F7BA8 /* strcpy.c */; }; + C0E345CB1C582ECB00E749C2 /* strlcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518B13D4DABD004F7BA8 /* strlcpy.c */; }; + C0E345CC1C582ECB00E749C2 /* strncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518E13D4DAEA004F7BA8 /* strncpy.c */; }; + C0E345CD1C582ECB00E749C2 /* stpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060513DDEDF10094DD56 /* stpcpy.c */; }; + C0E345CE1C582ECB00E749C2 /* stpncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060913DDEEA10094DD56 /* stpncpy.c */; }; + C0E345CF1C582ECB00E749C2 /* strcat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060C13DDF26A0094DD56 /* strcat.c */; }; + C0E345D01C582ECB00E749C2 /* strncat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060F13DDF4340094DD56 /* strncat.c */; }; + C0E345D11C582ECB00E749C2 /* strlcat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4061213DDF6A20094DD56 /* strlcat.c */; }; + C0E345D21C582ECB00E749C2 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; }; + C0E345D31C582ECB00E749C2 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; }; + C0E345D41C582ECB00E749C2 /* eos_stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C925D1FB151805C6003D315B /* eos_stubs.c */; }; + C0E345D51C582ECB00E749C2 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 63505E3A1548525D00B637D7 /* strnlen.s */; }; + C0E345D61C582ECB00E749C2 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; }; + C0E345D71C582ECB00E749C2 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + C0E345D81C582ECB00E749C2 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; + C0E345D91C582ECB00E749C2 /* memccpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F169A3C1643B7BA0029E851 /* memccpy_chk.c */; }; + C0E345DB1C582ECB00E749C2 /* libBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C2A94D138DFFD900287F00 /* libBase.a */; }; + C0E345DC1C582ECB00E749C2 /* libFreeBSD.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9257ED0138E1B5000B3107C /* libFreeBSD.a */; }; + C0E345DD1C582ECB00E749C2 /* libvCancelable.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9D94360138EC3E300FB7ACC /* libvCancelable.a */; }; + C0E345DE1C582ECB00E749C2 /* libTRE.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B122F2AD1432B8E600AF95D0 /* libTRE.a */; }; + C921D3891395B7DD001CE070 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C921D3831395B7DD001CE070 /* init_cpu_capabilities.c */; }; + C921D38A1395B7DD001CE070 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3841395B7DD001CE070 /* pthread_getspecific.s */; }; + C921D38B1395B7DD001CE070 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3851395B7DD001CE070 /* pthread_self.s */; }; + C921D38C1395B7DD001CE070 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3861395B7DD001CE070 /* pthread_set_self.s */; }; + C921D38D1395B7DD001CE070 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3871395B7DD001CE070 /* start_wqthread.s */; }; + C921D38E1395B7DD001CE070 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3881395B7DD001CE070 /* thread_start.s */; }; C9257ED5138E1C2E00B3107C /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; }; C9257ED6138E1C2E00B3107C /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; C9257ED7138E1C2E00B3107C /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; @@ -167,9 +843,7 @@ C9257F33138E1C8200B3107C /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; settings = {COMPILER_FLAGS = "-include gen/__dirent.h"; }; }; C9257F34138E1C8200B3107C /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; }; C9257F35138E1C8200B3107C /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; }; - C9257F36138E1C8200B3107C /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; }; C9257F37138E1C8200B3107C /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; - C9257F38138E1C8200B3107C /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; C9257F39138E1C8200B3107C /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; settings = {COMPILER_FLAGS = "-include gen/__dirent.h"; }; }; C9257F3A138E1C8200B3107C /* readpassphrase.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53769138D9E990028D27C /* readpassphrase.c */; }; C9257F3B138E1C8200B3107C /* rewinddir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5376B138D9E990028D27C /* rewinddir.c */; settings = {COMPILER_FLAGS = "-include gen/__dirent.h"; }; }; @@ -326,6 +1000,7 @@ C9257FD4138E1CC000B3107C /* makebuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B9C138D9E990028D27C /* makebuf.c */; }; C9257FD5138E1CC000B3107C /* mktemp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA0138D9E990028D27C /* mktemp.c */; }; C9257FD6138E1CC000B3107C /* perror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA2138D9E990028D27C /* perror.c */; }; + C9257FD7138E1CC000B3107C /* printf-pos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA3138D9E990028D27C /* printf-pos.c */; }; C9257FD8138E1CC000B3107C /* printf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA7138D9E990028D27C /* printf.c */; }; C9257FD9138E1CC000B3107C /* putc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BAF138D9E990028D27C /* putc.c */; }; C9257FDA138E1CC000B3107C /* putchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB0138D9E990028D27C /* putchar.c */; }; @@ -354,7 +1029,9 @@ C9257FF1138E1CC000B3107C /* ungetwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE4138D9E990028D27C /* ungetwc.c */; }; C9257FF2138E1CC000B3107C /* vasprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE6138D9E990028D27C /* vasprintf.c */; }; C9257FF3138E1CC000B3107C /* vdprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE8138D9E990028D27C /* vdprintf.c */; }; + C9257FF4138E1CC000B3107C /* vfprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEA138D9E990028D27C /* vfprintf.c */; }; C9257FF5138E1CC000B3107C /* vfscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEC138D9E990028D27C /* vfscanf.c */; }; + C9257FF6138E1CC000B3107C /* vfwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEE138D9E9A0028D27C /* vfwprintf.c */; }; C9257FF7138E1CC000B3107C /* vfwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF0138D9E9A0028D27C /* vfwscanf.c */; }; C9257FF8138E1CC000B3107C /* vprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF2138D9E9A0028D27C /* vprintf.c */; }; C9257FF9138E1CC000B3107C /* vscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF4138D9E9A0028D27C /* vscanf.c */; }; @@ -377,29 +1054,17 @@ C925800A138E1CC000B3107C /* strptime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD3138D9E9A0028D27C /* strptime.c */; }; C925800B138E1CC000B3107C /* time32.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD6138D9E9A0028D27C /* time32.c */; }; C925800C138E1CC000B3107C /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; - C925800D138E1CD200B3107C /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; }; - C925800E138E1CD200B3107C /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; }; - C925800F138E1CD200B3107C /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; }; C9258010138E1CD200B3107C /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; - C9258011138E1CD200B3107C /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; }; - C9258012138E1CD200B3107C /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; }; - C9258013138E1CD200B3107C /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; }; - C9258014138E1CD200B3107C /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; }; C9258015138E1CD200B3107C /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; - C9258016138E1CD200B3107C /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; }; - C9258017138E1CD200B3107C /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; settings = {COMPILER_FLAGS = "-fno-builtin"; }; }; C9258018138E1CD200B3107C /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; C925801B138E1CD200B3107C /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; C925801C138E1CD200B3107C /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; - C925801E138E1CD200B3107C /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; }; - C925801F138E1CD200B3107C /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; }; C9258020138E1CD200B3107C /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; C9258022138E1CD200B3107C /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; C9258023138E1CD200B3107C /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; }; C9258024138E1CD200B3107C /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; }; C9258027138E1CD200B3107C /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; C9258028138E1CD200B3107C /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; - C925802A138E1CD200B3107C /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; }; C925802C138E1CD200B3107C /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; C925802D138E1CD200B3107C /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; C925802E138E1CD200B3107C /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; @@ -444,12 +1109,7 @@ C9258055138E1CD200B3107C /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; C9258058138E1CDD00B3107C /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; C92580CC138E2D3100B3107C /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; - C9258122138E3CA100B3107C /* magmallocProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D5138D9E990028D27C /* magmallocProvider.d */; }; - C932C2D013AB1C73004EDA12 /* SpinlocksWFE.c in Sources */ = {isa = PBXBuildFile; fileRef = C932C2CF13AB1C73004EDA12 /* SpinlocksWFE.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; - C932C2D313AB20C8004EDA12 /* OSAtomicUP.c in Sources */ = {isa = PBXBuildFile; fileRef = C995462713AAA25000A531B4 /* OSAtomicUP.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; - C932C2D413AB20C8004EDA12 /* Spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C97C344013AB0E1B00713550 /* Spinlocks.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; - C932C2D513AB20C8004EDA12 /* SpinlocksUP.c in Sources */ = {isa = PBXBuildFile; fileRef = C980F8EB13AB168D0069AB06 /* SpinlocksUP.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; - C932C2D613AB20C8004EDA12 /* SpinlocksWFE.c in Sources */ = {isa = PBXBuildFile; fileRef = C932C2CF13AB1C73004EDA12 /* SpinlocksWFE.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; + C925D1FD1518F4A2003D315B /* eos_stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C925D1FB151805C6003D315B /* eos_stubs.c */; }; C9421014138F23CA004BA536 /* frune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E3138D9E990028D27C /* frune.c */; settings = {COMPILER_FLAGS = "-D__FBSDID=__RCSID"; }; }; C9421015138F23CA004BA536 /* mbrune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EB138D9E990028D27C /* mbrune.c */; settings = {COMPILER_FLAGS = "-D__FBSDID=__RCSID"; }; }; C9421016138F23CA004BA536 /* runedepreciated.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EF138D9E990028D27C /* runedepreciated.c */; settings = {COMPILER_FLAGS = "-D__FBSDID=__RCSID"; }; }; @@ -460,11 +1120,6 @@ C9421024138F2661004BA536 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; C9421025138F2661004BA536 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; C942103213900C8A004BA536 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; - C942103313900C8A004BA536 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; }; - C942103413900C8A004BA536 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; }; - C942103513900C8A004BA536 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; }; - C942103613900C8A004BA536 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; }; - C942103713900C8A004BA536 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; }; C942103913900C8A004BA536 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; }; C942103A13900C8A004BA536 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; C942103B13900C8A004BA536 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; @@ -477,11 +1132,7 @@ C942104213900C8A004BA536 /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SETREUID"; }; }; C942104313900C8A004BA536 /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; C942104413900C8A004BA536 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; }; - C942104513900C8A004BA536 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; }; C942104613900C8A004BA536 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; - C942104713900C8A004BA536 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; }; - C942104813900C8A004BA536 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; }; - C942104913900C8A004BA536 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; }; C942104A13900C8A004BA536 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; C942104B13900C8A004BA536 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; }; C942104C13900C8A004BA536 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; }; @@ -546,18 +1197,8 @@ C942108713900C8A004BA536 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; }; C942108813900C8A004BA536 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; C942108913900C8A004BA536 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; - C942108A13900C8A004BA536 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; }; - C942108B13900C8A004BA536 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; }; - C942108C13900C8A004BA536 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; }; - C942108D13900C8A004BA536 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; }; - C942108E13900C8A004BA536 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; }; - C942108F13900C8A004BA536 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; }; - C942109013900C8A004BA536 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; }; - C942109113900C8A004BA536 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; }; - C942109213900C8A004BA536 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; }; C942109313900C8A004BA536 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; }; C942109413900C8A004BA536 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; - C942109513900C8A004BA536 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; }; C942109613900C8A004BA536 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_CONFSTR"; }; }; C942109713900C8A004BA536 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY"; }; }; C942109813900C8A004BA536 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; @@ -603,7 +1244,6 @@ C94210C013900C8A004BA536 /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS___OPENDIR2 -DLIBC_ALIAS_OPENDIR -include gen/__dirent.h"; }; }; C94210C113900C8A004BA536 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; }; C94210C213900C8A004BA536 /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; }; - C94210C313900C8A004BA536 /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PSELECT $(FreeBSD_CFLAGS)"; }; }; C94210C413900C8A004BA536 /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; C94210C513900C8A004BA536 /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; C94210C613900C8A004BA536 /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; @@ -647,42 +1287,19 @@ C94210EC13900C8A004BA536 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; C94210ED13900C8A004BA536 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; C94210EE13900C8A004BA536 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; - C94210EF13900C8A004BA536 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; }; - C94210F013900C8A004BA536 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; }; - C94210F113900C8A004BA536 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; }; - C94210F213900C8A004BA536 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; }; C94210F313900C8A004BA536 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; }; C94210F413900C8A004BA536 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; C94210F513900C8A004BA536 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW"; }; }; C94210F613900C8A004BA536 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; - C94210F713900C8A004BA536 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; }; C94210F813900C8A004BA536 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; }; - C94210F913900C8A004BA536 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; }; - C94210FA13900C8A004BA536 /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; }; C94210FB13900C8A004BA536 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; C94210FC13900C8A004BA536 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; - C94210FD13900C8A004BA536 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; }; - C94210FE13900C8A004BA536 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; }; C94210FF13900C8A004BA536 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; - C942110013900C8A004BA536 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; }; C942110113900C8A004BA536 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; C942110213900C8A004BA536 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; C942110313900C8A004BA536 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; C942110413900C8A004BA536 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; C942110613900C8A004BA536 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; - C942110713900C8A004BA536 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; }; - C942110813900C8A004BA536 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; }; - C942110913900C8A004BA536 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; }; - C942110A13900C8A004BA536 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; }; - C942110B13900C8A004BA536 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; }; - C942110C13900C8A004BA536 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; }; - C942110D13900C8A004BA536 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; }; - C942110E13900C8A004BA536 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; }; - C942110F13900C8A004BA536 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; }; - C942111013900C8A004BA536 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; }; - C942111113900C8A004BA536 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; }; - C942111213900C8A004BA536 /* mach_absolute_time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53848138D9E990028D27C /* mach_absolute_time.c */; }; - C942111313900C8A004BA536 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; }; C942112613900C8A004BA536 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; }; C942112713900C8A004BA536 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; }; C942112813900C8A004BA536 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; }; @@ -771,30 +1388,7 @@ C942117B13900C8A004BA536 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; C942117C13900C8A004BA536 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; C942117D13900C8A004BA536 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; - C942118613900C8A004BA536 /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; }; - C942118713900C8A004BA536 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_CANCEL -DLIBC_ALIAS_PTHREAD_SETCANCELSTATE -DLIBC_ALIAS_PTHREAD_SETCANCELTYPE -DLIBC_ALIAS_PTHREAD_SIGMASK -DLIBC_ALIAS_PTHREAD_TESTCANCEL"; }; }; - C942118813900C8A004BA536 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; }; - C942118913900C8A004BA536 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_INIT"; }; }; - C942118A13900C8A004BA536 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY"; }; }; - C942118B13900C8A004BA536 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_RWLOCK_DESTROY -DLIBC_ALIAS_PTHREAD_RWLOCK_INIT -DLIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK"; }; }; - C942118C13900C8A004BA536 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; }; - C942118D13900C8A004BA536 /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; }; - C942118E13900C8A004BA536 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; }; C942119113900C8A004BA536 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; - C942119413900C8A004BA536 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; - C942119513900C8A004BA536 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; - C942119613900C8A004BA536 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; - C942119713900C8A004BA536 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; - C942119813900C8A004BA536 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; - C942119913900C8A004BA536 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; - C942119A13900C8A004BA536 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; - C942119B13900C8A004BA536 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; - C942119C13900C8A004BA536 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; - C942119D13900C8A004BA536 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; - C942119E13900C8A004BA536 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; - C942119F13900C8A004BA536 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; - C94211A013900C8A004BA536 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; - C94211A113900C8A004BA536 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; C94211A213900C8A004BA536 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; }; C94211A313900C8A004BA536 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; }; C94211A413900C8A004BA536 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; }; @@ -960,29 +1554,17 @@ C942124413900C8A004BA536 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; C942124513900C8A004BA536 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; settings = {COMPILER_FLAGS = "-D_DARWIN_UNLIMITED_STREAMS"; }; }; C942124613900C8A004BA536 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; - C942124713900C8A004BA536 /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; }; - C942124813900C8A004BA536 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; }; - C942124913900C8A004BA536 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; }; C942124A13900C8A004BA536 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; - C942124B13900C8A004BA536 /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; }; - C942124C13900C8A004BA536 /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; }; - C942124D13900C8A004BA536 /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; }; - C942124E13900C8A004BA536 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; }; C942124F13900C8A004BA536 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; - C942125013900C8A004BA536 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; }; - C942125113900C8A004BA536 /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; settings = {COMPILER_FLAGS = "-fno-builtin"; }; }; C942125213900C8A004BA536 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; C942125513900C8A004BA536 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; C942125613900C8A004BA536 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; - C942125813900C8A004BA536 /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; - C942125913900C8A004BA536 /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; }; C942125A13900C8A004BA536 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; C942125C13900C8A004BA536 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; C942125D13900C8A004BA536 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; C942125E13900C8A004BA536 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRERROR"; }; }; C942126113900C8A004BA536 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; C942126213900C8A004BA536 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; - C942126413900C8A004BA536 /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; C942126613900C8A004BA536 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; C942126713900C8A004BA536 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; C942126813900C8A004BA536 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; @@ -1025,15 +1607,12 @@ C942128D13900C8A004BA536 /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; }; C942128E13900C8A004BA536 /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; }; C942128F13900C8A004BA536 /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; - C942129013900C8A004BA536 /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; }; + C942129013900C8A004BA536 /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; C942129113900C8A004BA536 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; C942129213900C8A004BA536 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; - C942129313900C8A004BA536 /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; }; C942129413900C8A004BA536 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; - C942129513900C8A004BA536 /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; }; C942129613900C8A004BA536 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; C942129713900C8A004BA536 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; }; - C942129813900C8A004BA536 /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; }; C942129913900C8A004BA536 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; C942129A13900C8A004BA536 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_MSGCTL -DKERNEL"; }; }; C942129B13900C8A004BA536 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; }; @@ -1045,14 +1624,8 @@ C94212A113900C8A004BA536 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; C94212A213900C8A004BA536 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SHMCTL -DKERNEL"; }; }; C94212A313900C8A004BA536 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; - C94212A413900C8A004BA536 /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; }; - C94212A513900C8A004BA536 /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; }; - C94212A613900C8A004BA536 /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; }; C94212A713900C8A004BA536 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; C94212A813900C8A004BA536 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; - C94212A913900C8A004BA536 /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; }; - C94212AA13900C8A004BA536 /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; }; - C94212AB13900C8A004BA536 /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; }; C94212AC13900C8A004BA536 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; }; C94212AD13900C8A004BA536 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; C94212AE13900C8A004BA536 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; @@ -1069,128 +1642,22 @@ C94212B913900C8A004BA536 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; }; C94212BA13900C8A004BA536 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; }; C94212BB13900C8A004BA536 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; }; - C94212BC13900C8A004BA536 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; }; - C94212BD13900C8A004BA536 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; }; - C94212BE13900C8A004BA536 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; }; - C94212BF13900C8A004BA536 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; }; - C94212C013900C8A004BA536 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; }; - C94212C113900C8A004BA536 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; }; - C94212C213900C8A004BA536 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; }; - C94212C313900C8A004BA536 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; }; - C94212C413900C8A004BA536 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; }; - C94212C513900C8A004BA536 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; }; C94212C613900C8A004BA536 /* scandir_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB350E138F769B0075BB52 /* scandir_b.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; - C94212D113900ED1004BA536 /* dirhelper.defs in Sources */ = {isa = PBXBuildFile; fileRef = C9B53614138D9E980028D27C /* dirhelper.defs */; }; - C94212D213900ED1004BA536 /* asl_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CA138D9E990028D27C /* asl_ipc.defs */; }; - C94212DE13901595004BA536 /* _ctx_start.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF1138D9E9A0028D27C /* _ctx_start.S */; }; - C94212DF13901595004BA536 /* _setcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF2138D9E9A0028D27C /* _setcontext.S */; }; - C94212E013901595004BA536 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF3138D9E9A0028D27C /* cpu_number.s */; }; - C94212E113901595004BA536 /* getcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF4138D9E9A0028D27C /* getcontext.S */; }; - C94212E213901595004BA536 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF6138D9E9A0028D27C /* icacheinval.s */; }; C94212E413901595004BA536 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF9138D9E9A0028D27C /* mcount.s */; }; - C94212E513901595004BA536 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB3555138F7F6A0075BB52 /* setjmperr.c */; }; - C94212E713901595004BA536 /* preempt.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFE138D9E9A0028D27C /* preempt.s */; }; - C94212E813901595004BA536 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFF138D9E9A0028D27C /* pthread_getspecific.s */; }; - C94212E913901595004BA536 /* pthread_mutex_lock.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E00138D9E9A0028D27C /* pthread_mutex_lock.s */; }; - C94212EA13901595004BA536 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E01138D9E9A0028D27C /* pthread_self.s */; }; - C94212EB13901595004BA536 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E02138D9E9A0028D27C /* pthread_set_self.s */; }; - C94212EC13901595004BA536 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E03138D9E9A0028D27C /* start_wqthread.s */; }; - C94212ED13901595004BA536 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E04138D9E9A0028D27C /* thread_start.s */; }; - C94212EF13901595004BA536 /* __bzero.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E08138D9E9A0028D27C /* __bzero.s */; }; - C94212F013901595004BA536 /* bcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0A138D9E9A0028D27C /* bcopy_sse3x.s */; }; - C94212F113901595004BA536 /* bcopy_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0B138D9E9A0028D27C /* bcopy_sse42.s */; }; - C94212F213901595004BA536 /* bzero_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0D138D9E9A0028D27C /* bzero_sse2.s */; }; - C94212F313901595004BA536 /* bzero_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0E138D9E9A0028D27C /* bzero_sse42.s */; }; - C94212F413901595004BA536 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0F138D9E9A0028D27C /* ffs.s */; }; - C94212F513901595004BA536 /* longcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E10138D9E9A0028D27C /* longcopy_sse3x.s */; }; - C94212F713901595004BA536 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E12138D9E9A0028D27C /* memcmp.s */; }; - C94212F813901595004BA536 /* memset.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E15138D9E9A0028D27C /* memset.s */; }; - C94212F913901595004BA536 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E16138D9E9A0028D27C /* strcmp.s */; }; C94212FA13901595004BA536 /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E17138D9E9A0028D27C /* strcpy.s */; }; - C94212FB13901595004BA536 /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E18138D9E9A0028D27C /* strlcat.s */; }; - C94212FC13901595004BA536 /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E19138D9E9A0028D27C /* strlcpy.s */; }; C94212FD13901595004BA536 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1A138D9E9A0028D27C /* strlen.s */; }; - C94212FE13901595004BA536 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1B138D9E9A0028D27C /* strncmp.s */; }; C94212FF13901595004BA536 /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1C138D9E9A0028D27C /* strncpy.s */; }; - C942130013901595004BA536 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1E138D9E9A0028D27C /* _setjmp.s */; }; - C942130113901595004BA536 /* _sigtramp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1F138D9E9A0028D27C /* _sigtramp.s */; }; - C942130213901595004BA536 /* i386_gettimeofday_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E21138D9E9A0028D27C /* i386_gettimeofday_asm.s */; }; - C942130413901595004BA536 /* nanotime.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E23138D9E9A0028D27C /* nanotime.s */; }; - C942130513901595004BA536 /* OSAtomic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E24138D9E9A0028D27C /* OSAtomic.s */; }; - C942130613901595004BA536 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E25138D9E9A0028D27C /* setjmp.s */; }; - C942130713901595004BA536 /* spinlocks_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E27138D9E9A0028D27C /* spinlocks_asm.s */; }; - C942130A13903959004BA536 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B1138D9E980028D27C /* cpu_number.s */; }; - C942130B13903959004BA536 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B2138D9E980028D27C /* icacheinval.s */; }; - C942130C13903959004BA536 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B8138D9E980028D27C /* pthread_getspecific.s */; }; - C942130D13903959004BA536 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B9138D9E980028D27C /* pthread_self.s */; }; - C942130E13903959004BA536 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BA138D9E980028D27C /* pthread_set_self.s */; }; - C942130F13903959004BA536 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BB138D9E980028D27C /* start_wqthread.s */; }; - C942131013903959004BA536 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BC138D9E980028D27C /* thread_start.s */; }; - C942131313903959004BA536 /* bcopy_Generic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C2138D9E980028D27C /* bcopy_Generic.s */; }; - C942131613903959004BA536 /* bzero_Generic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C5138D9E980028D27C /* bzero_Generic.s */; }; - C942131713903959004BA536 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C7138D9E980028D27C /* ffs.s */; }; - C942131813903959004BA536 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C9138D9E980028D27C /* memcmp.s */; }; - C942131913903959004BA536 /* memset_pattern.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CA138D9E980028D27C /* memset_pattern.s */; }; - C942131A13903959004BA536 /* strchr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CB138D9E980028D27C /* strchr.s */; }; - C942131B13903959004BA536 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CC138D9E980028D27C /* strcmp.s */; }; C942131E13903959004BA536 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CF138D9E980028D27C /* strlen.s */; }; - C942131F13903959004BA536 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D0138D9E980028D27C /* strncmp.s */; }; C942132113903959004BA536 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D2138D9E980028D27C /* strnlen.s */; }; C942132213903959004BA536 /* strstr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D3138D9E980028D27C /* strstr.s */; }; - C942132313903959004BA536 /* _longjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D5138D9E980028D27C /* _longjmp.s */; }; - C942132413903959004BA536 /* _setjmp.h in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D6138D9E980028D27C /* _setjmp.h */; }; - C942132513903959004BA536 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D7138D9E980028D27C /* _setjmp.s */; }; - C942132613903959004BA536 /* longjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DA138D9E980028D27C /* longjmp.s */; }; - C942132713903959004BA536 /* mach_absolute_time.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DB138D9E980028D27C /* mach_absolute_time.s */; }; - C942132913903959004BA536 /* OSAtomic_resolvers.h in Sources */ = {isa = PBXBuildFile; fileRef = C9B535E0138D9E980028D27C /* OSAtomic_resolvers.h */; }; - C942132A13903959004BA536 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535E1138D9E980028D27C /* setjmp.s */; }; - C94213311390396E004BA536 /* _ctx_start.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53811138D9E990028D27C /* _ctx_start.S */; }; - C94213321390396E004BA536 /* _setcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53812138D9E990028D27C /* _setcontext.S */; }; - C94213331390396E004BA536 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53813138D9E990028D27C /* cpu_number.s */; }; - C94213341390396E004BA536 /* getcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53814138D9E990028D27C /* getcontext.S */; }; - C94213351390396E004BA536 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53816138D9E990028D27C /* icacheinval.s */; }; C94213361390396E004BA536 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53819138D9E990028D27C /* mcount.s */; }; - C94213371390396E004BA536 /* preempt.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53820138D9E990028D27C /* preempt.s */; }; - C94213381390396E004BA536 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53821138D9E990028D27C /* pthread_getspecific.s */; }; - C94213391390396E004BA536 /* pthread_mutex_lock.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53822138D9E990028D27C /* pthread_mutex_lock.s */; }; - C942133A1390396E004BA536 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53823138D9E990028D27C /* pthread_self.s */; }; - C942133B1390396E004BA536 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53824138D9E990028D27C /* pthread_set_self.s */; }; - C942133C1390396E004BA536 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53825138D9E990028D27C /* start_wqthread.s */; }; - C942133D1390396E004BA536 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53826138D9E990028D27C /* thread_start.s */; }; - C942133E1390396E004BA536 /* __bzero.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382A138D9E990028D27C /* __bzero.s */; }; - C942133F1390396E004BA536 /* bcopy_scalar.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382C138D9E990028D27C /* bcopy_scalar.s */; }; - C94213401390396E004BA536 /* bcopy_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382D138D9E990028D27C /* bcopy_sse2.s */; }; - C94213411390396E004BA536 /* bcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382E138D9E990028D27C /* bcopy_sse3x.s */; }; - C94213421390396E004BA536 /* bcopy_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382F138D9E990028D27C /* bcopy_sse42.s */; }; - C94213431390396E004BA536 /* bzero_scalar.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53831138D9E990028D27C /* bzero_scalar.s */; }; - C94213441390396E004BA536 /* bzero_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53832138D9E990028D27C /* bzero_sse2.s */; }; - C94213451390396E004BA536 /* bzero_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53833138D9E990028D27C /* bzero_sse42.s */; }; - C94213461390396E004BA536 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53834138D9E990028D27C /* ffs.s */; }; - C94213471390396E004BA536 /* longcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53835138D9E990028D27C /* longcopy_sse3x.s */; }; - C94213481390396E004BA536 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53837138D9E990028D27C /* memcmp.s */; }; - C94213491390396E004BA536 /* memset.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383A138D9E990028D27C /* memset.s */; }; - C942134A1390396E004BA536 /* memset_pattern_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383B138D9E990028D27C /* memset_pattern_sse2.s */; }; - C942134B1390396E004BA536 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383C138D9E990028D27C /* strcmp.s */; }; C942134C1390396E004BA536 /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383D138D9E990028D27C /* strcpy.s */; }; C942134D1390396E004BA536 /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383E138D9E990028D27C /* strlcat.s */; }; C942134E1390396E004BA536 /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383F138D9E990028D27C /* strlcpy.s */; }; C942134F1390396E004BA536 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53840138D9E990028D27C /* strlen.s */; }; - C94213501390396E004BA536 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53841138D9E990028D27C /* strncmp.s */; }; C94213511390396E004BA536 /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53842138D9E990028D27C /* strncpy.s */; }; - C94213521390396E004BA536 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53844138D9E990028D27C /* _setjmp.s */; }; - C94213531390396E004BA536 /* _sigtramp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53845138D9E990028D27C /* _sigtramp.s */; }; - C94213541390396E004BA536 /* i386_gettimeofday_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53847138D9E990028D27C /* i386_gettimeofday_asm.s */; }; - C94213551390396E004BA536 /* mach_absolute_time_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53849138D9E990028D27C /* mach_absolute_time_asm.s */; }; - C94213561390396E004BA536 /* OSAtomic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384B138D9E990028D27C /* OSAtomic.s */; }; - C94213571390396E004BA536 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384C138D9E990028D27C /* setjmp.s */; }; - C94213581390396E004BA536 /* spinlocks_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384E138D9E990028D27C /* spinlocks_asm.s */; }; C95B7ED7138F3BEA004311DA /* rune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53989138D9E990028D27C /* rune.c */; }; C95B7EDD138F3C55004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; - C95B7EDE138F3C55004311DA /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; }; - C95B7EDF138F3C55004311DA /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; }; - C95B7EE0138F3C55004311DA /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; }; - C95B7EE1138F3C55004311DA /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; }; - C95B7EE2138F3C55004311DA /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; }; C95B7EE4138F3C55004311DA /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; }; C95B7EE5138F3C55004311DA /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; C95B7EE6138F3C55004311DA /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; @@ -1203,11 +1670,7 @@ C95B7EED138F3C55004311DA /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; }; C95B7EEE138F3C55004311DA /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; C95B7EEF138F3C55004311DA /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; }; - C95B7EF0138F3C55004311DA /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; }; C95B7EF1138F3C55004311DA /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; - C95B7EF2138F3C55004311DA /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; }; - C95B7EF3138F3C55004311DA /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; }; - C95B7EF4138F3C55004311DA /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; }; C95B7EF5138F3C55004311DA /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; C95B7EF6138F3C55004311DA /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; }; C95B7EF7138F3C55004311DA /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; }; @@ -1272,18 +1735,8 @@ C95B7F32138F3C55004311DA /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; }; C95B7F33138F3C55004311DA /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; C95B7F34138F3C55004311DA /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; - C95B7F35138F3C55004311DA /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; }; - C95B7F36138F3C55004311DA /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; }; - C95B7F37138F3C55004311DA /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; }; - C95B7F38138F3C55004311DA /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; }; - C95B7F39138F3C55004311DA /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; }; - C95B7F3A138F3C55004311DA /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; }; - C95B7F3B138F3C55004311DA /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; }; - C95B7F3C138F3C55004311DA /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; }; - C95B7F3D138F3C55004311DA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; }; C95B7F3E138F3C55004311DA /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; }; C95B7F3F138F3C55004311DA /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; - C95B7F40138F3C55004311DA /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; }; C95B7F41138F3C55004311DA /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; }; C95B7F42138F3C55004311DA /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; }; C95B7F43138F3C55004311DA /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; @@ -1329,7 +1782,6 @@ C95B7F6B138F3C55004311DA /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; }; C95B7F6C138F3C55004311DA /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; }; C95B7F6D138F3C55004311DA /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; }; - C95B7F6E138F3C55004311DA /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PSELECT"; }; }; C95B7F6F138F3C55004311DA /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; C95B7F70138F3C55004311DA /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; C95B7F71138F3C55004311DA /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; }; @@ -1373,42 +1825,19 @@ C95B7F97138F3C55004311DA /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; C95B7F98138F3C55004311DA /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; C95B7F99138F3C55004311DA /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; - C95B7F9A138F3C55004311DA /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; }; - C95B7F9B138F3C55004311DA /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; }; - C95B7F9C138F3C55004311DA /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; }; - C95B7F9D138F3C55004311DA /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; }; C95B7F9E138F3C55004311DA /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; }; C95B7F9F138F3C55004311DA /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; C95B7FA0138F3C55004311DA /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; }; C95B7FA1138F3C55004311DA /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; - C95B7FA2138F3C55004311DA /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; }; C95B7FA3138F3C55004311DA /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; }; - C95B7FA4138F3C55004311DA /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; }; - C95B7FA5138F3C55004311DA /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; }; C95B7FA6138F3C55004311DA /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; C95B7FA7138F3C55004311DA /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; - C95B7FA8138F3C55004311DA /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; }; - C95B7FA9138F3C55004311DA /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; }; C95B7FAA138F3C55004311DA /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; - C95B7FAB138F3C55004311DA /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; }; C95B7FAC138F3C55004311DA /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; C95B7FAD138F3C55004311DA /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; C95B7FAE138F3C55004311DA /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; C95B7FAF138F3C55004311DA /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; C95B7FB1138F3C55004311DA /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; - C95B7FB2138F3C55004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; }; - C95B7FB3138F3C55004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; }; - C95B7FB4138F3C55004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; }; - C95B7FB5138F3C55004311DA /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; }; - C95B7FB6138F3C55004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; }; - C95B7FB7138F3C55004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; }; - C95B7FB8138F3C55004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; }; - C95B7FB9138F3C55004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; }; - C95B7FBA138F3C55004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; }; - C95B7FBB138F3C55004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; }; - C95B7FBC138F3C55004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; }; - C95B7FBD138F3C55004311DA /* mach_absolute_time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53848138D9E990028D27C /* mach_absolute_time.c */; }; - C95B7FBE138F3C55004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; }; C95B7FD1138F3C55004311DA /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; }; C95B7FD2138F3C55004311DA /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; }; C95B7FD3138F3C55004311DA /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; }; @@ -1497,30 +1926,7 @@ C95B8026138F3C55004311DA /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; C95B8027138F3C55004311DA /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; C95B8028138F3C55004311DA /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; - C95B8031138F3C55004311DA /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; }; - C95B8032138F3C55004311DA /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; }; - C95B8033138F3C55004311DA /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; }; - C95B8034138F3C55004311DA /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; }; - C95B8035138F3C55004311DA /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; }; - C95B8036138F3C55004311DA /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; }; - C95B8037138F3C55004311DA /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; }; - C95B8038138F3C55004311DA /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; }; - C95B8039138F3C55004311DA /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; }; C95B803C138F3C55004311DA /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; - C95B803F138F3C55004311DA /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; - C95B8040138F3C55004311DA /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; - C95B8041138F3C55004311DA /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; - C95B8042138F3C55004311DA /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; - C95B8043138F3C55004311DA /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; - C95B8044138F3C55004311DA /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; - C95B8045138F3C55004311DA /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; - C95B8046138F3C55004311DA /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; - C95B8047138F3C55004311DA /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; - C95B8048138F3C55004311DA /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; - C95B8049138F3C55004311DA /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; - C95B804A138F3C55004311DA /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; - C95B804B138F3C55004311DA /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; - C95B804C138F3C55004311DA /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; C95B804D138F3C55004311DA /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; }; C95B804E138F3C55004311DA /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; }; C95B804F138F3C55004311DA /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; }; @@ -1686,29 +2092,17 @@ C95B80EF138F3C55004311DA /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; C95B80F0138F3C55004311DA /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; }; C95B80F1138F3C55004311DA /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; - C95B80F2138F3C55004311DA /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; }; - C95B80F3138F3C55004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; }; - C95B80F4138F3C55004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; }; C95B80F5138F3C55004311DA /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; - C95B80F6138F3C55004311DA /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; }; - C95B80F7138F3C55004311DA /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; }; - C95B80F8138F3C55004311DA /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; }; - C95B80F9138F3C55004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; }; C95B80FA138F3C55004311DA /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; - C95B80FB138F3C55004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; }; - C95B80FC138F3C55004311DA /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; }; C95B80FD138F3C55004311DA /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; C95B8100138F3C55004311DA /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; C95B8101138F3C55004311DA /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; - C95B8103138F3C55004311DA /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; }; - C95B8104138F3C55004311DA /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; }; C95B8105138F3C55004311DA /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; C95B8107138F3C55004311DA /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; C95B8108138F3C55004311DA /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; }; C95B8109138F3C55004311DA /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; }; C95B810C138F3C55004311DA /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; C95B810D138F3C55004311DA /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; - C95B810F138F3C55004311DA /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; }; C95B8111138F3C55004311DA /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; C95B8112138F3C55004311DA /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; C95B8113138F3C55004311DA /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; @@ -1751,15 +2145,12 @@ C95B8138138F3C55004311DA /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; }; C95B8139138F3C55004311DA /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; }; C95B813A138F3C55004311DA /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; - C95B813B138F3C55004311DA /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; }; + C95B813B138F3C55004311DA /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; C95B813C138F3C55004311DA /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; C95B813D138F3C55004311DA /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; - C95B813E138F3C55004311DA /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; }; C95B813F138F3C55004311DA /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; - C95B8140138F3C55004311DA /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; }; C95B8141138F3C55004311DA /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; C95B8142138F3C55004311DA /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; }; - C95B8143138F3C55004311DA /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; }; C95B8144138F3C55004311DA /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; C95B8145138F3C55004311DA /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; }; C95B8146138F3C55004311DA /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; }; @@ -1771,14 +2162,8 @@ C95B814C138F3C55004311DA /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; C95B814D138F3C55004311DA /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; }; C95B814E138F3C55004311DA /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; - C95B814F138F3C55004311DA /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; }; - C95B8150138F3C55004311DA /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; }; - C95B8151138F3C55004311DA /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; }; C95B8152138F3C55004311DA /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; C95B8153138F3C55004311DA /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; - C95B8154138F3C55004311DA /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; }; - C95B8155138F3C55004311DA /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; }; - C95B8156138F3C55004311DA /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; }; C95B8157138F3C55004311DA /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; }; C95B8158138F3C55004311DA /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; C95B8159138F3C55004311DA /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; @@ -1795,22 +2180,7 @@ C95B8164138F3C55004311DA /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; }; C95B8165138F3C55004311DA /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; }; C95B8166138F3C55004311DA /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; }; - C95B8167138F3C55004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; }; - C95B8168138F3C55004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; }; - C95B8169138F3C55004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; }; - C95B816A138F3C55004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; }; - C95B816B138F3C55004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; }; - C95B816C138F3C55004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; }; - C95B816D138F3C55004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; }; - C95B816E138F3C55004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; }; - C95B816F138F3C55004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; }; - C95B8170138F3C55004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; }; C95B8188138F52B0004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; - C95B8189138F52B0004311DA /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; }; - C95B818A138F52B0004311DA /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; }; - C95B818B138F52B0004311DA /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; }; - C95B818C138F52B0004311DA /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; }; - C95B818D138F52B0004311DA /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; }; C95B818F138F52B0004311DA /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; }; C95B8190138F52B0004311DA /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; C95B8191138F52B0004311DA /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; @@ -1823,11 +2193,7 @@ C95B8198138F52B0004311DA /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; }; C95B8199138F52B0004311DA /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; C95B819A138F52B0004311DA /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; }; - C95B819B138F52B0004311DA /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; }; C95B819C138F52B0004311DA /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; - C95B819D138F52B0004311DA /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; }; - C95B819E138F52B0004311DA /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; }; - C95B819F138F52B0004311DA /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; }; C95B81A0138F52B0004311DA /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; C95B81A1138F52B0004311DA /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; }; C95B81A2138F52B0004311DA /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; }; @@ -1892,18 +2258,8 @@ C95B81DD138F52B0004311DA /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; }; C95B81DE138F52B0004311DA /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; C95B81DF138F52B0004311DA /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; - C95B81E0138F52B0004311DA /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; }; - C95B81E1138F52B0004311DA /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; }; - C95B81E2138F52B0004311DA /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; }; - C95B81E3138F52B0004311DA /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; }; - C95B81E4138F52B0004311DA /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; }; - C95B81E5138F52B0004311DA /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; }; - C95B81E6138F52B0004311DA /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; }; - C95B81E7138F52B0004311DA /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; }; - C95B81E8138F52B0004311DA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; }; C95B81E9138F52B0004311DA /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; }; C95B81EA138F52B0004311DA /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; - C95B81EB138F52B0004311DA /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; }; C95B81EC138F52B0004311DA /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; }; C95B81ED138F52B0004311DA /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; }; C95B81EE138F52B0004311DA /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; @@ -1949,7 +2305,6 @@ C95B8216138F52B0004311DA /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; }; C95B8217138F52B0004311DA /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; }; C95B8218138F52B0004311DA /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; }; - C95B8219138F52B0004311DA /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PSELECT"; }; }; C95B821A138F52B0004311DA /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; C95B821B138F52B0004311DA /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; C95B821C138F52B0004311DA /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; }; @@ -1993,42 +2348,19 @@ C95B8242138F52B0004311DA /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; C95B8243138F52B0004311DA /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; C95B8244138F52B0004311DA /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; - C95B8245138F52B0004311DA /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; }; - C95B8246138F52B0004311DA /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; }; - C95B8247138F52B0004311DA /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; }; - C95B8248138F52B0004311DA /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; }; C95B8249138F52B0004311DA /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; }; C95B824A138F52B0004311DA /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; C95B824B138F52B0004311DA /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; }; C95B824C138F52B0004311DA /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; - C95B824D138F52B0004311DA /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; }; C95B824E138F52B0004311DA /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; }; - C95B824F138F52B0004311DA /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; }; - C95B8250138F52B0004311DA /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; }; C95B8251138F52B0004311DA /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; C95B8252138F52B0004311DA /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; - C95B8253138F52B0004311DA /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; }; - C95B8254138F52B0004311DA /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; }; C95B8255138F52B0004311DA /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; - C95B8256138F52B0004311DA /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; }; C95B8257138F52B0004311DA /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; C95B8258138F52B0004311DA /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; C95B8259138F52B0004311DA /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; C95B825A138F52B0004311DA /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; C95B825C138F52B0004311DA /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; - C95B825D138F52B0004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; }; - C95B825E138F52B0004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; }; - C95B825F138F52B0004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; }; - C95B8260138F52B0004311DA /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; }; - C95B8261138F52B0004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; }; - C95B8262138F52B0004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; }; - C95B8263138F52B0004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; }; - C95B8264138F52B0004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; }; - C95B8265138F52B0004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; }; - C95B8266138F52B0004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; }; - C95B8267138F52B0004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; }; - C95B8268138F52B0004311DA /* mach_absolute_time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53848138D9E990028D27C /* mach_absolute_time.c */; }; - C95B8269138F52B0004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; }; C95B827C138F52B0004311DA /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; }; C95B827D138F52B0004311DA /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; }; C95B827E138F52B0004311DA /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; }; @@ -2117,30 +2449,7 @@ C95B82D1138F52B0004311DA /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; C95B82D2138F52B0004311DA /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; C95B82D3138F52B0004311DA /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; - C95B82DC138F52B0004311DA /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; }; - C95B82DD138F52B0004311DA /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; }; - C95B82DE138F52B0004311DA /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; }; - C95B82DF138F52B0004311DA /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; }; - C95B82E0138F52B0004311DA /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; }; - C95B82E1138F52B0004311DA /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; }; - C95B82E2138F52B0004311DA /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; }; - C95B82E3138F52B0004311DA /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; }; - C95B82E4138F52B0004311DA /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; }; C95B82E7138F52B0004311DA /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; - C95B82EA138F52B0004311DA /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; - C95B82EB138F52B0004311DA /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; - C95B82EC138F52B0004311DA /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; - C95B82ED138F52B0004311DA /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; - C95B82EE138F52B0004311DA /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; - C95B82EF138F52B0004311DA /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; - C95B82F0138F52B0004311DA /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; - C95B82F1138F52B0004311DA /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; - C95B82F2138F52B0004311DA /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; - C95B82F3138F52B0004311DA /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; - C95B82F4138F52B0004311DA /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; - C95B82F5138F52B0004311DA /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; - C95B82F6138F52B0004311DA /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; - C95B82F7138F52B0004311DA /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; C95B82F8138F52B0004311DA /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; }; C95B82F9138F52B0004311DA /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; }; C95B82FA138F52B0004311DA /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; }; @@ -2306,29 +2615,17 @@ C95B839A138F52B0004311DA /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; C95B839B138F52B0004311DA /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; }; C95B839C138F52B0004311DA /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; - C95B839D138F52B0004311DA /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; }; - C95B839E138F52B0004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; }; - C95B839F138F52B0004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; }; C95B83A0138F52B0004311DA /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; - C95B83A1138F52B0004311DA /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; }; - C95B83A2138F52B0004311DA /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; }; - C95B83A3138F52B0004311DA /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; }; - C95B83A4138F52B0004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; }; C95B83A5138F52B0004311DA /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; - C95B83A6138F52B0004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; }; - C95B83A7138F52B0004311DA /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; }; C95B83A8138F52B0004311DA /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; C95B83AB138F52B0004311DA /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; C95B83AC138F52B0004311DA /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; - C95B83AE138F52B0004311DA /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; }; - C95B83AF138F52B0004311DA /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; }; C95B83B0138F52B0004311DA /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; C95B83B2138F52B0004311DA /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; C95B83B3138F52B0004311DA /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; }; C95B83B4138F52B0004311DA /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; }; C95B83B7138F52B0004311DA /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; C95B83B8138F52B0004311DA /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; - C95B83BA138F52B0004311DA /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; }; C95B83BC138F52B0004311DA /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; C95B83BD138F52B0004311DA /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; C95B83BE138F52B0004311DA /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; @@ -2371,15 +2668,12 @@ C95B83E3138F52B0004311DA /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; }; C95B83E4138F52B0004311DA /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; }; C95B83E5138F52B0004311DA /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; - C95B83E6138F52B0004311DA /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; }; + C95B83E6138F52B0004311DA /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; C95B83E7138F52B0004311DA /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; C95B83E8138F52B0004311DA /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; - C95B83E9138F52B0004311DA /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; }; C95B83EA138F52B0004311DA /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; - C95B83EB138F52B0004311DA /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; }; C95B83EC138F52B0004311DA /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; C95B83ED138F52B0004311DA /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; }; - C95B83EE138F52B0004311DA /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; }; C95B83EF138F52B0004311DA /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; C95B83F0138F52B0004311DA /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; }; C95B83F1138F52B0004311DA /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; }; @@ -2391,14 +2685,8 @@ C95B83F7138F52B0004311DA /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; C95B83F8138F52B0004311DA /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; }; C95B83F9138F52B0004311DA /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; - C95B83FA138F52B0004311DA /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; }; - C95B83FB138F52B0004311DA /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; }; - C95B83FC138F52B0004311DA /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; }; C95B83FD138F52B0004311DA /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; C95B83FE138F52B0004311DA /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; - C95B83FF138F52B0004311DA /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; }; - C95B8400138F52B0004311DA /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; }; - C95B8401138F52B0004311DA /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; }; C95B8402138F52B0004311DA /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; }; C95B8403138F52B0004311DA /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; C95B8404138F52B0004311DA /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; @@ -2415,22 +2703,7 @@ C95B840F138F52B0004311DA /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; }; C95B8410138F52B0004311DA /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; }; C95B8411138F52B0004311DA /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; }; - C95B8412138F52B0004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; }; - C95B8413138F52B0004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; }; - C95B8414138F52B0004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; }; - C95B8415138F52B0004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; }; - C95B8416138F52B0004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; }; - C95B8417138F52B0004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; }; - C95B8418138F52B0004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; }; - C95B8419138F52B0004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; }; - C95B841A138F52B0004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; }; - C95B841B138F52B0004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; }; C95B842E138F53DB004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; - C95B842F138F53DB004311DA /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; }; - C95B8430138F53DB004311DA /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; }; - C95B8431138F53DB004311DA /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; }; - C95B8432138F53DB004311DA /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; }; - C95B8433138F53DB004311DA /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; }; C95B8435138F53DB004311DA /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; }; C95B8436138F53DB004311DA /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; C95B8437138F53DB004311DA /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; @@ -2443,11 +2716,7 @@ C95B843E138F53DB004311DA /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; }; C95B843F138F53DB004311DA /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; C95B8440138F53DB004311DA /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; }; - C95B8441138F53DB004311DA /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; }; C95B8442138F53DB004311DA /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; - C95B8443138F53DB004311DA /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; }; - C95B8444138F53DB004311DA /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; }; - C95B8445138F53DB004311DA /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; }; C95B8446138F53DB004311DA /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; C95B8447138F53DB004311DA /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; }; C95B8448138F53DB004311DA /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; }; @@ -2512,18 +2781,8 @@ C95B8483138F53DB004311DA /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; }; C95B8484138F53DB004311DA /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; C95B8485138F53DB004311DA /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; - C95B8486138F53DB004311DA /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; }; - C95B8487138F53DB004311DA /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; }; - C95B8488138F53DB004311DA /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; }; - C95B8489138F53DB004311DA /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; }; - C95B848A138F53DB004311DA /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; }; - C95B848B138F53DB004311DA /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; }; - C95B848C138F53DB004311DA /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; }; - C95B848D138F53DB004311DA /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; }; - C95B848E138F53DB004311DA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; }; C95B848F138F53DB004311DA /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; }; C95B8490138F53DB004311DA /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; - C95B8491138F53DB004311DA /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; }; C95B8492138F53DB004311DA /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; }; C95B8493138F53DB004311DA /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; }; C95B8494138F53DB004311DA /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; @@ -2569,7 +2828,6 @@ C95B84BC138F53DB004311DA /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; }; C95B84BD138F53DB004311DA /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; }; C95B84BE138F53DB004311DA /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; }; - C95B84BF138F53DB004311DA /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PSELECT $(FreeBSD_CFLAGS)"; }; }; C95B84C0138F53DB004311DA /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; C95B84C1138F53DB004311DA /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; C95B84C2138F53DB004311DA /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; }; @@ -2613,42 +2871,19 @@ C95B84E8138F53DB004311DA /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; C95B84E9138F53DB004311DA /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; C95B84EA138F53DB004311DA /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; - C95B84EB138F53DB004311DA /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; }; - C95B84EC138F53DB004311DA /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; }; - C95B84ED138F53DB004311DA /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; }; - C95B84EE138F53DB004311DA /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; }; C95B84EF138F53DB004311DA /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; }; C95B84F0138F53DB004311DA /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; C95B84F1138F53DB004311DA /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; }; C95B84F2138F53DB004311DA /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; - C95B84F3138F53DB004311DA /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; }; C95B84F4138F53DB004311DA /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; }; - C95B84F5138F53DB004311DA /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; }; - C95B84F6138F53DB004311DA /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; }; C95B84F7138F53DB004311DA /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; C95B84F8138F53DB004311DA /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; - C95B84F9138F53DB004311DA /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; }; - C95B84FA138F53DB004311DA /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; }; C95B84FB138F53DB004311DA /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; - C95B84FC138F53DB004311DA /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; }; C95B84FD138F53DB004311DA /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; C95B84FE138F53DB004311DA /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; C95B84FF138F53DB004311DA /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; C95B8500138F53DB004311DA /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; C95B8502138F53DB004311DA /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; - C95B8503138F53DB004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; }; - C95B8504138F53DB004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; }; - C95B8505138F53DB004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; }; - C95B8506138F53DB004311DA /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; }; - C95B8507138F53DB004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; }; - C95B8508138F53DB004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; }; - C95B8509138F53DB004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; }; - C95B850A138F53DB004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; }; - C95B850B138F53DB004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; }; - C95B850C138F53DB004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; }; - C95B850D138F53DB004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; }; - C95B850E138F53DB004311DA /* mach_absolute_time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53848138D9E990028D27C /* mach_absolute_time.c */; }; - C95B850F138F53DB004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; }; C95B8522138F53DB004311DA /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; }; C95B8523138F53DB004311DA /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; }; C95B8524138F53DB004311DA /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; }; @@ -2737,30 +2972,7 @@ C95B8577138F53DB004311DA /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; C95B8578138F53DB004311DA /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; C95B8579138F53DB004311DA /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; - C95B8582138F53DB004311DA /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; }; - C95B8583138F53DB004311DA /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; }; - C95B8584138F53DB004311DA /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; }; - C95B8585138F53DB004311DA /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; }; - C95B8586138F53DB004311DA /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; }; - C95B8587138F53DB004311DA /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; }; - C95B8588138F53DB004311DA /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; }; - C95B8589138F53DB004311DA /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; }; - C95B858A138F53DB004311DA /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; }; C95B858D138F53DB004311DA /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; - C95B8590138F53DB004311DA /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; - C95B8591138F53DB004311DA /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; - C95B8592138F53DB004311DA /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; - C95B8593138F53DB004311DA /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; - C95B8594138F53DB004311DA /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; - C95B8595138F53DB004311DA /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; - C95B8596138F53DB004311DA /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; - C95B8597138F53DB004311DA /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; - C95B8598138F53DB004311DA /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; - C95B8599138F53DB004311DA /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; - C95B859A138F53DB004311DA /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; - C95B859B138F53DB004311DA /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; - C95B859C138F53DB004311DA /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; - C95B859D138F53DB004311DA /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; C95B859E138F53DB004311DA /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; }; C95B859F138F53DB004311DA /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; }; C95B85A0138F53DB004311DA /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; }; @@ -2926,29 +3138,17 @@ C95B8640138F53DB004311DA /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; C95B8641138F53DB004311DA /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; }; C95B8642138F53DB004311DA /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; - C95B8643138F53DB004311DA /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; }; - C95B8644138F53DB004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; }; - C95B8645138F53DB004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; }; C95B8646138F53DB004311DA /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; - C95B8647138F53DB004311DA /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; }; - C95B8648138F53DB004311DA /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; }; - C95B8649138F53DB004311DA /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; }; - C95B864A138F53DB004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; }; C95B864B138F53DB004311DA /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; - C95B864C138F53DB004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; }; - C95B864D138F53DB004311DA /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; }; C95B864E138F53DB004311DA /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; C95B8651138F53DB004311DA /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; C95B8652138F53DB004311DA /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; - C95B8654138F53DB004311DA /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; }; - C95B8655138F53DB004311DA /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; }; C95B8656138F53DB004311DA /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; C95B8658138F53DB004311DA /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; C95B8659138F53DB004311DA /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; }; C95B865A138F53DB004311DA /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; }; C95B865D138F53DB004311DA /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; C95B865E138F53DB004311DA /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; - C95B8660138F53DB004311DA /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; }; C95B8662138F53DB004311DA /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; C95B8663138F53DB004311DA /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; C95B8664138F53DB004311DA /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; @@ -2991,15 +3191,12 @@ C95B8689138F53DB004311DA /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; }; C95B868A138F53DB004311DA /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; }; C95B868B138F53DB004311DA /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; - C95B868C138F53DB004311DA /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; }; + C95B868C138F53DB004311DA /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; C95B868D138F53DB004311DA /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; C95B868E138F53DB004311DA /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; - C95B868F138F53DB004311DA /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; }; C95B8690138F53DB004311DA /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; - C95B8691138F53DB004311DA /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; }; C95B8692138F53DB004311DA /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; C95B8693138F53DB004311DA /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; }; - C95B8694138F53DB004311DA /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; }; C95B8695138F53DB004311DA /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; C95B8696138F53DB004311DA /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; }; C95B8697138F53DB004311DA /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; }; @@ -3011,14 +3208,8 @@ C95B869D138F53DB004311DA /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; C95B869E138F53DB004311DA /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; }; C95B869F138F53DB004311DA /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; - C95B86A0138F53DB004311DA /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; }; - C95B86A1138F53DB004311DA /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; }; - C95B86A2138F53DB004311DA /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; }; C95B86A3138F53DB004311DA /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; C95B86A4138F53DB004311DA /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; - C95B86A5138F53DB004311DA /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; }; - C95B86A6138F53DB004311DA /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; }; - C95B86A7138F53DB004311DA /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; }; C95B86A8138F53DB004311DA /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; }; C95B86A9138F53DB004311DA /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; C95B86AA138F53DB004311DA /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; @@ -3035,23 +3226,7 @@ C95B86B5138F53DB004311DA /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; }; C95B86B6138F53DB004311DA /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; }; C95B86B7138F53DB004311DA /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; }; - C95B86B8138F53DB004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; }; - C95B86B9138F53DB004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; }; - C95B86BA138F53DB004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; }; - C95B86BB138F53DB004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; }; - C95B86BC138F53DB004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; }; - C95B86BD138F53DB004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; }; - C95B86BE138F53DB004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; }; - C95B86BF138F53DB004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; }; - C95B86C0138F53DB004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; }; - C95B86C1138F53DB004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; }; - C965CBF2143BBEC7003912CE /* deps.c in Sources */ = {isa = PBXBuildFile; fileRef = C965CBF1143BBEC7003912CE /* deps.c */; }; C9765EB2138EC61900741512 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; - C9765EB3138EC61900741512 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; }; - C9765EB4138EC61900741512 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; }; - C9765EB5138EC61900741512 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; }; - C9765EB6138EC61900741512 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; }; - C9765EB7138EC61900741512 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; }; C9765EB9138EC61900741512 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; }; C9765EBA138EC61900741512 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; C9765EBB138EC61900741512 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; @@ -3064,11 +3239,7 @@ C9765EC2138EC61900741512 /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; }; C9765EC3138EC61900741512 /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; C9765EC4138EC61900741512 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; }; - C9765EC5138EC61900741512 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; }; C9765EC6138EC61900741512 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; - C9765EC7138EC61900741512 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; }; - C9765EC8138EC61900741512 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; }; - C9765EC9138EC61900741512 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; }; C9765ECA138EC61900741512 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; C9765ECB138EC61900741512 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; }; C9765ECC138EC61900741512 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; }; @@ -3133,18 +3304,8 @@ C9765F07138EC61900741512 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; }; C9765F08138EC61900741512 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; C9765F09138EC61900741512 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; - C9765F0A138EC61900741512 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; }; - C9765F0B138EC61900741512 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; }; - C9765F0C138EC61900741512 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; }; - C9765F0D138EC61900741512 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; }; - C9765F0E138EC61900741512 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; }; - C9765F0F138EC61900741512 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; }; - C9765F10138EC61900741512 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; }; - C9765F11138EC61900741512 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; }; - C9765F12138EC61900741512 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; }; C9765F13138EC61900741512 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; }; C9765F14138EC61900741512 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; - C9765F15138EC61900741512 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; }; C9765F16138EC61900741512 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; }; C9765F17138EC61900741512 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; }; C9765F18138EC61900741512 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; @@ -3188,9 +3349,8 @@ C9765F3E138EC61900741512 /* nice.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374C138D9E990028D27C /* nice.c */; }; C9765F3F138EC61900741512 /* nrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374E138D9E990028D27C /* nrand48.c */; }; C9765F40138EC61900741512 /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; }; - C9765F41138EC61900741512 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; }; + C9765F41138EC61900741512 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; }; C9765F42138EC61900741512 /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; }; - C9765F43138EC61900741512 /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PSELECT"; }; }; C9765F44138EC61900741512 /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; C9765F45138EC61900741512 /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; C9765F46138EC61900741512 /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; }; @@ -3205,7 +3365,7 @@ C9765F4F138EC61900741512 /* siginterrupt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377C138D9E990028D27C /* siginterrupt.c */; }; C9765F50138EC61900741512 /* siglist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377D138D9E990028D27C /* siglist.c */; }; C9765F51138EC61900741512 /* signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53781138D9E990028D27C /* signal.c */; }; - C9765F52138EC61900741512 /* sleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53787138D9E990028D27C /* sleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SLEEP"; }; }; + C9765F52138EC61900741512 /* sleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53787138D9E990028D27C /* sleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SLEEP -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; }; C9765F53138EC61900741512 /* srand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53789138D9E990028D27C /* srand48.c */; }; C9765F54138EC61900741512 /* stringlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378C138D9E990028D27C /* stringlist.c */; }; C9765F55138EC61900741512 /* sysconf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378E138D9E990028D27C /* sysconf.c */; }; @@ -3213,7 +3373,7 @@ C9765F57138EC61900741512 /* sysctlbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53794138D9E990028D27C /* sysctlbyname.c */; }; C9765F58138EC61900741512 /* sysctlnametomib.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53795138D9E990028D27C /* sysctlnametomib.c */; }; C9765F59138EC61900741512 /* telldir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53796138D9E990028D27C /* telldir.c */; }; - C9765F5A138EC61900741512 /* termios.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5379A138D9E990028D27C /* termios.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TCDRAIN"; }; }; + C9765F5A138EC61900741512 /* termios.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5379A138D9E990028D27C /* termios.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TCDRAIN -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; }; C9765F5B138EC61900741512 /* time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5379E138D9E990028D27C /* time.c */; }; C9765F5C138EC61900741512 /* times.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A2138D9E990028D27C /* times.c */; }; C9765F5D138EC61900741512 /* timezone.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A4138D9E990028D27C /* timezone.c */; }; @@ -3222,54 +3382,31 @@ C9765F60138EC61900741512 /* ualarm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537AC138D9E990028D27C /* ualarm.c */; }; C9765F61138EC61900741512 /* ulimit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B0138D9E990028D27C /* ulimit.c */; }; C9765F62138EC61900741512 /* unvis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B2138D9E990028D27C /* unvis.c */; }; - C9765F63138EC61900741512 /* usleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B6138D9E990028D27C /* usleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_USLEEP"; }; }; + C9765F63138EC61900741512 /* usleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B6138D9E990028D27C /* usleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_USLEEP -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; }; C9765F64138EC61900741512 /* utime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BA138D9E990028D27C /* utime.c */; }; C9765F65138EC61900741512 /* vis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BC138D9E990028D27C /* vis.c */; }; - C9765F66138EC61900741512 /* wait.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BE138D9E990028D27C /* wait.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAIT"; }; }; + C9765F66138EC61900741512 /* wait.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BE138D9E990028D27C /* wait.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAIT -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; }; C9765F67138EC61900741512 /* wait3.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C0138D9E990028D27C /* wait3.c */; }; - C9765F68138EC61900741512 /* waitpid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C1138D9E990028D27C /* waitpid.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAITPID"; }; }; + C9765F68138EC61900741512 /* waitpid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C1138D9E990028D27C /* waitpid.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAITPID -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; }; C9765F69138EC61900741512 /* fts.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C4138D9E990028D27C /* fts.c */; }; C9765F6A138EC61900741512 /* get_compat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C6138D9E990028D27C /* get_compat.c */; }; C9765F6B138EC61900741512 /* getloadavg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CA138D9E990028D27C /* getloadavg.c */; }; C9765F6C138EC61900741512 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; C9765F6D138EC61900741512 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; C9765F6E138EC61900741512 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; - C9765F6F138EC61900741512 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; }; - C9765F70138EC61900741512 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; }; - C9765F71138EC61900741512 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; }; - C9765F72138EC61900741512 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; }; C9765F73138EC61900741512 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; }; C9765F74138EC61900741512 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; C9765F75138EC61900741512 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; }; C9765F76138EC61900741512 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; - C9765F77138EC61900741512 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; }; C9765F78138EC61900741512 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; }; - C9765F79138EC61900741512 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; }; - C9765F7A138EC61900741512 /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; }; C9765F7B138EC61900741512 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; C9765F7C138EC61900741512 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; - C9765F7D138EC61900741512 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; }; - C9765F7E138EC61900741512 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; }; C9765F7F138EC61900741512 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; - C9765F80138EC61900741512 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; }; C9765F81138EC61900741512 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; C9765F82138EC61900741512 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; C9765F83138EC61900741512 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; C9765F84138EC61900741512 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; C9765F86138EC61900741512 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; - C9765F87138EC61900741512 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; }; - C9765F88138EC61900741512 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; }; - C9765F89138EC61900741512 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; }; - C9765F8A138EC61900741512 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; }; - C9765F8B138EC61900741512 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; }; - C9765F8C138EC61900741512 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; }; - C9765F8D138EC61900741512 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; }; - C9765F8E138EC61900741512 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; }; - C9765F8F138EC61900741512 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; }; - C9765F90138EC61900741512 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; }; - C9765F91138EC61900741512 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; }; - C9765F92138EC61900741512 /* mach_absolute_time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53848138D9E990028D27C /* mach_absolute_time.c */; }; - C9765F93138EC61900741512 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; }; C9765FA6138EC61900741512 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; }; C9765FA7138EC61900741512 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; }; C9765FA8138EC61900741512 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; }; @@ -3358,30 +3495,7 @@ C9765FFB138EC61900741512 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; C9765FFC138EC61900741512 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; C9765FFD138EC61900741512 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; - C9766006138EC61900741512 /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; }; - C9766007138EC61900741512 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; }; - C9766008138EC61900741512 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; }; - C9766009138EC61900741512 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; }; - C976600A138EC61900741512 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; }; - C976600B138EC61900741512 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; }; - C976600C138EC61900741512 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; }; - C976600D138EC61900741512 /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; }; - C976600E138EC61900741512 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; }; C9766011138EC61900741512 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; - C9766014138EC61900741512 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; - C9766015138EC61900741512 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; - C9766016138EC61900741512 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; - C9766017138EC61900741512 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; - C9766018138EC61900741512 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; - C9766019138EC61900741512 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; - C976601A138EC61A00741512 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; - C976601B138EC61A00741512 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; - C976601C138EC61A00741512 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; - C976601D138EC61A00741512 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; - C976601E138EC61A00741512 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; - C976601F138EC61A00741512 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; - C9766020138EC61A00741512 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; - C9766021138EC61A00741512 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; C9766022138EC61A00741512 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; }; C9766023138EC61A00741512 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; }; C9766024138EC61A00741512 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; }; @@ -3547,29 +3661,17 @@ C97660C4138EC61A00741512 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; C97660C5138EC61A00741512 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; }; C97660C6138EC61A00741512 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; - C97660C7138EC61A00741512 /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; }; - C97660C8138EC61A00741512 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; }; - C97660C9138EC61A00741512 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; }; C97660CA138EC61A00741512 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; - C97660CB138EC61A00741512 /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; }; - C97660CC138EC61A00741512 /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; }; - C97660CD138EC61A00741512 /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; }; - C97660CE138EC61A00741512 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; }; C97660CF138EC61A00741512 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; - C97660D0138EC61A00741512 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; }; - C97660D1138EC61A00741512 /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; }; C97660D2138EC61A00741512 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; C97660D5138EC61A00741512 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; C97660D6138EC61A00741512 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; - C97660D8138EC61A00741512 /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; }; - C97660D9138EC61A00741512 /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; }; C97660DA138EC61A00741512 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; C97660DC138EC61A00741512 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; C97660DD138EC61A00741512 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; }; C97660DE138EC61A00741512 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; }; C97660E1138EC61A00741512 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; C97660E2138EC61A00741512 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; - C97660E4138EC61A00741512 /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; }; C97660E6138EC61A00741512 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; C97660E7138EC61A00741512 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; C97660E8138EC61A00741512 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; @@ -3612,15 +3714,12 @@ C976610D138EC61A00741512 /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; }; C976610E138EC61A00741512 /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; }; C976610F138EC61A00741512 /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; - C9766110138EC61A00741512 /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; }; + C9766110138EC61A00741512 /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; C9766111138EC61A00741512 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; C9766112138EC61A00741512 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; - C9766113138EC61A00741512 /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; }; C9766114138EC61A00741512 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; - C9766115138EC61A00741512 /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; }; C9766116138EC61A00741512 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; C9766117138EC61A00741512 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; }; - C9766118138EC61A00741512 /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; }; C9766119138EC61A00741512 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; C976611A138EC61A00741512 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; }; C976611B138EC61A00741512 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; }; @@ -3632,14 +3731,8 @@ C9766121138EC61A00741512 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; C9766122138EC61A00741512 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; }; C9766123138EC61A00741512 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; - C9766124138EC61A00741512 /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; }; - C9766125138EC61A00741512 /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; }; - C9766126138EC61A00741512 /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; }; C9766127138EC61A00741512 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; C9766128138EC61A00741512 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; - C9766129138EC61A00741512 /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; }; - C976612A138EC61A00741512 /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; }; - C976612B138EC61A00741512 /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; }; C976612C138EC61A00741512 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; }; C976612D138EC61A00741512 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; C976612E138EC61A00741512 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; @@ -3656,21 +3749,588 @@ C9766139138EC61A00741512 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; }; C976613A138EC61A00741512 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; }; C976613B138EC61A00741512 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; }; - C976613C138EC61A00741512 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; }; - C976613D138EC61A00741512 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; }; - C976613E138EC61A00741512 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; }; - C976613F138EC61A00741512 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; }; - C9766140138EC61A00741512 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; }; - C9766141138EC61A00741512 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; }; - C9766142138EC61A00741512 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; }; - C9766143138EC61A00741512 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; }; - C9766144138EC61A00741512 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; }; - C9766145138EC61A00741512 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; }; - C97C344113AB0E1B00713550 /* Spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C97C344013AB0E1B00713550 /* Spinlocks.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; - C980F8EC13AB168D0069AB06 /* SpinlocksUP.c in Sources */ = {isa = PBXBuildFile; fileRef = C980F8EB13AB168D0069AB06 /* SpinlocksUP.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; + C97A6F291517AF53005E1998 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53819138D9E990028D27C /* mcount.s */; }; + C97A6F3F1517AF53005E1998 /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383D138D9E990028D27C /* strcpy.s */; }; + C97A6F401517AF53005E1998 /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383E138D9E990028D27C /* strlcat.s */; }; + C97A6F411517AF53005E1998 /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383F138D9E990028D27C /* strlcpy.s */; }; + C97A6F421517AF53005E1998 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53840138D9E990028D27C /* strlen.s */; }; + C97A6F441517AF53005E1998 /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53842138D9E990028D27C /* strncpy.s */; }; + C97A6F5A1517AF53005E1998 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CF138D9E980028D27C /* strlen.s */; }; + C97A6F5C1517AF53005E1998 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D2138D9E980028D27C /* strnlen.s */; }; + C97A6F5D1517AF53005E1998 /* strstr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D3138D9E980028D27C /* strstr.s */; }; + C97A6F6D1517AF53005E1998 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF9138D9E9A0028D27C /* mcount.s */; }; + C97A6F761517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C97A6F791517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C97A6F7A1517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C97A6F7E1517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C97A6F8F1517AF53005E1998 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; + C97A6F961517AF53005E1998 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; }; + C97A6F971517AF53005E1998 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; + C97A6F981517AF53005E1998 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; + C97A6F991517AF53005E1998 /* killpg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53601138D9E980028D27C /* killpg.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_KILLPG"; }; }; + C97A6F9A1517AF53005E1998 /* sethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53603138D9E980028D27C /* sethostid.c */; }; + C97A6F9B1517AF53005E1998 /* setpgrp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53604138D9E980028D27C /* setpgrp.c */; }; + C97A6F9C1517AF53005E1998 /* setrgid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53606138D9E980028D27C /* setrgid.c */; }; + C97A6F9D1517AF53005E1998 /* setruid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53608138D9E980028D27C /* setruid.c */; }; + C97A6F9E1517AF53005E1998 /* setregid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360A138D9E980028D27C /* setregid.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SETREGID"; }; }; + C97A6F9F1517AF53005E1998 /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SETREUID"; }; }; + C97A6FA01517AF53005E1998 /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; + C97A6FA11517AF53005E1998 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; }; + C97A6FA31517AF53005E1998 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; + C97A6FA71517AF53005E1998 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; + C97A6FA81517AF53005E1998 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; }; + C97A6FA91517AF53005E1998 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; }; + C97A6FAA1517AF53005E1998 /* bt_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53622138D9E980028D27C /* bt_debug.c */; }; + C97A6FAB1517AF53005E1998 /* bt_delete.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53623138D9E980028D27C /* bt_delete.c */; }; + C97A6FAC1517AF53005E1998 /* bt_get.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53624138D9E980028D27C /* bt_get.c */; }; + C97A6FAD1517AF53005E1998 /* bt_open.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53625138D9E980028D27C /* bt_open.c */; }; + C97A6FAE1517AF53005E1998 /* bt_overflow.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53626138D9E980028D27C /* bt_overflow.c */; }; + C97A6FAF1517AF53005E1998 /* bt_page.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53628138D9E980028D27C /* bt_page.c */; }; + C97A6FB01517AF53005E1998 /* bt_put.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53629138D9E980028D27C /* bt_put.c */; }; + C97A6FB11517AF53005E1998 /* bt_search.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362A138D9E980028D27C /* bt_search.c */; }; + C97A6FB21517AF53005E1998 /* bt_seq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362B138D9E980028D27C /* bt_seq.c */; }; + C97A6FB31517AF53005E1998 /* bt_split.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362D138D9E980028D27C /* bt_split.c */; }; + C97A6FB41517AF53005E1998 /* bt_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362F138D9E980028D27C /* bt_utils.c */; }; + C97A6FB51517AF53005E1998 /* db.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53636138D9E980028D27C /* db.c */; }; + C97A6FB61517AF53005E1998 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5363B138D9E980028D27C /* hash.c */; }; + C97A6FB71517AF53005E1998 /* hash_bigkey.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5363F138D9E980028D27C /* hash_bigkey.c */; }; + C97A6FB81517AF53005E1998 /* hash_buf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53641138D9E980028D27C /* hash_buf.c */; }; + C97A6FB91517AF53005E1998 /* hash_func.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53643138D9E980028D27C /* hash_func.c */; }; + C97A6FBA1517AF53005E1998 /* hash_log2.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53645138D9E980028D27C /* hash_log2.c */; }; + C97A6FBB1517AF53005E1998 /* hash_page.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53647138D9E980028D27C /* hash_page.c */; }; + C97A6FBC1517AF53005E1998 /* ndbm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53649138D9E980028D27C /* ndbm.c */; }; + C97A6FBD1517AF53005E1998 /* mpool.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5365A138D9E980028D27C /* mpool.c */; }; + C97A6FBE1517AF53005E1998 /* rec_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53661138D9E980028D27C /* rec_close.c */; }; + C97A6FBF1517AF53005E1998 /* rec_delete.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53662138D9E980028D27C /* rec_delete.c */; }; + C97A6FC01517AF53005E1998 /* rec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53663138D9E980028D27C /* rec_get.c */; }; + C97A6FC11517AF53005E1998 /* rec_open.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53664138D9E980028D27C /* rec_open.c */; }; + C97A6FC21517AF53005E1998 /* rec_put.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53665138D9E980028D27C /* rec_put.c */; }; + C97A6FC31517AF53005E1998 /* rec_search.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53666138D9E980028D27C /* rec_search.c */; }; + C97A6FC41517AF53005E1998 /* rec_seq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53667138D9E980028D27C /* rec_seq.c */; }; + C97A6FC51517AF53005E1998 /* rec_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53668138D9E980028D27C /* rec_utils.c */; }; + C97A6FC61517AF53005E1998 /* brk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5366E138D9E980028D27C /* brk.c */; }; + C97A6FC71517AF53005E1998 /* bsd_signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53670138D9E980028D27C /* bsd_signal.c */; }; + C97A6FC81517AF53005E1998 /* lchflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53672138D9E980028D27C /* lchflags.c */; }; + C97A6FC91517AF53005E1998 /* lchmod.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53674138D9E980028D27C /* lchmod.c */; }; + C97A6FCA1517AF53005E1998 /* lutimes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53676138D9E980028D27C /* lutimes.c */; }; + C97A6FCB1517AF53005E1998 /* statvfs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53679138D9E980028D27C /* statvfs.c */; }; + C97A6FCC1517AF53005E1998 /* tcgetsid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5367B138D9E980028D27C /* tcgetsid.c */; }; + C97A6FCD1517AF53005E1998 /* _ldbl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5368E138D9E980028D27C /* _ldbl_util.c */; }; + C97A6FCE1517AF53005E1998 /* _hdtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53691138D9E980028D27C /* _hdtoa.c */; }; + C97A6FCF1517AF53005E1998 /* _ldtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53693138D9E980028D27C /* _ldtoa.c */; }; + C97A6FD01517AF53005E1998 /* gdtoa-dmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53695138D9E980028D27C /* gdtoa-dmisc.c */; }; + C97A6FD11517AF53005E1998 /* gdtoa-dtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53696138D9E980028D27C /* gdtoa-dtoa.c */; }; + C97A6FD21517AF53005E1998 /* gdtoa-gdtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53697138D9E980028D27C /* gdtoa-gdtoa.c */; }; + C97A6FD31517AF53005E1998 /* gdtoa-gethex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53698138D9E980028D27C /* gdtoa-gethex.c */; }; + C97A6FD41517AF53005E1998 /* gdtoa-gmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369A138D9E980028D27C /* gdtoa-gmisc.c */; }; + C97A6FD51517AF53005E1998 /* gdtoa-hd_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369B138D9E980028D27C /* gdtoa-hd_init.c */; }; + C97A6FD61517AF53005E1998 /* gdtoa-hexnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369C138D9E980028D27C /* gdtoa-hexnan.c */; }; + C97A6FD71517AF53005E1998 /* gdtoa-misc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369E138D9E980028D27C /* gdtoa-misc.c */; }; + C97A6FD81517AF53005E1998 /* gdtoa-smisc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A0138D9E980028D27C /* gdtoa-smisc.c */; }; + C97A6FD91517AF53005E1998 /* gdtoa-strtod.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A1138D9E980028D27C /* gdtoa-strtod.c */; }; + C97A6FDA1517AF53005E1998 /* gdtoa-strtodg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A3138D9E980028D27C /* gdtoa-strtodg.c */; }; + C97A6FDB1517AF53005E1998 /* gdtoa-strtof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A5138D9E980028D27C /* gdtoa-strtof.c */; }; + C97A6FDC1517AF53005E1998 /* gdtoa-strtoIg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A7138D9E980028D27C /* gdtoa-strtoIg.c */; }; + C97A6FDD1517AF53005E1998 /* gdtoa-strtopdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A8138D9E980028D27C /* gdtoa-strtopdd.c */; }; + C97A6FDE1517AF53005E1998 /* gdtoa-strtopx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AA138D9E980028D27C /* gdtoa-strtopx.c */; }; + C97A6FDF1517AF53005E1998 /* gdtoa-strtord.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AC138D9E980028D27C /* gdtoa-strtord.c */; }; + C97A6FE01517AF53005E1998 /* gdtoa-sum.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AE138D9E980028D27C /* gdtoa-sum.c */; }; + C97A6FE11517AF53005E1998 /* gdtoa-ulp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AF138D9E980028D27C /* gdtoa-ulp.c */; }; + C97A6FE21517AF53005E1998 /* glue.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B5138D9E980028D27C /* glue.c */; }; + C97A6FE31517AF53005E1998 /* machdep_ldisd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B6138D9E980028D27C /* machdep_ldisd.c */; }; + C97A6FE41517AF53005E1998 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; }; + C97A6FE51517AF53005E1998 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; + C97A6FE61517AF53005E1998 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; + C97A6FF01517AF53005E1998 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; }; + C97A6FF11517AF53005E1998 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; + C97A6FF31517AF53005E1998 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_CONFSTR"; }; }; + C97A6FF41517AF53005E1998 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY"; }; }; + C97A6FF51517AF53005E1998 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; + C97A6FF61517AF53005E1998 /* disklabel.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E1138D9E990028D27C /* disklabel.c */; }; + C97A6FF71517AF53005E1998 /* errlst.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E2138D9E990028D27C /* errlst.c */; }; + C97A6FF81517AF53005E1998 /* filesec.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E4138D9E990028D27C /* filesec.c */; }; + C97A6FF91517AF53005E1998 /* _rand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E6138D9E990028D27C /* _rand48.c */; }; + C97A6FFA1517AF53005E1998 /* alarm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536EA138D9E990028D27C /* alarm.c */; }; + C97A6FFB1517AF53005E1998 /* arc4random.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536EC138D9E990028D27C /* arc4random.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A6FFC1517AF53005E1998 /* assert.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536EE138D9E990028D27C /* assert.c */; }; + C97A6FFD1517AF53005E1998 /* basename.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536F2138D9E990028D27C /* basename.c */; }; + C97A6FFE1517AF53005E1998 /* clock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536F5138D9E990028D27C /* clock.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CLOCK"; }; }; + C97A6FFF1517AF53005E1998 /* closedir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536F6138D9E990028D27C /* closedir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CLOSEDIR -include gen/__dirent.h"; }; }; + C97A70001517AF53005E1998 /* ctermid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536FA138D9E990028D27C /* ctermid.c */; }; + C97A70011517AF53005E1998 /* daemon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536FD138D9E990028D27C /* daemon.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A70021517AF53005E1998 /* dirname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53701138D9E990028D27C /* dirname.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A70031517AF53005E1998 /* drand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53703138D9E990028D27C /* drand48.c */; }; + C97A70041517AF53005E1998 /* erand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53705138D9E990028D27C /* erand48.c */; }; + C97A70051517AF53005E1998 /* err.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53709138D9E990028D27C /* err.c */; }; + C97A70061517AF53005E1998 /* exec.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5370D138D9E990028D27C /* exec.c */; }; + C97A70071517AF53005E1998 /* fmtcheck.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53710138D9E990028D27C /* fmtcheck.c */; }; + C97A70081517AF53005E1998 /* fmtmsg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53712138D9E990028D27C /* fmtmsg.c */; }; + C97A70091517AF53005E1998 /* fnmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53716138D9E990028D27C /* fnmatch.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FNMATCH"; }; }; + C97A700A1517AF53005E1998 /* ftok.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5371A138D9E990028D27C /* ftok.c */; }; + C97A700B1517AF53005E1998 /* getbsize.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5371C138D9E990028D27C /* getbsize.c */; }; + C97A700C1517AF53005E1998 /* getcap.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5371E138D9E990028D27C /* getcap.c */; }; + C97A700D1517AF53005E1998 /* getcwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53722138D9E990028D27C /* getcwd.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A700E1517AF53005E1998 /* gethostname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53726138D9E990028D27C /* gethostname.c */; }; + C97A700F1517AF53005E1998 /* getlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53728138D9E990028D27C /* getlogin.c */; }; + C97A70101517AF53005E1998 /* getmntinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5372C138D9E990028D27C /* getmntinfo.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A70111517AF53005E1998 /* getpagesize.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5372F138D9E990028D27C /* getpagesize.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A70121517AF53005E1998 /* getpeereid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53732138D9E990028D27C /* getpeereid.c */; }; + C97A70131517AF53005E1998 /* getprogname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53735138D9E990028D27C /* getprogname.c */; }; + C97A70141517AF53005E1998 /* glob.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53739138D9E990028D27C /* glob.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_GLOB"; }; }; + C97A70151517AF53005E1998 /* isatty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5373B138D9E990028D27C /* isatty.c */; }; + C97A70161517AF53005E1998 /* jrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5373D138D9E990028D27C /* jrand48.c */; }; + C97A70171517AF53005E1998 /* lcong48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5373F138D9E990028D27C /* lcong48.c */; }; + C97A70181517AF53005E1998 /* lockf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53743138D9E990028D27C /* lockf.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_LOCKF"; }; }; + C97A70191517AF53005E1998 /* lrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53745138D9E990028D27C /* lrand48.c */; }; + C97A701A1517AF53005E1998 /* mrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53749138D9E990028D27C /* mrand48.c */; }; + C97A701B1517AF53005E1998 /* nice.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374C138D9E990028D27C /* nice.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_NICE"; }; }; + C97A701C1517AF53005E1998 /* nrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374E138D9E990028D27C /* nrand48.c */; }; + C97A701D1517AF53005E1998 /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS___OPENDIR2 -DLIBC_ALIAS_OPENDIR -include gen/__dirent.h"; }; }; + C97A701E1517AF53005E1998 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; }; + C97A701F1517AF53005E1998 /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; }; + C97A70211517AF53005E1998 /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; + C97A70221517AF53005E1998 /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; + C97A70231517AF53005E1998 /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; + C97A70241517AF53005E1998 /* readpassphrase.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53769138D9E990028D27C /* readpassphrase.c */; }; + C97A70251517AF53005E1998 /* rewinddir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5376B138D9E990028D27C /* rewinddir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_REWINDDIR -include gen/__dirent.h"; }; }; + C97A70261517AF53005E1998 /* scandir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5376E138D9E990028D27C /* scandir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; + C97A70271517AF53005E1998 /* seed48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53771138D9E990028D27C /* seed48.c */; }; + C97A70281517AF53005E1998 /* seekdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53773138D9E990028D27C /* seekdir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SEEKDIR -include gen/__dirent.h"; }; }; + C97A70291517AF53005E1998 /* sethostname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53774138D9E990028D27C /* sethostname.c */; }; + C97A702A1517AF53005E1998 /* setmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53776138D9E990028D27C /* setmode.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SETMODE"; }; }; + C97A702B1517AF53005E1998 /* setprogname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53778138D9E990028D27C /* setprogname.c */; }; + C97A702C1517AF53005E1998 /* siginterrupt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377C138D9E990028D27C /* siginterrupt.c */; }; + C97A702D1517AF53005E1998 /* siglist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377D138D9E990028D27C /* siglist.c */; }; + C97A702E1517AF53005E1998 /* signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53781138D9E990028D27C /* signal.c */; }; + C97A702F1517AF53005E1998 /* sleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53787138D9E990028D27C /* sleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SLEEP"; }; }; + C97A70301517AF53005E1998 /* srand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53789138D9E990028D27C /* srand48.c */; }; + C97A70311517AF53005E1998 /* stringlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378C138D9E990028D27C /* stringlist.c */; }; + C97A70321517AF53005E1998 /* sysconf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378E138D9E990028D27C /* sysconf.c */; }; + C97A70331517AF53005E1998 /* sysctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53792138D9E990028D27C /* sysctl.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A70341517AF53005E1998 /* sysctlbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53794138D9E990028D27C /* sysctlbyname.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A70351517AF53005E1998 /* sysctlnametomib.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53795138D9E990028D27C /* sysctlnametomib.c */; }; + C97A70361517AF53005E1998 /* telldir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53796138D9E990028D27C /* telldir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS__SEEKDIR -DLIBC_ALIAS_TELLDIR -include gen/__dirent.h"; }; }; + C97A70371517AF53005E1998 /* termios.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5379A138D9E990028D27C /* termios.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TCDRAIN"; }; }; + C97A70381517AF53005E1998 /* time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5379E138D9E990028D27C /* time.c */; }; + C97A70391517AF53005E1998 /* times.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A2138D9E990028D27C /* times.c */; }; + C97A703A1517AF53005E1998 /* timezone.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A4138D9E990028D27C /* timezone.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A703B1517AF53005E1998 /* ttyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A7138D9E990028D27C /* ttyname.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TTYNAME_R"; }; }; + C97A703C1517AF53005E1998 /* ttyslot.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A9138D9E990028D27C /* ttyslot.c */; }; + C97A703D1517AF53005E1998 /* ualarm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537AC138D9E990028D27C /* ualarm.c */; }; + C97A703E1517AF53005E1998 /* ulimit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B0138D9E990028D27C /* ulimit.c */; }; + C97A703F1517AF53005E1998 /* unvis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B2138D9E990028D27C /* unvis.c */; }; + C97A70401517AF53005E1998 /* usleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B6138D9E990028D27C /* usleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_USLEEP"; }; }; + C97A70411517AF53005E1998 /* utime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BA138D9E990028D27C /* utime.c */; }; + C97A70421517AF53005E1998 /* vis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BC138D9E990028D27C /* vis.c */; }; + C97A70431517AF53005E1998 /* wait.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BE138D9E990028D27C /* wait.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAIT"; }; }; + C97A70441517AF53005E1998 /* wait3.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C0138D9E990028D27C /* wait3.c */; }; + C97A70451517AF53005E1998 /* waitpid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C1138D9E990028D27C /* waitpid.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAITPID"; }; }; + C97A70461517AF53005E1998 /* fts.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C4138D9E990028D27C /* fts.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTS_CHILDREN -DLIBC_ALIAS_FTS_CLOSE -DLIBC_ALIAS_FTS_OPEN -DLIBC_ALIAS_FTS_OPEN_B -DLIBC_ALIAS_FTS_READ -DLIBC_ALIAS_FTS_SET"; }; }; + C97A70471517AF53005E1998 /* get_compat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C6138D9E990028D27C /* get_compat.c */; }; + C97A70481517AF53005E1998 /* getloadavg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CA138D9E990028D27C /* getloadavg.c */; }; + C97A70491517AF53005E1998 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; + C97A704A1517AF53005E1998 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; + C97A704B1517AF53005E1998 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; + C97A70501517AF53005E1998 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; }; + C97A70511517AF53005E1998 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; + C97A70521517AF53005E1998 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW"; }; }; + C97A70531517AF53005E1998 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; + C97A70551517AF53005E1998 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; }; + C97A70581517AF53005E1998 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; + C97A70591517AF53005E1998 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; + C97A705C1517AF53005E1998 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; + C97A705E1517AF53005E1998 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; + C97A705F1517AF53005E1998 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; + C97A70601517AF53005E1998 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; + C97A70611517AF53005E1998 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; + C97A70621517AF53005E1998 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; + C97A70701517AF53005E1998 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; }; + C97A70711517AF53005E1998 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; }; + C97A70721517AF53005E1998 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; }; + C97A70731517AF53005E1998 /* collate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5390B138D9E990028D27C /* collate.c */; }; + C97A70741517AF53005E1998 /* collcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5390F138D9E990028D27C /* collcmp.c */; }; + C97A70751517AF53005E1998 /* euc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53916138D9E990028D27C /* euc.c */; }; + C97A70761517AF53005E1998 /* fix_grouping.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53918138D9E990028D27C /* fix_grouping.c */; }; + C97A70771517AF53005E1998 /* gb18030.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5391B138D9E990028D27C /* gb18030.c */; }; + C97A70781517AF53005E1998 /* gb2312.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5391E138D9E990028D27C /* gb2312.c */; }; + C97A70791517AF53005E1998 /* gbk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53921138D9E990028D27C /* gbk.c */; }; + C97A707A1517AF53005E1998 /* ldpart.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53946138D9E990028D27C /* ldpart.c */; }; + C97A707B1517AF53005E1998 /* lmessages.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5394A138D9E990028D27C /* lmessages.c */; }; + C97A707C1517AF53005E1998 /* lmonetary.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5394E138D9E990028D27C /* lmonetary.c */; }; + C97A707D1517AF53005E1998 /* lnumeric.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53952138D9E990028D27C /* lnumeric.c */; }; + C97A707E1517AF53005E1998 /* localeconv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53958138D9E990028D27C /* localeconv.c */; }; + C97A707F1517AF53005E1998 /* mblen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5395C138D9E990028D27C /* mblen.c */; }; + C97A70801517AF53005E1998 /* mbrlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53962138D9E990028D27C /* mbrlen.c */; }; + C97A70811517AF53005E1998 /* mbrtowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53966138D9E990028D27C /* mbrtowc.c */; }; + C97A70821517AF53005E1998 /* mbsinit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5396A138D9E990028D27C /* mbsinit.c */; }; + C97A70831517AF53005E1998 /* mbsnrtowcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5396C138D9E990028D27C /* mbsnrtowcs.c */; }; + C97A70841517AF53005E1998 /* mbsrtowcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53970138D9E990028D27C /* mbsrtowcs.c */; }; + C97A70851517AF53005E1998 /* mbstowcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53974138D9E990028D27C /* mbstowcs.c */; }; + C97A70861517AF53005E1998 /* mbtowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53978138D9E990028D27C /* mbtowc.c */; }; + C97A70871517AF53005E1998 /* mskanji.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5397B138D9E990028D27C /* mskanji.c */; }; + C97A70881517AF53005E1998 /* nextwctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53980138D9E990028D27C /* nextwctype.c */; }; + C97A70891517AF53005E1998 /* nl_langinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53984138D9E990028D27C /* nl_langinfo.c */; }; + C97A708A1517AF53005E1998 /* nomacros.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53986138D9E990028D27C /* nomacros.c */; }; + C97A708B1517AF53005E1998 /* none.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53987138D9E990028D27C /* none.c */; }; + C97A708C1517AF53005E1998 /* rune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53989138D9E990028D27C /* rune.c */; }; + C97A708D1517AF53005E1998 /* runetype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5398B138D9E990028D27C /* runetype.c */; }; + C97A708E1517AF53005E1998 /* setlocale.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5398F138D9E990028D27C /* setlocale.c */; }; + C97A708F1517AF53005E1998 /* setrunelocale.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53993138D9E990028D27C /* setrunelocale.c */; }; + C97A70901517AF53005E1998 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53995138D9E990028D27C /* table.c */; }; + C97A70911517AF53005E1998 /* tolower.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5399A138D9E990028D27C /* tolower.c */; }; + C97A70921517AF53005E1998 /* toupper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5399E138D9E990028D27C /* toupper.c */; }; + C97A70931517AF53005E1998 /* utf2.c in Sources */ = {isa = PBXBuildFile; fileRef = C9FA32F8138E4A5C0089A94B /* utf2.c */; }; + C97A70941517AF53005E1998 /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539A6138D9E990028D27C /* utf8.c */; }; + C97A70951517AF53005E1998 /* wcrtomb.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539AA138D9E990028D27C /* wcrtomb.c */; }; + C97A70961517AF53005E1998 /* wcsftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539AE138D9E990028D27C /* wcsftime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WCSFTIME -DLIBC_ALIAS_WCSFTIME_L"; }; }; + C97A70971517AF53005E1998 /* wcsnrtombs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539B0138D9E990028D27C /* wcsnrtombs.c */; }; + C97A70981517AF53005E1998 /* wcsrtombs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539B4138D9E990028D27C /* wcsrtombs.c */; }; + C97A70991517AF53005E1998 /* wcstod.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539B8138D9E990028D27C /* wcstod.c */; }; + C97A709A1517AF53005E1998 /* wcstof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539BA138D9E990028D27C /* wcstof.c */; }; + C97A709B1517AF53005E1998 /* wcstoimax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539BC138D9E990028D27C /* wcstoimax.c */; }; + C97A709C1517AF53005E1998 /* wcstol.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C0138D9E990028D27C /* wcstol.c */; }; + C97A709D1517AF53005E1998 /* wcstold.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C2138D9E990028D27C /* wcstold.c */; }; + C97A709E1517AF53005E1998 /* wcstoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C4138D9E990028D27C /* wcstoll.c */; }; + C97A709F1517AF53005E1998 /* wcstombs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C8138D9E990028D27C /* wcstombs.c */; }; + C97A70A01517AF53005E1998 /* wcstoul.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539CA138D9E990028D27C /* wcstoul.c */; }; + C97A70A11517AF53005E1998 /* wcstoull.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539CC138D9E990028D27C /* wcstoull.c */; }; + C97A70A21517AF53005E1998 /* wcstoumax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539CE138D9E990028D27C /* wcstoumax.c */; }; + C97A70A31517AF53005E1998 /* wctob.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539D0138D9E990028D27C /* wctob.c */; }; + C97A70A41517AF53005E1998 /* wctomb.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539D4138D9E990028D27C /* wctomb.c */; }; + C97A70A51517AF53005E1998 /* wctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539D8138D9E990028D27C /* wctrans.c */; }; + C97A70A61517AF53005E1998 /* wctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539DC138D9E990028D27C /* wctype.c */; }; + C97A70A71517AF53005E1998 /* wcwidth.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E0138D9E990028D27C /* wcwidth.c */; }; + C97A70A81517AF53005E1998 /* frune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E3138D9E990028D27C /* frune.c */; }; + C97A70A91517AF53005E1998 /* isctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E5138D9E990028D27C /* isctype.c */; }; + C97A70AA1517AF53005E1998 /* iswctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E7138D9E990028D27C /* iswctype.c */; }; + C97A70AB1517AF53005E1998 /* lconv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E8138D9E990028D27C /* lconv.c */; }; + C97A70AC1517AF53005E1998 /* mbrune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EB138D9E990028D27C /* mbrune.c */; }; + C97A70AD1517AF53005E1998 /* runedepreciated.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EF138D9E990028D27C /* runedepreciated.c */; }; + C97A70AE1517AF53005E1998 /* setinvalidrune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539F1138D9E990028D27C /* setinvalidrune.c */; }; + C97A70AF1517AF53005E1998 /* xlocale.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539F7138D9E990028D27C /* xlocale.c */; }; + C97A70B01517AF53005E1998 /* addr2ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A16138D9E990028D27C /* addr2ascii.c */; }; + C97A70B11517AF53005E1998 /* ascii2addr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A17138D9E990028D27C /* ascii2addr.c */; }; + C97A70B21517AF53005E1998 /* inet_addr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A1A138D9E990028D27C /* inet_addr.c */; }; + C97A70B31517AF53005E1998 /* inet_lnaof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A1C138D9E990028D27C /* inet_lnaof.c */; }; + C97A70B41517AF53005E1998 /* inet_makeaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A1D138D9E990028D27C /* inet_makeaddr.c */; }; + C97A70B51517AF53005E1998 /* inet_net_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A20138D9E990028D27C /* inet_net_ntop.c */; }; + C97A70B61517AF53005E1998 /* inet_net_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A21138D9E990028D27C /* inet_net_pton.c */; }; + C97A70B71517AF53005E1998 /* inet_neta.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A23138D9E990028D27C /* inet_neta.c */; }; + C97A70B81517AF53005E1998 /* inet_netof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A24138D9E990028D27C /* inet_netof.c */; }; + C97A70B91517AF53005E1998 /* inet_network.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A25138D9E990028D27C /* inet_network.c */; }; + C97A70BA1517AF53005E1998 /* inet_ntoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A27138D9E990028D27C /* inet_ntoa.c */; }; + C97A70BB1517AF53005E1998 /* linkaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2A138D9E990028D27C /* linkaddr.c */; }; + C97A70BC1517AF53005E1998 /* nsap_addr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2B138D9E990028D27C /* nsap_addr.c */; }; + C97A70BD1517AF53005E1998 /* recv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2D138D9E990028D27C /* recv.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_RECV"; }; }; + C97A70BE1517AF53005E1998 /* send.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2F138D9E990028D27C /* send.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SEND"; }; }; + C97A70BF1517AF53005E1998 /* sockatmark.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A33138D9E990028D27C /* sockatmark.c */; }; + C97A70C01517AF53005E1998 /* sourcefilter.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A36138D9E990028D27C /* sourcefilter.c */; }; + C97A70C11517AF53005E1998 /* msgcat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A3F138D9E990028D27C /* msgcat.c */; }; + C97A70C21517AF53005E1998 /* acl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A4C138D9E990028D27C /* acl.c */; }; + C97A70C31517AF53005E1998 /* acl_entry.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A59138D9E990028D27C /* acl_entry.c */; }; + C97A70C41517AF53005E1998 /* acl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5A138D9E990028D27C /* acl_file.c */; }; + C97A70C51517AF53005E1998 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; + C97A70C61517AF53005E1998 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; + C97A70C71517AF53005E1998 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; + C97A70D11517AF53005E1998 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; + C97A70D21517AF53005E1998 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; + C97A70D31517AF53005E1998 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; + C97A70D41517AF53005E1998 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; + C97A70D51517AF53005E1998 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; + C97A70D61517AF53005E1998 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; + C97A70D71517AF53005E1998 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; + C97A70D81517AF53005E1998 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; + C97A70D91517AF53005E1998 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; + C97A70DA1517AF53005E1998 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; + C97A70DB1517AF53005E1998 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; + C97A70DC1517AF53005E1998 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; + C97A70DD1517AF53005E1998 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; + C97A70DE1517AF53005E1998 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; + C97A70DF1517AF53005E1998 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; + C97A70E01517AF53005E1998 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; }; + C97A70E11517AF53005E1998 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; }; + C97A70E21517AF53005E1998 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; }; + C97A70E31517AF53005E1998 /* dprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B33138D9E990028D27C /* dprintf.c */; }; + C97A70E41517AF53005E1998 /* fclose.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B36138D9E990028D27C /* fclose.c */; }; + C97A70E51517AF53005E1998 /* fdopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B38138D9E990028D27C /* fdopen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FDOPEN"; }; }; + C97A70E61517AF53005E1998 /* feof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B3A138D9E990028D27C /* feof.c */; }; + C97A70E71517AF53005E1998 /* ferror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B3C138D9E990028D27C /* ferror.c */; }; + C97A70E81517AF53005E1998 /* fflush.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B3E138D9E990028D27C /* fflush.c */; }; + C97A70E91517AF53005E1998 /* fgetc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B40138D9E990028D27C /* fgetc.c */; }; + C97A70EA1517AF53005E1998 /* fgetln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B43138D9E990028D27C /* fgetln.c */; }; + C97A70EB1517AF53005E1998 /* fgetpos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B45138D9E990028D27C /* fgetpos.c */; }; + C97A70EC1517AF53005E1998 /* fgets.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B47138D9E990028D27C /* fgets.c */; }; + C97A70ED1517AF53005E1998 /* fgetwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B48138D9E990028D27C /* fgetwc.c */; }; + C97A70EE1517AF53005E1998 /* fgetwln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B4C138D9E990028D27C /* fgetwln.c */; }; + C97A70EF1517AF53005E1998 /* fgetws.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B50138D9E990028D27C /* fgetws.c */; }; + C97A70F01517AF53005E1998 /* fileno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B52138D9E990028D27C /* fileno.c */; }; + C97A70F11517AF53005E1998 /* findfp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B53138D9E990028D27C /* findfp.c */; }; + C97A70F21517AF53005E1998 /* flags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B55138D9E990028D27C /* flags.c */; }; + C97A70F31517AF53005E1998 /* fopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B5C138D9E990028D27C /* fopen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FOPEN"; }; }; + C97A70F41517AF53005E1998 /* fprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B5E138D9E990028D27C /* fprintf.c */; }; + C97A70F51517AF53005E1998 /* fpurge.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B60138D9E990028D27C /* fpurge.c */; }; + C97A70F61517AF53005E1998 /* fputc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B61138D9E990028D27C /* fputc.c */; }; + C97A70F71517AF53005E1998 /* fputs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B64138D9E990028D27C /* fputs.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FPUTS"; }; }; + C97A70F81517AF53005E1998 /* fputwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B66138D9E990028D27C /* fputwc.c */; }; + C97A70F91517AF53005E1998 /* fputws.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B6A138D9E990028D27C /* fputws.c */; }; + C97A70FA1517AF53005E1998 /* fread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B6E138D9E990028D27C /* fread.c */; }; + C97A70FB1517AF53005E1998 /* freopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B70138D9E990028D27C /* freopen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FREOPEN"; }; }; + C97A70FC1517AF53005E1998 /* fscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B72138D9E990028D27C /* fscanf.c */; }; + C97A70FD1517AF53005E1998 /* fseek.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B76138D9E990028D27C /* fseek.c */; }; + C97A70FE1517AF53005E1998 /* fsetpos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B77138D9E990028D27C /* fsetpos.c */; }; + C97A70FF1517AF53005E1998 /* ftell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B78138D9E990028D27C /* ftell.c */; }; + C97A71001517AF53005E1998 /* funopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B7B138D9E990028D27C /* funopen.c */; }; + C97A71011517AF53005E1998 /* fvwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B7D138D9E990028D27C /* fvwrite.c */; }; + C97A71021517AF53005E1998 /* fwalk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B7F138D9E990028D27C /* fwalk.c */; }; + C97A71031517AF53005E1998 /* fwide.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B82138D9E990028D27C /* fwide.c */; }; + C97A71041517AF53005E1998 /* fwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B83138D9E990028D27C /* fwprintf.c */; }; + C97A71051517AF53005E1998 /* fwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B85138D9E990028D27C /* fwrite.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FWRITE"; }; }; + C97A71061517AF53005E1998 /* fwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B87138D9E990028D27C /* fwscanf.c */; }; + C97A71071517AF53005E1998 /* getc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B8B138D9E990028D27C /* getc.c */; }; + C97A71081517AF53005E1998 /* getchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B8C138D9E990028D27C /* getchar.c */; }; + C97A71091517AF53005E1998 /* getdelim.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B8D138D9E990028D27C /* getdelim.c */; }; + C97A710A1517AF53005E1998 /* getline.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B90138D9E990028D27C /* getline.c */; }; + C97A710B1517AF53005E1998 /* gets.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B91138D9E990028D27C /* gets.c */; }; + C97A710C1517AF53005E1998 /* getw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B92138D9E990028D27C /* getw.c */; }; + C97A710D1517AF53005E1998 /* getwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B95138D9E990028D27C /* getwc.c */; }; + C97A710E1517AF53005E1998 /* getwchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B97138D9E990028D27C /* getwchar.c */; }; + C97A710F1517AF53005E1998 /* makebuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B9C138D9E990028D27C /* makebuf.c */; }; + C97A71101517AF53005E1998 /* mktemp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA0138D9E990028D27C /* mktemp.c */; }; + C97A71111517AF53005E1998 /* perror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA2138D9E990028D27C /* perror.c */; }; + C97A71121517AF53005E1998 /* printf-pos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA3138D9E990028D27C /* printf-pos.c */; }; + C97A71131517AF53005E1998 /* printf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA7138D9E990028D27C /* printf.c */; }; + C97A71141517AF53005E1998 /* putc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BAF138D9E990028D27C /* putc.c */; }; + C97A71151517AF53005E1998 /* putchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB0138D9E990028D27C /* putchar.c */; }; + C97A71161517AF53005E1998 /* puts.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB1138D9E990028D27C /* puts.c */; }; + C97A71171517AF53005E1998 /* putw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB3138D9E990028D27C /* putw.c */; }; + C97A71181517AF53005E1998 /* putwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB6138D9E990028D27C /* putwc.c */; }; + C97A71191517AF53005E1998 /* putwchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB8138D9E990028D27C /* putwchar.c */; }; + C97A711A1517AF53005E1998 /* refill.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BBA138D9E990028D27C /* refill.c */; }; + C97A711B1517AF53005E1998 /* remove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BBE138D9E990028D27C /* remove.c */; }; + C97A711C1517AF53005E1998 /* rewind.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BBF138D9E990028D27C /* rewind.c */; }; + C97A711D1517AF53005E1998 /* rget.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC1138D9E990028D27C /* rget.c */; }; + C97A711E1517AF53005E1998 /* scanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC4138D9E990028D27C /* scanf.c */; }; + C97A711F1517AF53005E1998 /* setbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC8138D9E990028D27C /* setbuf.c */; }; + C97A71201517AF53005E1998 /* setbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC9138D9E990028D27C /* setbuffer.c */; }; + C97A71211517AF53005E1998 /* setvbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCA138D9E990028D27C /* setvbuf.c */; }; + C97A71221517AF53005E1998 /* snprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCB138D9E990028D27C /* snprintf.c */; }; + C97A71231517AF53005E1998 /* sprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCD138D9E990028D27C /* sprintf.c */; }; + C97A71241517AF53005E1998 /* sscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCF138D9E990028D27C /* sscanf.c */; }; + C97A71251517AF53005E1998 /* stdio.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD3138D9E990028D27C /* stdio.c */; }; + C97A71261517AF53005E1998 /* swprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD4138D9E990028D27C /* swprintf.c */; }; + C97A71271517AF53005E1998 /* swscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD6138D9E990028D27C /* swscanf.c */; }; + C97A71281517AF53005E1998 /* tempnam.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD8138D9E990028D27C /* tempnam.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TEMPNAM"; }; }; + C97A71291517AF53005E1998 /* tmpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BDA138D9E990028D27C /* tmpfile.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -D_DARWIN_UNLIMITED_STREAMS"; }; }; + C97A712A1517AF53005E1998 /* tmpnam.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BDD138D9E990028D27C /* tmpnam.c */; }; + C97A712B1517AF53005E1998 /* ungetc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE1138D9E990028D27C /* ungetc.c */; }; + C97A712C1517AF53005E1998 /* ungetwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE4138D9E990028D27C /* ungetwc.c */; }; + C97A712D1517AF53005E1998 /* vasprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE6138D9E990028D27C /* vasprintf.c */; }; + C97A712E1517AF53005E1998 /* vdprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE8138D9E990028D27C /* vdprintf.c */; }; + C97A712F1517AF53005E1998 /* vfprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEA138D9E990028D27C /* vfprintf.c */; }; + C97A71301517AF53005E1998 /* vfscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEC138D9E990028D27C /* vfscanf.c */; }; + C97A71311517AF53005E1998 /* vfwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEE138D9E9A0028D27C /* vfwprintf.c */; }; + C97A71321517AF53005E1998 /* vfwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF0138D9E9A0028D27C /* vfwscanf.c */; }; + C97A71331517AF53005E1998 /* vprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF2138D9E9A0028D27C /* vprintf.c */; }; + C97A71341517AF53005E1998 /* vscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF4138D9E9A0028D27C /* vscanf.c */; }; + C97A71351517AF53005E1998 /* vsnprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF6138D9E9A0028D27C /* vsnprintf.c */; }; + C97A71361517AF53005E1998 /* vsprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF8138D9E9A0028D27C /* vsprintf.c */; }; + C97A71371517AF53005E1998 /* vsscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BFA138D9E9A0028D27C /* vsscanf.c */; }; + C97A71381517AF53005E1998 /* vswprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BFC138D9E9A0028D27C /* vswprintf.c */; }; + C97A71391517AF53005E1998 /* vswscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BFE138D9E9A0028D27C /* vswscanf.c */; }; + C97A713A1517AF53005E1998 /* vwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C00138D9E9A0028D27C /* vwprintf.c */; }; + C97A713B1517AF53005E1998 /* vwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C02138D9E9A0028D27C /* vwscanf.c */; }; + C97A713C1517AF53005E1998 /* wbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C04138D9E9A0028D27C /* wbuf.c */; }; + C97A713D1517AF53005E1998 /* wprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C08138D9E9A0028D27C /* wprintf.c */; }; + C97A713E1517AF53005E1998 /* wscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C0C138D9E9A0028D27C /* wscanf.c */; }; + C97A713F1517AF53005E1998 /* wsetup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C0E138D9E9A0028D27C /* wsetup.c */; }; + C97A71401517AF53005E1998 /* a64l.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C18138D9E9A0028D27C /* a64l.c */; }; + C97A71411517AF53005E1998 /* _Exit_.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C1A138D9E9A0028D27C /* _Exit_.c */; }; + C97A71421517AF53005E1998 /* abort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C1D138D9E9A0028D27C /* abort.c */; }; + C97A71431517AF53005E1998 /* abs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C21138D9E9A0028D27C /* abs.c */; }; + C97A71441517AF53005E1998 /* atexit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C26138D9E9A0028D27C /* atexit.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A71451517AF53005E1998 /* atof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C2C138D9E9A0028D27C /* atof.c */; }; + C97A71461517AF53005E1998 /* atoi.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C30138D9E9A0028D27C /* atoi.c */; }; + C97A71471517AF53005E1998 /* atol.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C34138D9E9A0028D27C /* atol.c */; }; + C97A71481517AF53005E1998 /* atoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C36138D9E9A0028D27C /* atoll.c */; }; + C97A71491517AF53005E1998 /* bsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C3A138D9E9A0028D27C /* bsearch.c */; }; + C97A714A1517AF53005E1998 /* div.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C3E138D9E9A0028D27C /* div.c */; }; + C97A714B1517AF53005E1998 /* exit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C40138D9E9A0028D27C /* exit.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A714C1517AF53005E1998 /* getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C44138D9E9A0028D27C /* getenv.c */; }; + C97A714D1517AF53005E1998 /* getopt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C47138D9E9A0028D27C /* getopt.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_GETOPT"; }; }; + C97A714E1517AF53005E1998 /* getopt_long.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C4A138D9E9A0028D27C /* getopt_long.c */; }; + C97A714F1517AF53005E1998 /* getsubopt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C4D138D9E9A0028D27C /* getsubopt.c */; }; + C97A71501517AF53005E1998 /* hcreate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C4F138D9E9A0028D27C /* hcreate.c */; }; + C97A71511517AF53005E1998 /* heapsort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C50138D9E9A0028D27C /* heapsort.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A71521517AF53005E1998 /* heapsort_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94357138EC0C600FB7ACC /* heapsort_b.c */; }; + C97A71531517AF53005E1998 /* heapsort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94358138EC0C600FB7ACC /* heapsort_r.c */; }; + C97A71541517AF53005E1998 /* imaxabs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C54138D9E9A0028D27C /* imaxabs.c */; }; + C97A71551517AF53005E1998 /* imaxdiv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C57138D9E9A0028D27C /* imaxdiv.c */; }; + C97A71561517AF53005E1998 /* insque.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C5A138D9E9A0028D27C /* insque.c */; }; + C97A71571517AF53005E1998 /* labs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C5D138D9E9A0028D27C /* labs.c */; }; + C97A71581517AF53005E1998 /* ldiv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C60138D9E9A0028D27C /* ldiv.c */; }; + C97A71591517AF53005E1998 /* llabs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C63138D9E9A0028D27C /* llabs.c */; }; + C97A715A1517AF53005E1998 /* lldiv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C66138D9E9A0028D27C /* lldiv.c */; }; + C97A715B1517AF53005E1998 /* lsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C69138D9E9A0028D27C /* lsearch.c */; }; + C97A715C1517AF53005E1998 /* merge.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C6C138D9E9A0028D27C /* merge.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A715D1517AF53005E1998 /* putenv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C6F138D9E9A0028D27C /* putenv.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PUTENV"; }; }; + C97A715E1517AF53005E1998 /* qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C73138D9E9A0028D27C /* qsort.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A715F1517AF53005E1998 /* qsort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C75138D9E9A0028D27C /* qsort_r.c */; }; + C97A71601517AF53005E1998 /* radixsort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C78138D9E9A0028D27C /* radixsort.c */; }; + C97A71611517AF53005E1998 /* rand.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C7C138D9E9A0028D27C /* rand.c */; }; + C97A71621517AF53005E1998 /* random.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C7F138D9E9A0028D27C /* random.c */; }; + C97A71631517AF53005E1998 /* reallocf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C81138D9E9A0028D27C /* reallocf.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A71641517AF53005E1998 /* realpath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C84138D9E9A0028D27C /* realpath.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_REALPATH"; }; }; + C97A71651517AF53005E1998 /* remque.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C86138D9E9A0028D27C /* remque.c */; }; + C97A71661517AF53005E1998 /* setenv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C87138D9E9A0028D27C /* setenv.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_REALPATH"; }; }; + C97A71671517AF53005E1998 /* strhash.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C89138D9E9A0028D27C /* strhash.c */; }; + C97A71681517AF53005E1998 /* strtoimax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C8D138D9E9A0028D27C /* strtoimax.c */; }; + C97A71691517AF53005E1998 /* strtol.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C91138D9E9A0028D27C /* strtol.c */; }; + C97A716A1517AF53005E1998 /* strtoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C93138D9E9A0028D27C /* strtoll.c */; }; + C97A716B1517AF53005E1998 /* strtoq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C95138D9E9A0028D27C /* strtoq.c */; }; + C97A716C1517AF53005E1998 /* strtoul.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C99138D9E9A0028D27C /* strtoul.c */; }; + C97A716D1517AF53005E1998 /* strtoull.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C9B138D9E9A0028D27C /* strtoull.c */; }; + C97A716E1517AF53005E1998 /* strtoumax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C9D138D9E9A0028D27C /* strtoumax.c */; }; + C97A716F1517AF53005E1998 /* strtouq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C9F138D9E9A0028D27C /* strtouq.c */; }; + C97A71701517AF53005E1998 /* system.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA3138D9E9A0028D27C /* system.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SYSTEM"; }; }; + C97A71711517AF53005E1998 /* tdelete.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA5138D9E9A0028D27C /* tdelete.c */; }; + C97A71721517AF53005E1998 /* tfind.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA6138D9E9A0028D27C /* tfind.c */; }; + C97A71731517AF53005E1998 /* tsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA9138D9E9A0028D27C /* tsearch.c */; }; + C97A71741517AF53005E1998 /* twalk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CAA138D9E9A0028D27C /* twalk.c */; }; + C97A71751517AF53005E1998 /* grantpt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CAC138D9E9A0028D27C /* grantpt.c */; }; + C97A71761517AF53005E1998 /* l64a.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CAD138D9E9A0028D27C /* l64a.c */; }; + C97A71771517AF53005E1998 /* strfmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB2138D9E9A0028D27C /* strfmon.c */; }; + C97A71781517AF53005E1998 /* ecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB7138D9E9A0028D27C /* ecvt.c */; }; + C97A71791517AF53005E1998 /* gcvt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB9138D9E9A0028D27C /* gcvt.c */; }; + C97A717A1517AF53005E1998 /* qsort_b-fbsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CBD138D9E9A0028D27C /* qsort_b-fbsd.c */; }; + C97A717B1517AF53005E1998 /* asctime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CC2138D9E9A0028D27C /* asctime.c */; }; + C97A717C1517AF53005E1998 /* difftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CC6138D9E9A0028D27C /* difftime.c */; }; + C97A717D1517AF53005E1998 /* ftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CC9138D9E9A0028D27C /* ftime.c */; }; + C97A717E1517AF53005E1998 /* localtime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CCA138D9E9A0028D27C /* localtime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_MKTIME"; }; }; + C97A717F1517AF53005E1998 /* strftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CCF138D9E9A0028D27C /* strftime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRFTIME -DLIBC_ALIAS_STRFTIME_L"; }; }; + C97A71801517AF53005E1998 /* strptime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD3138D9E9A0028D27C /* strptime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRPTIME -DLIBC_ALIAS_STRPTIME_L"; }; }; + C97A71811517AF53005E1998 /* time32.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD6138D9E9A0028D27C /* time32.c */; }; + C97A71821517AF53005E1998 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; + C97A71831517AF53005E1998 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; settings = {COMPILER_FLAGS = "-D_DARWIN_UNLIMITED_STREAMS"; }; }; + C97A71841517AF53005E1998 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; + C97A71881517AF53005E1998 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; + C97A718D1517AF53005E1998 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; + C97A71901517AF53005E1998 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; + C97A71911517AF53005E1998 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; + C97A71921517AF53005E1998 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; + C97A71951517AF53005E1998 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; + C97A71961517AF53005E1998 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; + C97A71971517AF53005E1998 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A71981517AF53005E1998 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRERROR"; }; }; + C97A71991517AF53005E1998 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; + C97A719A1517AF53005E1998 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; + C97A719C1517AF53005E1998 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; + C97A719D1517AF53005E1998 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; + C97A719E1517AF53005E1998 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; + C97A719F1517AF53005E1998 /* strpbrk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D49138D9E9A0028D27C /* strpbrk.c */; }; + C97A71A01517AF53005E1998 /* strrchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D4C138D9E9A0028D27C /* strrchr.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A71A11517AF53005E1998 /* strsep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D4F138D9E9A0028D27C /* strsep.c */; }; + C97A71A21517AF53005E1998 /* strsignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D50138D9E9A0028D27C /* strsignal.c */; }; + C97A71A31517AF53005E1998 /* strspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D54138D9E9A0028D27C /* strspn.c */; }; + C97A71A41517AF53005E1998 /* strstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D57138D9E9A0028D27C /* strstr.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; }; + C97A71A51517AF53005E1998 /* strtok.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D5A138D9E9A0028D27C /* strtok.c */; }; + C97A71A61517AF53005E1998 /* strxfrm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D5D138D9E9A0028D27C /* strxfrm.c */; }; + C97A71A71517AF53005E1998 /* swab.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D61138D9E9A0028D27C /* swab.c */; }; + C97A71A81517AF53005E1998 /* wcpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D63138D9E9A0028D27C /* wcpcpy.c */; }; + C97A71A91517AF53005E1998 /* wcpncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D64138D9E9A0028D27C /* wcpncpy.c */; }; + C97A71AA1517AF53005E1998 /* wcscasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D65138D9E9A0028D27C /* wcscasecmp.c */; }; + C97A71AB1517AF53005E1998 /* wcscat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D67138D9E9A0028D27C /* wcscat.c */; }; + C97A71AC1517AF53005E1998 /* wcschr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D68138D9E9A0028D27C /* wcschr.c */; }; + C97A71AD1517AF53005E1998 /* wcscmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D69138D9E9A0028D27C /* wcscmp.c */; }; + C97A71AE1517AF53005E1998 /* wcscoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D6C138D9E9A0028D27C /* wcscoll.c */; }; + C97A71AF1517AF53005E1998 /* wcscpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D6E138D9E9A0028D27C /* wcscpy.c */; }; + C97A71B01517AF53005E1998 /* wcscspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D6F138D9E9A0028D27C /* wcscspn.c */; }; + C97A71B11517AF53005E1998 /* wcsdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D70138D9E9A0028D27C /* wcsdup.c */; }; + C97A71B21517AF53005E1998 /* wcslcat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D71138D9E9A0028D27C /* wcslcat.c */; }; + C97A71B31517AF53005E1998 /* wcslcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D72138D9E9A0028D27C /* wcslcpy.c */; }; + C97A71B41517AF53005E1998 /* wcslen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D73138D9E9A0028D27C /* wcslen.c */; }; + C97A71B51517AF53005E1998 /* wcsncasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D74138D9E9A0028D27C /* wcsncasecmp.c */; }; + C97A71B61517AF53005E1998 /* wcsncat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D76138D9E9A0028D27C /* wcsncat.c */; }; + C97A71B71517AF53005E1998 /* wcsncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D77138D9E9A0028D27C /* wcsncmp.c */; }; + C97A71B81517AF53005E1998 /* wcsncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D78138D9E9A0028D27C /* wcsncpy.c */; }; + C97A71B91517AF53005E1998 /* wcsnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D79138D9E9A0028D27C /* wcsnlen.c */; }; + C97A71BA1517AF53005E1998 /* wcspbrk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7A138D9E9A0028D27C /* wcspbrk.c */; }; + C97A71BB1517AF53005E1998 /* wcsrchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7B138D9E9A0028D27C /* wcsrchr.c */; }; + C97A71BC1517AF53005E1998 /* wcsspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7C138D9E9A0028D27C /* wcsspn.c */; }; + C97A71BD1517AF53005E1998 /* wcsstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7D138D9E9A0028D27C /* wcsstr.c */; }; + C97A71BE1517AF53005E1998 /* wcstok.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D80138D9E9A0028D27C /* wcstok.c */; }; + C97A71BF1517AF53005E1998 /* wcswidth.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D83138D9E9A0028D27C /* wcswidth.c */; }; + C97A71C01517AF53005E1998 /* wcsxfrm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D87138D9E9A0028D27C /* wcsxfrm.c */; }; + C97A71C11517AF53005E1998 /* wmemchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8B138D9E9A0028D27C /* wmemchr.c */; }; + C97A71C21517AF53005E1998 /* wmemcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8C138D9E9A0028D27C /* wmemcmp.c */; }; + C97A71C31517AF53005E1998 /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; }; + C97A71C41517AF53005E1998 /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; }; + C97A71C51517AF53005E1998 /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; + C97A71C61517AF53005E1998 /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; + C97A71C71517AF53005E1998 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; + C97A71C81517AF53005E1998 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; + C97A71CA1517AF53005E1998 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; + C97A71CC1517AF53005E1998 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; + C97A71CD1517AF53005E1998 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; }; + C97A71CF1517AF53005E1998 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; + C97A71D01517AF53005E1998 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_MSGCTL -DKERNEL"; }; }; + C97A71D11517AF53005E1998 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; }; + C97A71D21517AF53005E1998 /* openx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAB138D9E9A0028D27C /* openx_np.c */; }; + C97A71D31517AF53005E1998 /* OSMemoryNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAC138D9E9A0028D27C /* OSMemoryNotification.c */; }; + C97A71D41517AF53005E1998 /* OSThermalNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAD138D9E9A0028D27C /* OSThermalNotification.c */; }; + C97A71D51517AF53005E1998 /* posix_spawn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAE138D9E9A0028D27C /* posix_spawn.c */; }; + C97A71D61517AF53005E1998 /* semctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB2138D9E9A0028D27C /* semctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SEMCTL -DKERNEL"; }; }; + C97A71D71517AF53005E1998 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; + C97A71D81517AF53005E1998 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SHMCTL -DKERNEL"; }; }; + C97A71D91517AF53005E1998 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; + C97A71DA1517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C97A71DD1517AF53005E1998 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; + C97A71DE1517AF53005E1998 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; + C97A71E21517AF53005E1998 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; }; + C97A71E31517AF53005E1998 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; + C97A71E41517AF53005E1998 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; + C97A71E51517AF53005E1998 /* logout.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCC138D9E9A0028D27C /* logout.c */; }; + C97A71E61517AF53005E1998 /* logwtmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCD138D9E9A0028D27C /* logwtmp.c */; }; + C97A71E71517AF53005E1998 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; }; + C97A71E81517AF53005E1998 /* opendev.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DD0138D9E9A0028D27C /* opendev.c */; }; + C97A71E91517AF53005E1998 /* pty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DD2138D9E9A0028D27C /* pty.c */; }; + C97A71EA1517AF53005E1998 /* clear.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DD9138D9E9A0028D27C /* clear.c */; }; + C97A71EB1517AF53005E1998 /* compare.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDA138D9E9A0028D27C /* compare.c */; }; + C97A71EC1517AF53005E1998 /* copy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDB138D9E9A0028D27C /* copy.c */; }; + C97A71ED1517AF53005E1998 /* gen_uuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDC138D9E9A0028D27C /* gen_uuid.c */; }; + C97A71EE1517AF53005E1998 /* isnull.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDE138D9E9A0028D27C /* isnull.c */; }; + C97A71EF1517AF53005E1998 /* pack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE0138D9E9A0028D27C /* pack.c */; }; + C97A71F01517AF53005E1998 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; }; + C97A71F11517AF53005E1998 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; }; + C97A71F21517AF53005E1998 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; }; + C97A71F71517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C97A71F81517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C97A71F91517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C97A71FA1517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; }; + C97A71FD1517AF53005E1998 /* scandir_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB350E138F769B0075BB52 /* scandir_b.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; + C97A71FF1517AF53005E1998 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C921D3831395B7DD001CE070 /* init_cpu_capabilities.c */; }; + C97A72001517AF53005E1998 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3841395B7DD001CE070 /* pthread_getspecific.s */; }; + C97A72011517AF53005E1998 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3851395B7DD001CE070 /* pthread_self.s */; }; + C97A72021517AF53005E1998 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3861395B7DD001CE070 /* pthread_set_self.s */; }; + C97A72031517AF53005E1998 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3871395B7DD001CE070 /* start_wqthread.s */; }; + C97A72041517AF53005E1998 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3881395B7DD001CE070 /* thread_start.s */; }; + C97A720D1517AF53005E1998 /* strcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518613D4D966004F7BA8 /* strcpy.c */; }; + C97A720E1517AF53005E1998 /* strlcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518B13D4DABD004F7BA8 /* strlcpy.c */; }; + C97A720F1517AF53005E1998 /* strncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518E13D4DAEA004F7BA8 /* strncpy.c */; }; + C97A72101517AF53005E1998 /* stpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060513DDEDF10094DD56 /* stpcpy.c */; }; + C97A72111517AF53005E1998 /* stpncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060913DDEEA10094DD56 /* stpncpy.c */; }; + C97A72121517AF53005E1998 /* strcat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060C13DDF26A0094DD56 /* strcat.c */; }; + C97A72131517AF53005E1998 /* strncat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060F13DDF4340094DD56 /* strncat.c */; }; + C97A72141517AF53005E1998 /* strlcat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4061213DDF6A20094DD56 /* strlcat.c */; }; + C97A72161517AF53005E1998 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; }; + C97A72171517AF53005E1998 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; }; C98373971395989E00E5C052 /* OSMemoryNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAC138D9E9A0028D27C /* OSMemoryNotification.c */; }; C98373981395989E00E5C052 /* OSThermalNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAD138D9E9A0028D27C /* OSThermalNotification.c */; }; - C995462813AAA25000A531B4 /* OSAtomicUP.c in Sources */ = {isa = PBXBuildFile; fileRef = C995462713AAA25000A531B4 /* OSAtomicUP.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; + C98E2B4C139851B7002A3ABB /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C921D3831395B7DD001CE070 /* init_cpu_capabilities.c */; }; + C98E2B4D139851B7002A3ABB /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3841395B7DD001CE070 /* pthread_getspecific.s */; }; + C98E2B4E139851B7002A3ABB /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3851395B7DD001CE070 /* pthread_self.s */; }; + C98E2B4F139851B7002A3ABB /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3861395B7DD001CE070 /* pthread_set_self.s */; }; + C98E2B50139851B7002A3ABB /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3871395B7DD001CE070 /* start_wqthread.s */; }; + C98E2B51139851B7002A3ABB /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3881395B7DD001CE070 /* thread_start.s */; }; C9A12853138E0BE00003880A /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; C9A12854138E0C1C0003880A /* isctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E5138D9E990028D27C /* isctype.c */; }; C9A12855138E0C1C0003880A /* iswctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E7138D9E990028D27C /* iswctype.c */; }; @@ -3681,33 +4341,8 @@ C9A128A3138E0CD10003880A /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; C9A128A4138E0CD10003880A /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; C9A128A5138E0CD10003880A /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; - C9A128A6138E0D0B0003880A /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; }; - C9A128A7138E0D0B0003880A /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; }; - C9A128A8138E0D0B0003880A /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; }; - C9A128A9138E0D0B0003880A /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; }; - C9A128AA138E0D0B0003880A /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; }; - C9A128AB138E0D0B0003880A /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; }; - C9A128AC138E0D0B0003880A /* stack.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFE138D9E990028D27C /* stack.s */; }; - C9A128AD138E0D0B0003880A /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; settings = {COMPILER_FLAGS = "-U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0"; }; }; - C9A128B3138E0D950003880A /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; - C9A128B4138E0D950003880A /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; - C9A128B5138E0D950003880A /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; - C9A128B6138E0D950003880A /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; - C9A128B7138E0D950003880A /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; - C9A128B8138E0D950003880A /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; - C9A128B9138E0D950003880A /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; - C9A128BA138E0D950003880A /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; - C9A128BB138E0D950003880A /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; - C9A128BC138E0D950003880A /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; - C9A128BD138E0D950003880A /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; - C9A128BE138E0D950003880A /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; - C9A128BF138E0D950003880A /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; - C9A128C0138E0D950003880A /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; C9A12929138E0EF00003880A /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; }; C9A1292A138E0EF00003880A /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; - C9A12974138E10AB0003880A /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; }; - C9A12975138E10AB0003880A /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; }; - C9A12976138E10AB0003880A /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; }; C9A12977138E10C40003880A /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; settings = {COMPILER_FLAGS = " -D__FBSDID=__RCSID"; }; }; C9A12978138E10C40003880A /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; C9A12979138E10C40003880A /* logwtmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCD138D9E9A0028D27C /* logwtmp.c */; }; @@ -3722,60 +4357,16 @@ C9A12982138E10FB0003880A /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; settings = {COMPILER_FLAGS = "-include $(SRCROOT)/uuid/uuid-config.h"; }; }; C9A12983138E10FB0003880A /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; settings = {COMPILER_FLAGS = "-include $(SRCROOT)/uuid/uuid-config.h"; }; }; C9A12984138E10FB0003880A /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; settings = {COMPILER_FLAGS = "-include $(SRCROOT)/uuid/uuid-config.h"; }; }; - C9B4E3D813BBBF2D0008A9BB /* OSAtomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B4E3D713BBBF2D0008A9BB /* OSAtomic.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; - C9B4E3DE13BBCE5F0008A9BB /* OSAtomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B4E3D713BBBF2D0008A9BB /* OSAtomic.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; }; - C9B53E57138DA5910028D27C /* _ctx_start.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF1138D9E9A0028D27C /* _ctx_start.S */; }; - C9B53E58138DA5910028D27C /* _setcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF2138D9E9A0028D27C /* _setcontext.S */; }; - C9B53E59138DA5910028D27C /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF3138D9E9A0028D27C /* cpu_number.s */; }; - C9B53E5A138DA5910028D27C /* getcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF4138D9E9A0028D27C /* getcontext.S */; }; - C9B53E5B138DA5910028D27C /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; }; - C9B53E5C138DA5910028D27C /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF6138D9E9A0028D27C /* icacheinval.s */; }; - C9B53E5D138DA5910028D27C /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; }; + C9AE91B51517D31A00A2626C /* libBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C2A94D138DFFD900287F00 /* libBase.a */; }; + C9AE91B71517D31C00A2626C /* libFreeBSD.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9257ED0138E1B5000B3107C /* libFreeBSD.a */; }; + C9AE91B81517D32200A2626C /* libvCancelable.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9D94360138EC3E300FB7ACC /* libvCancelable.a */; }; + C9AE91B91517D32900A2626C /* libTRE.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B122F2AD1432B8E600AF95D0 /* libTRE.a */; }; C9B53E5E138DA5910028D27C /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF9138D9E9A0028D27C /* mcount.s */; }; - C9B53E5F138DA5910028D27C /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; }; - C9B53E60138DA5910028D27C /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; }; - C9B53E62138DA5950028D27C /* preempt.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFE138D9E9A0028D27C /* preempt.s */; }; - C9B53E63138DA5950028D27C /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFF138D9E9A0028D27C /* pthread_getspecific.s */; }; - C9B53E64138DA5950028D27C /* pthread_mutex_lock.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E00138D9E9A0028D27C /* pthread_mutex_lock.s */; }; - C9B53E65138DA5950028D27C /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E01138D9E9A0028D27C /* pthread_self.s */; }; - C9B53E66138DA5950028D27C /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E02138D9E9A0028D27C /* pthread_set_self.s */; }; - C9B53E67138DA5950028D27C /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E03138D9E9A0028D27C /* start_wqthread.s */; }; - C9B53E68138DA5950028D27C /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E04138D9E9A0028D27C /* thread_start.s */; }; - C9B53E69138DA59F0028D27C /* __bzero.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E08138D9E9A0028D27C /* __bzero.s */; }; - C9B53E6A138DA59F0028D27C /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; }; - C9B53E6B138DA59F0028D27C /* bcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0A138D9E9A0028D27C /* bcopy_sse3x.s */; }; - C9B53E6C138DA59F0028D27C /* bcopy_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0B138D9E9A0028D27C /* bcopy_sse42.s */; }; - C9B53E6D138DA59F0028D27C /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; }; - C9B53E6E138DA59F0028D27C /* bzero_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0D138D9E9A0028D27C /* bzero_sse2.s */; }; - C9B53E6F138DA59F0028D27C /* bzero_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0E138D9E9A0028D27C /* bzero_sse42.s */; }; - C9B53E70138DA59F0028D27C /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0F138D9E9A0028D27C /* ffs.s */; }; - C9B53E71138DA59F0028D27C /* longcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E10138D9E9A0028D27C /* longcopy_sse3x.s */; }; - C9B53E72138DA59F0028D27C /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E12138D9E9A0028D27C /* memcmp.s */; }; - C9B53E73138DA59F0028D27C /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; }; - C9B53E74138DA59F0028D27C /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; }; - C9B53E75138DA59F0028D27C /* memset.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E15138D9E9A0028D27C /* memset.s */; }; - C9B53E76138DA59F0028D27C /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E16138D9E9A0028D27C /* strcmp.s */; }; C9B53E77138DA59F0028D27C /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E17138D9E9A0028D27C /* strcpy.s */; }; - C9B53E78138DA59F0028D27C /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E18138D9E9A0028D27C /* strlcat.s */; }; - C9B53E79138DA59F0028D27C /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E19138D9E9A0028D27C /* strlcpy.s */; }; C9B53E7A138DA59F0028D27C /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1A138D9E9A0028D27C /* strlen.s */; }; - C9B53E7B138DA59F0028D27C /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1B138D9E9A0028D27C /* strncmp.s */; }; C9B53E7C138DA59F0028D27C /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1C138D9E9A0028D27C /* strncpy.s */; }; - C9B53E7D138DA5A30028D27C /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1E138D9E9A0028D27C /* _setjmp.s */; }; - C9B53E7E138DA5A30028D27C /* _sigtramp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1F138D9E9A0028D27C /* _sigtramp.s */; }; - C9B53E7F138DA5A30028D27C /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; }; - C9B53E80138DA5A30028D27C /* i386_gettimeofday_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E21138D9E9A0028D27C /* i386_gettimeofday_asm.s */; }; - C9B53E81138DA5A30028D27C /* nanotime.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E23138D9E9A0028D27C /* nanotime.s */; }; - C9B53E82138DA5A30028D27C /* OSAtomic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E24138D9E9A0028D27C /* OSAtomic.s */; }; - C9B53E83138DA5A30028D27C /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E25138D9E9A0028D27C /* setjmp.s */; }; - C9B53E84138DA5A30028D27C /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; }; - C9B53E85138DA5A30028D27C /* spinlocks_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E27138D9E9A0028D27C /* spinlocks_asm.s */; }; C9C2A959138E025700287F00 /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; C9C2A95A138E025700287F00 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; }; - C9C2A95B138E03C700287F00 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; }; - C9C2A95C138E03C700287F00 /* dirhelper.defs in Sources */ = {isa = PBXBuildFile; fileRef = C9B53614138D9E980028D27C /* dirhelper.defs */; }; - C9C2A95D138E03C700287F00 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; }; - C9C2A95E138E03C700287F00 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; }; C9C2A97D138E058200287F00 /* brk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5366E138D9E980028D27C /* brk.c */; }; C9C2A97E138E058200287F00 /* bsd_signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53670138D9E980028D27C /* bsd_signal.c */; }; C9C2A97F138E058200287F00 /* lchflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53672138D9E980028D27C /* lchflags.c */; }; @@ -3783,18 +4374,7 @@ C9C2A981138E058200287F00 /* lutimes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53676138D9E980028D27C /* lutimes.c */; }; C9C2A982138E058200287F00 /* statvfs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53679138D9E980028D27C /* statvfs.c */; }; C9C2A983138E058200287F00 /* tcgetsid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5367B138D9E980028D27C /* tcgetsid.c */; }; - C9C2A998138E06D900287F00 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; }; - C9C2A999138E06D900287F00 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; }; - C9C2A99A138E06D900287F00 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; }; - C9C2A99B138E06D900287F00 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; }; - C9C2A99C138E06D900287F00 /* asl_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CA138D9E990028D27C /* asl_ipc.defs */; }; - C9C2A99D138E06D900287F00 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; }; - C9C2A99E138E06D900287F00 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; }; - C9C2A99F138E06D900287F00 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; }; - C9C2A9A0138E06D900287F00 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; }; - C9C2A9A1138E06D900287F00 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; }; C9C2A9A2138E06D900287F00 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; - C9C2A9A3138E06D900287F00 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; }; C9C2A9A4138E06D900287F00 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; }; C9C2A9A5138E06D900287F00 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; }; C9C2A9A6138E06D900287F00 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; @@ -3807,124 +4387,32 @@ C9C2A9AD138E072500287F00 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; C9C2A9AE138E072500287F00 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; C9C2A9AF138E072500287F00 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; - C9C2A9B0138E072500287F00 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; }; - C9C2A9B1138E072500287F00 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; }; - C9C2A9B2138E072500287F00 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; }; - C9C2A9B4138E072500287F00 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; }; C9C2A9B5138E072500287F00 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; }; C9C2A9B6138E072500287F00 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; }; - C9C2A9B7138E072500287F00 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; }; C9C2A9B8138E072500287F00 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; C9C2A9B9138E072600287F00 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; - C9C2A9BA138E072600287F00 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; }; - C9C2A9BB138E072600287F00 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; }; C9C2A9BC138E072600287F00 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; - C9C2A9BD138E072600287F00 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; }; C9C2A9BE138E072600287F00 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; C9C2A9BF138E072600287F00 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; C9C2A9C0138E072600287F00 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; - C9C2A9C1138E072600287F00 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; - C9CF595A13CD0B9600674871 /* memset_pattern.c in Sources */ = {isa = PBXBuildFile; fileRef = C9CF595913CD0B9600674871 /* memset_pattern.c */; }; C9D94333138DB75B00FB7ACC /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; C9D94359138EC0C600FB7ACC /* heapsort_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94357138EC0C600FB7ACC /* heapsort_b.c */; }; C9D9435A138EC0C600FB7ACC /* heapsort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94358138EC0C600FB7ACC /* heapsort_r.c */; }; - C9EB2F4C138F68A80075BB52 /* _ctx_start.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53811138D9E990028D27C /* _ctx_start.S */; }; - C9EB2F4D138F68A80075BB52 /* _setcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53812138D9E990028D27C /* _setcontext.S */; }; - C9EB2F4E138F68A80075BB52 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53813138D9E990028D27C /* cpu_number.s */; }; - C9EB2F4F138F68A80075BB52 /* getcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53814138D9E990028D27C /* getcontext.S */; }; - C9EB2F50138F68A80075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; }; - C9EB2F51138F68A80075BB52 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53816138D9E990028D27C /* icacheinval.s */; }; - C9EB2F52138F68A80075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; }; C9EB2F53138F68A80075BB52 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53819138D9E990028D27C /* mcount.s */; }; - C9EB2F54138F68A80075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; }; - C9EB2F55138F68A80075BB52 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; }; - C9EB2F56138F68A80075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; }; - C9EB2F57138F68A80075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; }; - C9EB2F58138F68A80075BB52 /* preempt.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53820138D9E990028D27C /* preempt.s */; }; - C9EB2F59138F68A80075BB52 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53821138D9E990028D27C /* pthread_getspecific.s */; }; - C9EB2F5A138F68A80075BB52 /* pthread_mutex_lock.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53822138D9E990028D27C /* pthread_mutex_lock.s */; }; - C9EB2F5B138F68A80075BB52 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53823138D9E990028D27C /* pthread_self.s */; }; - C9EB2F5C138F68A80075BB52 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53824138D9E990028D27C /* pthread_set_self.s */; }; - C9EB2F5D138F68A80075BB52 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53825138D9E990028D27C /* start_wqthread.s */; }; - C9EB2F5E138F68A80075BB52 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53826138D9E990028D27C /* thread_start.s */; }; - C9EB2F60138F68A80075BB52 /* __bzero.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382A138D9E990028D27C /* __bzero.s */; }; - C9EB2F61138F68A80075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; }; - C9EB2F62138F68A80075BB52 /* bcopy_scalar.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382C138D9E990028D27C /* bcopy_scalar.s */; }; - C9EB2F63138F68A80075BB52 /* bcopy_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382D138D9E990028D27C /* bcopy_sse2.s */; }; - C9EB2F64138F68A80075BB52 /* bcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382E138D9E990028D27C /* bcopy_sse3x.s */; }; - C9EB2F65138F68A80075BB52 /* bcopy_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382F138D9E990028D27C /* bcopy_sse42.s */; }; - C9EB2F66138F68A80075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; }; - C9EB2F67138F68A80075BB52 /* bzero_scalar.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53831138D9E990028D27C /* bzero_scalar.s */; }; - C9EB2F68138F68A80075BB52 /* bzero_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53832138D9E990028D27C /* bzero_sse2.s */; }; - C9EB2F69138F68A80075BB52 /* bzero_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53833138D9E990028D27C /* bzero_sse42.s */; }; - C9EB2F6A138F68A80075BB52 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53834138D9E990028D27C /* ffs.s */; }; - C9EB2F6B138F68A80075BB52 /* longcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53835138D9E990028D27C /* longcopy_sse3x.s */; }; - C9EB2F6C138F68A80075BB52 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53837138D9E990028D27C /* memcmp.s */; }; - C9EB2F6D138F68A80075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; }; - C9EB2F6E138F68A80075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; }; - C9EB2F6F138F68A80075BB52 /* memset.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383A138D9E990028D27C /* memset.s */; }; - C9EB2F70138F68A80075BB52 /* memset_pattern_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383B138D9E990028D27C /* memset_pattern_sse2.s */; }; - C9EB2F71138F68A80075BB52 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383C138D9E990028D27C /* strcmp.s */; }; C9EB2F72138F68A80075BB52 /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383D138D9E990028D27C /* strcpy.s */; }; C9EB2F73138F68A80075BB52 /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383E138D9E990028D27C /* strlcat.s */; }; C9EB2F74138F68A80075BB52 /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383F138D9E990028D27C /* strlcpy.s */; }; C9EB2F75138F68A80075BB52 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53840138D9E990028D27C /* strlen.s */; }; - C9EB2F76138F68A80075BB52 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53841138D9E990028D27C /* strncmp.s */; }; C9EB2F77138F68A80075BB52 /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53842138D9E990028D27C /* strncpy.s */; }; - C9EB2F78138F68A80075BB52 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53844138D9E990028D27C /* _setjmp.s */; }; - C9EB2F79138F68A80075BB52 /* _sigtramp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53845138D9E990028D27C /* _sigtramp.s */; }; - C9EB2F7A138F68A80075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; }; - C9EB2F7B138F68A80075BB52 /* i386_gettimeofday_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53847138D9E990028D27C /* i386_gettimeofday_asm.s */; }; - C9EB2F7C138F68A80075BB52 /* mach_absolute_time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53848138D9E990028D27C /* mach_absolute_time.c */; }; - C9EB2F7D138F68A80075BB52 /* mach_absolute_time_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53849138D9E990028D27C /* mach_absolute_time_asm.s */; }; - C9EB2F7E138F68A80075BB52 /* OSAtomic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384B138D9E990028D27C /* OSAtomic.s */; }; - C9EB2F7F138F68A80075BB52 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384C138D9E990028D27C /* setjmp.s */; }; - C9EB2F80138F68A80075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; }; - C9EB2F81138F68A80075BB52 /* spinlocks_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384E138D9E990028D27C /* spinlocks_asm.s */; }; - C9EB2F82138F68CB0075BB52 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B1138D9E980028D27C /* cpu_number.s */; }; - C9EB2F83138F68CB0075BB52 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B2138D9E980028D27C /* icacheinval.s */; }; C9EB2F84138F68CB0075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; - C9EB2F85138F68CB0075BB52 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B8138D9E980028D27C /* pthread_getspecific.s */; }; - C9EB2F86138F68CB0075BB52 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B9138D9E980028D27C /* pthread_self.s */; }; - C9EB2F87138F68CB0075BB52 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BA138D9E980028D27C /* pthread_set_self.s */; }; - C9EB2F88138F68CB0075BB52 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BB138D9E980028D27C /* start_wqthread.s */; }; - C9EB2F89138F68CB0075BB52 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BC138D9E980028D27C /* thread_start.s */; }; - C9EB2F8B138F68CB0075BB52 /* bcopy_CortexA8.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C0138D9E980028D27C /* bcopy_CortexA8.s */; }; - C9EB2F8C138F68CB0075BB52 /* bcopy_CortexA9.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C1138D9E980028D27C /* bcopy_CortexA9.s */; }; - C9EB2F8D138F68CB0075BB52 /* bcopy_Generic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C2138D9E980028D27C /* bcopy_Generic.s */; }; - C9EB2F8E138F68CB0075BB52 /* bzero_CortexA8.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C3138D9E980028D27C /* bzero_CortexA8.s */; }; - C9EB2F8F138F68CB0075BB52 /* bzero_CortexA9.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C4138D9E980028D27C /* bzero_CortexA9.s */; }; - C9EB2F90138F68CB0075BB52 /* bzero_Generic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C5138D9E980028D27C /* bzero_Generic.s */; }; - C9EB2F91138F68CB0075BB52 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; }; - C9EB2F92138F68CB0075BB52 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C7138D9E980028D27C /* ffs.s */; }; - C9EB2F93138F68CB0075BB52 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C9138D9E980028D27C /* memcmp.s */; }; - C9EB2F94138F68CB0075BB52 /* memset_pattern.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CA138D9E980028D27C /* memset_pattern.s */; }; - C9EB2F95138F68CB0075BB52 /* strchr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CB138D9E980028D27C /* strchr.s */; }; - C9EB2F96138F68CB0075BB52 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CC138D9E980028D27C /* strcmp.s */; }; C9EB2F99138F68CB0075BB52 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CF138D9E980028D27C /* strlen.s */; }; - C9EB2F9A138F68CB0075BB52 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D0138D9E980028D27C /* strncmp.s */; }; C9EB2F9C138F68CB0075BB52 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D2138D9E980028D27C /* strnlen.s */; }; C9EB2F9D138F68CB0075BB52 /* strstr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D3138D9E980028D27C /* strstr.s */; }; - C9EB2F9E138F68CB0075BB52 /* _longjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D5138D9E980028D27C /* _longjmp.s */; }; - C9EB2FA0138F68CB0075BB52 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D7138D9E980028D27C /* _setjmp.s */; }; - C9EB2FA1138F68CB0075BB52 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; }; - C9EB2FA2138F68CB0075BB52 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; }; - C9EB2FA3138F68CB0075BB52 /* longjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DA138D9E980028D27C /* longjmp.s */; }; - C9EB2FA4138F68CB0075BB52 /* mach_absolute_time.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DB138D9E980028D27C /* mach_absolute_time.s */; }; - C9EB2FA5138F68CB0075BB52 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; }; - C9EB2FA7138F68CB0075BB52 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; }; - C9EB2FA9138F68CB0075BB52 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535E1138D9E980028D27C /* setjmp.s */; }; - C9EB2FBB138F6A920075BB52 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; }; C9EB2FC1138F6BB00075BB52 /* merge_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB2FC0138F6BB00075BB52 /* merge_b.c */; }; C9EB2FC4138F6C5C0075BB52 /* psort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB2FC3138F6C5C0075BB52 /* psort.c */; }; C9EB2FC7138F6CE10075BB52 /* psort_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB2FC5138F6CE10075BB52 /* psort_b.c */; settings = {COMPILER_FLAGS = "-DI_AM_PSORT_B"; }; }; C9EB2FC8138F6CE10075BB52 /* psort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB2FC6138F6CE10075BB52 /* psort_r.c */; settings = {COMPILER_FLAGS = "-DI_AM_PSORT_R"; }; }; C9EB2FCD138F6D880075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; - C9EB2FCE138F6D880075BB52 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; }; - C9EB2FCF138F6D880075BB52 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; }; - C9EB2FD0138F6D880075BB52 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; }; - C9EB2FD1138F6D880075BB52 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; }; - C9EB2FD2138F6D880075BB52 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; }; C9EB2FD4138F6D880075BB52 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; }; C9EB2FD5138F6D880075BB52 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; C9EB2FD6138F6D880075BB52 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; @@ -3937,11 +4425,7 @@ C9EB2FDD138F6D880075BB52 /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SETREUID"; }; }; C9EB2FDE138F6D880075BB52 /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; C9EB2FDF138F6D880075BB52 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; }; - C9EB2FE0138F6D880075BB52 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; }; C9EB2FE1138F6D880075BB52 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; - C9EB2FE2138F6D880075BB52 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; }; - C9EB2FE3138F6D880075BB52 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; }; - C9EB2FE4138F6D880075BB52 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; }; C9EB2FE5138F6D880075BB52 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; C9EB2FE6138F6D880075BB52 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; }; C9EB2FE7138F6D880075BB52 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; }; @@ -4006,18 +4490,8 @@ C9EB3022138F6D880075BB52 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; }; C9EB3023138F6D880075BB52 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; C9EB3024138F6D880075BB52 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; - C9EB3025138F6D880075BB52 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; }; - C9EB3026138F6D880075BB52 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; }; - C9EB3027138F6D880075BB52 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; }; - C9EB3028138F6D880075BB52 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; }; - C9EB3029138F6D880075BB52 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; }; - C9EB302A138F6D880075BB52 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; }; - C9EB302B138F6D880075BB52 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; }; - C9EB302C138F6D880075BB52 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; }; - C9EB302D138F6D880075BB52 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; }; C9EB302E138F6D880075BB52 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; }; C9EB302F138F6D880075BB52 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; - C9EB3030138F6D880075BB52 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; }; C9EB3031138F6D880075BB52 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_CONFSTR"; }; }; C9EB3032138F6D880075BB52 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY"; }; }; C9EB3033138F6D880075BB52 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; @@ -4063,7 +4537,6 @@ C9EB305B138F6D880075BB52 /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS___OPENDIR2 -DLIBC_ALIAS_OPENDIR -include gen/__dirent.h"; }; }; C9EB305C138F6D880075BB52 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; }; C9EB305D138F6D880075BB52 /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; }; - C9EB305E138F6D880075BB52 /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PSELECT $(FreeBSD_CFLAGS)"; }; }; C9EB305F138F6D880075BB52 /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; C9EB3060138F6D880075BB52 /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; C9EB3061138F6D880075BB52 /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; @@ -4107,42 +4580,19 @@ C9EB3087138F6D880075BB52 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; C9EB3088138F6D880075BB52 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; C9EB3089138F6D880075BB52 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; - C9EB308A138F6D880075BB52 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; }; - C9EB308B138F6D880075BB52 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; }; - C9EB308C138F6D880075BB52 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; }; - C9EB308D138F6D880075BB52 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; }; C9EB308E138F6D880075BB52 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; }; C9EB308F138F6D880075BB52 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; C9EB3090138F6D880075BB52 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW"; }; }; C9EB3091138F6D880075BB52 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; - C9EB3092138F6D880075BB52 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; }; C9EB3093138F6D880075BB52 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; }; - C9EB3094138F6D880075BB52 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; }; - C9EB3095138F6D880075BB52 /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; }; C9EB3096138F6D880075BB52 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; C9EB3097138F6D880075BB52 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; - C9EB3098138F6D880075BB52 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; }; - C9EB3099138F6D880075BB52 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; }; C9EB309A138F6D880075BB52 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; - C9EB309B138F6D880075BB52 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; }; C9EB309C138F6D880075BB52 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; C9EB309D138F6D880075BB52 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; C9EB309E138F6D880075BB52 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; C9EB309F138F6D880075BB52 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; C9EB30A1138F6D880075BB52 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; - C9EB30A2138F6D880075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; }; - C9EB30A3138F6D880075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; }; - C9EB30A4138F6D880075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; }; - C9EB30A5138F6D880075BB52 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; }; - C9EB30A6138F6D880075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; }; - C9EB30A7138F6D880075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; }; - C9EB30A8138F6D880075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; }; - C9EB30A9138F6D880075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; }; - C9EB30AA138F6D880075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; }; - C9EB30AB138F6D880075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; }; - C9EB30AC138F6D880075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; }; - C9EB30AD138F6D880075BB52 /* mach_absolute_time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53848138D9E990028D27C /* mach_absolute_time.c */; }; - C9EB30AE138F6D880075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; }; C9EB30C1138F6D880075BB52 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; }; C9EB30C2138F6D880075BB52 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; }; C9EB30C3138F6D880075BB52 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; }; @@ -4231,30 +4681,7 @@ C9EB3116138F6D880075BB52 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; C9EB3117138F6D880075BB52 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; C9EB3118138F6D880075BB52 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; - C9EB3121138F6D880075BB52 /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; }; - C9EB3122138F6D880075BB52 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_CANCEL -DLIBC_ALIAS_PTHREAD_SETCANCELSTATE -DLIBC_ALIAS_PTHREAD_SETCANCELTYPE -DLIBC_ALIAS_PTHREAD_SIGMASK -DLIBC_ALIAS_PTHREAD_TESTCANCEL"; }; }; - C9EB3123138F6D880075BB52 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; }; - C9EB3124138F6D880075BB52 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_INIT"; }; }; - C9EB3125138F6D880075BB52 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY"; }; }; - C9EB3126138F6D880075BB52 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_RWLOCK_DESTROY -DLIBC_ALIAS_PTHREAD_RWLOCK_INIT -DLIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK"; }; }; - C9EB3127138F6D880075BB52 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; }; - C9EB3128138F6D880075BB52 /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; }; - C9EB3129138F6D880075BB52 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; }; C9EB312C138F6D880075BB52 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; - C9EB312F138F6D880075BB52 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; - C9EB3130138F6D880075BB52 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; - C9EB3131138F6D880075BB52 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; - C9EB3132138F6D880075BB52 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; - C9EB3133138F6D880075BB52 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; - C9EB3134138F6D880075BB52 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; - C9EB3135138F6D880075BB52 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; - C9EB3136138F6D880075BB52 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; - C9EB3137138F6D880075BB52 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; - C9EB3138138F6D880075BB52 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; - C9EB3139138F6D880075BB52 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; - C9EB313A138F6D880075BB52 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; - C9EB313B138F6D880075BB52 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; - C9EB313C138F6D880075BB52 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; C9EB313D138F6D880075BB52 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; }; C9EB313E138F6D880075BB52 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; }; C9EB313F138F6D880075BB52 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; }; @@ -4420,29 +4847,17 @@ C9EB31DF138F6D880075BB52 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; C9EB31E0138F6D880075BB52 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; settings = {COMPILER_FLAGS = "-D_DARWIN_UNLIMITED_STREAMS"; }; }; C9EB31E1138F6D880075BB52 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; - C9EB31E2138F6D880075BB52 /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; }; - C9EB31E3138F6D880075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; }; - C9EB31E4138F6D880075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; }; C9EB31E5138F6D880075BB52 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; - C9EB31E6138F6D880075BB52 /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; }; - C9EB31E7138F6D880075BB52 /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; }; - C9EB31E8138F6D880075BB52 /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; }; - C9EB31E9138F6D880075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; }; C9EB31EA138F6D880075BB52 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; - C9EB31EB138F6D880075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; }; - C9EB31EC138F6D880075BB52 /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; }; C9EB31ED138F6D880075BB52 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; C9EB31F0138F6D880075BB52 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; C9EB31F1138F6D880075BB52 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; - C9EB31F3138F6D880075BB52 /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; }; - C9EB31F4138F6D880075BB52 /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; }; C9EB31F5138F6D880075BB52 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; C9EB31F7138F6D880075BB52 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; C9EB31F8138F6D880075BB52 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; }; C9EB31F9138F6D880075BB52 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRERROR"; }; }; C9EB31FC138F6D880075BB52 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; C9EB31FD138F6D880075BB52 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; - C9EB31FF138F6D880075BB52 /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; }; C9EB3201138F6D880075BB52 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; C9EB3202138F6D880075BB52 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; C9EB3203138F6D880075BB52 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; @@ -4485,15 +4900,12 @@ C9EB3228138F6D880075BB52 /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; }; C9EB3229138F6D880075BB52 /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; }; C9EB322A138F6D880075BB52 /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; - C9EB322B138F6D880075BB52 /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; }; + C9EB322B138F6D880075BB52 /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; C9EB322C138F6D880075BB52 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; C9EB322D138F6D880075BB52 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; - C9EB322E138F6D880075BB52 /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; }; C9EB322F138F6D880075BB52 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; - C9EB3230138F6D880075BB52 /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; }; C9EB3231138F6D880075BB52 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; C9EB3232138F6D880075BB52 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; }; - C9EB3233138F6D880075BB52 /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; }; C9EB3234138F6D880075BB52 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; C9EB3235138F6D880075BB52 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_MSGCTL -DKERNEL"; }; }; C9EB3236138F6D880075BB52 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; }; @@ -4505,14 +4917,8 @@ C9EB323C138F6D880075BB52 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; C9EB323D138F6D880075BB52 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SHMCTL -DKERNEL"; }; }; C9EB323E138F6D880075BB52 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; - C9EB323F138F6D880075BB52 /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; }; - C9EB3240138F6D880075BB52 /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; }; - C9EB3241138F6D880075BB52 /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; }; C9EB3242138F6D880075BB52 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; C9EB3243138F6D880075BB52 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; - C9EB3244138F6D880075BB52 /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; }; - C9EB3245138F6D880075BB52 /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; }; - C9EB3246138F6D880075BB52 /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; }; C9EB3247138F6D880075BB52 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; }; C9EB3248138F6D880075BB52 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; C9EB3249138F6D880075BB52 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; @@ -4529,22 +4935,7 @@ C9EB3254138F6D880075BB52 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; }; C9EB3255138F6D880075BB52 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; }; C9EB3256138F6D880075BB52 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; }; - C9EB3257138F6D880075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; }; - C9EB3258138F6D880075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; }; - C9EB3259138F6D880075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; }; - C9EB325A138F6D880075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; }; - C9EB325B138F6D880075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; }; - C9EB325C138F6D880075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; }; - C9EB325D138F6D880075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; }; - C9EB325E138F6D880075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; }; - C9EB325F138F6D880075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; }; - C9EB3260138F6D880075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; }; C9EB3274138F75580075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; }; - C9EB3275138F75580075BB52 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; }; - C9EB3276138F75580075BB52 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; }; - C9EB3277138F75580075BB52 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; }; - C9EB3278138F75580075BB52 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; }; - C9EB3279138F75580075BB52 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; }; C9EB327B138F75580075BB52 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; }; C9EB327C138F75580075BB52 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; }; C9EB327D138F75580075BB52 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; }; @@ -4557,11 +4948,7 @@ C9EB3284138F75580075BB52 /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SETREUID"; }; }; C9EB3285138F75580075BB52 /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; }; C9EB3286138F75580075BB52 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; }; - C9EB3287138F75580075BB52 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; }; C9EB3288138F75580075BB52 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; - C9EB3289138F75580075BB52 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; }; - C9EB328A138F75580075BB52 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; }; - C9EB328B138F75580075BB52 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; }; C9EB328C138F75580075BB52 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; }; C9EB328D138F75580075BB52 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; }; C9EB328E138F75580075BB52 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; }; @@ -4626,18 +5013,8 @@ C9EB32C9138F75580075BB52 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; }; C9EB32CA138F75580075BB52 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; }; C9EB32CB138F75580075BB52 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; }; - C9EB32CC138F75580075BB52 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; }; - C9EB32CD138F75580075BB52 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; }; - C9EB32CE138F75580075BB52 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; }; - C9EB32CF138F75580075BB52 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; }; - C9EB32D0138F75580075BB52 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; }; - C9EB32D1138F75580075BB52 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; }; - C9EB32D2138F75580075BB52 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; }; - C9EB32D3138F75580075BB52 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; }; - C9EB32D4138F75580075BB52 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; }; C9EB32D5138F75580075BB52 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; }; C9EB32D6138F75580075BB52 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; }; - C9EB32D7138F75580075BB52 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; }; C9EB32D8138F75580075BB52 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_CONFSTR"; }; }; C9EB32D9138F75580075BB52 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY"; }; }; C9EB32DA138F75580075BB52 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; }; @@ -4683,7 +5060,6 @@ C9EB3302138F75580075BB52 /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS___OPENDIR2 -DLIBC_ALIAS_OPENDIR -include gen/__dirent.h"; }; }; C9EB3303138F75580075BB52 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; }; C9EB3304138F75580075BB52 /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; }; - C9EB3305138F75580075BB52 /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PSELECT $(FreeBSD_CFLAGS)"; }; }; C9EB3306138F75580075BB52 /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; }; C9EB3307138F75580075BB52 /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; }; C9EB3308138F75580075BB52 /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; @@ -4727,42 +5103,19 @@ C9EB332E138F75580075BB52 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; }; C9EB332F138F75580075BB52 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; }; C9EB3330138F75580075BB52 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; }; - C9EB3331138F75580075BB52 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; }; - C9EB3332138F75580075BB52 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; }; - C9EB3333138F75580075BB52 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; }; - C9EB3334138F75580075BB52 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; }; C9EB3335138F75580075BB52 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; }; C9EB3336138F75580075BB52 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; }; C9EB3337138F75580075BB52 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW"; }; }; C9EB3338138F75580075BB52 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; - C9EB3339138F75580075BB52 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; }; C9EB333A138F75580075BB52 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; }; - C9EB333B138F75580075BB52 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; }; - C9EB333C138F75580075BB52 /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; }; C9EB333D138F75580075BB52 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; }; C9EB333E138F75580075BB52 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; }; - C9EB333F138F75580075BB52 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; }; - C9EB3340138F75580075BB52 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; }; C9EB3341138F75580075BB52 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; }; - C9EB3342138F75580075BB52 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; }; C9EB3343138F75580075BB52 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; }; C9EB3344138F75580075BB52 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; }; C9EB3345138F75580075BB52 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; }; C9EB3346138F75580075BB52 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; }; C9EB3348138F75580075BB52 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; }; - C9EB3349138F75580075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; }; - C9EB334A138F75580075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; }; - C9EB334B138F75580075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; }; - C9EB334C138F75580075BB52 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; }; - C9EB334D138F75580075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; }; - C9EB334E138F75580075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; }; - C9EB334F138F75580075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; }; - C9EB3350138F75580075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; }; - C9EB3351138F75580075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; }; - C9EB3352138F75580075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; }; - C9EB3353138F75580075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; }; - C9EB3354138F75580075BB52 /* mach_absolute_time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53848138D9E990028D27C /* mach_absolute_time.c */; }; - C9EB3355138F75580075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; }; C9EB3368138F75580075BB52 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; }; C9EB3369138F75580075BB52 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; }; C9EB336A138F75580075BB52 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; }; @@ -4851,30 +5204,7 @@ C9EB33BD138F75580075BB52 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; }; C9EB33BE138F75580075BB52 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; }; C9EB33BF138F75580075BB52 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; }; - C9EB33C8138F75580075BB52 /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; }; - C9EB33C9138F75580075BB52 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_CANCEL -DLIBC_ALIAS_PTHREAD_SETCANCELSTATE -DLIBC_ALIAS_PTHREAD_SETCANCELTYPE -DLIBC_ALIAS_PTHREAD_SIGMASK -DLIBC_ALIAS_PTHREAD_TESTCANCEL"; }; }; - C9EB33CA138F75580075BB52 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; }; - C9EB33CB138F75580075BB52 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_INIT"; }; }; - C9EB33CC138F75580075BB52 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY"; }; }; - C9EB33CD138F75580075BB52 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_RWLOCK_DESTROY -DLIBC_ALIAS_PTHREAD_RWLOCK_INIT -DLIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK"; }; }; - C9EB33CE138F75580075BB52 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; }; - C9EB33CF138F75580075BB52 /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; }; - C9EB33D0138F75580075BB52 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; }; C9EB33D3138F75580075BB52 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; }; - C9EB33D6138F75580075BB52 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; }; - C9EB33D7138F75580075BB52 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; }; - C9EB33D8138F75580075BB52 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; }; - C9EB33D9138F75580075BB52 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; }; - C9EB33DA138F75580075BB52 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; }; - C9EB33DB138F75580075BB52 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; }; - C9EB33DC138F75580075BB52 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; }; - C9EB33DD138F75580075BB52 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; }; - C9EB33DE138F75580075BB52 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; }; - C9EB33DF138F75580075BB52 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; }; - C9EB33E0138F75580075BB52 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; }; - C9EB33E1138F75580075BB52 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; }; - C9EB33E2138F75580075BB52 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; }; - C9EB33E3138F75580075BB52 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; }; C9EB33E4138F75580075BB52 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; }; C9EB33E5138F75580075BB52 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; }; C9EB33E6138F75580075BB52 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; }; @@ -5040,29 +5370,17 @@ C9EB3486138F75580075BB52 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; }; C9EB3487138F75580075BB52 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; settings = {COMPILER_FLAGS = "-D_DARWIN_UNLIMITED_STREAMS"; }; }; C9EB3488138F75580075BB52 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; }; - C9EB3489138F75580075BB52 /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; }; - C9EB348A138F75580075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; }; - C9EB348B138F75580075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; }; C9EB348C138F75580075BB52 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; }; - C9EB348D138F75580075BB52 /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; }; - C9EB348E138F75580075BB52 /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; }; - C9EB348F138F75580075BB52 /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; }; - C9EB3490138F75580075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; }; C9EB3491138F75580075BB52 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; }; - C9EB3492138F75580075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; }; - C9EB3493138F75580075BB52 /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; }; C9EB3494138F75580075BB52 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; }; C9EB3497138F75580075BB52 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; }; C9EB3498138F75580075BB52 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; }; - C9EB349A138F75580075BB52 /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; }; - C9EB349B138F75580075BB52 /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; }; C9EB349C138F75580075BB52 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; }; C9EB349E138F75580075BB52 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; }; C9EB349F138F75580075BB52 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; }; C9EB34A0138F75580075BB52 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRERROR"; }; }; C9EB34A3138F75580075BB52 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; }; C9EB34A4138F75580075BB52 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; }; - C9EB34A6138F75580075BB52 /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; }; C9EB34A8138F75580075BB52 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; }; C9EB34A9138F75580075BB52 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; }; C9EB34AA138F75580075BB52 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; }; @@ -5105,15 +5423,12 @@ C9EB34CF138F75580075BB52 /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; }; C9EB34D0138F75580075BB52 /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; }; C9EB34D1138F75580075BB52 /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; }; - C9EB34D2138F75580075BB52 /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; }; + C9EB34D2138F75580075BB52 /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; C9EB34D3138F75580075BB52 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; C9EB34D4138F75580075BB52 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; - C9EB34D5138F75580075BB52 /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; }; C9EB34D6138F75580075BB52 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; - C9EB34D7138F75580075BB52 /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; }; C9EB34D8138F75580075BB52 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; C9EB34D9138F75580075BB52 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; }; - C9EB34DA138F75580075BB52 /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; }; C9EB34DB138F75580075BB52 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; C9EB34DC138F75580075BB52 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_MSGCTL -DKERNEL"; }; }; C9EB34DD138F75580075BB52 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; }; @@ -5125,14 +5440,8 @@ C9EB34E3138F75580075BB52 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; C9EB34E4138F75580075BB52 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SHMCTL -DKERNEL"; }; }; C9EB34E5138F75580075BB52 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; - C9EB34E6138F75580075BB52 /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; }; - C9EB34E7138F75580075BB52 /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; }; - C9EB34E8138F75580075BB52 /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; }; C9EB34E9138F75580075BB52 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; C9EB34EA138F75580075BB52 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; - C9EB34EB138F75580075BB52 /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; }; - C9EB34EC138F75580075BB52 /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; }; - C9EB34ED138F75580075BB52 /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; }; C9EB34EE138F75580075BB52 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; }; C9EB34EF138F75580075BB52 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; C9EB34F0138F75580075BB52 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; }; @@ -5149,43 +5458,26 @@ C9EB34FB138F75580075BB52 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; }; C9EB34FC138F75580075BB52 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; }; C9EB34FD138F75580075BB52 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; }; - C9EB34FE138F75580075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; }; - C9EB34FF138F75580075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; }; - C9EB3500138F75580075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; }; - C9EB3501138F75580075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; }; - C9EB3502138F75580075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; }; - C9EB3503138F75580075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; }; - C9EB3504138F75580075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; }; - C9EB3505138F75580075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; }; - C9EB3506138F75580075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; }; - C9EB3507138F75580075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; }; C9EB350F138F769B0075BB52 /* scandir_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB350E138F769B0075BB52 /* scandir_b.c */; }; C9EB3510138F76A10075BB52 /* scandir_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB350E138F769B0075BB52 /* scandir_b.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; }; C9EB3542138F7D0A0075BB52 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; }; C9EB3543138F7D0A0075BB52 /* logout.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCC138D9E9A0028D27C /* logout.c */; }; C9EB3550138F7EA50075BB52 /* getmntinfo64.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB354F138F7EA50075BB52 /* getmntinfo64.c */; }; - C9EB3556138F7F6A0075BB52 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB3555138F7F6A0075BB52 /* setjmperr.c */; }; C9EB3558138F7FF40075BB52 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; }; C9EB355C138F81A40075BB52 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; }; - C9EB355E138F81AB0075BB52 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; }; + C9ECE2771950E384008E8672 /* atexit_receipt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9ECE2761950E384008E8672 /* atexit_receipt.c */; }; C9FA32F4138E49550089A94B /* abort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C1D138D9E9A0028D27C /* abort.c */; }; C9FA32F9138E4A5C0089A94B /* utf2.c in Sources */ = {isa = PBXBuildFile; fileRef = C9FA32F8138E4A5C0089A94B /* utf2.c */; }; - C9FA32FB138E4BD00089A94B /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; }; + C9FA32FB138E4BD00089A94B /* _libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* _libc_init.c */; }; C9FA32FC138E4BD00089A94B /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; }; C9FA32FD138E4BD00089A94B /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; }; - C9FA32FE138E4BD00089A94B /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; }; C9FA32FF138E4BD00089A94B /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; }; - C9FA3300138E4BD00089A94B /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; }; C9FA3301138E4BD00089A94B /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; }; - C9FA3302138E4BD00089A94B /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; }; C9FA3303138E4BD00089A94B /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; }; C9FA3304138E4BD00089A94B /* openx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAB138D9E9A0028D27C /* openx_np.c */; }; C9FA3307138E4BD00089A94B /* posix_spawn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAE138D9E9A0028D27C /* posix_spawn.c */; }; C9FA3308138E4BD00089A94B /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; }; C9FA3309138E4BD00089A94B /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; }; - C9FA330A138E4BD00089A94B /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; }; - C9FA330B138E4BD00089A94B /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; }; - C9FA330C138E4BD00089A94B /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; }; C9FA330D138E4BD00089A94B /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; }; C9FA330E138E4BD00089A94B /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; }; C9FA3312138E4C490089A94B /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; settings = {COMPILER_FLAGS = "-fno-stack-protector"; }; }; @@ -5245,9 +5537,41 @@ C9FA334B138E4D040089A94B /* gcvt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB9138D9E9A0028D27C /* gcvt.c */; }; C9FA334C138E4D040089A94B /* qsort_b-fbsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CBD138D9E9A0028D27C /* qsort_b-fbsd.c */; }; C9FA334D138E4D0C0089A94B /* strfmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB2138D9E9A0028D27C /* strfmon.c */; }; + FC2ED610157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + FC2ED611157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + FC2ED612157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + FC2ED613157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + FC2ED614157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + FC2ED615157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + FC2ED616157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + FC2ED617157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + FC2ED618157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; }; + FC2ED619157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; + FC2ED61A157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; + FC2ED61B157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; + FC2ED61C157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; + FC2ED61D157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; + FC2ED61E157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; + FC2ED61F157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; + FC2ED620157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; + FC2ED621157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 3F51211616C318EB00AFB431 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3F51206A16C3174300AFB431; + remoteInfo = FortifySource; + }; + 928F25D41BEAD2AE007B13C7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 928F25D01BEACED7007B13C7; + remoteInfo = darwintests; + }; B122F2D81432BA8700AF95D0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = C9B53597138D9A690028D27C /* Project object */; @@ -5255,12 +5579,61 @@ remoteGlobalIDString = B122F0E71432B8E600AF95D0; remoteInfo = TRE; }; - B1E96508157E749200FCCEE7 /* PBXContainerItemProxy */ = { + C0E343851C582ECB00E749C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C9C2A94C138DFFD900287F00; + remoteInfo = Base; + }; + C0E343871C582ECB00E749C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C9257ECF138E1B5000B3107C; + remoteInfo = FreeBSD; + }; + C0E343891C582ECB00E749C2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = C9B53597138D9A690028D27C /* Project object */; proxyType = 1; - remoteGlobalIDString = B1E96340157E722200FCCEE7; - remoteInfo = FreeBSD_gcc; + remoteGlobalIDString = B122F0E71432B8E600AF95D0; + remoteInfo = TRE; + }; + C0E3438B1C582ECB00E749C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C9D9435F138EC3E300FB7ACC; + remoteInfo = Variant_Cancelable; + }; + C0E3438D1C582ECB00E749C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C95B7ED9138F3C55004311DA; + remoteInfo = Variant_DarwinExtsn; + }; + C0E345E51C58323000E749C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C0E343831C582ECB00E749C2; + remoteInfo = libc_static; + }; + C925D2001518FA5D003D315B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C95B7ED9138F3C55004311DA; + remoteInfo = Variant_DarwinExtsn; + }; + C925D2021518FEBE003D315B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C97A6F1E1517AF53005E1998; + remoteInfo = libc_eOS.a; }; C942130813901709004BA536 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -5290,6 +5663,34 @@ remoteGlobalIDString = C95B842A138F53DB004311DA; remoteInfo = Variant_Pre1050; }; + C9AE91BA1517D33100A2626C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C9C2A94C138DFFD900287F00; + remoteInfo = Base; + }; + C9AE91BC1517D33100A2626C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C9257ECF138E1B5000B3107C; + remoteInfo = FreeBSD; + }; + C9AE91BE1517D33100A2626C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = B122F0E71432B8E600AF95D0; + remoteInfo = TRE; + }; + C9AE91C01517D33100A2626C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C9B53597138D9A690028D27C /* Project object */; + proxyType = 1; + remoteGlobalIDString = C9D9435F138EC3E300FB7ACC; + remoteInfo = Variant_Cancelable; + }; C9BD3C38138F16EE00B389FD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = C9B53597138D9A690028D27C /* Project object */; @@ -5342,21 +5743,41 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 3F2208E714358B4A00386F5B /* asl_fd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asl_fd.c; sourceTree = ""; }; + 147CDFCF1B7C14FA00831EC6 /* clock_gettime.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = clock_gettime.3; sourceTree = ""; }; + 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = clock_gettime.c; sourceTree = ""; }; + 2DF67CDD184F9CBE00B83A3D /* debug_private.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = debug_private.c; path = os/debug_private.c; sourceTree = ""; }; + 2DF67CE7184F9CD000B83A3D /* debug_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = debug_private.h; path = os/debug_private.h; sourceTree = ""; }; + 3F169A3C1643B7BA0029E851 /* memccpy_chk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memccpy_chk.c; sourceTree = ""; }; + 3F18DE1F162A732C008B15AC /* memset_s.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = memset_s.3; sourceTree = ""; }; + 3F18DE20162A732C008B15AC /* memset_s.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memset_s.c; sourceTree = ""; }; + 3F267F36163FC8880089A0A6 /* rb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rb.c; sourceTree = ""; }; + 3F267F37163FC8880089A0A6 /* rbtree.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rbtree.3; sourceTree = ""; }; + 3F267F39163FC8BD0089A0A6 /* rbtree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rbtree.h; sourceTree = ""; }; + 3F45E3121A6DC12E00AFF01E /* abort_unsupported.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = abort_unsupported.sh; sourceTree = ""; }; + 3F5120F116C3174300AFB431 /* libFortifySource.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFortifySource.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3F89F3DC13E9194C00F6856C /* mkpath_np.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = mkpath_np.3; sourceTree = ""; }; 3F89F3DD13E9194C00F6856C /* mkpath_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mkpath_np.c; sourceTree = ""; }; + 3FA8F3081643AB4300D37078 /* strlcat_chk.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strlcat_chk.c; sourceTree = ""; }; + 3FA8F3091643AB4300D37078 /* strlcpy_chk.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strlcpy_chk.c; sourceTree = ""; }; 3FB7E1B4146EF2E000843438 /* dirfd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirfd.c; sourceTree = ""; }; + 3FD14572171D42B300B7BAF5 /* bcopy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bcopy.c; sourceTree = ""; }; + 3FF283231A4764240098AD2C /* sim-compat-symlink.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "sim-compat-symlink.sh"; sourceTree = ""; }; + 4B2C64A215519BAF00342BFA /* assumes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = assumes.c; path = os/assumes.c; sourceTree = ""; }; + 4B2C64AB15519C3400342BFA /* assumes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = assumes.h; path = os/assumes.h; sourceTree = ""; }; 6310518613D4D966004F7BA8 /* strcpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strcpy.c; sourceTree = ""; }; 6310518B13D4DABD004F7BA8 /* strlcpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strlcpy.c; sourceTree = ""; }; 6310518E13D4DAEA004F7BA8 /* strncpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strncpy.c; sourceTree = ""; }; - 634C4C3713BCEADC008CA66D /* memset_pattern_Swift.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = memset_pattern_Swift.s; sourceTree = ""; }; - 6358199013B53DD800CDF61C /* bzero_Swift.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = bzero_Swift.s; sourceTree = ""; }; - 6358199213B53ECB00CDF61C /* bcopy_Swift.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = bcopy_Swift.s; sourceTree = ""; }; + 63505E3A1548525D00B637D7 /* strnlen.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strnlen.s; sourceTree = ""; }; + 639D126615595DDE00D0403A /* strnlen.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strnlen.s; sourceTree = ""; }; 63D4060513DDEDF10094DD56 /* stpcpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stpcpy.c; sourceTree = ""; }; 63D4060913DDEEA10094DD56 /* stpncpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stpncpy.c; sourceTree = ""; }; 63D4060C13DDF26A0094DD56 /* strcat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strcat.c; sourceTree = ""; }; 63D4060F13DDF4340094DD56 /* strncat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strncat.c; sourceTree = ""; }; 63D4061213DDF6A20094DD56 /* strlcat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strlcat.c; sourceTree = ""; }; + 928BD0FD1D7606EA00EC01FC /* timingsafe_bcmp.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = timingsafe_bcmp.3; sourceTree = ""; }; + 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = timingsafe_bcmp.c; sourceTree = ""; }; + 928BD1091D7608A400EC01FC /* environ.7 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = environ.7; sourceTree = ""; }; + 92ABC7E81D375FC2000DF880 /* compatibility_hacks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compatibility_hacks.c; sourceTree = ""; }; B122F2AD1432B8E600AF95D0 /* libTRE.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTRE.a; sourceTree = BUILT_PRODUCTS_DIR; }; B122F2AF1432B95B00AF95D0 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; }; B122F2B11432B95B00AF95D0 /* regcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regcomp.c; sourceTree = ""; }; @@ -5380,71 +5801,59 @@ B122F2C31432B95B00AF95D0 /* tre-0.8.0.tar.bz2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "tre-0.8.0.tar.bz2"; sourceTree = ""; }; B122F2C41432B95B00AF95D0 /* tre-config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "tre-config.h"; sourceTree = ""; }; B122F2C51432B95B00AF95D0 /* tre-last-matched.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "tre-last-matched.h"; sourceTree = ""; }; + B12613EE158818EC0077E3CC /* xprintf_errno.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_errno.c; sourceTree = ""; }; + B12613EF158818EC0077E3CC /* xprintf_float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_float.c; sourceTree = ""; }; + B12613F0158818EC0077E3CC /* xprintf_hexdump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_hexdump.c; sourceTree = ""; }; + B12613F1158818EC0077E3CC /* xprintf_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_int.c; sourceTree = ""; }; + B12613F2158818EC0077E3CC /* xprintf_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xprintf_private.h; sourceTree = ""; }; + B12613F3158818EC0077E3CC /* xprintf_quote.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_quote.c; sourceTree = ""; }; + B12613F4158818EC0077E3CC /* xprintf_str.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_str.c; sourceTree = ""; }; + B12613F5158818EC0077E3CC /* xprintf_time.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_time.c; sourceTree = ""; }; + B12613F6158818EC0077E3CC /* xprintf_vis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_vis.c; sourceTree = ""; }; + B12613F7158818EC0077E3CC /* xprintf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf.c; sourceTree = ""; }; + B126140215881A000077E3CC /* xprintf_comp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_comp.c; sourceTree = ""; }; + B126140315881A000077E3CC /* xprintf_domain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_domain.c; sourceTree = ""; }; + B126140415881A000077E3CC /* xprintf_domain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xprintf_domain.h; sourceTree = ""; }; + B126140715881A420077E3CC /* printf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = printf.h; sourceTree = ""; }; + B1795371158B0E35008990E8 /* xprintf_all_in_one.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_all_in_one.c; sourceTree = ""; }; + B1795372158B0E35008990E8 /* xprintf_exec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_exec.c; sourceTree = ""; }; B19C64591450F8B900032373 /* sync_volume_np.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sync_volume_np.3; sourceTree = ""; }; B19C645B1450F90200032373 /* sync_volume_np.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sync_volume_np.c; sourceTree = ""; }; - B1E96506157E722200FCCEE7 /* libFreeBSD_gcc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFreeBSD_gcc.a; sourceTree = BUILT_PRODUCTS_DIR; }; + C06E02D11CA0C9CA00B07322 /* tests */ = {isa = PBXFileReference; lastKnownFileType = folder; path = tests; sourceTree = ""; }; + C0E343811C58299D00E749C2 /* skip_installhdrs.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = skip_installhdrs.sh; sourceTree = ""; }; + C0E345E21C582ECB00E749C2 /* libc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libc.a; sourceTree = BUILT_PRODUCTS_DIR; }; + C0E345E31C58300F00E749C2 /* libc_static.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = libc_static.xcconfig; sourceTree = ""; }; C9194B4C140E3BC700BE0C3A /* build_linklists.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build_linklists.sh; sourceTree = ""; }; + C921D3831395B7DD001CE070 /* init_cpu_capabilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = init_cpu_capabilities.c; sourceTree = ""; }; + C921D3841395B7DD001CE070 /* pthread_getspecific.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = pthread_getspecific.s; sourceTree = ""; }; + C921D3851395B7DD001CE070 /* pthread_self.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = pthread_self.s; sourceTree = ""; }; + C921D3861395B7DD001CE070 /* pthread_set_self.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = pthread_set_self.s; sourceTree = ""; }; + C921D3871395B7DD001CE070 /* start_wqthread.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = start_wqthread.s; sourceTree = ""; }; + C921D3881395B7DD001CE070 /* thread_start.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = thread_start.s; sourceTree = ""; }; C9257ED0138E1B5000B3107C /* libFreeBSD.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFreeBSD.a; sourceTree = BUILT_PRODUCTS_DIR; }; C9258105138E2D3100B3107C /* libNetBSD.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNetBSD.a; sourceTree = BUILT_PRODUCTS_DIR; }; - C9265D1113B1CF970090BA1C /* clean_simulator.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = clean_simulator.sh; sourceTree = ""; }; - C932C2CF13AB1C73004EDA12 /* SpinlocksWFE.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SpinlocksWFE.c; sourceTree = ""; }; + C925D1FB151805C6003D315B /* eos_stubs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = eos_stubs.c; sourceTree = ""; }; C93D6150143D31E300EB9023 /* sanitise_headers.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = sanitise_headers.sh; sourceTree = ""; }; - C94212CC13900C8A004BA536 /* libc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libc.a; sourceTree = BUILT_PRODUCTS_DIR; }; - C94212DD13900FC3004BA536 /* mig_headers.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = mig_headers.sh; sourceTree = ""; }; + C94212CC13900C8A004BA536 /* libc_dyld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libc_dyld.a; sourceTree = BUILT_PRODUCTS_DIR; }; C942135913904CBC004BA536 /* manpages.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = manpages.sh; sourceTree = ""; }; C942135A13905D1C004BA536 /* manpages.lst */ = {isa = PBXFileReference; explicitFileType = text; path = manpages.lst; sourceTree = ""; }; C95B7ED8138F3C11004311DA /* rune32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rune32.h; sourceTree = ""; }; C95B8176138F3C55004311DA /* libvDarwinExtsn.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libvDarwinExtsn.a; sourceTree = BUILT_PRODUCTS_DIR; }; C95B8421138F52B0004311DA /* libvDarwinExtsnCancelable.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libvDarwinExtsnCancelable.a; sourceTree = BUILT_PRODUCTS_DIR; }; C95B86C7138F53DB004311DA /* libvPre1050.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libvPre1050.a; sourceTree = BUILT_PRODUCTS_DIR; }; - C965CBF1143BBEC7003912CE /* deps.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = deps.c; sourceTree = BUILT_PRODUCTS_DIR; }; C965CBF4143BC1BF003912CE /* force_libc_to_build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = force_libc_to_build.sh; sourceTree = ""; }; C9766150138EC9D400741512 /* patch_headers_variants.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = patch_headers_variants.pl; sourceTree = ""; }; C9766153138ECF0000741512 /* variants.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = variants.xcconfig; sourceTree = ""; }; C976616B138EF14100741512 /* generate_features.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = generate_features.pl; sourceTree = ""; }; - C97C344013AB0E1B00713550 /* Spinlocks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Spinlocks.c; sourceTree = ""; }; - C980F8EB13AB168D0069AB06 /* SpinlocksUP.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SpinlocksUP.c; sourceTree = ""; }; + C97A721C1517AF53005E1998 /* libc_eOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libc_eOS.a; sourceTree = BUILT_PRODUCTS_DIR; }; C9950E6A1390D2CA009863B6 /* headers.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = headers.sh; sourceTree = ""; }; - C995462713AAA25000A531B4 /* OSAtomicUP.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = OSAtomicUP.c; sourceTree = ""; }; - C9B4E3D513BBBF060008A9BB /* OSAtomicLoadStoreEx.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = OSAtomicLoadStoreEx.c; sourceTree = ""; }; - C9B4E3D713BBBF2D0008A9BB /* OSAtomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = OSAtomic.c; sourceTree = ""; }; - C9B4E3D913BBC24E0008A9BB /* SpinlocksLoadStoreEx.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SpinlocksLoadStoreEx.c; sourceTree = ""; }; + C9A288A71ACDBA95004A33A7 /* Makefile.inc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.pascal; path = Makefile.inc; sourceTree = ""; }; + C9AE91AE1517CDAC00A2626C /* eos.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = eos.xcconfig; sourceTree = ""; }; C9B535AE138D9E980028D27C /* APPLE_LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = APPLE_LICENSE; sourceTree = ""; }; - C9B535B1138D9E980028D27C /* cpu_number.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = cpu_number.s; sourceTree = ""; }; - C9B535B2138D9E980028D27C /* icacheinval.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = icacheinval.s; sourceTree = ""; }; C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = init_cpu_capabilities.c; sourceTree = ""; }; - C9B535B8138D9E980028D27C /* pthread_getspecific.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_getspecific.s; sourceTree = ""; }; - C9B535B9138D9E980028D27C /* pthread_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_self.s; sourceTree = ""; }; - C9B535BA138D9E980028D27C /* pthread_set_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_set_self.s; sourceTree = ""; }; - C9B535BB138D9E980028D27C /* start_wqthread.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = start_wqthread.s; sourceTree = ""; }; - C9B535BC138D9E980028D27C /* thread_start.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = thread_start.s; sourceTree = ""; }; - C9B535C0138D9E980028D27C /* bcopy_CortexA8.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_CortexA8.s; sourceTree = ""; }; - C9B535C1138D9E980028D27C /* bcopy_CortexA9.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_CortexA9.s; sourceTree = ""; }; - C9B535C2138D9E980028D27C /* bcopy_Generic.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_Generic.s; sourceTree = ""; }; - C9B535C3138D9E980028D27C /* bzero_CortexA8.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_CortexA8.s; sourceTree = ""; }; - C9B535C4138D9E980028D27C /* bzero_CortexA9.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_CortexA9.s; sourceTree = ""; }; - C9B535C5138D9E980028D27C /* bzero_Generic.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_Generic.s; sourceTree = ""; }; - C9B535C6138D9E980028D27C /* dyld_resolvers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dyld_resolvers.c; sourceTree = ""; }; - C9B535C7138D9E980028D27C /* ffs.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = ffs.s; sourceTree = ""; }; - C9B535C9138D9E980028D27C /* memcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memcmp.s; sourceTree = ""; }; - C9B535CA138D9E980028D27C /* memset_pattern.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memset_pattern.s; sourceTree = ""; }; - C9B535CB138D9E980028D27C /* strchr.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strchr.s; sourceTree = ""; }; - C9B535CC138D9E980028D27C /* strcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcmp.s; sourceTree = ""; }; C9B535CF138D9E980028D27C /* strlen.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlen.s; sourceTree = ""; }; - C9B535D0138D9E980028D27C /* strncmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncmp.s; sourceTree = ""; }; C9B535D2138D9E980028D27C /* strnlen.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strnlen.s; sourceTree = ""; }; C9B535D3138D9E980028D27C /* strstr.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strstr.s; sourceTree = ""; }; - C9B535D5138D9E980028D27C /* _longjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _longjmp.s; sourceTree = ""; }; - C9B535D6138D9E980028D27C /* _setjmp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _setjmp.h; sourceTree = ""; }; - C9B535D7138D9E980028D27C /* _setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setjmp.s; sourceTree = ""; }; - C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = arm_commpage_gettimeofday.c; sourceTree = ""; }; - C9B535D9138D9E980028D27C /* gcc_atomic.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gcc_atomic.c; sourceTree = ""; }; - C9B535DA138D9E980028D27C /* longjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = longjmp.s; sourceTree = ""; }; - C9B535DB138D9E980028D27C /* mach_absolute_time.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = mach_absolute_time.s; sourceTree = ""; }; - C9B535DD138D9E980028D27C /* OSAtomic-v4.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "OSAtomic-v4.c"; sourceTree = ""; }; - C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = OSAtomic_resolvers.c; sourceTree = ""; }; - C9B535E0138D9E980028D27C /* OSAtomic_resolvers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSAtomic_resolvers.h; sourceTree = ""; }; - C9B535E1138D9E980028D27C /* setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = setjmp.s; sourceTree = ""; }; C9B535F7138D9E980028D27C /* creat.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = creat.2; sourceTree = ""; }; C9B535F8138D9E980028D27C /* creat.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = creat.c; sourceTree = ""; }; C9B535FA138D9E980028D27C /* gethostid.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = gethostid.3; sourceTree = ""; }; @@ -5465,15 +5874,7 @@ C9B5360F138D9E980028D27C /* sigpause.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sigpause.2; sourceTree = ""; }; C9B53610138D9E980028D27C /* sigsetmask.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sigsetmask.2; sourceTree = ""; }; C9B53611138D9E980028D27C /* sigvec.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sigvec.2; sourceTree = ""; }; - C9B53613138D9E980028D27C /* _dirhelper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = _dirhelper.c; sourceTree = ""; }; - C9B53614138D9E980028D27C /* dirhelper.defs */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.mig; path = dirhelper.defs; sourceTree = ""; }; - C9B53615138D9E980028D27C /* dirhelper_priv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dirhelper_priv.h; sourceTree = ""; }; C9B53616138D9E980028D27C /* kvm.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = kvm.c; sourceTree = ""; }; - C9B53617138D9E980028D27C /* libproc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = libproc.c; sourceTree = ""; }; - C9B53618138D9E980028D27C /* libproc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libproc.h; sourceTree = ""; }; - C9B53619138D9E980028D27C /* libproc_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libproc_internal.h; sourceTree = ""; }; - C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = MKGetTimeBaseInfo.c; sourceTree = ""; }; - C9B5361C138D9E980028D27C /* proc_listpidspath.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = proc_listpidspath.c; sourceTree = ""; }; C9B53620138D9E980028D27C /* bt_close.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bt_close.c; sourceTree = ""; }; C9B53621138D9E980028D27C /* bt_conv.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bt_conv.c; sourceTree = ""; }; C9B53622138D9E980028D27C /* bt_debug.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bt_debug.c; sourceTree = ""; }; @@ -5534,7 +5935,6 @@ C9B5367D138D9E980028D27C /* _fbsd_compat_.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _fbsd_compat_.h; sourceTree = ""; }; C9B5367E138D9E980028D27C /* _fpmath.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _fpmath.h; sourceTree = ""; }; C9B5367F138D9E980028D27C /* fpmath.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fpmath.h; sourceTree = ""; }; - C9B53680138D9E980028D27C /* libc_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libc_private.h; sourceTree = ""; }; C9B53682138D9E980028D27C /* atomic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = atomic.h; sourceTree = ""; }; C9B53683138D9E980028D27C /* namespace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = namespace.h; sourceTree = ""; }; C9B53684138D9E980028D27C /* port_after.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = port_after.h; sourceTree = ""; }; @@ -5577,29 +5977,9 @@ C9B536BD138D9E980028D27C /* gd_qnan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = gd_qnan.h; sourceTree = ""; }; C9B536BE138D9E980028D27C /* gdtoa.tgz */ = {isa = PBXFileReference; lastKnownFileType = file; path = gdtoa.tgz; sourceTree = ""; }; C9B536C1138D9E990028D27C /* __dirent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = __dirent.h; sourceTree = ""; }; - C9B536C2138D9E990028D27C /* _simple.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = _simple.c; sourceTree = ""; }; - C9B536C3138D9E990028D27C /* _simple.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _simple.h; sourceTree = ""; }; - C9B536C4138D9E990028D27C /* asl.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = asl.3; sourceTree = ""; }; - C9B536C5138D9E990028D27C /* asl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl.c; sourceTree = ""; }; - C9B536C6138D9E990028D27C /* asl_core.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_core.c; sourceTree = ""; }; - C9B536C7138D9E990028D27C /* asl_core.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_core.h; sourceTree = ""; }; - C9B536C8138D9E990028D27C /* asl_file.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_file.c; sourceTree = ""; }; - C9B536C9138D9E990028D27C /* asl_file.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_file.h; sourceTree = ""; }; - C9B536CA138D9E990028D27C /* asl_ipc.defs */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.mig; path = asl_ipc.defs; sourceTree = ""; }; - C9B536CB138D9E990028D27C /* asl_legacy1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_legacy1.c; sourceTree = ""; }; - C9B536CC138D9E990028D27C /* asl_legacy1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_legacy1.h; sourceTree = ""; }; - C9B536CD138D9E990028D27C /* asl_msg.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_msg.c; sourceTree = ""; }; - C9B536CE138D9E990028D27C /* asl_msg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_msg.h; sourceTree = ""; }; - C9B536CF138D9E990028D27C /* asl_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_private.h; sourceTree = ""; }; - C9B536D0138D9E990028D27C /* asl_store.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_store.c; sourceTree = ""; }; - C9B536D1138D9E990028D27C /* asl_store.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_store.h; sourceTree = ""; }; - C9B536D2138D9E990028D27C /* asl_util.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_util.c; sourceTree = ""; }; - C9B536D3138D9E990028D27C /* assumes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = assumes.c; sourceTree = ""; }; - C9B536D4138D9E990028D27C /* assumes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = assumes.h; sourceTree = ""; }; C9B536D5138D9E990028D27C /* authentication.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = authentication.c; sourceTree = ""; }; C9B536D6138D9E990028D27C /* backtrace.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = backtrace.3; sourceTree = ""; }; C9B536D7138D9E990028D27C /* backtrace.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = backtrace.c; sourceTree = ""; }; - C9B536D8138D9E990028D27C /* cache.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cache.c; sourceTree = ""; }; C9B536D9138D9E990028D27C /* compat.5 */ = {isa = PBXFileReference; lastKnownFileType = text; path = compat.5; sourceTree = ""; }; C9B536DA138D9E990028D27C /* confstr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = confstr.3; sourceTree = ""; }; C9B536DB138D9E990028D27C /* confstr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = confstr.c; sourceTree = ""; }; @@ -5647,7 +6027,6 @@ C9B5371C138D9E990028D27C /* getbsize.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getbsize.c; sourceTree = ""; }; C9B5371D138D9E990028D27C /* getcap.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getcap.3; sourceTree = ""; }; C9B5371E138D9E990028D27C /* getcap.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getcap.c; sourceTree = ""; }; - C9B53720138D9E990028D27C /* getcontext.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getcontext.3; sourceTree = ""; }; C9B53721138D9E990028D27C /* getcwd.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getcwd.3; sourceTree = ""; }; C9B53722138D9E990028D27C /* getcwd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getcwd.c; sourceTree = ""; }; C9B53724138D9E990028D27C /* gethostname.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = gethostname.3; sourceTree = ""; }; @@ -5670,7 +6049,6 @@ C9B53741138D9E990028D27C /* lockf.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = lockf.3; sourceTree = ""; }; C9B53743138D9E990028D27C /* lockf.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lockf.c; sourceTree = ""; }; C9B53745138D9E990028D27C /* lrand48.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lrand48.c; sourceTree = ""; }; - C9B53747138D9E990028D27C /* makecontext.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = makecontext.3; sourceTree = ""; }; C9B53749138D9E990028D27C /* mrand48.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mrand48.c; sourceTree = ""; }; C9B5374B138D9E990028D27C /* nice.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = nice.3; sourceTree = ""; }; C9B5374C138D9E990028D27C /* nice.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = nice.c; sourceTree = ""; }; @@ -5680,8 +6058,6 @@ C9B53753138D9E990028D27C /* pause.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pause.c; sourceTree = ""; }; C9B53755138D9E990028D27C /* popen.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = popen.3; sourceTree = ""; }; C9B53757138D9E990028D27C /* popen.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = popen.c; sourceTree = ""; }; - C9B53759138D9E990028D27C /* pselect.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pselect.3; sourceTree = ""; }; - C9B5375B138D9E990028D27C /* pselect.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pselect.c; sourceTree = ""; }; C9B5375D138D9E990028D27C /* psignal.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = psignal.3; sourceTree = ""; }; C9B5375F138D9E990028D27C /* psignal.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = psignal.c; sourceTree = ""; }; C9B53760138D9E990028D27C /* raise.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = raise.3; sourceTree = ""; }; @@ -5731,7 +6107,6 @@ C9B537A9138D9E990028D27C /* ttyslot.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ttyslot.c; sourceTree = ""; }; C9B537AA138D9E990028D27C /* ualarm.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = ualarm.3; sourceTree = ""; }; C9B537AC138D9E990028D27C /* ualarm.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ualarm.c; sourceTree = ""; }; - C9B537AD138D9E990028D27C /* ucontext.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = ucontext.3; sourceTree = ""; }; C9B537AE138D9E990028D27C /* ulimit.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = ulimit.3; sourceTree = ""; }; C9B537B0138D9E990028D27C /* ulimit.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ulimit.c; sourceTree = ""; }; C9B537B1138D9E990028D27C /* unvis.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = unvis.3; sourceTree = ""; }; @@ -5760,15 +6135,6 @@ C9B537CF138D9E990028D27C /* getvfsbyname.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getvfsbyname.3; sourceTree = ""; }; C9B537D0138D9E990028D27C /* getvfsbyname.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getvfsbyname.c; sourceTree = ""; }; C9B537D1138D9E990028D27C /* intro.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = intro.3; sourceTree = ""; }; - C9B537D2138D9E990028D27C /* isinf.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = isinf.c; sourceTree = ""; }; - C9B537D3138D9E990028D27C /* isnan.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = isnan.c; sourceTree = ""; }; - C9B537D4138D9E990028D27C /* magazine_malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = magazine_malloc.c; sourceTree = ""; }; - C9B537D5138D9E990028D27C /* magmallocProvider.d */ = {isa = PBXFileReference; explicitFileType = sourcecode.dtrace; path = magmallocProvider.d; sourceTree = ""; }; - C9B537D7138D9E990028D27C /* malloc.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = malloc.3; sourceTree = ""; }; - C9B537D8138D9E990028D27C /* malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = malloc.c; sourceTree = ""; }; - C9B537D9138D9E990028D27C /* malloc_printf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = malloc_printf.h; sourceTree = ""; }; - C9B537DA138D9E990028D27C /* malloc_size.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = malloc_size.3; sourceTree = ""; }; - C9B537DB138D9E990028D27C /* malloc_zone_malloc.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = malloc_zone_malloc.3; sourceTree = ""; }; C9B537DC138D9E990028D27C /* nanosleep.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = nanosleep.c; sourceTree = ""; }; C9B537DE138D9E990028D27C /* endutxent.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = endutxent.3; sourceTree = ""; }; C9B537E0138D9E990028D27C /* getlastlogx.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getlastlogx.3; sourceTree = ""; }; @@ -5777,25 +6143,14 @@ C9B537E6138D9E990028D27C /* nftw.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = nftw.c; sourceTree = ""; }; C9B537E7138D9E990028D27C /* nlist.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = nlist.3; sourceTree = ""; }; C9B537E8138D9E990028D27C /* nlist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = nlist.c; sourceTree = ""; }; - C9B537E9138D9E990028D27C /* NSSystemDirectories.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = NSSystemDirectories.c; sourceTree = ""; }; C9B537EA138D9E990028D27C /* oldsyslog.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = oldsyslog.c; sourceTree = ""; }; - C9B537EB138D9E990028D27C /* platfunc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = platfunc.c; sourceTree = ""; }; - C9B537EC138D9E990028D27C /* platfunc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = platfunc.h; sourceTree = ""; }; C9B537ED138D9E990028D27C /* posix_memalign.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = posix_memalign.3; sourceTree = ""; }; C9B537EE138D9E990028D27C /* pwcache.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pwcache.3; sourceTree = ""; }; - C9B537EF138D9E990028D27C /* scalable_malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = scalable_malloc.c; sourceTree = ""; }; - C9B537F0138D9E990028D27C /* scalable_malloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = scalable_malloc.h; sourceTree = ""; }; - C9B537F1138D9E990028D27C /* setjmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = setjmp.3; sourceTree = ""; }; C9B537F2138D9E990028D27C /* setlogin.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = setlogin.c; sourceTree = ""; }; C9B537F3138D9E990028D27C /* sigsetops.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sigsetops.3; sourceTree = ""; }; C9B537F4138D9E990028D27C /* sigsetops.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sigsetops.c; sourceTree = ""; }; - C9B537F5138D9E990028D27C /* stack_logging.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stack_logging.c; sourceTree = ""; }; - C9B537F6138D9E990028D27C /* stack_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stack_logging.h; sourceTree = ""; }; - C9B537F7138D9E990028D27C /* stack_logging_disk.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stack_logging_disk.c; sourceTree = ""; }; C9B537F8138D9E990028D27C /* strtofflags.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strtofflags.3; sourceTree = ""; }; C9B537F9138D9E990028D27C /* strtofflags.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strtofflags.c; sourceTree = ""; }; - C9B537FA138D9E990028D27C /* syslog.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = syslog.3; sourceTree = ""; }; - C9B537FB138D9E990028D27C /* syslog.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = syslog.c; sourceTree = ""; }; C9B537FC138D9E990028D27C /* tcgetpgrp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = tcgetpgrp.3; sourceTree = ""; }; C9B537FD138D9E990028D27C /* tcsendbreak.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = tcsendbreak.3; sourceTree = ""; }; C9B537FE138D9E990028D27C /* tcsetattr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = tcsetattr.3; sourceTree = ""; }; @@ -5811,61 +6166,13 @@ C9B53808138D9E990028D27C /* wordexp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = wordexp.c; sourceTree = ""; }; C9B5380B138D9E990028D27C /* gmon.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gmon.c; sourceTree = ""; }; C9B5380D138D9E990028D27C /* moncontrol.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = moncontrol.3; sourceTree = ""; }; - C9B53811138D9E990028D27C /* _ctx_start.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _ctx_start.S; sourceTree = ""; }; - C9B53812138D9E990028D27C /* _setcontext.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setcontext.S; sourceTree = ""; }; - C9B53813138D9E990028D27C /* cpu_number.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = cpu_number.s; sourceTree = ""; }; - C9B53814138D9E990028D27C /* getcontext.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = getcontext.S; sourceTree = ""; }; - C9B53815138D9E990028D27C /* getmcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getmcontext.c; sourceTree = ""; }; - C9B53816138D9E990028D27C /* icacheinval.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = icacheinval.s; sourceTree = ""; }; - C9B53817138D9E990028D27C /* makecontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = makecontext.c; sourceTree = ""; }; C9B53819138D9E990028D27C /* mcount.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = mcount.s; sourceTree = ""; }; - C9B5381A138D9E990028D27C /* setcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = setcontext.c; sourceTree = ""; }; - C9B5381B138D9E990028D27C /* setjmperr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = setjmperr.c; sourceTree = ""; }; - C9B5381C138D9E990028D27C /* swapcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = swapcontext.c; sourceTree = ""; }; - C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = init_cpu_capabilities.c; sourceTree = ""; }; - C9B53820138D9E990028D27C /* preempt.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = preempt.s; sourceTree = ""; }; - C9B53821138D9E990028D27C /* pthread_getspecific.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_getspecific.s; sourceTree = ""; }; - C9B53822138D9E990028D27C /* pthread_mutex_lock.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_mutex_lock.s; sourceTree = ""; }; - C9B53823138D9E990028D27C /* pthread_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_self.s; sourceTree = ""; }; - C9B53824138D9E990028D27C /* pthread_set_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_set_self.s; sourceTree = ""; }; - C9B53825138D9E990028D27C /* start_wqthread.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = start_wqthread.s; sourceTree = ""; }; - C9B53826138D9E990028D27C /* thread_start.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = thread_start.s; sourceTree = ""; }; - C9B5382A138D9E990028D27C /* __bzero.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = __bzero.s; sourceTree = ""; }; - C9B5382B138D9E990028D27C /* bcopy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bcopy.c; sourceTree = ""; }; - C9B5382C138D9E990028D27C /* bcopy_scalar.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_scalar.s; sourceTree = ""; }; - C9B5382D138D9E990028D27C /* bcopy_sse2.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse2.s; sourceTree = ""; }; - C9B5382E138D9E990028D27C /* bcopy_sse3x.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse3x.s; sourceTree = ""; }; - C9B5382F138D9E990028D27C /* bcopy_sse42.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse42.s; sourceTree = ""; }; - C9B53830138D9E990028D27C /* bzero.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bzero.c; sourceTree = ""; }; - C9B53831138D9E990028D27C /* bzero_scalar.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_scalar.s; sourceTree = ""; }; - C9B53832138D9E990028D27C /* bzero_sse2.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_sse2.s; sourceTree = ""; }; - C9B53833138D9E990028D27C /* bzero_sse42.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_sse42.s; sourceTree = ""; }; - C9B53834138D9E990028D27C /* ffs.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = ffs.s; sourceTree = ""; }; - C9B53835138D9E990028D27C /* longcopy_sse3x.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = longcopy_sse3x.s; sourceTree = ""; }; - C9B53837138D9E990028D27C /* memcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memcmp.s; sourceTree = ""; }; - C9B53838138D9E990028D27C /* memcpy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memcpy.c; sourceTree = ""; }; - C9B53839138D9E990028D27C /* memmove.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memmove.c; sourceTree = ""; }; - C9B5383A138D9E990028D27C /* memset.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memset.s; sourceTree = ""; }; - C9B5383B138D9E990028D27C /* memset_pattern_sse2.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memset_pattern_sse2.s; sourceTree = ""; }; - C9B5383C138D9E990028D27C /* strcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcmp.s; sourceTree = ""; }; C9B5383D138D9E990028D27C /* strcpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcpy.s; sourceTree = ""; }; C9B5383E138D9E990028D27C /* strlcat.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlcat.s; sourceTree = ""; }; C9B5383F138D9E990028D27C /* strlcpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlcpy.s; sourceTree = ""; }; C9B53840138D9E990028D27C /* strlen.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlen.s; sourceTree = ""; }; - C9B53841138D9E990028D27C /* strncmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncmp.s; sourceTree = ""; }; C9B53842138D9E990028D27C /* strncpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncpy.s; sourceTree = ""; }; - C9B53844138D9E990028D27C /* _setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setjmp.s; sourceTree = ""; }; - C9B53845138D9E990028D27C /* _sigtramp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _sigtramp.s; sourceTree = ""; }; - C9B53846138D9E990028D27C /* atomic.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = atomic.c; sourceTree = ""; }; - C9B53847138D9E990028D27C /* i386_gettimeofday_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = i386_gettimeofday_asm.s; sourceTree = ""; }; - C9B53848138D9E990028D27C /* mach_absolute_time.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mach_absolute_time.c; sourceTree = ""; }; - C9B53849138D9E990028D27C /* mach_absolute_time_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = mach_absolute_time_asm.s; sourceTree = ""; }; - C9B5384B138D9E990028D27C /* OSAtomic.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = OSAtomic.s; sourceTree = ""; }; - C9B5384C138D9E990028D27C /* setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = setjmp.s; sourceTree = ""; }; - C9B5384D138D9E990028D27C /* spinlocks.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = spinlocks.c; sourceTree = ""; }; - C9B5384E138D9E990028D27C /* spinlocks_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = spinlocks_asm.s; sourceTree = ""; }; C9B53850138D9E990028D27C /* _locale.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _locale.h; sourceTree = ""; }; - C9B53851138D9E990028D27C /* _structs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _structs.h; sourceTree = ""; }; C9B53852138D9E990028D27C /* _types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _types.h; sourceTree = ""; }; C9B53853138D9E990028D27C /* _wctype.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _wctype.h; sourceTree = ""; }; C9B53854138D9E990028D27C /* _xlocale.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _xlocale.h; sourceTree = ""; }; @@ -5876,13 +6183,11 @@ C9B5385B138D9E990028D27C /* nameser_compat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = nameser_compat.h; sourceTree = ""; }; C9B5385C138D9E990028D27C /* telnet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = telnet.h; sourceTree = ""; }; C9B5385D138D9E990028D27C /* tftp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tftp.h; sourceTree = ""; }; - C9B5385E138D9E990028D27C /* asl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl.h; sourceTree = ""; }; C9B5385F138D9E990028D27C /* asm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asm.h; sourceTree = ""; }; C9B53860138D9E990028D27C /* assert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = assert.h; sourceTree = ""; }; C9B53861138D9E990028D27C /* authentication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = authentication.h; sourceTree = ""; }; C9B53862138D9E990028D27C /* bitstring.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bitstring.h; sourceTree = ""; }; C9B53863138D9E990028D27C /* cpio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cpio.h; sourceTree = ""; }; - C9B53864138D9E990028D27C /* CrashReporterClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CrashReporterClient.h; sourceTree = ""; }; C9B53865138D9E990028D27C /* crt_externs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = crt_externs.h; sourceTree = ""; }; C9B53866138D9E990028D27C /* ctype.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ctype.h; sourceTree = ""; }; C9B53867138D9E990028D27C /* db.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = db.h; sourceTree = ""; }; @@ -5906,13 +6211,9 @@ C9B5387C138D9E990028D27C /* langinfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = langinfo.h; sourceTree = ""; }; C9B5387D138D9E990028D27C /* libc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libc.h; sourceTree = ""; }; C9B5387E138D9E990028D27C /* libgen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libgen.h; sourceTree = ""; }; - C9B53881138D9E990028D27C /* OSAtomic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSAtomic.h; sourceTree = ""; }; - C9B53882138D9E990028D27C /* OSCacheControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSCacheControl.h; sourceTree = ""; }; - C9B53883138D9E990028D27C /* OSMemoryNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSMemoryNotification.h; sourceTree = ""; }; C9B53884138D9E990028D27C /* OSThermalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSThermalNotification.h; sourceTree = ""; }; C9B53885138D9E990028D27C /* limits.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = limits.h; sourceTree = ""; }; C9B53886138D9E990028D27C /* locale.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = locale.h; sourceTree = ""; }; - C9B5388A138D9E990028D27C /* malloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = malloc.h; sourceTree = ""; }; C9B5388B138D9E990028D27C /* memory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = ""; }; C9B5388C138D9E990028D27C /* monetary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = monetary.h; sourceTree = ""; }; C9B5388D138D9E990028D27C /* monitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = monitor.h; sourceTree = ""; }; @@ -5920,7 +6221,6 @@ C9B5388F138D9E990028D27C /* ndbm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ndbm.h; sourceTree = ""; }; C9B53891138D9E990028D27C /* utmpx.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = utmpx.h; sourceTree = ""; }; C9B53893138D9E990028D27C /* nlist.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = nlist.h; sourceTree = ""; }; - C9B53894138D9E990028D27C /* NSSystemDirectories.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSSystemDirectories.h; sourceTree = ""; }; C9B53899138D9E990028D27C /* paths.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = paths.h; sourceTree = ""; }; C9B5389A138D9E990028D27C /* poll.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = poll.h; sourceTree = ""; }; C9B5389D138D9E990028D27C /* routed.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = routed.h; sourceTree = ""; }; @@ -5937,14 +6237,10 @@ C9B538AA138D9E990028D27C /* _stdio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _stdio.h; sourceTree = ""; }; C9B538AB138D9E990028D27C /* _string.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _string.h; sourceTree = ""; }; C9B538AD138D9E990028D27C /* semaphore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = semaphore.h; sourceTree = ""; }; - C9B538AE138D9E990028D27C /* setjmp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setjmp.h; sourceTree = ""; }; C9B538AF138D9E990028D27C /* sgtty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sgtty.h; sourceTree = ""; }; C9B538B0138D9E990028D27C /* signal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = signal.h; sourceTree = ""; }; - C9B538B1138D9E990028D27C /* spawn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = spawn.h; sourceTree = ""; }; - C9B538B2138D9E990028D27C /* spawn_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = spawn_private.h; sourceTree = ""; }; C9B538B3138D9E990028D27C /* stab.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stab.h; sourceTree = ""; }; C9B538B4138D9E990028D27C /* standards.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = standards.h; sourceTree = ""; }; - C9B538B5138D9E990028D27C /* stdbool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stdbool.h; sourceTree = ""; }; C9B538B6138D9E990028D27C /* stddef.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stddef.h; sourceTree = ""; }; C9B538B7138D9E990028D27C /* stdint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stdint.h; sourceTree = ""; }; C9B538B8138D9E990028D27C /* stdio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stdio.h; sourceTree = ""; }; @@ -5965,7 +6261,6 @@ C9B538C9138D9E990028D27C /* time.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = time.h; sourceTree = ""; }; C9B538CA138D9E990028D27C /* timeconv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = timeconv.h; sourceTree = ""; }; C9B538CB138D9E990028D27C /* ttyent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ttyent.h; sourceTree = ""; }; - C9B538CC138D9E990028D27C /* ucontext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ucontext.h; sourceTree = ""; }; C9B538CD138D9E990028D27C /* ulimit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ulimit.h; sourceTree = ""; }; C9B538CE138D9E990028D27C /* unistd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unistd.h; sourceTree = ""; }; C9B538CF138D9E990028D27C /* util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; @@ -6130,7 +6425,6 @@ C9B539F8138D9E990028D27C /* xlocale_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = xlocale_private.h; sourceTree = ""; }; C9B53A05138D9E990028D27C /* assert.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = assert.3; sourceTree = ""; }; C9B53A06138D9E990028D27C /* bitstring.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = bitstring.3; sourceTree = ""; }; - C9B53A07138D9E990028D27C /* environ.7 */ = {isa = PBXFileReference; lastKnownFileType = text; path = environ.7; sourceTree = ""; }; C9B53A09138D9E990028D27C /* stdarg.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = stdarg.3; sourceTree = ""; }; C9B53A0B138D9E990028D27C /* gethostuuid.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = gethostuuid.2; sourceTree = ""; }; C9B53A0D138D9E990028D27C /* utmp.5 */ = {isa = PBXFileReference; lastKnownFileType = text; path = utmp.5; sourceTree = ""; }; @@ -6161,7 +6455,6 @@ C9B53A33138D9E990028D27C /* sockatmark.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sockatmark.c; sourceTree = ""; }; C9B53A34138D9E990028D27C /* sourcefilter.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sourcefilter.3; sourceTree = ""; }; C9B53A36138D9E990028D27C /* sourcefilter.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sourcefilter.c; sourceTree = ""; }; - C9B53A39138D9E990028D27C /* rcmdsh.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = rcmdsh.3; sourceTree = ""; }; C9B53A3C138D9E990028D27C /* catclose.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = catclose.3; sourceTree = ""; }; C9B53A3D138D9E990028D27C /* catgets.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = catgets.3; sourceTree = ""; }; C9B53A3E138D9E990028D27C /* catopen.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = catopen.3; sourceTree = ""; }; @@ -6208,76 +6501,6 @@ C9B53A6F138D9E990028D27C /* acl_translate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = acl_translate.c; sourceTree = ""; }; C9B53A70138D9E990028D27C /* acl_valid.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = acl_valid.3; sourceTree = ""; }; C9B53A71138D9E990028D27C /* aclvar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = aclvar.h; sourceTree = ""; }; - C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mk_pthread_impl.c; sourceTree = ""; }; - C9B53ABD138D9E990028D27C /* plockstat.d */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.dtrace; path = plockstat.d; sourceTree = ""; }; - C9B53ABE138D9E990028D27C /* posix_sched.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = posix_sched.h; sourceTree = ""; }; - C9B53ABF138D9E990028D27C /* pthread.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread.3; sourceTree = ""; }; - C9B53AC0138D9E990028D27C /* pthread.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread.c; sourceTree = ""; }; - C9B53AC1138D9E990028D27C /* pthread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread.h; sourceTree = ""; }; - C9B53AC2138D9E990028D27C /* pthread_atfork.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_atfork.3; sourceTree = ""; }; - C9B53AC3138D9E990028D27C /* pthread_attr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr.3; sourceTree = ""; }; - C9B53AC4138D9E990028D27C /* pthread_attr_init_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_init_destroy.3; sourceTree = ""; }; - C9B53AC5138D9E990028D27C /* pthread_attr_set_getdetachstate.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getdetachstate.3; sourceTree = ""; }; - C9B53AC6138D9E990028D27C /* pthread_attr_set_getinheritsched.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getinheritsched.3; sourceTree = ""; }; - C9B53AC7138D9E990028D27C /* pthread_attr_set_getschedparam.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getschedparam.3; sourceTree = ""; }; - C9B53AC8138D9E990028D27C /* pthread_attr_set_getschedpolicy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getschedpolicy.3; sourceTree = ""; }; - C9B53AC9138D9E990028D27C /* pthread_attr_set_getscope.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getscope.3; sourceTree = ""; }; - C9B53ACA138D9E990028D27C /* pthread_attr_set_getstackaddr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getstackaddr.3; sourceTree = ""; }; - C9B53ACB138D9E990028D27C /* pthread_attr_set_getstacksize.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getstacksize.3; sourceTree = ""; }; - C9B53ACC138D9E990028D27C /* pthread_cancel.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cancel.3; sourceTree = ""; }; - C9B53ACD138D9E990028D27C /* pthread_cancelable.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_cancelable.c; sourceTree = ""; }; - C9B53ACE138D9E990028D27C /* pthread_cleanup_pop.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cleanup_pop.3; sourceTree = ""; }; - C9B53ACF138D9E990028D27C /* pthread_cleanup_push.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cleanup_push.3; sourceTree = ""; }; - C9B53AD0138D9E990028D27C /* pthread_cond.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_cond.c; sourceTree = ""; }; - C9B53AD1138D9E990028D27C /* pthread_cond_broadcast.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_broadcast.3; sourceTree = ""; }; - C9B53AD2138D9E990028D27C /* pthread_cond_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_destroy.3; sourceTree = ""; }; - C9B53AD3138D9E990028D27C /* pthread_cond_init.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_init.3; sourceTree = ""; }; - C9B53AD4138D9E990028D27C /* pthread_cond_signal.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_signal.3; sourceTree = ""; }; - C9B53AD5138D9E990028D27C /* pthread_cond_timedwait.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_timedwait.3; sourceTree = ""; }; - C9B53AD6138D9E990028D27C /* pthread_cond_wait.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_wait.3; sourceTree = ""; }; - C9B53AD7138D9E990028D27C /* pthread_condattr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_condattr.3; sourceTree = ""; }; - C9B53AD8138D9E990028D27C /* pthread_create.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_create.3; sourceTree = ""; }; - C9B53AD9138D9E990028D27C /* pthread_detach.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_detach.3; sourceTree = ""; }; - C9B53ADA138D9E990028D27C /* pthread_equal.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_equal.3; sourceTree = ""; }; - C9B53ADB138D9E990028D27C /* pthread_exit.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_exit.3; sourceTree = ""; }; - C9B53ADC138D9E990028D27C /* pthread_getschedparam.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_getschedparam.3; sourceTree = ""; }; - C9B53ADD138D9E990028D27C /* pthread_getspecific.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_getspecific.3; sourceTree = ""; }; - C9B53ADE138D9E990028D27C /* pthread_impl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_impl.h; sourceTree = ""; }; - C9B53ADF138D9E990028D27C /* pthread_internals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_internals.h; sourceTree = ""; }; - C9B53AE0138D9E990028D27C /* pthread_join.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_join.3; sourceTree = ""; }; - C9B53AE1138D9E990028D27C /* pthread_key_create.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_key_create.3; sourceTree = ""; }; - C9B53AE2138D9E990028D27C /* pthread_key_delete.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_key_delete.3; sourceTree = ""; }; - C9B53AE3138D9E990028D27C /* pthread_machdep.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_machdep.h; sourceTree = ""; }; - C9B53AE4138D9E990028D27C /* pthread_mutex.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_mutex.c; sourceTree = ""; }; - C9B53AE5138D9E990028D27C /* pthread_mutex_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_destroy.3; sourceTree = ""; }; - C9B53AE6138D9E990028D27C /* pthread_mutex_init.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_init.3; sourceTree = ""; }; - C9B53AE7138D9E990028D27C /* pthread_mutex_lock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_lock.3; sourceTree = ""; }; - C9B53AE8138D9E990028D27C /* pthread_mutex_trylock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_trylock.3; sourceTree = ""; }; - C9B53AE9138D9E990028D27C /* pthread_mutex_unlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_unlock.3; sourceTree = ""; }; - C9B53AEA138D9E990028D27C /* pthread_mutexattr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutexattr.3; sourceTree = ""; }; - C9B53AEB138D9E990028D27C /* pthread_once.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_once.3; sourceTree = ""; }; - C9B53AEC138D9E990028D27C /* pthread_rwlock.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_rwlock.c; sourceTree = ""; }; - C9B53AED138D9E990028D27C /* pthread_rwlock_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_destroy.3; sourceTree = ""; }; - C9B53AEE138D9E990028D27C /* pthread_rwlock_init.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_init.3; sourceTree = ""; }; - C9B53AEF138D9E990028D27C /* pthread_rwlock_rdlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_rdlock.3; sourceTree = ""; }; - C9B53AF0138D9E990028D27C /* pthread_rwlock_unlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_unlock.3; sourceTree = ""; }; - C9B53AF1138D9E990028D27C /* pthread_rwlock_wrlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_wrlock.3; sourceTree = ""; }; - C9B53AF2138D9E990028D27C /* pthread_rwlockattr_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlockattr_destroy.3; sourceTree = ""; }; - C9B53AF3138D9E990028D27C /* pthread_rwlockattr_getpshared.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlockattr_getpshared.3; sourceTree = ""; }; - C9B53AF4138D9E990028D27C /* pthread_rwlockattr_init.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlockattr_init.3; sourceTree = ""; }; - C9B53AF5138D9E990028D27C /* pthread_rwlockattr_setpshared.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlockattr_setpshared.3; sourceTree = ""; }; - C9B53AF6138D9E990028D27C /* pthread_self.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_self.3; sourceTree = ""; }; - C9B53AF7138D9E990028D27C /* pthread_setcancelstate.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_setcancelstate.3; sourceTree = ""; }; - C9B53AF8138D9E990028D27C /* pthread_setspecific.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_setspecific.3; sourceTree = ""; }; - C9B53AF9138D9E990028D27C /* pthread_spinlock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_spinlock.h; sourceTree = ""; }; - C9B53AFA138D9E990028D27C /* pthread_spis.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_spis.h; sourceTree = ""; }; - C9B53AFB138D9E990028D27C /* pthread_tsd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_tsd.c; sourceTree = ""; }; - C9B53AFC138D9E990028D27C /* pthread_workqueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_workqueue.h; sourceTree = ""; }; - C9B53AFD138D9E990028D27C /* sched.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sched.h; sourceTree = ""; }; - C9B53AFE138D9E990028D27C /* stack.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = stack.s; sourceTree = ""; }; - C9B53B00138D9E990028D27C /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; - C9B53B01138D9E990028D27C /* pthread_atfork_test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_atfork_test.c; sourceTree = ""; }; - C9B53B02138D9E990028D27C /* thread_setup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = thread_setup.c; sourceTree = ""; }; C9B53B06138D9E990028D27C /* cname.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cname.h; sourceTree = ""; }; C9B53B08138D9E990028D27C /* COPYRIGHT */ = {isa = PBXFileReference; lastKnownFileType = text; path = COPYRIGHT; sourceTree = ""; }; C9B53B0B138D9E990028D27C /* re_format.7 */ = {isa = PBXFileReference; lastKnownFileType = text; path = re_format.7; sourceTree = ""; }; @@ -6558,29 +6781,19 @@ C9B53CE2138D9E9A0028D27C /* timegm.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = timegm.3; sourceTree = ""; }; C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = timezone_unix03.c; sourceTree = ""; }; C9B53CE6138D9E9A0028D27C /* bcmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = bcmp.3; sourceTree = ""; }; - C9B53CE8138D9E9A0028D27C /* bcmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bcmp.c; sourceTree = ""; }; C9B53CE9138D9E9A0028D27C /* bcopy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = bcopy.3; sourceTree = ""; }; - C9B53CEB138D9E9A0028D27C /* bcopy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bcopy.c; sourceTree = ""; }; C9B53CED138D9E9A0028D27C /* bstring.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = bstring.3; sourceTree = ""; }; C9B53CEF138D9E9A0028D27C /* bzero.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = bzero.3; sourceTree = ""; }; - C9B53CF1138D9E9A0028D27C /* bzero.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bzero.c; sourceTree = ""; }; - C9B53CF3138D9E9A0028D27C /* ffs.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = ffs.3; sourceTree = ""; }; C9B53CF5138D9E9A0028D27C /* index.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = index.3; sourceTree = ""; }; C9B53CF7138D9E9A0028D27C /* index.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = index.c; sourceTree = ""; }; C9B53CF8138D9E9A0028D27C /* memccpy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memccpy.3; sourceTree = ""; }; - C9B53CFA138D9E9A0028D27C /* memccpy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memccpy.c; sourceTree = ""; }; C9B53CFB138D9E9A0028D27C /* memchr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memchr.3; sourceTree = ""; }; - C9B53CFD138D9E9A0028D27C /* memchr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memchr.c; sourceTree = ""; }; C9B53CFE138D9E9A0028D27C /* memcmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memcmp.3; sourceTree = ""; }; - C9B53D00138D9E9A0028D27C /* memcmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memcmp.c; sourceTree = ""; }; C9B53D01138D9E9A0028D27C /* memcpy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memcpy.3; sourceTree = ""; }; - C9B53D03138D9E9A0028D27C /* memcpy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memcpy.c; sourceTree = ""; }; C9B53D05138D9E9A0028D27C /* memmem.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memmem.3; sourceTree = ""; }; C9B53D06138D9E9A0028D27C /* memmem.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memmem.c; sourceTree = ""; }; C9B53D07138D9E9A0028D27C /* memmove.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memmove.3; sourceTree = ""; }; - C9B53D09138D9E9A0028D27C /* memmove.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memmove.c; sourceTree = ""; }; C9B53D0B138D9E9A0028D27C /* memset.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memset.3; sourceTree = ""; }; - C9B53D0D138D9E9A0028D27C /* memset.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memset.c; sourceTree = ""; }; C9B53D0E138D9E9A0028D27C /* rindex.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = rindex.3; sourceTree = ""; }; C9B53D10138D9E9A0028D27C /* rindex.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rindex.c; sourceTree = ""; }; C9B53D13138D9E9A0028D27C /* strcasecmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcasecmp.3; sourceTree = ""; }; @@ -6588,13 +6801,10 @@ C9B53D17138D9E9A0028D27C /* strcasestr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strcasestr.c; sourceTree = ""; }; C9B53D19138D9E9A0028D27C /* strcat.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcat.3; sourceTree = ""; }; C9B53D1C138D9E9A0028D27C /* strchr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strchr.3; sourceTree = ""; }; - C9B53D1E138D9E9A0028D27C /* strchr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strchr.c; sourceTree = ""; }; C9B53D20138D9E9A0028D27C /* strcmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcmp.3; sourceTree = ""; }; - C9B53D22138D9E9A0028D27C /* strcmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strcmp.c; sourceTree = ""; }; C9B53D24138D9E9A0028D27C /* strcoll.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcoll.3; sourceTree = ""; }; C9B53D26138D9E9A0028D27C /* strcoll.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strcoll.c; sourceTree = ""; }; C9B53D28138D9E9A0028D27C /* strcpy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcpy.3; sourceTree = ""; }; - C9B53D2B138D9E9A0028D27C /* strcspn.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcspn.3; sourceTree = ""; }; C9B53D2D138D9E9A0028D27C /* strcspn.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strcspn.c; sourceTree = ""; }; C9B53D2E138D9E9A0028D27C /* strdup.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strdup.3; sourceTree = ""; }; C9B53D30138D9E9A0028D27C /* strdup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strdup.c; sourceTree = ""; }; @@ -6606,13 +6816,11 @@ C9B53D3C138D9E9A0028D27C /* strlen.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strlen.c; sourceTree = ""; }; C9B53D3E138D9E9A0028D27C /* strmode.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strmode.3; sourceTree = ""; }; C9B53D40138D9E9A0028D27C /* strmode.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strmode.c; sourceTree = ""; }; - C9B53D42138D9E9A0028D27C /* strncmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strncmp.c; sourceTree = ""; }; C9B53D44138D9E9A0028D27C /* strndup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strndup.c; sourceTree = ""; }; C9B53D45138D9E9A0028D27C /* strnlen.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strnlen.c; sourceTree = ""; }; C9B53D46138D9E9A0028D27C /* strnstr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strnstr.c; sourceTree = ""; }; C9B53D47138D9E9A0028D27C /* strpbrk.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strpbrk.3; sourceTree = ""; }; C9B53D49138D9E9A0028D27C /* strpbrk.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strpbrk.c; sourceTree = ""; }; - C9B53D4A138D9E9A0028D27C /* strrchr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strrchr.3; sourceTree = ""; }; C9B53D4C138D9E9A0028D27C /* strrchr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strrchr.c; sourceTree = ""; }; C9B53D4E138D9E9A0028D27C /* strsep.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strsep.3; sourceTree = ""; }; C9B53D4F138D9E9A0028D27C /* strsep.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strsep.c; sourceTree = ""; }; @@ -6664,23 +6872,13 @@ C9B53D8F138D9E9A0028D27C /* wmemset.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = wmemset.c; sourceTree = ""; }; C9B53D91138D9E9A0028D27C /* memset_pattern.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memset_pattern.3; sourceTree = ""; }; C9B53D92138D9E9A0028D27C /* strip-header.ed */ = {isa = PBXFileReference; lastKnownFileType = text; path = "strip-header.ed"; sourceTree = ""; }; - C9B53D94138D9E9A0028D27C /* __libc_init.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = __libc_init.c; sourceTree = ""; }; + C9B53D94138D9E9A0028D27C /* _libc_init.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = _libc_init.c; sourceTree = ""; }; C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = _libc_fork_child.c; sourceTree = ""; }; - C9B53D96138D9E9A0028D27C /* atomic.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = atomic.3; sourceTree = ""; }; - C9B53D97138D9E9A0028D27C /* barrier.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = barrier.3; sourceTree = ""; }; - C9B53D98138D9E9A0028D27C /* cache.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = cache.3; sourceTree = ""; }; C9B53D99138D9E9A0028D27C /* chmodx_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = chmodx_np.c; sourceTree = ""; }; - C9B53D9A138D9E9A0028D27C /* CLIB-LIST */ = {isa = PBXFileReference; lastKnownFileType = text; path = "CLIB-LIST"; sourceTree = ""; }; - C9B53D9B138D9E9A0028D27C /* context-stubs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "context-stubs.c"; sourceTree = ""; }; C9B53D9C138D9E9A0028D27C /* crt_externs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = crt_externs.c; sourceTree = ""; }; - C9B53D9D138D9E9A0028D27C /* errno.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = errno.c; sourceTree = ""; }; C9B53D9E138D9E9A0028D27C /* fork.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fork.c; sourceTree = ""; }; C9B53D9F138D9E9A0028D27C /* getgroups.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getgroups.c; sourceTree = ""; }; - C9B53DA0138D9E9A0028D27C /* getiopolicy_np.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getiopolicy_np.3; sourceTree = ""; }; - C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getiopolicy_np.c; sourceTree = ""; }; C9B53DA2138D9E9A0028D27C /* gettimeofday.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gettimeofday.c; sourceTree = ""; }; - C9B53DA4138D9E9A0028D27C /* MISSING-MANPAGE */ = {isa = PBXFileReference; lastKnownFileType = text; path = "MISSING-MANPAGE"; sourceTree = ""; }; - C9B53DA5138D9E9A0028D27C /* MISSING_SYSCALLS */ = {isa = PBXFileReference; lastKnownFileType = text; path = MISSING_SYSCALLS; sourceTree = ""; }; C9B53DA6138D9E9A0028D27C /* msgctl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = msgctl.c; sourceTree = ""; }; C9B53DA7138D9E9A0028D27C /* nanosleep.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = nanosleep.2; sourceTree = ""; }; C9B53DA9138D9E9A0028D27C /* stack_protector.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stack_protector.c; sourceTree = ""; }; @@ -6688,27 +6886,13 @@ C9B53DAC138D9E9A0028D27C /* OSMemoryNotification.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = OSMemoryNotification.c; sourceTree = ""; }; C9B53DAD138D9E9A0028D27C /* OSThermalNotification.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = OSThermalNotification.c; sourceTree = ""; }; C9B53DAE138D9E9A0028D27C /* posix_spawn.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = posix_spawn.c; sourceTree = ""; }; - C9B53DAF138D9E9A0028D27C /* pthread_kill.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_kill.2; sourceTree = ""; }; - C9B53DB0138D9E9A0028D27C /* pthread_sigmask.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_sigmask.2; sourceTree = ""; }; - C9B53DB1138D9E9A0028D27C /* REQUIRED-MACROS */ = {isa = PBXFileReference; lastKnownFileType = text; path = "REQUIRED-MACROS"; sourceTree = ""; }; C9B53DB2138D9E9A0028D27C /* semctl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = semctl.c; sourceTree = ""; }; C9B53DB3138D9E9A0028D27C /* settimeofday.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = settimeofday.c; sourceTree = ""; }; C9B53DB4138D9E9A0028D27C /* shmctl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = shmctl.c; sourceTree = ""; }; C9B53DB5138D9E9A0028D27C /* sigaction.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sigaction.c; sourceTree = ""; }; - C9B53DB6138D9E9A0028D27C /* sigcatch.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sigcatch.c; sourceTree = ""; }; - C9B53DB7138D9E9A0028D27C /* sigcatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sigcatch.h; sourceTree = ""; }; - C9B53DB8138D9E9A0028D27C /* sigtramp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sigtramp.c; sourceTree = ""; }; C9B53DB9138D9E9A0028D27C /* sigwait.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sigwait.2; sourceTree = ""; }; - C9B53DBA138D9E9A0028D27C /* slot_name.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = slot_name.c; sourceTree = ""; }; - C9B53DBB138D9E9A0028D27C /* spinlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = spinlock.3; sourceTree = ""; }; C9B53DBC138D9E9A0028D27C /* statx_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = statx_np.c; sourceTree = ""; }; - C9B53DBD138D9E9A0028D27C /* SYSCALL-LIST */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SYSCALL-LIST"; sourceTree = ""; }; C9B53DBE138D9E9A0028D27C /* umaskx_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = umaskx_np.c; sourceTree = ""; }; - C9B53DC0138D9E9A0028D27C /* cprocs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cprocs.c; sourceTree = ""; }; - C9B53DC1138D9E9A0028D27C /* cthread_internals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cthread_internals.h; sourceTree = ""; }; - C9B53DC2138D9E9A0028D27C /* cthreads.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cthreads.c; sourceTree = ""; }; - C9B53DC3138D9E9A0028D27C /* cthreads.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cthreads.h; sourceTree = ""; }; - C9B53DC5138D9E9A0028D27C /* mig_support.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mig_support.c; sourceTree = ""; }; C9B53DC7138D9E9A0028D27C /* fparseln.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = fparseln.3; sourceTree = ""; }; C9B53DC8138D9E9A0028D27C /* fparseln.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fparseln.c; sourceTree = ""; }; C9B53DC9138D9E9A0028D27C /* login.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = login.3; sourceTree = ""; }; @@ -6741,57 +6925,13 @@ C9B53DEA138D9E9A0028D27C /* uuid_parse.3.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = uuid_parse.3.in; sourceTree = ""; }; C9B53DEB138D9E9A0028D27C /* uuid_unparse.3.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = uuid_unparse.3.in; sourceTree = ""; }; C9B53DED138D9E9A0028D27C /* uuidP.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = uuidP.h; sourceTree = ""; }; - C9B53DF1138D9E9A0028D27C /* _ctx_start.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _ctx_start.S; sourceTree = ""; }; - C9B53DF2138D9E9A0028D27C /* _setcontext.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setcontext.S; sourceTree = ""; }; - C9B53DF3138D9E9A0028D27C /* cpu_number.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = cpu_number.s; sourceTree = ""; }; - C9B53DF4138D9E9A0028D27C /* getcontext.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = getcontext.S; sourceTree = ""; }; - C9B53DF5138D9E9A0028D27C /* getmcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getmcontext.c; sourceTree = ""; }; - C9B53DF6138D9E9A0028D27C /* icacheinval.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = icacheinval.s; sourceTree = ""; }; - C9B53DF7138D9E9A0028D27C /* makecontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = makecontext.c; sourceTree = ""; }; C9B53DF9138D9E9A0028D27C /* mcount.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = mcount.s; sourceTree = ""; }; - C9B53DFA138D9E9A0028D27C /* setcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = setcontext.c; sourceTree = ""; }; - C9B53DFB138D9E9A0028D27C /* swapcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = swapcontext.c; sourceTree = ""; }; - C9B53DFE138D9E9A0028D27C /* preempt.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = preempt.s; sourceTree = ""; }; - C9B53DFF138D9E9A0028D27C /* pthread_getspecific.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_getspecific.s; sourceTree = ""; }; - C9B53E00138D9E9A0028D27C /* pthread_mutex_lock.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_mutex_lock.s; sourceTree = ""; }; - C9B53E01138D9E9A0028D27C /* pthread_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_self.s; sourceTree = ""; }; - C9B53E02138D9E9A0028D27C /* pthread_set_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_set_self.s; sourceTree = ""; }; - C9B53E03138D9E9A0028D27C /* start_wqthread.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = start_wqthread.s; sourceTree = ""; }; - C9B53E04138D9E9A0028D27C /* thread_start.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = thread_start.s; sourceTree = ""; }; - C9B53E08138D9E9A0028D27C /* __bzero.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = __bzero.s; sourceTree = ""; }; - C9B53E09138D9E9A0028D27C /* bcopy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bcopy.c; sourceTree = ""; }; - C9B53E0A138D9E9A0028D27C /* bcopy_sse3x.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse3x.s; sourceTree = ""; }; - C9B53E0B138D9E9A0028D27C /* bcopy_sse42.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse42.s; sourceTree = ""; }; - C9B53E0C138D9E9A0028D27C /* bzero.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bzero.c; sourceTree = ""; }; - C9B53E0D138D9E9A0028D27C /* bzero_sse2.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_sse2.s; sourceTree = ""; }; - C9B53E0E138D9E9A0028D27C /* bzero_sse42.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_sse42.s; sourceTree = ""; }; - C9B53E0F138D9E9A0028D27C /* ffs.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = ffs.s; sourceTree = ""; }; - C9B53E10138D9E9A0028D27C /* longcopy_sse3x.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = longcopy_sse3x.s; sourceTree = ""; }; - C9B53E12138D9E9A0028D27C /* memcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memcmp.s; sourceTree = ""; }; - C9B53E13138D9E9A0028D27C /* memcpy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memcpy.c; sourceTree = ""; }; - C9B53E14138D9E9A0028D27C /* memmove.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memmove.c; sourceTree = ""; }; - C9B53E15138D9E9A0028D27C /* memset.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memset.s; sourceTree = ""; }; - C9B53E16138D9E9A0028D27C /* strcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcmp.s; sourceTree = ""; }; C9B53E17138D9E9A0028D27C /* strcpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcpy.s; sourceTree = ""; }; - C9B53E18138D9E9A0028D27C /* strlcat.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlcat.s; sourceTree = ""; }; - C9B53E19138D9E9A0028D27C /* strlcpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlcpy.s; sourceTree = ""; }; C9B53E1A138D9E9A0028D27C /* strlen.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlen.s; sourceTree = ""; }; - C9B53E1B138D9E9A0028D27C /* strncmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncmp.s; sourceTree = ""; }; C9B53E1C138D9E9A0028D27C /* strncpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncpy.s; sourceTree = ""; }; - C9B53E1E138D9E9A0028D27C /* _setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setjmp.s; sourceTree = ""; }; - C9B53E1F138D9E9A0028D27C /* _sigtramp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _sigtramp.s; sourceTree = ""; }; - C9B53E20138D9E9A0028D27C /* atomic.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = atomic.c; sourceTree = ""; }; - C9B53E21138D9E9A0028D27C /* i386_gettimeofday_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = i386_gettimeofday_asm.s; sourceTree = ""; }; - C9B53E23138D9E9A0028D27C /* nanotime.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = nanotime.s; sourceTree = ""; }; - C9B53E24138D9E9A0028D27C /* OSAtomic.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = OSAtomic.s; sourceTree = ""; }; - C9B53E25138D9E9A0028D27C /* setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = setjmp.s; sourceTree = ""; }; - C9B53E26138D9E9A0028D27C /* spinlocks.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = spinlocks.c; sourceTree = ""; }; - C9B53E27138D9E9A0028D27C /* spinlocks_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = spinlocks_asm.s; sourceTree = ""; }; C9B53E2C138DA0610028D27C /* libPlatform.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPlatform.a; sourceTree = BUILT_PRODUCTS_DIR; }; C9C2A948138DF7DD00287F00 /* libc.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = libc.xcconfig; sourceTree = ""; }; C9C2A94D138DFFD900287F00 /* libBase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBase.a; sourceTree = BUILT_PRODUCTS_DIR; }; - C9C62BDF13AA7F6A001FD88D /* OSAtomic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSAtomic.h; sourceTree = ""; }; - C9CF595913CD0B9600674871 /* memset_pattern.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memset_pattern.c; sourceTree = ""; }; C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = forceLibcToBuild.c; sourceTree = ""; }; C9D9432F138DB73300FB7ACC /* libsystem_c.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_c.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; C9D94357138EC0C600FB7ACC /* heapsort_b.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = heapsort_b.c; sourceTree = ""; }; @@ -6805,11 +6945,34 @@ C9EB350D138F75580075BB52 /* libvInode32.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libvInode32.a; sourceTree = BUILT_PRODUCTS_DIR; }; C9EB350E138F769B0075BB52 /* scandir_b.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scandir_b.c; sourceTree = ""; }; C9EB354F138F7EA50075BB52 /* getmntinfo64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getmntinfo64.c; sourceTree = ""; }; - C9EB3555138F7F6A0075BB52 /* setjmperr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = setjmperr.c; sourceTree = ""; }; + C9ECE2761950E384008E8672 /* atexit_receipt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atexit_receipt.c; sourceTree = ""; }; C9FA32F8138E4A5C0089A94B /* utf2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utf2.c; sourceTree = ""; }; + C9FACC591ACDBA54009F33F1 /* Makefile.inc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.pascal; name = Makefile.inc; path = Platforms/appletvos/Makefile.inc; sourceTree = SOURCE_ROOT; }; + E41BEA97178E72E100E348BB /* Libc.order */ = {isa = PBXFileReference; lastKnownFileType = text; path = Libc.order; sourceTree = ""; }; + E4A877A6174D82FB000DBB55 /* alias.list */ = {isa = PBXFileReference; lastKnownFileType = text; path = alias.list; sourceTree = ""; }; + FC2ED60E157D4BE70098EC69 /* inet_ntop.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet_ntop.c; sourceTree = ""; }; + FC2ED60F157D4BE70098EC69 /* inet_pton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet_pton.c; sourceTree = ""; }; + FC2ED623157D4DA90098EC69 /* inet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inet.h; sourceTree = ""; }; + FC60BAD116555A4A00033196 /* _intmax_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _intmax_t.h; sourceTree = ""; }; + FC60BAD216555A4A00033196 /* _nl_item.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _nl_item.h; sourceTree = ""; }; + FC60BAD316555A4A00033196 /* _uint16_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uint16_t.h; sourceTree = ""; }; + FC60BAD416555A4A00033196 /* _uint32_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uint32_t.h; sourceTree = ""; }; + FC60BAD516555A4A00033196 /* _uint64_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uint64_t.h; sourceTree = ""; }; + FC60BAD616555A4A00033196 /* _uint8_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uint8_t.h; sourceTree = ""; }; + FC60BAD716555A4A00033196 /* _uintmax_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uintmax_t.h; sourceTree = ""; }; + FC60BAD816555A4A00033196 /* _wctrans_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _wctrans_t.h; sourceTree = ""; }; + FC60BAD916555A4A00033196 /* _wctype_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _wctype_t.h; sourceTree = ""; }; + FC960EF21850F33A005B9A9A /* libc_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libc_private.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 3F5120ED16C3174300AFB431 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; B122F2A91432B8E600AF95D0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -6817,10 +6980,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B1E96502157E722200FCCEE7 /* Frameworks */ = { + C0E345DA1C582ECB00E749C2 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C0E345DB1C582ECB00E749C2 /* libBase.a in Frameworks */, + C0E345DC1C582ECB00E749C2 /* libFreeBSD.a in Frameworks */, + C0E345DD1C582ECB00E749C2 /* libvCancelable.a in Frameworks */, + C0E345DE1C582ECB00E749C2 /* libTRE.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6866,6 +7033,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C97A72181517AF53005E1998 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C9AE91B51517D31A00A2626C /* libBase.a in Frameworks */, + C9AE91B71517D31C00A2626C /* libFreeBSD.a in Frameworks */, + C9AE91B81517D32200A2626C /* libvCancelable.a in Frameworks */, + C9AE91B91517D32900A2626C /* libTRE.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; C9B53E29138DA0610028D27C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -6911,6 +7089,26 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 3F18DE1E162A732C008B15AC /* NetBSD */ = { + isa = PBXGroup; + children = ( + 3F18DE1F162A732C008B15AC /* memset_s.3 */, + 3F18DE20162A732C008B15AC /* memset_s.c */, + ); + path = NetBSD; + sourceTree = ""; + }; + 4B2C64A015519B0500342BFA /* os */ = { + isa = PBXGroup; + children = ( + 2DF67CE7184F9CD000B83A3D /* debug_private.h */, + 2DF67CDD184F9CBE00B83A3D /* debug_private.c */, + 4B2C64AB15519C3400342BFA /* assumes.h */, + 4B2C64A215519BAF00342BFA /* assumes.c */, + ); + name = os; + sourceTree = ""; + }; B122F2AE1432B95B00AF95D0 /* TRE */ = { isa = PBXGroup; children = ( @@ -6948,11 +7146,30 @@ path = lib; sourceTree = ""; }; + C975E22B1A12ECA00093B345 /* appletv */ = { + isa = PBXGroup; + children = ( + C9FACC591ACDBA54009F33F1 /* Makefile.inc */, + ); + name = appletv; + path = watchos; + sourceTree = ""; + }; + C9A288A61ACDBA95004A33A7 /* watchos */ = { + isa = PBXGroup; + children = ( + C9A288A71ACDBA95004A33A7 /* Makefile.inc */, + ); + name = watchos; + path = Platforms/watchos; + sourceTree = SOURCE_ROOT; + }; C9B53595138D9A690028D27C = { isa = PBXGroup; children = ( C9B535AE138D9E980028D27C /* APPLE_LICENSE */, C9B535AF138D9E980028D27C /* arm */, + C9B535E2138D9E980028D27C /* arm */, C9B535F5138D9E980028D27C /* compat-43 */, C9B53612138D9E980028D27C /* darwin */, C9B5361D138D9E980028D27C /* db */, @@ -6968,24 +7185,22 @@ C9B53A0E138D9E990028D27C /* nbsdcompat */, C9B53A11138D9E990028D27C /* net */, C9B53A3A138D9E990028D27C /* nls */, + 4B2C64A015519B0500342BFA /* os */, C9B53A45138D9E990028D27C /* Platforms */, C9B53A4A138D9E990028D27C /* posix1e */, - C9B53ABA138D9E990028D27C /* pthreads */, C9B53B03138D9E990028D27C /* regex */, - C9B53B1B138D9E990028D27C /* rpc */, C9B53B1D138D9E990028D27C /* secure */, C9B53B2D138D9E990028D27C /* stdio */, C9B53C16138D9E9A0028D27C /* stdlib */, C9B53CC0138D9E9A0028D27C /* stdtime */, C9B53CE4138D9E9A0028D27C /* string */, C9B53D93138D9E9A0028D27C /* sys */, - C9B53DBF138D9E9A0028D27C /* threads */, C9B53DC6138D9E9A0028D27C /* util */, C9B53DD3138D9E9A0028D27C /* uuid */, C9B53DEF138D9E9A0028D27C /* x86_64 */, C9C2A946138DF66900287F00 /* xcodescripts */, C9B535A9138D9E890028D27C /* Products */, - C965CBF1143BBEC7003912CE /* deps.c */, + C06E02D11CA0C9CA00B07322 /* tests */, ); indentWidth = 4; sourceTree = ""; @@ -7006,9 +7221,11 @@ C95B86C7138F53DB004311DA /* libvPre1050.a */, C9EB3266138F6D880075BB52 /* libvLegacy.a */, C9EB350D138F75580075BB52 /* libvInode32.a */, - C94212CC13900C8A004BA536 /* libc.a */, + C94212CC13900C8A004BA536 /* libc_dyld.a */, B122F2AD1432B8E600AF95D0 /* libTRE.a */, - B1E96506157E722200FCCEE7 /* libFreeBSD_gcc.a */, + C97A721C1517AF53005E1998 /* libc_eOS.a */, + 3F5120F116C3174300AFB431 /* libFortifySource.a */, + C0E345E21C582ECB00E749C2 /* libc.a */, ); name = Products; sourceTree = ""; @@ -7017,9 +7234,7 @@ isa = PBXGroup; children = ( C9B535B0138D9E980028D27C /* gen */, - C9B535B5138D9E980028D27C /* pthreads */, C9B535BF138D9E980028D27C /* string */, - C9B535D4138D9E980028D27C /* sys */, ); path = arm; sourceTree = ""; @@ -7027,73 +7242,35 @@ C9B535B0138D9E980028D27C /* gen */ = { isa = PBXGroup; children = ( - C9B535B1138D9E980028D27C /* cpu_number.s */, - C9B535B2138D9E980028D27C /* icacheinval.s */, + C925D1FB151805C6003D315B /* eos_stubs.c */, ); path = gen; sourceTree = ""; }; - C9B535B5138D9E980028D27C /* pthreads */ = { - isa = PBXGroup; - children = ( - C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */, - C9B535B8138D9E980028D27C /* pthread_getspecific.s */, - C9B535B9138D9E980028D27C /* pthread_self.s */, - C9B535BA138D9E980028D27C /* pthread_set_self.s */, - C9B535BB138D9E980028D27C /* start_wqthread.s */, - C9B535BC138D9E980028D27C /* thread_start.s */, - ); - path = pthreads; - sourceTree = ""; - }; C9B535BF138D9E980028D27C /* string */ = { isa = PBXGroup; children = ( - C9B535C0138D9E980028D27C /* bcopy_CortexA8.s */, - C9B535C1138D9E980028D27C /* bcopy_CortexA9.s */, - 6358199213B53ECB00CDF61C /* bcopy_Swift.s */, - C9B535C2138D9E980028D27C /* bcopy_Generic.s */, - C9B535C3138D9E980028D27C /* bzero_CortexA8.s */, - C9B535C4138D9E980028D27C /* bzero_CortexA9.s */, - 6358199013B53DD800CDF61C /* bzero_Swift.s */, - C9B535C5138D9E980028D27C /* bzero_Generic.s */, - C9B535C6138D9E980028D27C /* dyld_resolvers.c */, - C9B535C7138D9E980028D27C /* ffs.s */, - C9B535C9138D9E980028D27C /* memcmp.s */, - C9B535CA138D9E980028D27C /* memset_pattern.s */, - 634C4C3713BCEADC008CA66D /* memset_pattern_Swift.s */, - C9B535CB138D9E980028D27C /* strchr.s */, - C9B535CC138D9E980028D27C /* strcmp.s */, C9B535CF138D9E980028D27C /* strlen.s */, - C9B535D0138D9E980028D27C /* strncmp.s */, C9B535D2138D9E980028D27C /* strnlen.s */, C9B535D3138D9E980028D27C /* strstr.s */, ); path = string; sourceTree = ""; }; - C9B535D4138D9E980028D27C /* sys */ = { + C9B535E2138D9E980028D27C /* arm */ = { isa = PBXGroup; children = ( - C9B535D5138D9E980028D27C /* _longjmp.s */, - C9B535D6138D9E980028D27C /* _setjmp.h */, - C9B535D7138D9E980028D27C /* _setjmp.s */, - C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */, - C9B535D9138D9E980028D27C /* gcc_atomic.c */, - C9B535DA138D9E980028D27C /* longjmp.s */, - C9B535DB138D9E980028D27C /* mach_absolute_time.s */, - C9B535DD138D9E980028D27C /* OSAtomic-v4.c */, - C9C62BDF13AA7F6A001FD88D /* OSAtomic.h */, - C9B4E3D713BBBF2D0008A9BB /* OSAtomic.c */, - C995462713AAA25000A531B4 /* OSAtomicUP.c */, - C97C344013AB0E1B00713550 /* Spinlocks.c */, - C980F8EB13AB168D0069AB06 /* SpinlocksUP.c */, - C932C2CF13AB1C73004EDA12 /* SpinlocksWFE.c */, - C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */, - C9B535E0138D9E980028D27C /* OSAtomic_resolvers.h */, - C9B535E1138D9E980028D27C /* setjmp.s */, + C9B535EB138D9E980028D27C /* string */, ); - path = sys; + path = arm; + sourceTree = ""; + }; + C9B535EB138D9E980028D27C /* string */ = { + isa = PBXGroup; + children = ( + 63505E3A1548525D00B637D7 /* strnlen.s */, + ); + path = string; sourceTree = ""; }; C9B535F5138D9E980028D27C /* compat-43 */ = { @@ -7134,18 +7311,12 @@ C9B53612138D9E980028D27C /* darwin */ = { isa = PBXGroup; children = ( - C9B53613138D9E980028D27C /* _dirhelper.c */, - C9B53614138D9E980028D27C /* dirhelper.defs */, - C9B53615138D9E980028D27C /* dirhelper_priv.h */, + C9ECE2761950E384008E8672 /* atexit_receipt.c */, + 92ABC7E81D375FC2000DF880 /* compatibility_hacks.c */, C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */, + C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */, C9B53616138D9E980028D27C /* kvm.c */, - C9B53617138D9E980028D27C /* libproc.c */, - C9B53618138D9E980028D27C /* libproc.h */, - C9B53619138D9E980028D27C /* libproc_internal.h */, - C9B5361C138D9E980028D27C /* proc_listpidspath.c */, - C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */, - C9B4E3D513BBBF060008A9BB /* OSAtomicLoadStoreEx.c */, - C9B4E3D913BBC24E0008A9BB /* SpinlocksLoadStoreEx.c */, + FC960EF21850F33A005B9A9A /* libc_private.h */, ); path = darwin; sourceTree = ""; @@ -7323,7 +7494,6 @@ C9B5367D138D9E980028D27C /* _fbsd_compat_.h */, C9B5367E138D9E980028D27C /* _fpmath.h */, C9B5367F138D9E980028D27C /* fpmath.h */, - C9B53680138D9E980028D27C /* libc_private.h */, C9B53681138D9E980028D27C /* machine */, C9B53683138D9E980028D27C /* namespace.h */, C9B53684138D9E980028D27C /* port_after.h */, @@ -7403,31 +7573,12 @@ C9B536C0138D9E980028D27C /* gen */ = { isa = PBXGroup; children = ( + 147CDFCF1B7C14FA00831EC6 /* clock_gettime.3 */, + 147CDFD01B7C14FA00831EC6 /* clock_gettime.c */, C9B536C1138D9E990028D27C /* __dirent.h */, - C9B536C2138D9E990028D27C /* _simple.c */, - C9B536C3138D9E990028D27C /* _simple.h */, - C9B536C4138D9E990028D27C /* asl.3 */, - C9B536C5138D9E990028D27C /* asl.c */, - C9B536C6138D9E990028D27C /* asl_core.c */, - C9B536C7138D9E990028D27C /* asl_core.h */, - 3F2208E714358B4A00386F5B /* asl_fd.c */, - C9B536C8138D9E990028D27C /* asl_file.c */, - C9B536C9138D9E990028D27C /* asl_file.h */, - C9B536CA138D9E990028D27C /* asl_ipc.defs */, - C9B536CB138D9E990028D27C /* asl_legacy1.c */, - C9B536CC138D9E990028D27C /* asl_legacy1.h */, - C9B536CD138D9E990028D27C /* asl_msg.c */, - C9B536CE138D9E990028D27C /* asl_msg.h */, - C9B536CF138D9E990028D27C /* asl_private.h */, - C9B536D0138D9E990028D27C /* asl_store.c */, - C9B536D1138D9E990028D27C /* asl_store.h */, - C9B536D2138D9E990028D27C /* asl_util.c */, - C9B536D3138D9E990028D27C /* assumes.c */, - C9B536D4138D9E990028D27C /* assumes.h */, C9B536D5138D9E990028D27C /* authentication.c */, C9B536D6138D9E990028D27C /* backtrace.3 */, C9B536D7138D9E990028D27C /* backtrace.c */, - C9B536D8138D9E990028D27C /* cache.c */, C9B536D9138D9E990028D27C /* compat.5 */, C9B536DA138D9E990028D27C /* confstr.3 */, C9B536DB138D9E990028D27C /* confstr.c */, @@ -7457,41 +7608,22 @@ C9B537CF138D9E990028D27C /* getvfsbyname.3 */, C9B537D0138D9E990028D27C /* getvfsbyname.c */, C9B537D1138D9E990028D27C /* intro.3 */, - C9B537D2138D9E990028D27C /* isinf.c */, - C9B537D3138D9E990028D27C /* isnan.c */, - C9B537D4138D9E990028D27C /* magazine_malloc.c */, - C9B537D5138D9E990028D27C /* magmallocProvider.d */, - C9B537D7138D9E990028D27C /* malloc.3 */, - C9B537D8138D9E990028D27C /* malloc.c */, - C9B537D9138D9E990028D27C /* malloc_printf.h */, - C9B537DA138D9E990028D27C /* malloc_size.3 */, - C9B537DB138D9E990028D27C /* malloc_zone_malloc.3 */, C9B537DC138D9E990028D27C /* nanosleep.c */, C9B537DD138D9E990028D27C /* NetBSD */, C9B537E6138D9E990028D27C /* nftw.c */, C9B537E7138D9E990028D27C /* nlist.3 */, C9B537E8138D9E990028D27C /* nlist.c */, - C9B537E9138D9E990028D27C /* NSSystemDirectories.c */, C9B537EA138D9E990028D27C /* oldsyslog.c */, - C9B537EB138D9E990028D27C /* platfunc.c */, - C9B537EC138D9E990028D27C /* platfunc.h */, C9B537ED138D9E990028D27C /* posix_memalign.3 */, C9B537EE138D9E990028D27C /* pwcache.3 */, - C9B537EF138D9E990028D27C /* scalable_malloc.c */, - C9B537F0138D9E990028D27C /* scalable_malloc.h */, - C9B537F1138D9E990028D27C /* setjmp.3 */, + C9B53761138D9E990028D27C /* raise.c */, C9B537F2138D9E990028D27C /* setlogin.c */, C9B537F3138D9E990028D27C /* sigsetops.3 */, C9B537F4138D9E990028D27C /* sigsetops.c */, - C9B537F5138D9E990028D27C /* stack_logging.c */, - C9B537F6138D9E990028D27C /* stack_logging.h */, - C9B537F7138D9E990028D27C /* stack_logging_disk.c */, C9B537F8138D9E990028D27C /* strtofflags.3 */, C9B537F9138D9E990028D27C /* strtofflags.c */, B19C64591450F8B900032373 /* sync_volume_np.3 */, B19C645B1450F90200032373 /* sync_volume_np.c */, - C9B537FA138D9E990028D27C /* syslog.3 */, - C9B537FB138D9E990028D27C /* syslog.c */, C9B537FC138D9E990028D27C /* tcgetpgrp.3 */, C9B537FD138D9E990028D27C /* tcsendbreak.3 */, C9B537FE138D9E990028D27C /* tcsetattr.3 */, @@ -7503,8 +7635,6 @@ C9B53804138D9E990028D27C /* utmpx-darwin.c */, C9B53805138D9E990028D27C /* utmpx-darwin.h */, C9B53806138D9E990028D27C /* utmpx_thread.h */, - C9B53807138D9E990028D27C /* wordexp.3 */, - C9B53808138D9E990028D27C /* wordexp.c */, ); path = gen; sourceTree = ""; @@ -7549,7 +7679,6 @@ C9B5371A138D9E990028D27C /* ftok.c */, C9B5371C138D9E990028D27C /* getbsize.c */, C9B5371E138D9E990028D27C /* getcap.c */, - C9B53720138D9E990028D27C /* getcontext.3 */, C9B53721138D9E990028D27C /* getcwd.3 */, C9B53722138D9E990028D27C /* getcwd.c */, C9B53724138D9E990028D27C /* gethostname.3 */, @@ -7572,7 +7701,6 @@ C9B53741138D9E990028D27C /* lockf.3 */, C9B53743138D9E990028D27C /* lockf.c */, C9B53745138D9E990028D27C /* lrand48.c */, - C9B53747138D9E990028D27C /* makecontext.3 */, C9B53749138D9E990028D27C /* mrand48.c */, C9B5374B138D9E990028D27C /* nice.3 */, C9B5374C138D9E990028D27C /* nice.c */, @@ -7582,12 +7710,9 @@ C9B53753138D9E990028D27C /* pause.c */, C9B53755138D9E990028D27C /* popen.3 */, C9B53757138D9E990028D27C /* popen.c */, - C9B53759138D9E990028D27C /* pselect.3 */, - C9B5375B138D9E990028D27C /* pselect.c */, C9B5375D138D9E990028D27C /* psignal.3 */, C9B5375F138D9E990028D27C /* psignal.c */, C9B53760138D9E990028D27C /* raise.3 */, - C9B53761138D9E990028D27C /* raise.c */, C9B53762138D9E990028D27C /* rand48.3 */, C9B53764138D9E990028D27C /* rand48.h */, C9B53766138D9E990028D27C /* readdir.c */, @@ -7633,7 +7758,6 @@ C9B537A9138D9E990028D27C /* ttyslot.c */, C9B537AA138D9E990028D27C /* ualarm.3 */, C9B537AC138D9E990028D27C /* ualarm.c */, - C9B537AD138D9E990028D27C /* ucontext.3 */, C9B537AE138D9E990028D27C /* ulimit.3 */, C9B537B0138D9E990028D27C /* ulimit.c */, C9B537B1138D9E990028D27C /* unvis.3 */, @@ -7647,6 +7771,8 @@ C9B537BE138D9E990028D27C /* wait.c */, C9B537C0138D9E990028D27C /* wait3.c */, C9B537C1138D9E990028D27C /* waitpid.c */, + C9B53807138D9E990028D27C /* wordexp.3 */, + C9B53808138D9E990028D27C /* wordexp.c */, ); path = FreeBSD; sourceTree = ""; @@ -7654,6 +7780,8 @@ C9B537DD138D9E990028D27C /* NetBSD */ = { isa = PBXGroup; children = ( + 3F267F36163FC8880089A0A6 /* rb.c */, + 3F267F37163FC8880089A0A6 /* rbtree.3 */, C9B537DE138D9E990028D27C /* endutxent.3 */, C9B537E0138D9E990028D27C /* getlastlogx.3 */, C9B537E2138D9E990028D27C /* utmpx.5 */, @@ -7675,9 +7803,7 @@ isa = PBXGroup; children = ( C9B53810138D9E990028D27C /* gen */, - C9B5381D138D9E990028D27C /* pthreads */, C9B53829138D9E990028D27C /* string */, - C9B53843138D9E990028D27C /* sys */, ); path = i386; sourceTree = ""; @@ -7685,89 +7811,28 @@ C9B53810138D9E990028D27C /* gen */ = { isa = PBXGroup; children = ( - C9B53811138D9E990028D27C /* _ctx_start.S */, - C9B53812138D9E990028D27C /* _setcontext.S */, - C9B53813138D9E990028D27C /* cpu_number.s */, - C9B53814138D9E990028D27C /* getcontext.S */, - C9B53815138D9E990028D27C /* getmcontext.c */, - C9B53816138D9E990028D27C /* icacheinval.s */, - C9B53817138D9E990028D27C /* makecontext.c */, C9B53819138D9E990028D27C /* mcount.s */, - C9B5381A138D9E990028D27C /* setcontext.c */, - C9B5381B138D9E990028D27C /* setjmperr.c */, - C9B5381C138D9E990028D27C /* swapcontext.c */, ); path = gen; sourceTree = ""; }; - C9B5381D138D9E990028D27C /* pthreads */ = { - isa = PBXGroup; - children = ( - C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */, - C9B53820138D9E990028D27C /* preempt.s */, - C9B53821138D9E990028D27C /* pthread_getspecific.s */, - C9B53822138D9E990028D27C /* pthread_mutex_lock.s */, - C9B53823138D9E990028D27C /* pthread_self.s */, - C9B53824138D9E990028D27C /* pthread_set_self.s */, - C9B53825138D9E990028D27C /* start_wqthread.s */, - C9B53826138D9E990028D27C /* thread_start.s */, - ); - path = pthreads; - sourceTree = ""; - }; C9B53829138D9E990028D27C /* string */ = { isa = PBXGroup; children = ( - C9B5382A138D9E990028D27C /* __bzero.s */, - C9B5382B138D9E990028D27C /* bcopy.c */, - C9B5382C138D9E990028D27C /* bcopy_scalar.s */, - C9B5382D138D9E990028D27C /* bcopy_sse2.s */, - C9B5382E138D9E990028D27C /* bcopy_sse3x.s */, - C9B5382F138D9E990028D27C /* bcopy_sse42.s */, - C9B53830138D9E990028D27C /* bzero.c */, - C9B53831138D9E990028D27C /* bzero_scalar.s */, - C9B53832138D9E990028D27C /* bzero_sse2.s */, - C9B53833138D9E990028D27C /* bzero_sse42.s */, - C9B53834138D9E990028D27C /* ffs.s */, - C9B53835138D9E990028D27C /* longcopy_sse3x.s */, - C9B53837138D9E990028D27C /* memcmp.s */, - C9B53838138D9E990028D27C /* memcpy.c */, - C9B53839138D9E990028D27C /* memmove.c */, - C9B5383A138D9E990028D27C /* memset.s */, - C9B5383B138D9E990028D27C /* memset_pattern_sse2.s */, - C9B5383C138D9E990028D27C /* strcmp.s */, C9B5383D138D9E990028D27C /* strcpy.s */, C9B5383E138D9E990028D27C /* strlcat.s */, C9B5383F138D9E990028D27C /* strlcpy.s */, C9B53840138D9E990028D27C /* strlen.s */, - C9B53841138D9E990028D27C /* strncmp.s */, C9B53842138D9E990028D27C /* strncpy.s */, ); path = string; sourceTree = ""; }; - C9B53843138D9E990028D27C /* sys */ = { - isa = PBXGroup; - children = ( - C9B53844138D9E990028D27C /* _setjmp.s */, - C9B53845138D9E990028D27C /* _sigtramp.s */, - C9B53846138D9E990028D27C /* atomic.c */, - C9B53847138D9E990028D27C /* i386_gettimeofday_asm.s */, - C9B53848138D9E990028D27C /* mach_absolute_time.c */, - C9B53849138D9E990028D27C /* mach_absolute_time_asm.s */, - C9B5384B138D9E990028D27C /* OSAtomic.s */, - C9B5384C138D9E990028D27C /* setjmp.s */, - C9B5384D138D9E990028D27C /* spinlocks.c */, - C9B5384E138D9E990028D27C /* spinlocks_asm.s */, - ); - path = sys; - sourceTree = ""; - }; C9B5384F138D9E990028D27C /* include */ = { isa = PBXGroup; children = ( C9B53850138D9E990028D27C /* _locale.h */, - C9B53851138D9E990028D27C /* _structs.h */, + FC60BAD016555A4A00033196 /* _types */, C9B53852138D9E990028D27C /* _types.h */, C9B53853138D9E990028D27C /* _wctype.h */, C9B53854138D9E990028D27C /* _xlocale.h */, @@ -7775,13 +7840,11 @@ C9B53856138D9E990028D27C /* alloca.h */, C9B53857138D9E990028D27C /* ar.h */, C9B53858138D9E990028D27C /* arpa */, - C9B5385E138D9E990028D27C /* asl.h */, C9B5385F138D9E990028D27C /* asm.h */, C9B53860138D9E990028D27C /* assert.h */, C9B53861138D9E990028D27C /* authentication.h */, C9B53862138D9E990028D27C /* bitstring.h */, C9B53863138D9E990028D27C /* cpio.h */, - C9B53864138D9E990028D27C /* CrashReporterClient.h */, C9B53865138D9E990028D27C /* crt_externs.h */, C9B53866138D9E990028D27C /* ctype.h */, C9B53867138D9E990028D27C /* db.h */, @@ -7808,7 +7871,6 @@ C9B5387F138D9E990028D27C /* libkern */, C9B53885138D9E990028D27C /* limits.h */, C9B53886138D9E990028D27C /* locale.h */, - C9B53888138D9E990028D27C /* malloc */, C9B5388B138D9E990028D27C /* memory.h */, C9B5388C138D9E990028D27C /* monetary.h */, C9B5388D138D9E990028D27C /* monitor.h */, @@ -7816,9 +7878,9 @@ C9B5388F138D9E990028D27C /* ndbm.h */, C9B53890138D9E990028D27C /* NetBSD */, C9B53893138D9E990028D27C /* nlist.h */, - C9B53894138D9E990028D27C /* NSSystemDirectories.h */, C9B53899138D9E990028D27C /* paths.h */, C9B5389A138D9E990028D27C /* poll.h */, + B126140715881A420077E3CC /* printf.h */, C9B5389B138D9E990028D27C /* protocols */, C9B538A2138D9E990028D27C /* ranlib.h */, C9B538A3138D9E990028D27C /* readpassphrase.h */, @@ -7828,14 +7890,10 @@ C9B538A7138D9E990028D27C /* search.h */, C9B538A8138D9E990028D27C /* secure */, C9B538AD138D9E990028D27C /* semaphore.h */, - C9B538AE138D9E990028D27C /* setjmp.h */, C9B538AF138D9E990028D27C /* sgtty.h */, C9B538B0138D9E990028D27C /* signal.h */, - C9B538B1138D9E990028D27C /* spawn.h */, - C9B538B2138D9E990028D27C /* spawn_private.h */, C9B538B3138D9E990028D27C /* stab.h */, C9B538B4138D9E990028D27C /* standards.h */, - C9B538B5138D9E990028D27C /* stdbool.h */, C9B538B6138D9E990028D27C /* stddef.h */, C9B538B7138D9E990028D27C /* stdint.h */, C9B538B8138D9E990028D27C /* stdio.h */, @@ -7854,7 +7912,6 @@ C9B538C9138D9E990028D27C /* time.h */, C9B538CA138D9E990028D27C /* timeconv.h */, C9B538CB138D9E990028D27C /* ttyent.h */, - C9B538CC138D9E990028D27C /* ucontext.h */, C9B538CD138D9E990028D27C /* ulimit.h */, C9B538CE138D9E990028D27C /* unistd.h */, C9B538CF138D9E990028D27C /* util.h */, @@ -7874,6 +7931,7 @@ isa = PBXGroup; children = ( C9B53859138D9E990028D27C /* ftp.h */, + FC2ED623157D4DA90098EC69 /* inet.h */, C9B5385B138D9E990028D27C /* nameser_compat.h */, C9B5385C138D9E990028D27C /* telnet.h */, C9B5385D138D9E990028D27C /* tftp.h */, @@ -7892,22 +7950,11 @@ C9B5387F138D9E990028D27C /* libkern */ = { isa = PBXGroup; children = ( - C9B53881138D9E990028D27C /* OSAtomic.h */, - C9B53882138D9E990028D27C /* OSCacheControl.h */, - C9B53883138D9E990028D27C /* OSMemoryNotification.h */, C9B53884138D9E990028D27C /* OSThermalNotification.h */, ); path = libkern; sourceTree = ""; }; - C9B53888138D9E990028D27C /* malloc */ = { - isa = PBXGroup; - children = ( - C9B5388A138D9E990028D27C /* malloc.h */, - ); - path = malloc; - sourceTree = ""; - }; C9B53890138D9E990028D27C /* NetBSD */ = { isa = PBXGroup; children = ( @@ -7942,6 +7989,7 @@ children = ( C9B538C0138D9E990028D27C /* acl.h */, C9B538C1138D9E990028D27C /* cdefs.h */, + 3F267F39163FC8BD0089A0A6 /* rbtree.h */, C9B538C3138D9E990028D27C /* statvfs.h */, ); path = sys; @@ -8128,7 +8176,6 @@ children = ( C9B53A05138D9E990028D27C /* assert.3 */, C9B53A06138D9E990028D27C /* bitstring.3 */, - C9B53A07138D9E990028D27C /* environ.7 */, C9B53A08138D9E990028D27C /* FreeBSD */, C9B53A0B138D9E990028D27C /* gethostuuid.2 */, C9B53A0D138D9E990028D27C /* utmp.5 */, @@ -8140,6 +8187,7 @@ C9B53A08138D9E990028D27C /* FreeBSD */ = { isa = PBXGroup; children = ( + 928BD1091D7608A400EC01FC /* environ.7 */, C9B53A09138D9E990028D27C /* stdarg.3 */, ); path = FreeBSD; @@ -8157,10 +8205,11 @@ C9B53A11138D9E990028D27C /* net */ = { isa = PBXGroup; children = ( + FC2ED60E157D4BE70098EC69 /* inet_ntop.c */, + FC2ED60F157D4BE70098EC69 /* inet_pton.c */, C9B53A12138D9E990028D27C /* byteorder.3 */, C9B53A13138D9E990028D27C /* ethers.3 */, C9B53A14138D9E990028D27C /* FreeBSD */, - C9B53A39138D9E990028D27C /* rcmdsh.3 */, ); path = net; sourceTree = ""; @@ -8218,8 +8267,10 @@ C9B53A45138D9E990028D27C /* Platforms */ = { isa = PBXGroup; children = ( + C975E22B1A12ECA00093B345 /* appletv */, C9B53A46138D9E990028D27C /* iphoneos */, C9B53A48138D9E990028D27C /* macosx */, + C9A288A61ACDBA95004A33A7 /* watchos */, ); path = Platforms; sourceTree = ""; @@ -8286,91 +8337,6 @@ path = posix1e; sourceTree = ""; }; - C9B53ABA138D9E990028D27C /* pthreads */ = { - isa = PBXGroup; - children = ( - C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */, - C9B53ABD138D9E990028D27C /* plockstat.d */, - C9B53ABE138D9E990028D27C /* posix_sched.h */, - C9B53ABF138D9E990028D27C /* pthread.3 */, - C9B53AC0138D9E990028D27C /* pthread.c */, - C9B53AC1138D9E990028D27C /* pthread.h */, - C9B53AC2138D9E990028D27C /* pthread_atfork.3 */, - C9B53AC3138D9E990028D27C /* pthread_attr.3 */, - C9B53AC4138D9E990028D27C /* pthread_attr_init_destroy.3 */, - C9B53AC5138D9E990028D27C /* pthread_attr_set_getdetachstate.3 */, - C9B53AC6138D9E990028D27C /* pthread_attr_set_getinheritsched.3 */, - C9B53AC7138D9E990028D27C /* pthread_attr_set_getschedparam.3 */, - C9B53AC8138D9E990028D27C /* pthread_attr_set_getschedpolicy.3 */, - C9B53AC9138D9E990028D27C /* pthread_attr_set_getscope.3 */, - C9B53ACA138D9E990028D27C /* pthread_attr_set_getstackaddr.3 */, - C9B53ACB138D9E990028D27C /* pthread_attr_set_getstacksize.3 */, - C9B53ACC138D9E990028D27C /* pthread_cancel.3 */, - C9B53ACD138D9E990028D27C /* pthread_cancelable.c */, - C9B53ACE138D9E990028D27C /* pthread_cleanup_pop.3 */, - C9B53ACF138D9E990028D27C /* pthread_cleanup_push.3 */, - C9B53AD0138D9E990028D27C /* pthread_cond.c */, - C9B53AD1138D9E990028D27C /* pthread_cond_broadcast.3 */, - C9B53AD2138D9E990028D27C /* pthread_cond_destroy.3 */, - C9B53AD3138D9E990028D27C /* pthread_cond_init.3 */, - C9B53AD4138D9E990028D27C /* pthread_cond_signal.3 */, - C9B53AD5138D9E990028D27C /* pthread_cond_timedwait.3 */, - C9B53AD6138D9E990028D27C /* pthread_cond_wait.3 */, - C9B53AD7138D9E990028D27C /* pthread_condattr.3 */, - C9B53AD8138D9E990028D27C /* pthread_create.3 */, - C9B53AD9138D9E990028D27C /* pthread_detach.3 */, - C9B53ADA138D9E990028D27C /* pthread_equal.3 */, - C9B53ADB138D9E990028D27C /* pthread_exit.3 */, - C9B53ADC138D9E990028D27C /* pthread_getschedparam.3 */, - C9B53ADD138D9E990028D27C /* pthread_getspecific.3 */, - C9B53ADE138D9E990028D27C /* pthread_impl.h */, - C9B53ADF138D9E990028D27C /* pthread_internals.h */, - C9B53AE0138D9E990028D27C /* pthread_join.3 */, - C9B53AE1138D9E990028D27C /* pthread_key_create.3 */, - C9B53AE2138D9E990028D27C /* pthread_key_delete.3 */, - C9B53AE3138D9E990028D27C /* pthread_machdep.h */, - C9B53AE4138D9E990028D27C /* pthread_mutex.c */, - C9B53AE5138D9E990028D27C /* pthread_mutex_destroy.3 */, - C9B53AE6138D9E990028D27C /* pthread_mutex_init.3 */, - C9B53AE7138D9E990028D27C /* pthread_mutex_lock.3 */, - C9B53AE8138D9E990028D27C /* pthread_mutex_trylock.3 */, - C9B53AE9138D9E990028D27C /* pthread_mutex_unlock.3 */, - C9B53AEA138D9E990028D27C /* pthread_mutexattr.3 */, - C9B53AEB138D9E990028D27C /* pthread_once.3 */, - C9B53AEC138D9E990028D27C /* pthread_rwlock.c */, - C9B53AED138D9E990028D27C /* pthread_rwlock_destroy.3 */, - C9B53AEE138D9E990028D27C /* pthread_rwlock_init.3 */, - C9B53AEF138D9E990028D27C /* pthread_rwlock_rdlock.3 */, - C9B53AF0138D9E990028D27C /* pthread_rwlock_unlock.3 */, - C9B53AF1138D9E990028D27C /* pthread_rwlock_wrlock.3 */, - C9B53AF2138D9E990028D27C /* pthread_rwlockattr_destroy.3 */, - C9B53AF3138D9E990028D27C /* pthread_rwlockattr_getpshared.3 */, - C9B53AF4138D9E990028D27C /* pthread_rwlockattr_init.3 */, - C9B53AF5138D9E990028D27C /* pthread_rwlockattr_setpshared.3 */, - C9B53AF6138D9E990028D27C /* pthread_self.3 */, - C9B53AF7138D9E990028D27C /* pthread_setcancelstate.3 */, - C9B53AF8138D9E990028D27C /* pthread_setspecific.3 */, - C9B53AF9138D9E990028D27C /* pthread_spinlock.h */, - C9B53AFA138D9E990028D27C /* pthread_spis.h */, - C9B53AFB138D9E990028D27C /* pthread_tsd.c */, - C9B53AFC138D9E990028D27C /* pthread_workqueue.h */, - C9B53AFD138D9E990028D27C /* sched.h */, - C9B53AFE138D9E990028D27C /* stack.s */, - C9B53AFF138D9E990028D27C /* tests */, - C9B53B02138D9E990028D27C /* thread_setup.c */, - ); - path = pthreads; - sourceTree = ""; - }; - C9B53AFF138D9E990028D27C /* tests */ = { - isa = PBXGroup; - children = ( - C9B53B00138D9E990028D27C /* Makefile */, - C9B53B01138D9E990028D27C /* pthread_atfork_test.c */, - ); - path = tests; - sourceTree = ""; - }; C9B53B03138D9E990028D27C /* regex */ = { isa = PBXGroup; children = ( @@ -8394,17 +8360,11 @@ path = FreeBSD; sourceTree = ""; }; - C9B53B1B138D9E990028D27C /* rpc */ = { - isa = PBXGroup; - children = ( - ); - path = rpc; - sourceTree = ""; - }; C9B53B1D138D9E990028D27C /* secure */ = { isa = PBXGroup; children = ( C9B53B1E138D9E990028D27C /* chk_fail.c */, + 3F169A3C1643B7BA0029E851 /* memccpy_chk.c */, C9B53B20138D9E990028D27C /* memcpy_chk.c */, C9B53B21138D9E990028D27C /* memmove_chk.c */, C9B53B22138D9E990028D27C /* memset_chk.c */, @@ -8414,6 +8374,8 @@ C9B53B26138D9E990028D27C /* stpncpy_chk.c */, C9B53B27138D9E990028D27C /* strcat_chk.c */, C9B53B28138D9E990028D27C /* strcpy_chk.c */, + 3FA8F3081643AB4300D37078 /* strlcat_chk.c */, + 3FA8F3091643AB4300D37078 /* strlcpy_chk.c */, C9B53B29138D9E990028D27C /* strncat_chk.c */, C9B53B2A138D9E990028D27C /* strncpy_chk.c */, C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */, @@ -8432,6 +8394,11 @@ C9B53C13138D9E9A0028D27C /* scanf_l.3 */, C9B53C14138D9E9A0028D27C /* wprintf_l.3 */, C9B53C15138D9E9A0028D27C /* wscanf_l.3 */, + B1795371158B0E35008990E8 /* xprintf_all_in_one.c */, + B126140215881A000077E3CC /* xprintf_comp.c */, + B126140315881A000077E3CC /* xprintf_domain.c */, + B126140415881A000077E3CC /* xprintf_domain.h */, + B1795372158B0E35008990E8 /* xprintf_exec.c */, ); path = stdio; sourceTree = ""; @@ -8572,6 +8539,16 @@ C9B53C0A138D9E9A0028D27C /* wscanf.3 */, C9B53C0C138D9E9A0028D27C /* wscanf.c */, C9B53C0E138D9E9A0028D27C /* wsetup.c */, + B12613EE158818EC0077E3CC /* xprintf_errno.c */, + B12613EF158818EC0077E3CC /* xprintf_float.c */, + B12613F0158818EC0077E3CC /* xprintf_hexdump.c */, + B12613F1158818EC0077E3CC /* xprintf_int.c */, + B12613F2158818EC0077E3CC /* xprintf_private.h */, + B12613F3158818EC0077E3CC /* xprintf_quote.c */, + B12613F4158818EC0077E3CC /* xprintf_str.c */, + B12613F5158818EC0077E3CC /* xprintf_time.c */, + B12613F6158818EC0077E3CC /* xprintf_vis.c */, + B12613F7158818EC0077E3CC /* xprintf.c */, ); path = FreeBSD; sourceTree = ""; @@ -8750,9 +8727,10 @@ C9B53CE4138D9E9A0028D27C /* string */ = { isa = PBXGroup; children = ( + 3F18DE1E162A732C008B15AC /* NetBSD */, C9B53CE5138D9E9A0028D27C /* FreeBSD */, C9B53D91138D9E9A0028D27C /* memset_pattern.3 */, - C9CF595913CD0B9600674871 /* memset_pattern.c */, + 3FD14572171D42B300B7BAF5 /* bcopy.c */, 63D4060513DDEDF10094DD56 /* stpcpy.c */, 63D4060913DDEEA10094DD56 /* stpncpy.c */, 63D4060C13DDF26A0094DD56 /* strcat.c */, @@ -8769,29 +8747,19 @@ isa = PBXGroup; children = ( C9B53CE6138D9E9A0028D27C /* bcmp.3 */, - C9B53CE8138D9E9A0028D27C /* bcmp.c */, C9B53CE9138D9E9A0028D27C /* bcopy.3 */, - C9B53CEB138D9E9A0028D27C /* bcopy.c */, C9B53CED138D9E9A0028D27C /* bstring.3 */, C9B53CEF138D9E9A0028D27C /* bzero.3 */, - C9B53CF1138D9E9A0028D27C /* bzero.c */, - C9B53CF3138D9E9A0028D27C /* ffs.3 */, C9B53CF5138D9E9A0028D27C /* index.3 */, C9B53CF7138D9E9A0028D27C /* index.c */, C9B53CF8138D9E9A0028D27C /* memccpy.3 */, - C9B53CFA138D9E9A0028D27C /* memccpy.c */, C9B53CFB138D9E9A0028D27C /* memchr.3 */, - C9B53CFD138D9E9A0028D27C /* memchr.c */, C9B53CFE138D9E9A0028D27C /* memcmp.3 */, - C9B53D00138D9E9A0028D27C /* memcmp.c */, C9B53D01138D9E9A0028D27C /* memcpy.3 */, - C9B53D03138D9E9A0028D27C /* memcpy.c */, C9B53D05138D9E9A0028D27C /* memmem.3 */, C9B53D06138D9E9A0028D27C /* memmem.c */, C9B53D07138D9E9A0028D27C /* memmove.3 */, - C9B53D09138D9E9A0028D27C /* memmove.c */, C9B53D0B138D9E9A0028D27C /* memset.3 */, - C9B53D0D138D9E9A0028D27C /* memset.c */, C9B53D0E138D9E9A0028D27C /* rindex.3 */, C9B53D10138D9E9A0028D27C /* rindex.c */, C9B53D13138D9E9A0028D27C /* strcasecmp.3 */, @@ -8799,13 +8767,10 @@ C9B53D17138D9E9A0028D27C /* strcasestr.c */, C9B53D19138D9E9A0028D27C /* strcat.3 */, C9B53D1C138D9E9A0028D27C /* strchr.3 */, - C9B53D1E138D9E9A0028D27C /* strchr.c */, C9B53D20138D9E9A0028D27C /* strcmp.3 */, - C9B53D22138D9E9A0028D27C /* strcmp.c */, C9B53D24138D9E9A0028D27C /* strcoll.3 */, C9B53D26138D9E9A0028D27C /* strcoll.c */, C9B53D28138D9E9A0028D27C /* strcpy.3 */, - C9B53D2B138D9E9A0028D27C /* strcspn.3 */, C9B53D2D138D9E9A0028D27C /* strcspn.c */, C9B53D2E138D9E9A0028D27C /* strdup.3 */, C9B53D30138D9E9A0028D27C /* strdup.c */, @@ -8817,13 +8782,11 @@ C9B53D3C138D9E9A0028D27C /* strlen.c */, C9B53D3E138D9E9A0028D27C /* strmode.3 */, C9B53D40138D9E9A0028D27C /* strmode.c */, - C9B53D42138D9E9A0028D27C /* strncmp.c */, C9B53D44138D9E9A0028D27C /* strndup.c */, C9B53D45138D9E9A0028D27C /* strnlen.c */, C9B53D46138D9E9A0028D27C /* strnstr.c */, C9B53D47138D9E9A0028D27C /* strpbrk.3 */, C9B53D49138D9E9A0028D27C /* strpbrk.c */, - C9B53D4A138D9E9A0028D27C /* strrchr.3 */, C9B53D4C138D9E9A0028D27C /* strrchr.c */, C9B53D4E138D9E9A0028D27C /* strsep.3 */, C9B53D4F138D9E9A0028D27C /* strsep.c */, @@ -8838,6 +8801,8 @@ C9B53D5D138D9E9A0028D27C /* strxfrm.c */, C9B53D5F138D9E9A0028D27C /* swab.3 */, C9B53D61138D9E9A0028D27C /* swab.c */, + 928BD0FD1D7606EA00EC01FC /* timingsafe_bcmp.3 */, + 928BD0FE1D7606EA00EC01FC /* timingsafe_bcmp.c */, C9B53D63138D9E9A0028D27C /* wcpcpy.c */, C9B53D64138D9E9A0028D27C /* wcpncpy.c */, C9B53D65138D9E9A0028D27C /* wcscasecmp.c */, @@ -8880,23 +8845,13 @@ C9B53D93138D9E9A0028D27C /* sys */ = { isa = PBXGroup; children = ( - C9B53D94138D9E9A0028D27C /* __libc_init.c */, + C9B53D94138D9E9A0028D27C /* _libc_init.c */, C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */, - C9B53D96138D9E9A0028D27C /* atomic.3 */, - C9B53D97138D9E9A0028D27C /* barrier.3 */, - C9B53D98138D9E9A0028D27C /* cache.3 */, C9B53D99138D9E9A0028D27C /* chmodx_np.c */, - C9B53D9A138D9E9A0028D27C /* CLIB-LIST */, - C9B53D9B138D9E9A0028D27C /* context-stubs.c */, C9B53D9C138D9E9A0028D27C /* crt_externs.c */, - C9B53D9D138D9E9A0028D27C /* errno.c */, C9B53D9E138D9E9A0028D27C /* fork.c */, C9B53D9F138D9E9A0028D27C /* getgroups.c */, - C9B53DA0138D9E9A0028D27C /* getiopolicy_np.3 */, - C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */, C9B53DA2138D9E9A0028D27C /* gettimeofday.c */, - C9B53DA4138D9E9A0028D27C /* MISSING-MANPAGE */, - C9B53DA5138D9E9A0028D27C /* MISSING_SYSCALLS */, C9B53DA6138D9E9A0028D27C /* msgctl.c */, C9B53DA7138D9E9A0028D27C /* nanosleep.2 */, C9B53DA8138D9E9A0028D27C /* OpenBSD */, @@ -8904,21 +8859,12 @@ C9B53DAC138D9E9A0028D27C /* OSMemoryNotification.c */, C9B53DAD138D9E9A0028D27C /* OSThermalNotification.c */, C9B53DAE138D9E9A0028D27C /* posix_spawn.c */, - C9B53DAF138D9E9A0028D27C /* pthread_kill.2 */, - C9B53DB0138D9E9A0028D27C /* pthread_sigmask.2 */, - C9B53DB1138D9E9A0028D27C /* REQUIRED-MACROS */, C9B53DB2138D9E9A0028D27C /* semctl.c */, C9B53DB3138D9E9A0028D27C /* settimeofday.c */, C9B53DB4138D9E9A0028D27C /* shmctl.c */, C9B53DB5138D9E9A0028D27C /* sigaction.c */, - C9B53DB6138D9E9A0028D27C /* sigcatch.c */, - C9B53DB7138D9E9A0028D27C /* sigcatch.h */, - C9B53DB8138D9E9A0028D27C /* sigtramp.c */, C9B53DB9138D9E9A0028D27C /* sigwait.2 */, - C9B53DBA138D9E9A0028D27C /* slot_name.c */, - C9B53DBB138D9E9A0028D27C /* spinlock.3 */, C9B53DBC138D9E9A0028D27C /* statx_np.c */, - C9B53DBD138D9E9A0028D27C /* SYSCALL-LIST */, C9B53DBE138D9E9A0028D27C /* umaskx_np.c */, ); path = sys; @@ -8932,18 +8878,6 @@ path = OpenBSD; sourceTree = ""; }; - C9B53DBF138D9E9A0028D27C /* threads */ = { - isa = PBXGroup; - children = ( - C9B53DC0138D9E9A0028D27C /* cprocs.c */, - C9B53DC1138D9E9A0028D27C /* cthread_internals.h */, - C9B53DC2138D9E9A0028D27C /* cthreads.c */, - C9B53DC3138D9E9A0028D27C /* cthreads.h */, - C9B53DC5138D9E9A0028D27C /* mig_support.c */, - ); - path = threads; - sourceTree = ""; - }; C9B53DC6138D9E9A0028D27C /* util */ = { isa = PBXGroup; children = ( @@ -9004,9 +8938,7 @@ isa = PBXGroup; children = ( C9B53DF0138D9E9A0028D27C /* gen */, - C9B53DFC138D9E9A0028D27C /* pthreads */, C9B53E07138D9E9A0028D27C /* string */, - C9B53E1D138D9E9A0028D27C /* sys */, ); path = x86_64; sourceTree = ""; @@ -9014,100 +8946,99 @@ C9B53DF0138D9E9A0028D27C /* gen */ = { isa = PBXGroup; children = ( - C9B53DF1138D9E9A0028D27C /* _ctx_start.S */, - C9B53DF2138D9E9A0028D27C /* _setcontext.S */, - C9B53DF3138D9E9A0028D27C /* cpu_number.s */, - C9B53DF4138D9E9A0028D27C /* getcontext.S */, - C9B53DF5138D9E9A0028D27C /* getmcontext.c */, - C9B53DF6138D9E9A0028D27C /* icacheinval.s */, - C9B53DF7138D9E9A0028D27C /* makecontext.c */, C9B53DF9138D9E9A0028D27C /* mcount.s */, - C9B53DFA138D9E9A0028D27C /* setcontext.c */, - C9EB3555138F7F6A0075BB52 /* setjmperr.c */, - C9B53DFB138D9E9A0028D27C /* swapcontext.c */, ); path = gen; sourceTree = ""; }; - C9B53DFC138D9E9A0028D27C /* pthreads */ = { - isa = PBXGroup; - children = ( - C9B53DFE138D9E9A0028D27C /* preempt.s */, - C9B53DFF138D9E9A0028D27C /* pthread_getspecific.s */, - C9B53E00138D9E9A0028D27C /* pthread_mutex_lock.s */, - C9B53E01138D9E9A0028D27C /* pthread_self.s */, - C9B53E02138D9E9A0028D27C /* pthread_set_self.s */, - C9B53E03138D9E9A0028D27C /* start_wqthread.s */, - C9B53E04138D9E9A0028D27C /* thread_start.s */, - ); - path = pthreads; - sourceTree = ""; - }; C9B53E07138D9E9A0028D27C /* string */ = { isa = PBXGroup; children = ( - C9B53E08138D9E9A0028D27C /* __bzero.s */, - C9B53E09138D9E9A0028D27C /* bcopy.c */, - C9B53E0A138D9E9A0028D27C /* bcopy_sse3x.s */, - C9B53E0B138D9E9A0028D27C /* bcopy_sse42.s */, - C9B53E0C138D9E9A0028D27C /* bzero.c */, - C9B53E0D138D9E9A0028D27C /* bzero_sse2.s */, - C9B53E0E138D9E9A0028D27C /* bzero_sse42.s */, - C9B53E0F138D9E9A0028D27C /* ffs.s */, - C9B53E10138D9E9A0028D27C /* longcopy_sse3x.s */, - C9B53E12138D9E9A0028D27C /* memcmp.s */, - C9B53E13138D9E9A0028D27C /* memcpy.c */, - C9B53E14138D9E9A0028D27C /* memmove.c */, - C9B53E15138D9E9A0028D27C /* memset.s */, - C9B53E16138D9E9A0028D27C /* strcmp.s */, C9B53E17138D9E9A0028D27C /* strcpy.s */, - C9B53E18138D9E9A0028D27C /* strlcat.s */, - C9B53E19138D9E9A0028D27C /* strlcpy.s */, C9B53E1A138D9E9A0028D27C /* strlen.s */, - C9B53E1B138D9E9A0028D27C /* strncmp.s */, C9B53E1C138D9E9A0028D27C /* strncpy.s */, + 639D126615595DDE00D0403A /* strnlen.s */, ); path = string; sourceTree = ""; }; - C9B53E1D138D9E9A0028D27C /* sys */ = { - isa = PBXGroup; - children = ( - C9B53E1E138D9E9A0028D27C /* _setjmp.s */, - C9B53E1F138D9E9A0028D27C /* _sigtramp.s */, - C9B53E20138D9E9A0028D27C /* atomic.c */, - C9B53E21138D9E9A0028D27C /* i386_gettimeofday_asm.s */, - C9B53E23138D9E9A0028D27C /* nanotime.s */, - C9B53E24138D9E9A0028D27C /* OSAtomic.s */, - C9B53E25138D9E9A0028D27C /* setjmp.s */, - C9B53E26138D9E9A0028D27C /* spinlocks.c */, - C9B53E27138D9E9A0028D27C /* spinlocks_asm.s */, - ); - path = sys; - sourceTree = ""; - }; C9C2A946138DF66900287F00 /* xcodescripts */ = { isa = PBXGroup; children = ( + E4A877A6174D82FB000DBB55 /* alias.list */, C9C2A948138DF7DD00287F00 /* libc.xcconfig */, C9766153138ECF0000741512 /* variants.xcconfig */, + C9AE91AE1517CDAC00A2626C /* eos.xcconfig */, + C0E345E31C58300F00E749C2 /* libc_static.xcconfig */, + E41BEA97178E72E100E348BB /* Libc.order */, + 3F45E3121A6DC12E00AFF01E /* abort_unsupported.sh */, C9194B4C140E3BC700BE0C3A /* build_linklists.sh */, C9766150138EC9D400741512 /* patch_headers_variants.pl */, C976616B138EF14100741512 /* generate_features.pl */, - C94212DD13900FC3004BA536 /* mig_headers.sh */, C942135913904CBC004BA536 /* manpages.sh */, C9950E6A1390D2CA009863B6 /* headers.sh */, C9B53D92138D9E9A0028D27C /* strip-header.ed */, - C9265D1113B1CF970090BA1C /* clean_simulator.sh */, C965CBF4143BC1BF003912CE /* force_libc_to_build.sh */, C93D6150143D31E300EB9023 /* sanitise_headers.sh */, + 3FF283231A4764240098AD2C /* sim-compat-symlink.sh */, + C0E343811C58299D00E749C2 /* skip_installhdrs.sh */, ); path = xcodescripts; sourceTree = ""; }; + FC60BAD016555A4A00033196 /* _types */ = { + isa = PBXGroup; + children = ( + FC60BAD116555A4A00033196 /* _intmax_t.h */, + FC60BAD216555A4A00033196 /* _nl_item.h */, + FC60BAD316555A4A00033196 /* _uint16_t.h */, + FC60BAD416555A4A00033196 /* _uint32_t.h */, + FC60BAD516555A4A00033196 /* _uint64_t.h */, + FC60BAD616555A4A00033196 /* _uint8_t.h */, + FC60BAD716555A4A00033196 /* _uintmax_t.h */, + FC60BAD816555A4A00033196 /* _wctrans_t.h */, + FC60BAD916555A4A00033196 /* _wctype_t.h */, + ); + path = _types; + sourceTree = ""; + }; /* End PBXGroup section */ +/* Begin PBXLegacyTarget section */ + 928F25D01BEACED7007B13C7 /* darwintests */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = 928F25D11BEACED7007B13C7 /* Build configuration list for PBXLegacyTarget "darwintests" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + buildWorkingDirectory = tests/; + dependencies = ( + ); + name = darwintests; + passBuildSettingsInEnvironment = 1; + productName = darwintests; + }; +/* End PBXLegacyTarget section */ + /* Begin PBXNativeTarget section */ + 3F51206A16C3174300AFB431 /* FortifySource */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3F5120EE16C3174300AFB431 /* Build configuration list for PBXNativeTarget "FortifySource" */; + buildPhases = ( + 3F51206B16C3174300AFB431 /* Generate libc-features.h */, + 3F51206C16C3174300AFB431 /* Sources */, + 3F5120ED16C3174300AFB431 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FortifySource; + productName = Base; + productReference = 3F5120F116C3174300AFB431 /* libFortifySource.a */; + productType = "com.apple.product-type.library.static"; + }; B122F0E71432B8E600AF95D0 /* TRE */ = { isa = PBXNativeTarget; buildConfigurationList = B122F2AA1432B8E600AF95D0 /* Build configuration list for PBXNativeTarget "TRE" */; @@ -9125,21 +9056,29 @@ productReference = B122F2AD1432B8E600AF95D0 /* libTRE.a */; productType = "com.apple.product-type.library.static"; }; - B1E96340157E722200FCCEE7 /* FreeBSD_gcc */ = { + C0E343831C582ECB00E749C2 /* libc_static */ = { isa = PBXNativeTarget; - buildConfigurationList = B1E96503157E722200FCCEE7 /* Build configuration list for PBXNativeTarget "FreeBSD_gcc" */; + buildConfigurationList = C0E345DF1C582ECB00E749C2 /* Build configuration list for PBXNativeTarget "libc_static" */; buildPhases = ( - B1E96341157E722200FCCEE7 /* Generate libc-features.h */, - B1E96342157E722200FCCEE7 /* Sources */, - B1E96502157E722200FCCEE7 /* Frameworks */, + C0E3438E1C582ECB00E749C2 /* Build Link List */, + C0E3438F1C582ECB00E749C2 /* Generate libc-features.h */, + C0E343901C582ECB00E749C2 /* Patch Headers */, + C0E343911C582ECB00E749C2 /* Sources */, + C0E345DA1C582ECB00E749C2 /* Frameworks */, + C0E345E41C5830C200E749C2 /* Symlink libc.a to a loaderd path */, ); buildRules = ( ); dependencies = ( + C0E343841C582ECB00E749C2 /* PBXTargetDependency */, + C0E343861C582ECB00E749C2 /* PBXTargetDependency */, + C0E343881C582ECB00E749C2 /* PBXTargetDependency */, + C0E3438A1C582ECB00E749C2 /* PBXTargetDependency */, + C0E3438C1C582ECB00E749C2 /* PBXTargetDependency */, ); - name = FreeBSD_gcc; - productName = FreeBSD; - productReference = B1E96506157E722200FCCEE7 /* libFreeBSD_gcc.a */; + name = libc_static; + productName = "Variant Cancelable"; + productReference = C0E345E21C582ECB00E749C2 /* libc.a */; productType = "com.apple.product-type.library.static"; }; C9257ECF138E1B5000B3107C /* FreeBSD */ = { @@ -9176,24 +9115,23 @@ productReference = C9258105138E2D3100B3107C /* libNetBSD.a */; productType = "com.apple.product-type.library.static"; }; - C942102D13900C8A004BA536 /* libc.a */ = { + C942102D13900C8A004BA536 /* libc_dyld */ = { isa = PBXNativeTarget; - buildConfigurationList = C94212C913900C8A004BA536 /* Build configuration list for PBXNativeTarget "libc.a" */; + buildConfigurationList = C94212C913900C8A004BA536 /* Build configuration list for PBXNativeTarget "libc_dyld" */; buildPhases = ( C942102E13900C8A004BA536 /* Generate libc-features.h */, - C94212DC13900FAA004BA536 /* Compile MIG Headers */, - C942102F13900C8A004BA536 /* Generate dtrace headers */, C942103013900C8A004BA536 /* Patch Headers */, C942103113900C8A004BA536 /* Sources */, C94212C713900C8A004BA536 /* Frameworks */, + C0E343821C5829F500E749C2 /* Symlink libc_dyld.a to libc.a */, ); buildRules = ( ); dependencies = ( ); - name = libc.a; + name = libc_dyld; productName = "Variant Cancelable"; - productReference = C94212CC13900C8A004BA536 /* libc.a */; + productReference = C94212CC13900C8A004BA536 /* libc_dyld.a */; productType = "com.apple.product-type.library.static"; }; C95B7ED9138F3C55004311DA /* Variant_DarwinExtsn */ = { @@ -9250,6 +9188,30 @@ productReference = C95B86C7138F53DB004311DA /* libvPre1050.a */; productType = "com.apple.product-type.library.static"; }; + C97A6F1E1517AF53005E1998 /* libc_eOS.a */ = { + isa = PBXNativeTarget; + buildConfigurationList = C97A72191517AF53005E1998 /* Build configuration list for PBXNativeTarget "libc_eOS.a" */; + buildPhases = ( + C9AE91C21517E17600A2626C /* Build Link List */, + C97A6F1F1517AF53005E1998 /* Generate libc-features.h */, + C97A6F221517AF53005E1998 /* Patch Headers */, + C97A6F231517AF53005E1998 /* Sources */, + C97A72181517AF53005E1998 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + C9AE91BB1517D33100A2626C /* PBXTargetDependency */, + C9AE91BD1517D33100A2626C /* PBXTargetDependency */, + C9AE91BF1517D33100A2626C /* PBXTargetDependency */, + C9AE91C11517D33100A2626C /* PBXTargetDependency */, + C925D2011518FA5D003D315B /* PBXTargetDependency */, + ); + name = libc_eOS.a; + productName = "Variant Cancelable"; + productReference = C97A721C1517AF53005E1998 /* libc_eOS.a */; + productType = "com.apple.product-type.library.static"; + }; C9B53E2B138DA0610028D27C /* Platform */ = { isa = PBXNativeTarget; buildConfigurationList = C9B53E2D138DA0610028D27C /* Build configuration list for PBXNativeTarget "Platform" */; @@ -9272,8 +9234,6 @@ buildConfigurationList = C9C2A94E138DFFDA00287F00 /* Build configuration list for PBXNativeTarget "Base" */; buildPhases = ( C9BD3C3E138F18B200B389FD /* Generate libc-features.h */, - C91875E313FC6433001F2604 /* Compile MIG Headers */, - C9258127138E3EC800B3107C /* Generate dtrace headers */, C9C2A949138DFFD900287F00 /* Sources */, C9C2A94A138DFFD900287F00 /* Frameworks */, ); @@ -9290,21 +9250,21 @@ isa = PBXNativeTarget; buildConfigurationList = C9D94330138DB73300FB7ACC /* Build configuration list for PBXNativeTarget "libsystem_c.dylib" */; buildPhases = ( + 3F45E3181A6DC13C00AFF01E /* Enforce SUPPORTED_PLATFORMS */, C9950E6B1390D2DC009863B6 /* Install Headers */, C9194B4B140E3A7100BE0C3A /* Build Link Lists */, C9D9432B138DB73300FB7ACC /* Sources */, C9D9432C138DB73300FB7ACC /* Frameworks */, C942135B13905EB9004BA536 /* Install Manpages */, - C9265D1313B1CFD10090BA1C /* Clean Simulator Binaries */, C965CBF3143BBFF7003912CE /* Remove deps.c */, C93D6152143D321000EB9023 /* Sanitise Headers (rdar://problem/10241868) */, + 3FF283291A4764370098AD2C /* Simulator Build Compat Symlink */, ); buildRules = ( ); dependencies = ( C9FA32C8138E41800089A94B /* PBXTargetDependency */, C9FA32CA138E41800089A94B /* PBXTargetDependency */, - B1E96509157E749200FCCEE7 /* PBXTargetDependency */, C9FA32CC138E41800089A94B /* PBXTargetDependency */, B122F2D91432BA8700AF95D0 /* PBXTargetDependency */, C9D94335138DB75F00FB7ACC /* PBXTargetDependency */, @@ -9314,7 +9274,10 @@ C95B86CC138F546E004311DA /* PBXTargetDependency */, C9EB326D138F74D20075BB52 /* PBXTargetDependency */, C9EB3515138F771F0075BB52 /* PBXTargetDependency */, + 3F51211716C318EB00AFB431 /* PBXTargetDependency */, C942130913901709004BA536 /* PBXTargetDependency */, + C0E345E61C58323000E749C2 /* PBXTargetDependency */, + C925D2031518FEBE003D315B /* PBXTargetDependency */, ); name = libsystem_c.dylib; productName = Libc; @@ -9344,7 +9307,6 @@ buildConfigurationList = C9EB3263138F6D880075BB52 /* Build configuration list for PBXNativeTarget "Variant_Legacy" */; buildPhases = ( C9EB2FCA138F6D880075BB52 /* Generate libc-features.h */, - C9EB326B138F74600075BB52 /* Generate dtrace headers */, C9EB2FCB138F6D880075BB52 /* Patch Headers */, C9EB2FCC138F6D880075BB52 /* Sources */, C9EB3261138F6D880075BB52 /* Frameworks */, @@ -9363,7 +9325,6 @@ buildConfigurationList = C9EB350A138F75580075BB52 /* Build configuration list for PBXNativeTarget "Variant_Inode32" */; buildPhases = ( C9EB3270138F75580075BB52 /* Generate libc-features.h */, - C9EB3271138F75580075BB52 /* Generate dtrace headers */, C9EB3272138F75580075BB52 /* Patch Headers */, C9EB3273138F75580075BB52 /* Sources */, C9EB3508138F75580075BB52 /* Frameworks */, @@ -9383,7 +9344,15 @@ C9B53597138D9A690028D27C /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0430; + LastUpgradeCheck = 0700; + TargetAttributes = { + 925E7FE619E8945900AC7889 = { + CreatedOnToolsVersion = 6.1; + }; + 928F25D01BEACED7007B13C7 = { + CreatedOnToolsVersion = 7.1; + }; + }; }; buildConfigurationList = C9B5359A138D9A690028D27C /* Build configuration list for PBXProject "Libc" */; compatibilityVersion = "Xcode 3.2"; @@ -9398,11 +9367,12 @@ projectRoot = ""; targets = ( C9D9432E138DB73300FB7ACC /* libsystem_c.dylib */, - C942102D13900C8A004BA536 /* libc.a */, + C942102D13900C8A004BA536 /* libc_dyld */, + C0E343831C582ECB00E749C2 /* libc_static */, + C97A6F1E1517AF53005E1998 /* libc_eOS.a */, C9B53E2B138DA0610028D27C /* Platform */, C9C2A94C138DFFD900287F00 /* Base */, C9257ECF138E1B5000B3107C /* FreeBSD */, - B1E96340157E722200FCCEE7 /* FreeBSD_gcc */, C9258093138E2D3100B3107C /* NetBSD */, B122F0E71432B8E600AF95D0 /* TRE */, C9D9435F138EC3E300FB7ACC /* Variant_Cancelable */, @@ -9411,27 +9381,30 @@ C95B842A138F53DB004311DA /* Variant_Pre1050 */, C9EB2FC9138F6D880075BB52 /* Variant_Legacy */, C9EB326F138F75580075BB52 /* Variant_Inode32 */, + 3F51206A16C3174300AFB431 /* FortifySource */, + 925E7FE619E8945900AC7889 /* Libc_tests */, + 928F25D01BEACED7007B13C7 /* darwintests */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ - B122F0E81432B8E600AF95D0 /* Generate libc-features.h */ = { + 3F45E3181A6DC13C00AFF01E /* Enforce SUPPORTED_PLATFORMS */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "$(SRCROOT)/xcodescripts/abort_unsupported.sh", ); - name = "Generate libc-features.h"; + name = "Enforce SUPPORTED_PLATFORMS"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; - showEnvVarsInLog = 0; + shellPath = "/bin/bash -e -x"; + shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"\n"; }; - B1E96341157E722200FCCEE7 /* Generate libc-features.h */ = { + 3F51206B16C3174300AFB431 /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -9443,27 +9416,55 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C91875E313FC6433001F2604 /* Compile MIG Headers */ = { + 3FF283291A4764370098AD2C /* Simulator Build Compat Symlink */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/xcodescripts/sim-compat-symlink.sh", + ); + name = "Simulator Build Compat Symlink"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/bash; + shellScript = ". \"${SCRIPT_INPUT_FILE_0}\""; + }; + B122F0E81432B8E600AF95D0 /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "$(SRCROOT)/gen/asl_ipc.defs", - "$(SRCROOT)/xcodescripts/mig_headers.sh", ); - name = "Compile MIG Headers"; + name = "Generate libc-features.h"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = "/bin/bash -e"; - shellScript = ". \"${SCRIPT_INPUT_FILE_1}\""; + shellPath = /bin/sh; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C9194B4B140E3A7100BE0C3A /* Build Link Lists */ = { + C0E343821C5829F500E749C2 /* Symlink libc_dyld.a to libc.a */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/xcodescripts/skip_installhdrs.sh", + ); + name = "Symlink libc_dyld.a to libc.a"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = ". \"${SCRIPT_INPUT_FILE_0}\" /bin/ln -sf libc_dyld.a ${DSTROOT}${INSTALL_PATH}/libc.a"; + }; + C0E3438E1C582ECB00E749C2 /* Build Link List */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -9471,126 +9472,118 @@ inputPaths = ( "$(SRCROOT)/xcodescripts/build_linklists.sh", ); - name = "Build Link Lists"; + name = "Build Link List"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; shellScript = ". \"${SCRIPT_INPUT_FILE_0}\""; }; - C9258127138E3EC800B3107C /* Generate dtrace headers */ = { + C0E3438F1C582ECB00E749C2 /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "$(SRCROOT)/gen/magmallocProvider.d", - "$(SRCROOT)/pthreads/plockstat.d", ); - name = "Generate dtrace headers"; + name = "Generate libc-features.h"; outputPaths = ( - "$(DERIVED_FILE_DIR)/dtrace/magmallocProvider.h", - "$(DERIVED_FILE_DIR)/dtrace/plockstat.h", ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/bash; - shellScript = "dtrace -h -C -s ${SCRIPT_INPUT_FILE_0} -o ${SCRIPT_OUTPUT_FILE_0}\ndtrace -h -C -s ${SCRIPT_INPUT_FILE_1} -o ${SCRIPT_OUTPUT_FILE_1}"; + shellPath = /bin/sh; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C9265D1313B1CFD10090BA1C /* Clean Simulator Binaries */ = { + C0E343901C582ECB00E749C2 /* Patch Headers */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + buildActionMask = 2147483647; files = ( ); inputPaths = ( - "$(SRCROOT)/xcodescripts/clean_simulator.sh", ); - name = "Clean Simulator Binaries"; + name = "Patch Headers"; outputPaths = ( ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"\n"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/bash; + shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; showEnvVarsInLog = 0; }; - C93D6152143D321000EB9023 /* Sanitise Headers (rdar://problem/10241868) */ = { + C0E345E41C5830C200E749C2 /* Symlink libc.a to a loaderd path */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; files = ( ); inputPaths = ( - "$(SRCROOT)/xcodescripts/sanitise_headers.sh", + "$(SRCROOT)/xcodescripts/skip_installhdrs.sh", ); - name = "Sanitise Headers (rdar://problem/10241868)"; + name = "Symlink libc.a to a loaderd path"; outputPaths = ( + "${DSTROOT}/usr/local/lib/loaderd/libc.a", ); runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/bash; - shellScript = ". \"${SCRIPT_INPUT_FILE_0}\""; - showEnvVarsInLog = 0; + shellPath = /bin/sh; + shellScript = ". \"${SCRIPT_INPUT_FILE_0}\" /bin/ln -sf ../../../../${INSTALL_PATH}/libc.a ${DSTROOT}/usr/local/lib/loaderd/libc.a"; }; - C942102E13900C8A004BA536 /* Generate libc-features.h */ = { + C9194B4B140E3A7100BE0C3A /* Build Link Lists */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "$(SRCROOT)/xcodescripts/build_linklists.sh", ); - name = "Generate libc-features.h"; + name = "Build Link Lists"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; - showEnvVarsInLog = 0; + shellPath = /bin/bash; + shellScript = ". \"${SCRIPT_INPUT_FILE_0}\""; }; - C942102F13900C8A004BA536 /* Generate dtrace headers */ = { + C93D6152143D321000EB9023 /* Sanitise Headers (rdar://problem/10241868) */ = { isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 8; files = ( ); inputPaths = ( - "$(SRCROOT)/pthreads/plockstat.d", + "$(SRCROOT)/xcodescripts/sanitise_headers.sh", ); - name = "Generate dtrace headers"; + name = "Sanitise Headers (rdar://problem/10241868)"; outputPaths = ( - "$(DERIVED_FILE_DIR)/dtrace/plockstat.h", ); - runOnlyForDeploymentPostprocessing = 0; + runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/bash; - shellScript = "dtrace -h -C -s ${SCRIPT_INPUT_FILE_0} -o ${SCRIPT_OUTPUT_FILE_0}\n"; + shellScript = ". \"${SCRIPT_INPUT_FILE_0}\""; showEnvVarsInLog = 0; }; - C942103013900C8A004BA536 /* Patch Headers */ = { + C942102E13900C8A004BA536 /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Patch Headers"; + name = "Generate libc-features.h"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/bash; - shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; + shellPath = /bin/sh; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C94212DC13900FAA004BA536 /* Compile MIG Headers */ = { + C942103013900C8A004BA536 /* Patch Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "$(SRCROOT)/gen/asl_ipc.defs", - "$(SRCROOT)/xcodescripts/mig_headers.sh", ); - name = "Compile MIG Headers"; + name = "Patch Headers"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = "/bin/bash -e"; - shellScript = ". \"${SCRIPT_INPUT_FILE_1}\""; + shellPath = /bin/bash; + shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; showEnvVarsInLog = 0; }; C942135B13905EB9004BA536 /* Install Manpages */ = { @@ -9621,7 +9614,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; C95B7EDB138F3C55004311DA /* Patch Headers */ = { @@ -9636,7 +9629,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; + shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; showEnvVarsInLog = 0; }; C95B8185138F52B0004311DA /* Generate libc-features.h */ = { @@ -9651,7 +9644,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; C95B8186138F52B0004311DA /* Patch Headers */ = { @@ -9666,7 +9659,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; + shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; showEnvVarsInLog = 0; }; C95B842B138F53DB004311DA /* Generate libc-features.h */ = { @@ -9681,7 +9674,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; C95B842C138F53DB004311DA /* Patch Headers */ = { @@ -9696,7 +9689,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; + shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; showEnvVarsInLog = 0; }; C965CBF3143BBFF7003912CE /* Remove deps.c */ = { @@ -9726,7 +9719,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; + shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; showEnvVarsInLog = 0; }; C976616D138EF15900741512 /* Generate libc-features.h */ = { @@ -9741,71 +9734,71 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C9950E6B1390D2DC009863B6 /* Install Headers */ = { + C97A6F1F1517AF53005E1998 /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "$(SRCROOT)/xcodescripts/headers.sh", ); - name = "Install Headers"; + name = "Generate libc-features.h"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = "/bin/bash -e"; - shellScript = ". \"${SCRIPT_INPUT_FILE_0}\""; + shellPath = /bin/sh; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C9BD3C3C138F189200B389FD /* Generate libc-features.h */ = { + C97A6F221517AF53005E1998 /* Patch Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Generate libc-features.h"; + name = "Patch Headers"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellPath = /bin/bash; + shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; showEnvVarsInLog = 0; }; - C9BD3C3D138F189E00B389FD /* Generate libc-features.h */ = { + C9950E6B1390D2DC009863B6 /* Install Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "$(SRCROOT)/xcodescripts/headers.sh", ); - name = "Generate libc-features.h"; + name = "Install Headers"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellPath = "/bin/bash -e"; + shellScript = ". \"${SCRIPT_INPUT_FILE_0}\""; showEnvVarsInLog = 0; }; - C9BD3C3E138F18B200B389FD /* Generate libc-features.h */ = { + C9AE91C21517E17600A2626C /* Build Link List */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "$(SRCROOT)/xcodescripts/build_linklists.sh", ); - name = "Generate libc-features.h"; + name = "Build Link List"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; - showEnvVarsInLog = 0; + shellPath = /bin/bash; + shellScript = ". \"${SCRIPT_INPUT_FILE_0}\""; }; - C9BD3C3F138F18D200B389FD /* Generate libc-features.h */ = { + C9BD3C3C138F189200B389FD /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -9817,10 +9810,10 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C9EB2FCA138F6D880075BB52 /* Generate libc-features.h */ = { + C9BD3C3D138F189E00B389FD /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -9832,42 +9825,40 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C9EB2FCB138F6D880075BB52 /* Patch Headers */ = { + C9BD3C3E138F18B200B389FD /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Patch Headers"; + name = "Generate libc-features.h"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/bash; - shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; + shellPath = /bin/sh; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C9EB326B138F74600075BB52 /* Generate dtrace headers */ = { + C9BD3C3F138F18D200B389FD /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "$(SRCROOT)/pthreads/plockstat.d", ); - name = "Generate dtrace headers"; + name = "Generate libc-features.h"; outputPaths = ( - "$(DERIVED_FILE_DIR)/dtrace/plockstat.h", ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/bash; - shellScript = "dtrace -h -C -s ${SCRIPT_INPUT_FILE_0} -o ${SCRIPT_OUTPUT_FILE_0}\n"; + shellPath = /bin/sh; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C9EB3270138F75580075BB52 /* Generate libc-features.h */ = { + C9EB2FCA138F6D880075BB52 /* Generate libc-features.h */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -9879,24 +9870,37 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl"; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; - C9EB3271138F75580075BB52 /* Generate dtrace headers */ = { + C9EB2FCB138F6D880075BB52 /* Patch Headers */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "$(SRCROOT)/pthreads/plockstat.d", ); - name = "Generate dtrace headers"; + name = "Patch Headers"; outputPaths = ( - "$(DERIVED_FILE_DIR)/dtrace/plockstat.h", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "dtrace -h -C -s ${SCRIPT_INPUT_FILE_0} -o ${SCRIPT_OUTPUT_FILE_0}\n"; + shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; + showEnvVarsInLog = 0; + }; + C9EB3270138F75580075BB52 /* Generate libc-features.h */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Generate libc-features.h"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "perl \"$SRCROOT/xcodescripts/generate_features.pl\""; showEnvVarsInLog = 0; }; C9EB3272138F75580075BB52 /* Patch Headers */ = { @@ -9911,12 +9915,36 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; + shellScript = "perl \"${SRCROOT}/xcodescripts/patch_headers_variants.pl\" \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\""; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 3F51206C16C3174300AFB431 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3F51210F16C317FD00AFB431 /* strlcat_chk.c in Sources */, + 3F51210416C317FD00AFB431 /* chk_fail.c in Sources */, + 3F51210816C317FD00AFB431 /* memset_chk.c in Sources */, + 3F51211016C317FD00AFB431 /* strlcpy_chk.c in Sources */, + 3F51211116C317FD00AFB431 /* strncat_chk.c in Sources */, + 3F51211216C317FD00AFB431 /* strncpy_chk.c in Sources */, + 3F51210716C317FD00AFB431 /* memmove_chk.c in Sources */, + 3F51210E16C317FD00AFB431 /* strcpy_chk.c in Sources */, + 3F51210516C317FD00AFB431 /* memccpy_chk.c in Sources */, + 3F51210916C317FD00AFB431 /* snprintf_chk.c in Sources */, + 3F51210D16C317FD00AFB431 /* strcat_chk.c in Sources */, + 3F51211416C317FD00AFB431 /* vsprintf_chk.c in Sources */, + 3F51210B16C317FD00AFB431 /* stpcpy_chk.c in Sources */, + 3F51210A16C317FD00AFB431 /* sprintf_chk.c in Sources */, + 3F51210616C317FD00AFB431 /* memcpy_chk.c in Sources */, + 3F51210C16C317FD00AFB431 /* stpncpy_chk.c in Sources */, + 3F51211316C317FD00AFB431 /* vsnprintf_chk.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; B122F0E91432B8E600AF95D0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -9933,13 +9961,595 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B1E96342157E722200FCCEE7 /* Sources */ = { + C0E343911C582ECB00E749C2 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B1E96442157E722200FCCEE7 /* printf-pos.c in Sources */, - B1E9645F157E722200FCCEE7 /* vfprintf.c in Sources */, - B1E96461157E722200FCCEE7 /* vfwprintf.c in Sources */, + C0E343921C582ECB00E749C2 /* mcount.s in Sources */, + C0E343931C582ECB00E749C2 /* strcpy.s in Sources */, + C0E343941C582ECB00E749C2 /* strlcat.s in Sources */, + C0E343951C582ECB00E749C2 /* strlcpy.s in Sources */, + 928BD1011D76072200EC01FC /* timingsafe_bcmp.c in Sources */, + C0E343961C582ECB00E749C2 /* strlen.s in Sources */, + C0E343971C582ECB00E749C2 /* strncpy.s in Sources */, + C0E343981C582ECB00E749C2 /* strlen.s in Sources */, + C0E343991C582ECB00E749C2 /* strnlen.s in Sources */, + C0E3439A1C582ECB00E749C2 /* strstr.s in Sources */, + C0E3439B1C582ECB00E749C2 /* mcount.s in Sources */, + C0E3439C1C582ECB00E749C2 /* (null) in Sources */, + C0E3439D1C582ECB00E749C2 /* (null) in Sources */, + C0E3439E1C582ECB00E749C2 /* (null) in Sources */, + C0E3439F1C582ECB00E749C2 /* (null) in Sources */, + C0E343A01C582ECB00E749C2 /* init_cpu_capabilities.c in Sources */, + C0E343A11C582ECB00E749C2 /* creat.c in Sources */, + C0E343A21C582ECB00E749C2 /* gethostid.c in Sources */, + C0E343A31C582ECB00E749C2 /* getwd.c in Sources */, + C0E343A41C582ECB00E749C2 /* killpg.c in Sources */, + C0E343A51C582ECB00E749C2 /* sethostid.c in Sources */, + C0E343A61C582ECB00E749C2 /* setpgrp.c in Sources */, + C0E343A71C582ECB00E749C2 /* setrgid.c in Sources */, + C0E343A81C582ECB00E749C2 /* setruid.c in Sources */, + C0E343A91C582ECB00E749C2 /* setregid.c in Sources */, + C0E343AA1C582ECB00E749C2 /* setreuid.c in Sources */, + C0E343AB1C582ECB00E749C2 /* sigaltstk.c in Sources */, + C0E343AC1C582ECB00E749C2 /* sigcompat.c in Sources */, + C0E343AD1C582ECB00E749C2 /* kvm.c in Sources */, + C0E343AE1C582ECB00E749C2 /* forceLibcToBuild.c in Sources */, + C0E343AF1C582ECB00E749C2 /* bt_close.c in Sources */, + C0E343B01C582ECB00E749C2 /* bt_conv.c in Sources */, + C0E343B11C582ECB00E749C2 /* bt_debug.c in Sources */, + C0E343B21C582ECB00E749C2 /* bt_delete.c in Sources */, + C0E343B31C582ECB00E749C2 /* bt_get.c in Sources */, + C0E343B41C582ECB00E749C2 /* bt_open.c in Sources */, + C0E343B51C582ECB00E749C2 /* bt_overflow.c in Sources */, + C0E343B61C582ECB00E749C2 /* bt_page.c in Sources */, + C0E343B71C582ECB00E749C2 /* bt_put.c in Sources */, + C0E343B81C582ECB00E749C2 /* bt_search.c in Sources */, + C0E343B91C582ECB00E749C2 /* bt_seq.c in Sources */, + C0E343BA1C582ECB00E749C2 /* bt_split.c in Sources */, + C0E343BB1C582ECB00E749C2 /* bt_utils.c in Sources */, + C0E343BC1C582ECB00E749C2 /* db.c in Sources */, + C0E343BD1C582ECB00E749C2 /* hash.c in Sources */, + C0E343BE1C582ECB00E749C2 /* hash_bigkey.c in Sources */, + C0E343BF1C582ECB00E749C2 /* hash_buf.c in Sources */, + C0E343C01C582ECB00E749C2 /* hash_func.c in Sources */, + C0E343C11C582ECB00E749C2 /* hash_log2.c in Sources */, + C0E343C21C582ECB00E749C2 /* hash_page.c in Sources */, + C0E343C31C582ECB00E749C2 /* ndbm.c in Sources */, + C0E343C41C582ECB00E749C2 /* mpool.c in Sources */, + C0E343C51C582ECB00E749C2 /* rec_close.c in Sources */, + C0E343C61C582ECB00E749C2 /* rec_delete.c in Sources */, + C0E343C71C582ECB00E749C2 /* rec_get.c in Sources */, + C0E343C81C582ECB00E749C2 /* rec_open.c in Sources */, + C0E343C91C582ECB00E749C2 /* rec_put.c in Sources */, + C0E343CA1C582ECB00E749C2 /* rec_search.c in Sources */, + C0E343CB1C582ECB00E749C2 /* rec_seq.c in Sources */, + C0E343CC1C582ECB00E749C2 /* rec_utils.c in Sources */, + C0E343CD1C582ECB00E749C2 /* brk.c in Sources */, + C0E343CE1C582ECB00E749C2 /* bsd_signal.c in Sources */, + C0E343CF1C582ECB00E749C2 /* lchflags.c in Sources */, + C0E343D01C582ECB00E749C2 /* lchmod.c in Sources */, + C0E343D11C582ECB00E749C2 /* lutimes.c in Sources */, + C0E343D21C582ECB00E749C2 /* statvfs.c in Sources */, + C0E343D31C582ECB00E749C2 /* tcgetsid.c in Sources */, + C0E343D41C582ECB00E749C2 /* _ldbl_util.c in Sources */, + C0E343D51C582ECB00E749C2 /* _hdtoa.c in Sources */, + C0E343D61C582ECB00E749C2 /* _ldtoa.c in Sources */, + C0E343D71C582ECB00E749C2 /* gdtoa-dmisc.c in Sources */, + C0E343D81C582ECB00E749C2 /* gdtoa-dtoa.c in Sources */, + C0E343D91C582ECB00E749C2 /* gdtoa-gdtoa.c in Sources */, + C0E343DA1C582ECB00E749C2 /* gdtoa-gethex.c in Sources */, + C0E343DB1C582ECB00E749C2 /* gdtoa-gmisc.c in Sources */, + C0E343DC1C582ECB00E749C2 /* gdtoa-hd_init.c in Sources */, + C0E343DD1C582ECB00E749C2 /* gdtoa-hexnan.c in Sources */, + C0E343DE1C582ECB00E749C2 /* gdtoa-misc.c in Sources */, + C0E343DF1C582ECB00E749C2 /* gdtoa-smisc.c in Sources */, + C0E343E01C582ECB00E749C2 /* gdtoa-strtod.c in Sources */, + C0E343E11C582ECB00E749C2 /* gdtoa-strtodg.c in Sources */, + C0E343E21C582ECB00E749C2 /* gdtoa-strtof.c in Sources */, + C0E343E31C582ECB00E749C2 /* gdtoa-strtoIg.c in Sources */, + C0E343E41C582ECB00E749C2 /* gdtoa-strtopdd.c in Sources */, + C0E343E51C582ECB00E749C2 /* gdtoa-strtopx.c in Sources */, + C0E343E61C582ECB00E749C2 /* gdtoa-strtord.c in Sources */, + C0E343E71C582ECB00E749C2 /* gdtoa-sum.c in Sources */, + C0E343E81C582ECB00E749C2 /* gdtoa-ulp.c in Sources */, + C0E343E91C582ECB00E749C2 /* glue.c in Sources */, + C0E343EA1C582ECB00E749C2 /* machdep_ldisd.c in Sources */, + C0E343EB1C582ECB00E749C2 /* machdep_ldisdd.c in Sources */, + C0E343EC1C582ECB00E749C2 /* machdep_ldisQ.c in Sources */, + C0E343ED1C582ECB00E749C2 /* machdep_ldisx.c in Sources */, + C0E343EE1C582ECB00E749C2 /* authentication.c in Sources */, + C0E343EF1C582ECB00E749C2 /* backtrace.c in Sources */, + C0E343F01C582ECB00E749C2 /* confstr.c in Sources */, + C0E343F11C582ECB00E749C2 /* crypt.c in Sources */, + C0E343F21C582ECB00E749C2 /* devname.c in Sources */, + C0E343F31C582ECB00E749C2 /* disklabel.c in Sources */, + C0E343F41C582ECB00E749C2 /* errlst.c in Sources */, + C0E343F51C582ECB00E749C2 /* filesec.c in Sources */, + C0E343F61C582ECB00E749C2 /* _rand48.c in Sources */, + C0E343F71C582ECB00E749C2 /* alarm.c in Sources */, + C0E343F81C582ECB00E749C2 /* arc4random.c in Sources */, + C0E343F91C582ECB00E749C2 /* assert.c in Sources */, + C0E343FA1C582ECB00E749C2 /* basename.c in Sources */, + C0E343FB1C582ECB00E749C2 /* clock.c in Sources */, + C0E343FC1C582ECB00E749C2 /* closedir.c in Sources */, + C0E343FD1C582ECB00E749C2 /* ctermid.c in Sources */, + C0E343FE1C582ECB00E749C2 /* daemon.c in Sources */, + C0E343FF1C582ECB00E749C2 /* dirname.c in Sources */, + C0E344001C582ECB00E749C2 /* drand48.c in Sources */, + C0E344011C582ECB00E749C2 /* erand48.c in Sources */, + C0E344021C582ECB00E749C2 /* err.c in Sources */, + C0E344031C582ECB00E749C2 /* exec.c in Sources */, + C0E344041C582ECB00E749C2 /* fmtcheck.c in Sources */, + C0E344051C582ECB00E749C2 /* fmtmsg.c in Sources */, + C0E344061C582ECB00E749C2 /* fnmatch.c in Sources */, + C0E344071C582ECB00E749C2 /* ftok.c in Sources */, + C0E344081C582ECB00E749C2 /* getbsize.c in Sources */, + C0E344091C582ECB00E749C2 /* getcap.c in Sources */, + C0E3440A1C582ECB00E749C2 /* getcwd.c in Sources */, + C0E3440B1C582ECB00E749C2 /* gethostname.c in Sources */, + C0E3440C1C582ECB00E749C2 /* getlogin.c in Sources */, + C0E3440D1C582ECB00E749C2 /* getmntinfo.c in Sources */, + C0E3440E1C582ECB00E749C2 /* getpagesize.c in Sources */, + C0E3440F1C582ECB00E749C2 /* getpeereid.c in Sources */, + C0E344101C582ECB00E749C2 /* getprogname.c in Sources */, + C0E344111C582ECB00E749C2 /* glob.c in Sources */, + C0E344121C582ECB00E749C2 /* isatty.c in Sources */, + C0E344131C582ECB00E749C2 /* jrand48.c in Sources */, + C0E344141C582ECB00E749C2 /* lcong48.c in Sources */, + C0E344151C582ECB00E749C2 /* lockf.c in Sources */, + C0E344161C582ECB00E749C2 /* lrand48.c in Sources */, + C0E344171C582ECB00E749C2 /* mrand48.c in Sources */, + C0E344181C582ECB00E749C2 /* nice.c in Sources */, + C0E344191C582ECB00E749C2 /* nrand48.c in Sources */, + C0E3441A1C582ECB00E749C2 /* opendir.c in Sources */, + C0E3441B1C582ECB00E749C2 /* pause.c in Sources */, + C0E3441C1C582ECB00E749C2 /* popen.c in Sources */, + C0E3441D1C582ECB00E749C2 /* psignal.c in Sources */, + C0E3441E1C582ECB00E749C2 /* raise.c in Sources */, + C0E3441F1C582ECB00E749C2 /* readdir.c in Sources */, + C0E344201C582ECB00E749C2 /* readpassphrase.c in Sources */, + C0E344211C582ECB00E749C2 /* rewinddir.c in Sources */, + C0E344221C582ECB00E749C2 /* scandir.c in Sources */, + C0E344231C582ECB00E749C2 /* seed48.c in Sources */, + C0E344241C582ECB00E749C2 /* seekdir.c in Sources */, + C0E344251C582ECB00E749C2 /* sethostname.c in Sources */, + C0E344261C582ECB00E749C2 /* setmode.c in Sources */, + C0E344271C582ECB00E749C2 /* setprogname.c in Sources */, + C0E344281C582ECB00E749C2 /* siginterrupt.c in Sources */, + C0E344291C582ECB00E749C2 /* siglist.c in Sources */, + C0E3442A1C582ECB00E749C2 /* signal.c in Sources */, + C0E3442B1C582ECB00E749C2 /* sleep.c in Sources */, + C0E3442C1C582ECB00E749C2 /* srand48.c in Sources */, + C0E3442D1C582ECB00E749C2 /* stringlist.c in Sources */, + C0E3442E1C582ECB00E749C2 /* sysconf.c in Sources */, + C0E3442F1C582ECB00E749C2 /* sysctl.c in Sources */, + C0E344301C582ECB00E749C2 /* sysctlbyname.c in Sources */, + C0E344311C582ECB00E749C2 /* sysctlnametomib.c in Sources */, + C0E344321C582ECB00E749C2 /* telldir.c in Sources */, + C0E344331C582ECB00E749C2 /* termios.c in Sources */, + C0E344341C582ECB00E749C2 /* time.c in Sources */, + C0E344351C582ECB00E749C2 /* times.c in Sources */, + C0E344361C582ECB00E749C2 /* timezone.c in Sources */, + C0E344371C582ECB00E749C2 /* ttyname.c in Sources */, + C0E344381C582ECB00E749C2 /* ttyslot.c in Sources */, + C0E344391C582ECB00E749C2 /* ualarm.c in Sources */, + C0E3443A1C582ECB00E749C2 /* ulimit.c in Sources */, + C0E3443B1C582ECB00E749C2 /* unvis.c in Sources */, + C0E3443C1C582ECB00E749C2 /* usleep.c in Sources */, + C0E3443D1C582ECB00E749C2 /* utime.c in Sources */, + C0E3443E1C582ECB00E749C2 /* vis.c in Sources */, + C0E3443F1C582ECB00E749C2 /* wait.c in Sources */, + C0E344401C582ECB00E749C2 /* wait3.c in Sources */, + C0E344411C582ECB00E749C2 /* waitpid.c in Sources */, + C0E344421C582ECB00E749C2 /* fts.c in Sources */, + C0E344431C582ECB00E749C2 /* get_compat.c in Sources */, + C0E344441C582ECB00E749C2 /* getloadavg.c in Sources */, + C0E344451C582ECB00E749C2 /* getttyent.c in Sources */, + C0E344461C582ECB00E749C2 /* getusershell.c in Sources */, + C0E344471C582ECB00E749C2 /* getvfsbyname.c in Sources */, + C0E344481C582ECB00E749C2 /* nanosleep.c in Sources */, + C0E344491C582ECB00E749C2 /* utmpx.c in Sources */, + C0E3444A1C582ECB00E749C2 /* nftw.c in Sources */, + C0E3444B1C582ECB00E749C2 /* nlist.c in Sources */, + C0E3444C1C582ECB00E749C2 /* oldsyslog.c in Sources */, + C0E3444D1C582ECB00E749C2 /* setlogin.c in Sources */, + C0E3444E1C582ECB00E749C2 /* sigsetops.c in Sources */, + C0E3444F1C582ECB00E749C2 /* strtofflags.c in Sources */, + C0E344501C582ECB00E749C2 /* thread_stack_pcs.c in Sources */, + C0E344511C582ECB00E749C2 /* uname.c in Sources */, + C0E344521C582ECB00E749C2 /* utmpx-darwin.c in Sources */, + C0E344531C582ECB00E749C2 /* wordexp.c in Sources */, + C0E344541C582ECB00E749C2 /* gmon.c in Sources */, + C0E344551C582ECB00E749C2 /* ascii.c in Sources */, + C0E344561C582ECB00E749C2 /* big5.c in Sources */, + C0E344571C582ECB00E749C2 /* btowc.c in Sources */, + C0E344581C582ECB00E749C2 /* collate.c in Sources */, + C0E344591C582ECB00E749C2 /* collcmp.c in Sources */, + C0E3445A1C582ECB00E749C2 /* euc.c in Sources */, + C0E3445B1C582ECB00E749C2 /* fix_grouping.c in Sources */, + C0E3445C1C582ECB00E749C2 /* gb18030.c in Sources */, + C0E3445D1C582ECB00E749C2 /* gb2312.c in Sources */, + C0E3445E1C582ECB00E749C2 /* gbk.c in Sources */, + C0E3445F1C582ECB00E749C2 /* ldpart.c in Sources */, + C0E344601C582ECB00E749C2 /* lmessages.c in Sources */, + C0E344611C582ECB00E749C2 /* lmonetary.c in Sources */, + C0E344621C582ECB00E749C2 /* lnumeric.c in Sources */, + C0E344631C582ECB00E749C2 /* localeconv.c in Sources */, + C0E344641C582ECB00E749C2 /* mblen.c in Sources */, + C0E344651C582ECB00E749C2 /* mbrlen.c in Sources */, + C0E344661C582ECB00E749C2 /* mbrtowc.c in Sources */, + C0E344671C582ECB00E749C2 /* mbsinit.c in Sources */, + C0E344681C582ECB00E749C2 /* mbsnrtowcs.c in Sources */, + C0E344691C582ECB00E749C2 /* mbsrtowcs.c in Sources */, + C0E3446A1C582ECB00E749C2 /* mbstowcs.c in Sources */, + C0E3446B1C582ECB00E749C2 /* mbtowc.c in Sources */, + C0E3446C1C582ECB00E749C2 /* mskanji.c in Sources */, + C0E3446D1C582ECB00E749C2 /* nextwctype.c in Sources */, + C0E3446E1C582ECB00E749C2 /* nl_langinfo.c in Sources */, + C0E3446F1C582ECB00E749C2 /* nomacros.c in Sources */, + C0E344701C582ECB00E749C2 /* none.c in Sources */, + C0E344711C582ECB00E749C2 /* rune.c in Sources */, + C0E344721C582ECB00E749C2 /* runetype.c in Sources */, + C0E344731C582ECB00E749C2 /* setlocale.c in Sources */, + C0E344741C582ECB00E749C2 /* debug_private.c in Sources */, + C0E344751C582ECB00E749C2 /* setrunelocale.c in Sources */, + C0E344761C582ECB00E749C2 /* table.c in Sources */, + C0E344771C582ECB00E749C2 /* tolower.c in Sources */, + C0E344781C582ECB00E749C2 /* toupper.c in Sources */, + C0E344791C582ECB00E749C2 /* utf2.c in Sources */, + C0E3447A1C582ECB00E749C2 /* utf8.c in Sources */, + C0E3447B1C582ECB00E749C2 /* wcrtomb.c in Sources */, + C0E3447C1C582ECB00E749C2 /* wcsftime.c in Sources */, + C0E3447D1C582ECB00E749C2 /* wcsnrtombs.c in Sources */, + C0E3447E1C582ECB00E749C2 /* wcsrtombs.c in Sources */, + C0E3447F1C582ECB00E749C2 /* wcstod.c in Sources */, + C0E344801C582ECB00E749C2 /* wcstof.c in Sources */, + C0E344811C582ECB00E749C2 /* wcstoimax.c in Sources */, + C0E344821C582ECB00E749C2 /* wcstol.c in Sources */, + C0E344831C582ECB00E749C2 /* wcstold.c in Sources */, + C0E344841C582ECB00E749C2 /* wcstoll.c in Sources */, + C0E344851C582ECB00E749C2 /* wcstombs.c in Sources */, + C0E344861C582ECB00E749C2 /* wcstoul.c in Sources */, + C0E344871C582ECB00E749C2 /* wcstoull.c in Sources */, + C0E344881C582ECB00E749C2 /* wcstoumax.c in Sources */, + C0E344891C582ECB00E749C2 /* wctob.c in Sources */, + C0E3448A1C582ECB00E749C2 /* wctomb.c in Sources */, + C0E3448B1C582ECB00E749C2 /* wctrans.c in Sources */, + C0E3448C1C582ECB00E749C2 /* wctype.c in Sources */, + C0E3448D1C582ECB00E749C2 /* wcwidth.c in Sources */, + C0E3448E1C582ECB00E749C2 /* frune.c in Sources */, + C0E3448F1C582ECB00E749C2 /* isctype.c in Sources */, + C0E344901C582ECB00E749C2 /* iswctype.c in Sources */, + C0E344911C582ECB00E749C2 /* lconv.c in Sources */, + C0E344921C582ECB00E749C2 /* mbrune.c in Sources */, + C0E344931C582ECB00E749C2 /* runedepreciated.c in Sources */, + C0E344941C582ECB00E749C2 /* setinvalidrune.c in Sources */, + C0E344951C582ECB00E749C2 /* xlocale.c in Sources */, + C0E344961C582ECB00E749C2 /* addr2ascii.c in Sources */, + C0E344971C582ECB00E749C2 /* ascii2addr.c in Sources */, + C0E344981C582ECB00E749C2 /* inet_addr.c in Sources */, + C0E344991C582ECB00E749C2 /* inet_lnaof.c in Sources */, + C0E3449A1C582ECB00E749C2 /* inet_makeaddr.c in Sources */, + C0E3449B1C582ECB00E749C2 /* inet_net_ntop.c in Sources */, + C0E3449C1C582ECB00E749C2 /* inet_net_pton.c in Sources */, + C0E3449D1C582ECB00E749C2 /* inet_neta.c in Sources */, + C0E3449E1C582ECB00E749C2 /* inet_netof.c in Sources */, + C0E3449F1C582ECB00E749C2 /* inet_network.c in Sources */, + C0E344A01C582ECB00E749C2 /* inet_ntoa.c in Sources */, + C0E344A11C582ECB00E749C2 /* linkaddr.c in Sources */, + C0E344A21C582ECB00E749C2 /* nsap_addr.c in Sources */, + C0E344A31C582ECB00E749C2 /* recv.c in Sources */, + C0E344A41C582ECB00E749C2 /* send.c in Sources */, + C0E344A51C582ECB00E749C2 /* sockatmark.c in Sources */, + C0E344A61C582ECB00E749C2 /* sourcefilter.c in Sources */, + C0E344A71C582ECB00E749C2 /* msgcat.c in Sources */, + C0E344A81C582ECB00E749C2 /* acl.c in Sources */, + C0E344A91C582ECB00E749C2 /* acl_entry.c in Sources */, + C0E344AA1C582ECB00E749C2 /* acl_file.c in Sources */, + C0E344AB1C582ECB00E749C2 /* acl_flag.c in Sources */, + C0E344AC1C582ECB00E749C2 /* acl_perm.c in Sources */, + C0E344AD1C582ECB00E749C2 /* acl_translate.c in Sources */, + C0E344AE1C582ECB00E749C2 /* regerror.c in Sources */, + C0E344AF1C582ECB00E749C2 /* chk_fail.c in Sources */, + C0E344B01C582ECB00E749C2 /* memcpy_chk.c in Sources */, + C0E344B11C582ECB00E749C2 /* memmove_chk.c in Sources */, + C0E344B21C582ECB00E749C2 /* memset_chk.c in Sources */, + C0E344B31C582ECB00E749C2 /* snprintf_chk.c in Sources */, + C0E344B41C582ECB00E749C2 /* sprintf_chk.c in Sources */, + C0E344B51C582ECB00E749C2 /* stpcpy_chk.c in Sources */, + C0E344B61C582ECB00E749C2 /* stpncpy_chk.c in Sources */, + C0E344B71C582ECB00E749C2 /* strcat_chk.c in Sources */, + C0E344B81C582ECB00E749C2 /* strcpy_chk.c in Sources */, + C0E344B91C582ECB00E749C2 /* strlcat_chk.c in Sources */, + C0E344BA1C582ECB00E749C2 /* strlcpy_chk.c in Sources */, + C0E344BB1C582ECB00E749C2 /* strncat_chk.c in Sources */, + C0E344BC1C582ECB00E749C2 /* strncpy_chk.c in Sources */, + C0E344BD1C582ECB00E749C2 /* vsnprintf_chk.c in Sources */, + C0E344BE1C582ECB00E749C2 /* vsprintf_chk.c in Sources */, + C0E344BF1C582ECB00E749C2 /* _flock_stub.c in Sources */, + C0E344C01C582ECB00E749C2 /* asprintf.c in Sources */, + C0E344C11C582ECB00E749C2 /* clrerr.c in Sources */, + C0E344C21C582ECB00E749C2 /* dprintf.c in Sources */, + C0E344C31C582ECB00E749C2 /* fclose.c in Sources */, + C0E344C41C582ECB00E749C2 /* fdopen.c in Sources */, + C0E344C51C582ECB00E749C2 /* feof.c in Sources */, + C0E344C61C582ECB00E749C2 /* ferror.c in Sources */, + C0E344C71C582ECB00E749C2 /* fflush.c in Sources */, + C0E344C81C582ECB00E749C2 /* fgetc.c in Sources */, + C0E344C91C582ECB00E749C2 /* fgetln.c in Sources */, + C0E344CA1C582ECB00E749C2 /* fgetpos.c in Sources */, + C0E344CB1C582ECB00E749C2 /* fgets.c in Sources */, + C0E344CC1C582ECB00E749C2 /* fgetwc.c in Sources */, + C0E344CD1C582ECB00E749C2 /* fgetwln.c in Sources */, + C0E344CE1C582ECB00E749C2 /* fgetws.c in Sources */, + C0E344CF1C582ECB00E749C2 /* fileno.c in Sources */, + C0E344D01C582ECB00E749C2 /* findfp.c in Sources */, + C0E344D11C582ECB00E749C2 /* flags.c in Sources */, + C0E344D21C582ECB00E749C2 /* bcopy.c in Sources */, + C0E344D31C582ECB00E749C2 /* fopen.c in Sources */, + C0E344D41C582ECB00E749C2 /* fprintf.c in Sources */, + C0E344D51C582ECB00E749C2 /* fpurge.c in Sources */, + C0E344D61C582ECB00E749C2 /* fputc.c in Sources */, + C0E344D71C582ECB00E749C2 /* fputs.c in Sources */, + C0E344D81C582ECB00E749C2 /* fputwc.c in Sources */, + C0E344D91C582ECB00E749C2 /* fputws.c in Sources */, + C0E344DA1C582ECB00E749C2 /* fread.c in Sources */, + C0E344DB1C582ECB00E749C2 /* freopen.c in Sources */, + C0E344DC1C582ECB00E749C2 /* fscanf.c in Sources */, + C0E344DD1C582ECB00E749C2 /* fseek.c in Sources */, + C0E344DE1C582ECB00E749C2 /* fsetpos.c in Sources */, + C0E344DF1C582ECB00E749C2 /* ftell.c in Sources */, + C0E344E01C582ECB00E749C2 /* funopen.c in Sources */, + C0E344E11C582ECB00E749C2 /* fvwrite.c in Sources */, + C0E344E21C582ECB00E749C2 /* fwalk.c in Sources */, + C0E344E31C582ECB00E749C2 /* fwide.c in Sources */, + C0E344E41C582ECB00E749C2 /* fwprintf.c in Sources */, + C0E344E51C582ECB00E749C2 /* fwrite.c in Sources */, + C0E344E61C582ECB00E749C2 /* fwscanf.c in Sources */, + C0E344E71C582ECB00E749C2 /* getc.c in Sources */, + C0E344E81C582ECB00E749C2 /* getchar.c in Sources */, + C0E344E91C582ECB00E749C2 /* getdelim.c in Sources */, + C0E344EA1C582ECB00E749C2 /* getline.c in Sources */, + C0E344EB1C582ECB00E749C2 /* gets.c in Sources */, + C0E344EC1C582ECB00E749C2 /* getw.c in Sources */, + C0E344ED1C582ECB00E749C2 /* getwc.c in Sources */, + C0E344EE1C582ECB00E749C2 /* getwchar.c in Sources */, + C0E344EF1C582ECB00E749C2 /* makebuf.c in Sources */, + C0E344F01C582ECB00E749C2 /* mktemp.c in Sources */, + C0E344F11C582ECB00E749C2 /* perror.c in Sources */, + C0E344F21C582ECB00E749C2 /* printf-pos.c in Sources */, + C0E344F31C582ECB00E749C2 /* printf.c in Sources */, + C0E344F41C582ECB00E749C2 /* putc.c in Sources */, + C0E344F51C582ECB00E749C2 /* putchar.c in Sources */, + C0E344F61C582ECB00E749C2 /* puts.c in Sources */, + C0E344F71C582ECB00E749C2 /* putw.c in Sources */, + C0E344F81C582ECB00E749C2 /* putwc.c in Sources */, + C0E344F91C582ECB00E749C2 /* putwchar.c in Sources */, + C0E344FA1C582ECB00E749C2 /* refill.c in Sources */, + C0E344FB1C582ECB00E749C2 /* remove.c in Sources */, + C0E344FC1C582ECB00E749C2 /* rewind.c in Sources */, + C0E344FD1C582ECB00E749C2 /* rget.c in Sources */, + C0E344FE1C582ECB00E749C2 /* scanf.c in Sources */, + C0E344FF1C582ECB00E749C2 /* setbuf.c in Sources */, + C0E345001C582ECB00E749C2 /* setbuffer.c in Sources */, + C0E345011C582ECB00E749C2 /* setvbuf.c in Sources */, + C0E345021C582ECB00E749C2 /* snprintf.c in Sources */, + C0E345031C582ECB00E749C2 /* sprintf.c in Sources */, + C0E345041C582ECB00E749C2 /* sscanf.c in Sources */, + C0E345051C582ECB00E749C2 /* stdio.c in Sources */, + C0E345061C582ECB00E749C2 /* swprintf.c in Sources */, + C0E345071C582ECB00E749C2 /* swscanf.c in Sources */, + C0E345081C582ECB00E749C2 /* tempnam.c in Sources */, + C0E345091C582ECB00E749C2 /* tmpfile.c in Sources */, + C0E3450A1C582ECB00E749C2 /* tmpnam.c in Sources */, + C0E3450B1C582ECB00E749C2 /* ungetc.c in Sources */, + C0E3450C1C582ECB00E749C2 /* ungetwc.c in Sources */, + C0E3450D1C582ECB00E749C2 /* vasprintf.c in Sources */, + C0E3450E1C582ECB00E749C2 /* vdprintf.c in Sources */, + C0E3450F1C582ECB00E749C2 /* vfprintf.c in Sources */, + C0E345101C582ECB00E749C2 /* vfscanf.c in Sources */, + C0E345111C582ECB00E749C2 /* vfwprintf.c in Sources */, + C0E345121C582ECB00E749C2 /* vfwscanf.c in Sources */, + C0E345131C582ECB00E749C2 /* vprintf.c in Sources */, + C0E345141C582ECB00E749C2 /* vscanf.c in Sources */, + C0E345151C582ECB00E749C2 /* vsnprintf.c in Sources */, + C0E345161C582ECB00E749C2 /* vsprintf.c in Sources */, + C0E345171C582ECB00E749C2 /* vsscanf.c in Sources */, + C0E345181C582ECB00E749C2 /* vswprintf.c in Sources */, + C0E345191C582ECB00E749C2 /* vswscanf.c in Sources */, + C0E3451A1C582ECB00E749C2 /* vwprintf.c in Sources */, + C0E3451B1C582ECB00E749C2 /* vwscanf.c in Sources */, + C0E3451C1C582ECB00E749C2 /* wbuf.c in Sources */, + C0E3451D1C582ECB00E749C2 /* wprintf.c in Sources */, + C0E3451E1C582ECB00E749C2 /* wscanf.c in Sources */, + C0E3451F1C582ECB00E749C2 /* wsetup.c in Sources */, + C0E345201C582ECB00E749C2 /* a64l.c in Sources */, + C0E345211C582ECB00E749C2 /* _Exit_.c in Sources */, + C0E345221C582ECB00E749C2 /* abort.c in Sources */, + C0E345231C582ECB00E749C2 /* abs.c in Sources */, + C0E345241C582ECB00E749C2 /* atexit.c in Sources */, + C0E345251C582ECB00E749C2 /* atof.c in Sources */, + C0E345261C582ECB00E749C2 /* atoi.c in Sources */, + C0E345271C582ECB00E749C2 /* atol.c in Sources */, + C0E345281C582ECB00E749C2 /* atoll.c in Sources */, + C0E345291C582ECB00E749C2 /* bsearch.c in Sources */, + C0E3452A1C582ECB00E749C2 /* div.c in Sources */, + C0E3452B1C582ECB00E749C2 /* exit.c in Sources */, + C0E3452C1C582ECB00E749C2 /* getenv.c in Sources */, + C0E3452D1C582ECB00E749C2 /* getopt.c in Sources */, + C0E3452E1C582ECB00E749C2 /* getopt_long.c in Sources */, + C0E3452F1C582ECB00E749C2 /* getsubopt.c in Sources */, + C0E345301C582ECB00E749C2 /* hcreate.c in Sources */, + C0E345311C582ECB00E749C2 /* heapsort.c in Sources */, + C0E345321C582ECB00E749C2 /* heapsort_b.c in Sources */, + C0E345331C582ECB00E749C2 /* heapsort_r.c in Sources */, + C0E345341C582ECB00E749C2 /* imaxabs.c in Sources */, + C0E345351C582ECB00E749C2 /* imaxdiv.c in Sources */, + C0E345361C582ECB00E749C2 /* insque.c in Sources */, + C0E345371C582ECB00E749C2 /* labs.c in Sources */, + C0E345381C582ECB00E749C2 /* ldiv.c in Sources */, + C0E345391C582ECB00E749C2 /* llabs.c in Sources */, + C0E3453A1C582ECB00E749C2 /* lldiv.c in Sources */, + C0E3453B1C582ECB00E749C2 /* lsearch.c in Sources */, + C0E3453C1C582ECB00E749C2 /* merge.c in Sources */, + C0E3453D1C582ECB00E749C2 /* putenv.c in Sources */, + C0E3453E1C582ECB00E749C2 /* qsort.c in Sources */, + C0E3453F1C582ECB00E749C2 /* qsort_r.c in Sources */, + C0E345401C582ECB00E749C2 /* radixsort.c in Sources */, + C0E345411C582ECB00E749C2 /* rand.c in Sources */, + C0E345421C582ECB00E749C2 /* random.c in Sources */, + C0E345431C582ECB00E749C2 /* reallocf.c in Sources */, + C0E345441C582ECB00E749C2 /* realpath.c in Sources */, + C0E345451C582ECB00E749C2 /* remque.c in Sources */, + C0E345461C582ECB00E749C2 /* setenv.c in Sources */, + C0E345471C582ECB00E749C2 /* strhash.c in Sources */, + C0E345481C582ECB00E749C2 /* strtoimax.c in Sources */, + C0E345491C582ECB00E749C2 /* strtol.c in Sources */, + C0E3454A1C582ECB00E749C2 /* strtoll.c in Sources */, + C0E3454B1C582ECB00E749C2 /* strtoq.c in Sources */, + C0E3454C1C582ECB00E749C2 /* strtoul.c in Sources */, + C0E3454D1C582ECB00E749C2 /* strtoull.c in Sources */, + C0E3454E1C582ECB00E749C2 /* strtoumax.c in Sources */, + C0E3454F1C582ECB00E749C2 /* strtouq.c in Sources */, + C0E345501C582ECB00E749C2 /* system.c in Sources */, + C0E345511C582ECB00E749C2 /* tdelete.c in Sources */, + C0E345521C582ECB00E749C2 /* tfind.c in Sources */, + C0E345531C582ECB00E749C2 /* tsearch.c in Sources */, + C0E345541C582ECB00E749C2 /* twalk.c in Sources */, + C0E345551C582ECB00E749C2 /* grantpt.c in Sources */, + C0E345561C582ECB00E749C2 /* l64a.c in Sources */, + C0E345571C582ECB00E749C2 /* strfmon.c in Sources */, + C0E345581C582ECB00E749C2 /* ecvt.c in Sources */, + C0E345591C582ECB00E749C2 /* gcvt.c in Sources */, + C0E3455A1C582ECB00E749C2 /* qsort_b-fbsd.c in Sources */, + C0E3455B1C582ECB00E749C2 /* asctime.c in Sources */, + C0E3455C1C582ECB00E749C2 /* difftime.c in Sources */, + C0E3455D1C582ECB00E749C2 /* ftime.c in Sources */, + C0E3455E1C582ECB00E749C2 /* localtime.c in Sources */, + C0E3455F1C582ECB00E749C2 /* strftime.c in Sources */, + C0E345601C582ECB00E749C2 /* strptime.c in Sources */, + C0E345611C582ECB00E749C2 /* time32.c in Sources */, + C0E345621C582ECB00E749C2 /* timelocal.c in Sources */, + C0E345631C582ECB00E749C2 /* getdate.c in Sources */, + C0E345641C582ECB00E749C2 /* timezone_unix03.c in Sources */, + C0E345651C582ECB00E749C2 /* index.c in Sources */, + C0E345661C582ECB00E749C2 /* memmem.c in Sources */, + C0E345671C582ECB00E749C2 /* rindex.c in Sources */, + C0E345681C582ECB00E749C2 /* strcasecmp.c in Sources */, + C0E345691C582ECB00E749C2 /* strcasestr.c in Sources */, + C0E3456A1C582ECB00E749C2 /* strcoll.c in Sources */, + C0E3456B1C582ECB00E749C2 /* strcspn.c in Sources */, + C0E3456C1C582ECB00E749C2 /* strdup.c in Sources */, + C0E3456D1C582ECB00E749C2 /* strerror.c in Sources */, + C0E3456E1C582ECB00E749C2 /* strlen.c in Sources */, + C0E3456F1C582ECB00E749C2 /* strmode.c in Sources */, + C0E345701C582ECB00E749C2 /* strndup.c in Sources */, + C0E345711C582ECB00E749C2 /* strnlen.c in Sources */, + C0E345721C582ECB00E749C2 /* strnstr.c in Sources */, + C0E345731C582ECB00E749C2 /* strpbrk.c in Sources */, + C0E345741C582ECB00E749C2 /* strrchr.c in Sources */, + C0E345751C582ECB00E749C2 /* strsep.c in Sources */, + C0E345761C582ECB00E749C2 /* strsignal.c in Sources */, + C0E345771C582ECB00E749C2 /* strspn.c in Sources */, + C0E345781C582ECB00E749C2 /* strstr.c in Sources */, + C0E345791C582ECB00E749C2 /* strtok.c in Sources */, + C0E3457A1C582ECB00E749C2 /* strxfrm.c in Sources */, + C0E3457B1C582ECB00E749C2 /* swab.c in Sources */, + C0E3457C1C582ECB00E749C2 /* wcpcpy.c in Sources */, + C0E3457D1C582ECB00E749C2 /* wcpncpy.c in Sources */, + C0E3457E1C582ECB00E749C2 /* wcscasecmp.c in Sources */, + C0E3457F1C582ECB00E749C2 /* wcscat.c in Sources */, + C0E345801C582ECB00E749C2 /* wcschr.c in Sources */, + C0E345811C582ECB00E749C2 /* wcscmp.c in Sources */, + C0E345821C582ECB00E749C2 /* wcscoll.c in Sources */, + C0E345831C582ECB00E749C2 /* wcscpy.c in Sources */, + C0E345841C582ECB00E749C2 /* wcscspn.c in Sources */, + C0E345851C582ECB00E749C2 /* wcsdup.c in Sources */, + C0E345861C582ECB00E749C2 /* wcslcat.c in Sources */, + C0E345871C582ECB00E749C2 /* wcslcpy.c in Sources */, + C0E345881C582ECB00E749C2 /* wcslen.c in Sources */, + C0E345891C582ECB00E749C2 /* wcsncasecmp.c in Sources */, + C0E3458A1C582ECB00E749C2 /* wcsncat.c in Sources */, + C0E3458B1C582ECB00E749C2 /* wcsncmp.c in Sources */, + C0E3458C1C582ECB00E749C2 /* wcsncpy.c in Sources */, + C0E3458D1C582ECB00E749C2 /* wcsnlen.c in Sources */, + C0E3458E1C582ECB00E749C2 /* wcspbrk.c in Sources */, + C0E3458F1C582ECB00E749C2 /* wcsrchr.c in Sources */, + C0E345901C582ECB00E749C2 /* wcsspn.c in Sources */, + C0E345911C582ECB00E749C2 /* wcsstr.c in Sources */, + C0E345921C582ECB00E749C2 /* wcstok.c in Sources */, + C0E345931C582ECB00E749C2 /* wcswidth.c in Sources */, + C0E345941C582ECB00E749C2 /* wcsxfrm.c in Sources */, + C0E345951C582ECB00E749C2 /* wmemchr.c in Sources */, + C0E345961C582ECB00E749C2 /* wmemcmp.c in Sources */, + C0E345971C582ECB00E749C2 /* wmemcpy.c in Sources */, + C0E345981C582ECB00E749C2 /* wmemmove.c in Sources */, + C0E345991C582ECB00E749C2 /* wmemset.c in Sources */, + C0E3459A1C582ECB00E749C2 /* _libc_init.c in Sources */, + C0E3459B1C582ECB00E749C2 /* _libc_fork_child.c in Sources */, + C0E3459C1C582ECB00E749C2 /* chmodx_np.c in Sources */, + C0E3459D1C582ECB00E749C2 /* crt_externs.c in Sources */, + C0E3459E1C582ECB00E749C2 /* fork.c in Sources */, + C0E3459F1C582ECB00E749C2 /* getgroups.c in Sources */, + C0E345A01C582ECB00E749C2 /* gettimeofday.c in Sources */, + C0E345A11C582ECB00E749C2 /* msgctl.c in Sources */, + C0E345A21C582ECB00E749C2 /* stack_protector.c in Sources */, + C0E345A31C582ECB00E749C2 /* openx_np.c in Sources */, + C0E345A41C582ECB00E749C2 /* OSMemoryNotification.c in Sources */, + C0E345A51C582ECB00E749C2 /* OSThermalNotification.c in Sources */, + C0E345A61C582ECB00E749C2 /* posix_spawn.c in Sources */, + C0E345A71C582ECB00E749C2 /* semctl.c in Sources */, + C0E345A81C582ECB00E749C2 /* settimeofday.c in Sources */, + C0E345A91C582ECB00E749C2 /* shmctl.c in Sources */, + C0E345AA1C582ECB00E749C2 /* sigaction.c in Sources */, + C0E345AB1C582ECB00E749C2 /* (null) in Sources */, + C0E345AC1C582ECB00E749C2 /* statx_np.c in Sources */, + C0E345AD1C582ECB00E749C2 /* umaskx_np.c in Sources */, + C0E345AE1C582ECB00E749C2 /* fparseln.c in Sources */, + C0E345AF1C582ECB00E749C2 /* login.c in Sources */, + C0E345B01C582ECB00E749C2 /* login_tty.c in Sources */, + C0E345B11C582ECB00E749C2 /* logout.c in Sources */, + C0E345B21C582ECB00E749C2 /* logwtmp.c in Sources */, + C0E345B31C582ECB00E749C2 /* mkpath_np.c in Sources */, + C0E345B41C582ECB00E749C2 /* opendev.c in Sources */, + C0E345B51C582ECB00E749C2 /* pty.c in Sources */, + C0E345B61C582ECB00E749C2 /* clear.c in Sources */, + C0E345B71C582ECB00E749C2 /* compare.c in Sources */, + C0E345B81C582ECB00E749C2 /* copy.c in Sources */, + C0E345B91C582ECB00E749C2 /* gen_uuid.c in Sources */, + C0E345BA1C582ECB00E749C2 /* isnull.c in Sources */, + C0E345BB1C582ECB00E749C2 /* pack.c in Sources */, + C0E345BC1C582ECB00E749C2 /* parse.c in Sources */, + C0E345BD1C582ECB00E749C2 /* unpack.c in Sources */, + C0E345BE1C582ECB00E749C2 /* unparse.c in Sources */, + C0E345BF1C582ECB00E749C2 /* (null) in Sources */, + C0E345C01C582ECB00E749C2 /* (null) in Sources */, + C0E345C11C582ECB00E749C2 /* (null) in Sources */, + C0E345C21C582ECB00E749C2 /* (null) in Sources */, + C0E345C31C582ECB00E749C2 /* scandir_b.c in Sources */, + C0E345C41C582ECB00E749C2 /* init_cpu_capabilities.c in Sources */, + C0E345C51C582ECB00E749C2 /* pthread_getspecific.s in Sources */, + C0E345C61C582ECB00E749C2 /* pthread_self.s in Sources */, + C0E345C71C582ECB00E749C2 /* pthread_set_self.s in Sources */, + C0E345C81C582ECB00E749C2 /* start_wqthread.s in Sources */, + C0E345C91C582ECB00E749C2 /* thread_start.s in Sources */, + C0E345CA1C582ECB00E749C2 /* strcpy.c in Sources */, + C0E345CB1C582ECB00E749C2 /* strlcpy.c in Sources */, + C0E345CC1C582ECB00E749C2 /* strncpy.c in Sources */, + C0E345CD1C582ECB00E749C2 /* stpcpy.c in Sources */, + C0E345CE1C582ECB00E749C2 /* stpncpy.c in Sources */, + C0E345CF1C582ECB00E749C2 /* strcat.c in Sources */, + C0E345D01C582ECB00E749C2 /* strncat.c in Sources */, + C0E345D11C582ECB00E749C2 /* strlcat.c in Sources */, + C0E345D21C582ECB00E749C2 /* sync_volume_np.c in Sources */, + C0E345D31C582ECB00E749C2 /* dirfd.c in Sources */, + C0E345D41C582ECB00E749C2 /* eos_stubs.c in Sources */, + C0E345D51C582ECB00E749C2 /* strnlen.s in Sources */, + C0E345D61C582ECB00E749C2 /* assumes.c in Sources */, + C0E345D71C582ECB00E749C2 /* inet_ntop.c in Sources */, + C0E345D81C582ECB00E749C2 /* inet_pton.c in Sources */, + C0E345D91C582ECB00E749C2 /* memccpy_chk.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9985,6 +10595,7 @@ C9257EF8138E1C5D00B3107C /* rec_search.c in Sources */, C9257EF9138E1C5D00B3107C /* rec_seq.c in Sources */, C9257EFA138E1C5D00B3107C /* rec_utils.c in Sources */, + 928BD1021D76072C00EC01FC /* timingsafe_bcmp.c in Sources */, C9257EFB138E1C6A00B3107C /* _hdtoa.c in Sources */, C9257EFC138E1C6A00B3107C /* gdtoa-dmisc.c in Sources */, C9257EFD138E1C6A00B3107C /* gdtoa-dtoa.c in Sources */, @@ -10043,9 +10654,7 @@ C9257F33138E1C8200B3107C /* opendir.c in Sources */, C9257F34138E1C8200B3107C /* pause.c in Sources */, C9257F35138E1C8200B3107C /* popen.c in Sources */, - C9257F36138E1C8200B3107C /* pselect.c in Sources */, C9257F37138E1C8200B3107C /* psignal.c in Sources */, - C9257F38138E1C8200B3107C /* raise.c in Sources */, C9257F39138E1C8200B3107C /* readdir.c in Sources */, C9257F3A138E1C8200B3107C /* readpassphrase.c in Sources */, C9257F3B138E1C8200B3107C /* rewinddir.c in Sources */, @@ -10202,6 +10811,7 @@ C9257FD4138E1CC000B3107C /* makebuf.c in Sources */, C9257FD5138E1CC000B3107C /* mktemp.c in Sources */, C9257FD6138E1CC000B3107C /* perror.c in Sources */, + C9257FD7138E1CC000B3107C /* printf-pos.c in Sources */, C9257FD8138E1CC000B3107C /* printf.c in Sources */, C9257FD9138E1CC000B3107C /* putc.c in Sources */, C9257FDA138E1CC000B3107C /* putchar.c in Sources */, @@ -10230,7 +10840,9 @@ C9257FF1138E1CC000B3107C /* ungetwc.c in Sources */, C9257FF2138E1CC000B3107C /* vasprintf.c in Sources */, C9257FF3138E1CC000B3107C /* vdprintf.c in Sources */, + C9257FF4138E1CC000B3107C /* vfprintf.c in Sources */, C9257FF5138E1CC000B3107C /* vfscanf.c in Sources */, + C9257FF6138E1CC000B3107C /* vfwprintf.c in Sources */, C9257FF7138E1CC000B3107C /* vfwscanf.c in Sources */, C9257FF8138E1CC000B3107C /* vprintf.c in Sources */, C9257FF9138E1CC000B3107C /* vscanf.c in Sources */, @@ -10253,29 +10865,17 @@ C925800A138E1CC000B3107C /* strptime.c in Sources */, C925800B138E1CC000B3107C /* time32.c in Sources */, C925800C138E1CC000B3107C /* timelocal.c in Sources */, - C925800D138E1CD200B3107C /* bcmp.c in Sources */, - C925800E138E1CD200B3107C /* bcopy.c in Sources */, - C925800F138E1CD200B3107C /* bzero.c in Sources */, C9258010138E1CD200B3107C /* index.c in Sources */, - C9258011138E1CD200B3107C /* memccpy.c in Sources */, - C9258012138E1CD200B3107C /* memchr.c in Sources */, - C9258013138E1CD200B3107C /* memcmp.c in Sources */, - C9258014138E1CD200B3107C /* memcpy.c in Sources */, C9258015138E1CD200B3107C /* memmem.c in Sources */, - C9258016138E1CD200B3107C /* memmove.c in Sources */, - C9258017138E1CD200B3107C /* memset.c in Sources */, C9258018138E1CD200B3107C /* rindex.c in Sources */, C925801B138E1CD200B3107C /* strcasecmp.c in Sources */, C925801C138E1CD200B3107C /* strcasestr.c in Sources */, - C925801E138E1CD200B3107C /* strchr.c in Sources */, - C925801F138E1CD200B3107C /* strcmp.c in Sources */, C9258020138E1CD200B3107C /* strcoll.c in Sources */, C9258022138E1CD200B3107C /* strcspn.c in Sources */, C9258023138E1CD200B3107C /* strdup.c in Sources */, C9258024138E1CD200B3107C /* strerror.c in Sources */, C9258027138E1CD200B3107C /* strlen.c in Sources */, C9258028138E1CD200B3107C /* strmode.c in Sources */, - C925802A138E1CD200B3107C /* strncmp.c in Sources */, C925802C138E1CD200B3107C /* strndup.c in Sources */, C925802D138E1CD200B3107C /* strnlen.c in Sources */, C925802E138E1CD200B3107C /* strnstr.c in Sources */, @@ -10296,6 +10896,7 @@ C925803D138E1CD200B3107C /* wcscmp.c in Sources */, C925803E138E1CD200B3107C /* wcscoll.c in Sources */, C925803F138E1CD200B3107C /* wcscpy.c in Sources */, + B17726CD185A9AD600668DCA /* wordexp.c in Sources */, C9258040138E1CD200B3107C /* wcscspn.c in Sources */, C9258041138E1CD200B3107C /* wcsdup.c in Sources */, C9258042138E1CD200B3107C /* wcslcat.c in Sources */, @@ -10391,6 +10992,17 @@ C9EB2FC8138F6CE10075BB52 /* psort_r.c in Sources */, C9EB350F138F769B0075BB52 /* scandir_b.c in Sources */, C9EB3550138F7EA50075BB52 /* getmntinfo64.c in Sources */, + FC2ED612157D4BE80098EC69 /* inet_ntop.c in Sources */, + FC2ED61B157D4BE80098EC69 /* inet_pton.c in Sources */, + B12613F8158818EC0077E3CC /* xprintf_errno.c in Sources */, + B12613F9158818EC0077E3CC /* xprintf_float.c in Sources */, + B12613FA158818EC0077E3CC /* xprintf_hexdump.c in Sources */, + B12613FB158818EC0077E3CC /* xprintf_int.c in Sources */, + B12613FC158818EC0077E3CC /* xprintf_quote.c in Sources */, + B12613FD158818EC0077E3CC /* xprintf_str.c in Sources */, + B12613FE158818EC0077E3CC /* xprintf_time.c in Sources */, + B12613FF158818EC0077E3CC /* xprintf_vis.c in Sources */, + B1261400158818EC0077E3CC /* xprintf.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -10400,6 +11012,8 @@ files = ( C92580CC138E2D3100B3107C /* utmpx.c in Sources */, C9FA334D138E4D0C0089A94B /* strfmon.c in Sources */, + 3F18DE21162A732C008B15AC /* memset_s.c in Sources */, + 3F267F38163FC8880089A0A6 /* rb.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -10407,116 +11021,20 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C94213311390396E004BA536 /* _ctx_start.S in Sources */, - C94213321390396E004BA536 /* _setcontext.S in Sources */, - C94213331390396E004BA536 /* cpu_number.s in Sources */, - C94213341390396E004BA536 /* getcontext.S in Sources */, - C94213351390396E004BA536 /* icacheinval.s in Sources */, C94213361390396E004BA536 /* mcount.s in Sources */, - C94213371390396E004BA536 /* preempt.s in Sources */, - C94213381390396E004BA536 /* pthread_getspecific.s in Sources */, - C94213391390396E004BA536 /* pthread_mutex_lock.s in Sources */, - C942133A1390396E004BA536 /* pthread_self.s in Sources */, - C942133B1390396E004BA536 /* pthread_set_self.s in Sources */, - C942133C1390396E004BA536 /* start_wqthread.s in Sources */, - C942133D1390396E004BA536 /* thread_start.s in Sources */, - C942133E1390396E004BA536 /* __bzero.s in Sources */, - C942133F1390396E004BA536 /* bcopy_scalar.s in Sources */, - C94213401390396E004BA536 /* bcopy_sse2.s in Sources */, - C94213411390396E004BA536 /* bcopy_sse3x.s in Sources */, - C94213421390396E004BA536 /* bcopy_sse42.s in Sources */, - C94213431390396E004BA536 /* bzero_scalar.s in Sources */, - C94213441390396E004BA536 /* bzero_sse2.s in Sources */, - C94213451390396E004BA536 /* bzero_sse42.s in Sources */, - C94213461390396E004BA536 /* ffs.s in Sources */, - C94213471390396E004BA536 /* longcopy_sse3x.s in Sources */, - C94213481390396E004BA536 /* memcmp.s in Sources */, - C94213491390396E004BA536 /* memset.s in Sources */, - C942134A1390396E004BA536 /* memset_pattern_sse2.s in Sources */, - C942134B1390396E004BA536 /* strcmp.s in Sources */, C942134C1390396E004BA536 /* strcpy.s in Sources */, C942134D1390396E004BA536 /* strlcat.s in Sources */, C942134E1390396E004BA536 /* strlcpy.s in Sources */, C942134F1390396E004BA536 /* strlen.s in Sources */, - C94213501390396E004BA536 /* strncmp.s in Sources */, C94213511390396E004BA536 /* strncpy.s in Sources */, - C94213521390396E004BA536 /* _setjmp.s in Sources */, - C94213531390396E004BA536 /* _sigtramp.s in Sources */, - C94213541390396E004BA536 /* i386_gettimeofday_asm.s in Sources */, - C94213551390396E004BA536 /* mach_absolute_time_asm.s in Sources */, - C94213561390396E004BA536 /* OSAtomic.s in Sources */, - C94213571390396E004BA536 /* setjmp.s in Sources */, - C94213581390396E004BA536 /* spinlocks_asm.s in Sources */, - C942130A13903959004BA536 /* cpu_number.s in Sources */, - C942130B13903959004BA536 /* icacheinval.s in Sources */, - C942130C13903959004BA536 /* pthread_getspecific.s in Sources */, - C942130D13903959004BA536 /* pthread_self.s in Sources */, - C942130E13903959004BA536 /* pthread_set_self.s in Sources */, - C942130F13903959004BA536 /* start_wqthread.s in Sources */, - C942131013903959004BA536 /* thread_start.s in Sources */, - C942131313903959004BA536 /* bcopy_Generic.s in Sources */, - C942131613903959004BA536 /* bzero_Generic.s in Sources */, - C942131713903959004BA536 /* ffs.s in Sources */, - C942131813903959004BA536 /* memcmp.s in Sources */, - C942131913903959004BA536 /* memset_pattern.s in Sources */, - C942131A13903959004BA536 /* strchr.s in Sources */, - C942131B13903959004BA536 /* strcmp.s in Sources */, C942131E13903959004BA536 /* strlen.s in Sources */, - C942131F13903959004BA536 /* strncmp.s in Sources */, C942132113903959004BA536 /* strnlen.s in Sources */, C942132213903959004BA536 /* strstr.s in Sources */, - C942132313903959004BA536 /* _longjmp.s in Sources */, - C942132413903959004BA536 /* _setjmp.h in Sources */, - C942132513903959004BA536 /* _setjmp.s in Sources */, - C942132613903959004BA536 /* longjmp.s in Sources */, - C942132713903959004BA536 /* mach_absolute_time.s in Sources */, - C942132913903959004BA536 /* OSAtomic_resolvers.h in Sources */, - C942132A13903959004BA536 /* setjmp.s in Sources */, - C94212DE13901595004BA536 /* _ctx_start.S in Sources */, - C94212DF13901595004BA536 /* _setcontext.S in Sources */, - C94212E013901595004BA536 /* cpu_number.s in Sources */, - C94212E113901595004BA536 /* getcontext.S in Sources */, - C94212E213901595004BA536 /* icacheinval.s in Sources */, C94212E413901595004BA536 /* mcount.s in Sources */, - C94212E513901595004BA536 /* setjmperr.c in Sources */, - C94212E713901595004BA536 /* preempt.s in Sources */, - C94212E813901595004BA536 /* pthread_getspecific.s in Sources */, - C94212E913901595004BA536 /* pthread_mutex_lock.s in Sources */, - C94212EA13901595004BA536 /* pthread_self.s in Sources */, - C94212EB13901595004BA536 /* pthread_set_self.s in Sources */, - C94212EC13901595004BA536 /* start_wqthread.s in Sources */, - C94212ED13901595004BA536 /* thread_start.s in Sources */, - C94212EF13901595004BA536 /* __bzero.s in Sources */, - C94212F013901595004BA536 /* bcopy_sse3x.s in Sources */, - C94212F113901595004BA536 /* bcopy_sse42.s in Sources */, - C94212F213901595004BA536 /* bzero_sse2.s in Sources */, - C94212F313901595004BA536 /* bzero_sse42.s in Sources */, - C94212F413901595004BA536 /* ffs.s in Sources */, - C94212F513901595004BA536 /* longcopy_sse3x.s in Sources */, - C94212F713901595004BA536 /* memcmp.s in Sources */, - C94212F813901595004BA536 /* memset.s in Sources */, - C94212F913901595004BA536 /* strcmp.s in Sources */, C94212FA13901595004BA536 /* strcpy.s in Sources */, - C94212FB13901595004BA536 /* strlcat.s in Sources */, - C94212FC13901595004BA536 /* strlcpy.s in Sources */, C94212FD13901595004BA536 /* strlen.s in Sources */, - C94212FE13901595004BA536 /* strncmp.s in Sources */, C94212FF13901595004BA536 /* strncpy.s in Sources */, - C942130013901595004BA536 /* _setjmp.s in Sources */, - C942130113901595004BA536 /* _sigtramp.s in Sources */, - C942130213901595004BA536 /* i386_gettimeofday_asm.s in Sources */, - C942130413901595004BA536 /* nanotime.s in Sources */, - C942130513901595004BA536 /* OSAtomic.s in Sources */, - C942130613901595004BA536 /* setjmp.s in Sources */, - C942130713901595004BA536 /* spinlocks_asm.s in Sources */, - C94212D113900ED1004BA536 /* dirhelper.defs in Sources */, - C94212D213900ED1004BA536 /* asl_ipc.defs in Sources */, C942103213900C8A004BA536 /* init_cpu_capabilities.c in Sources */, - C942103313900C8A004BA536 /* dyld_resolvers.c in Sources */, - C942103413900C8A004BA536 /* arm_commpage_gettimeofday.c in Sources */, - C942103513900C8A004BA536 /* gcc_atomic.c in Sources */, - C942103613900C8A004BA536 /* OSAtomic-v4.c in Sources */, - C942103713900C8A004BA536 /* OSAtomic_resolvers.c in Sources */, C942103913900C8A004BA536 /* creat.c in Sources */, C942103A13900C8A004BA536 /* gethostid.c in Sources */, C942103B13900C8A004BA536 /* getwd.c in Sources */, @@ -10529,11 +11047,7 @@ C942104213900C8A004BA536 /* setreuid.c in Sources */, C942104313900C8A004BA536 /* sigaltstk.c in Sources */, C942104413900C8A004BA536 /* sigcompat.c in Sources */, - C942104513900C8A004BA536 /* _dirhelper.c in Sources */, C942104613900C8A004BA536 /* kvm.c in Sources */, - C942104713900C8A004BA536 /* libproc.c in Sources */, - C942104813900C8A004BA536 /* MKGetTimeBaseInfo.c in Sources */, - C942104913900C8A004BA536 /* proc_listpidspath.c in Sources */, C942104A13900C8A004BA536 /* forceLibcToBuild.c in Sources */, C942104B13900C8A004BA536 /* bt_close.c in Sources */, C942104C13900C8A004BA536 /* bt_conv.c in Sources */, @@ -10598,18 +11112,8 @@ C942108713900C8A004BA536 /* machdep_ldisdd.c in Sources */, C942108813900C8A004BA536 /* machdep_ldisQ.c in Sources */, C942108913900C8A004BA536 /* machdep_ldisx.c in Sources */, - C942108A13900C8A004BA536 /* _simple.c in Sources */, - C942108B13900C8A004BA536 /* asl.c in Sources */, - C942108C13900C8A004BA536 /* asl_core.c in Sources */, - C942108D13900C8A004BA536 /* asl_file.c in Sources */, - C942108E13900C8A004BA536 /* asl_legacy1.c in Sources */, - C942108F13900C8A004BA536 /* asl_msg.c in Sources */, - C942109013900C8A004BA536 /* asl_store.c in Sources */, - C942109113900C8A004BA536 /* asl_util.c in Sources */, - C942109213900C8A004BA536 /* assumes.c in Sources */, C942109313900C8A004BA536 /* authentication.c in Sources */, C942109413900C8A004BA536 /* backtrace.c in Sources */, - C942109513900C8A004BA536 /* cache.c in Sources */, C942109613900C8A004BA536 /* confstr.c in Sources */, C942109713900C8A004BA536 /* crypt.c in Sources */, C942109813900C8A004BA536 /* devname.c in Sources */, @@ -10626,6 +11130,7 @@ C94210A313900C8A004BA536 /* ctermid.c in Sources */, C94210A413900C8A004BA536 /* daemon.c in Sources */, C94210A513900C8A004BA536 /* dirname.c in Sources */, + 3FD14574171D42B300B7BAF5 /* bcopy.c in Sources */, C94210A613900C8A004BA536 /* drand48.c in Sources */, C94210A713900C8A004BA536 /* erand48.c in Sources */, C94210A813900C8A004BA536 /* err.c in Sources */, @@ -10655,7 +11160,6 @@ C94210C013900C8A004BA536 /* opendir.c in Sources */, C94210C113900C8A004BA536 /* pause.c in Sources */, C94210C213900C8A004BA536 /* popen.c in Sources */, - C94210C313900C8A004BA536 /* pselect.c in Sources */, C94210C413900C8A004BA536 /* psignal.c in Sources */, C94210C513900C8A004BA536 /* raise.c in Sources */, C94210C613900C8A004BA536 /* readdir.c in Sources */, @@ -10699,42 +11203,20 @@ C94210EC13900C8A004BA536 /* getttyent.c in Sources */, C94210ED13900C8A004BA536 /* getusershell.c in Sources */, C94210EE13900C8A004BA536 /* getvfsbyname.c in Sources */, - C94210EF13900C8A004BA536 /* isinf.c in Sources */, - C94210F013900C8A004BA536 /* isnan.c in Sources */, - C94210F113900C8A004BA536 /* magazine_malloc.c in Sources */, - C94210F213900C8A004BA536 /* malloc.c in Sources */, C94210F313900C8A004BA536 /* nanosleep.c in Sources */, C94210F413900C8A004BA536 /* utmpx.c in Sources */, + 147CDFD91B7C232100831EC6 /* clock_gettime.c in Sources */, C94210F513900C8A004BA536 /* nftw.c in Sources */, C94210F613900C8A004BA536 /* nlist.c in Sources */, - C94210F713900C8A004BA536 /* NSSystemDirectories.c in Sources */, C94210F813900C8A004BA536 /* oldsyslog.c in Sources */, - C94210F913900C8A004BA536 /* platfunc.c in Sources */, - C94210FA13900C8A004BA536 /* scalable_malloc.c in Sources */, C94210FB13900C8A004BA536 /* setlogin.c in Sources */, C94210FC13900C8A004BA536 /* sigsetops.c in Sources */, - C94210FD13900C8A004BA536 /* stack_logging.c in Sources */, - C94210FE13900C8A004BA536 /* stack_logging_disk.c in Sources */, C94210FF13900C8A004BA536 /* strtofflags.c in Sources */, - C942110013900C8A004BA536 /* syslog.c in Sources */, C942110113900C8A004BA536 /* thread_stack_pcs.c in Sources */, C942110213900C8A004BA536 /* uname.c in Sources */, C942110313900C8A004BA536 /* utmpx-darwin.c in Sources */, C942110413900C8A004BA536 /* wordexp.c in Sources */, C942110613900C8A004BA536 /* gmon.c in Sources */, - C942110713900C8A004BA536 /* getmcontext.c in Sources */, - C942110813900C8A004BA536 /* makecontext.c in Sources */, - C942110913900C8A004BA536 /* setcontext.c in Sources */, - C942110A13900C8A004BA536 /* setjmperr.c in Sources */, - C942110B13900C8A004BA536 /* swapcontext.c in Sources */, - C942110C13900C8A004BA536 /* init_cpu_capabilities.c in Sources */, - C942110D13900C8A004BA536 /* bcopy.c in Sources */, - C942110E13900C8A004BA536 /* bzero.c in Sources */, - C942110F13900C8A004BA536 /* memcpy.c in Sources */, - C942111013900C8A004BA536 /* memmove.c in Sources */, - C942111113900C8A004BA536 /* atomic.c in Sources */, - C942111213900C8A004BA536 /* mach_absolute_time.c in Sources */, - C942111313900C8A004BA536 /* spinlocks.c in Sources */, C942112613900C8A004BA536 /* ascii.c in Sources */, C942112713900C8A004BA536 /* big5.c in Sources */, C942112813900C8A004BA536 /* btowc.c in Sources */, @@ -10803,6 +11285,7 @@ C942116713900C8A004BA536 /* ascii2addr.c in Sources */, C942116813900C8A004BA536 /* inet_addr.c in Sources */, C942116913900C8A004BA536 /* inet_lnaof.c in Sources */, + 2DF67CDE184F9CBE00B83A3D /* debug_private.c in Sources */, C942116A13900C8A004BA536 /* inet_makeaddr.c in Sources */, C942116B13900C8A004BA536 /* inet_net_ntop.c in Sources */, C942116C13900C8A004BA536 /* inet_net_pton.c in Sources */, @@ -10823,30 +11306,7 @@ C942117B13900C8A004BA536 /* acl_flag.c in Sources */, C942117C13900C8A004BA536 /* acl_perm.c in Sources */, C942117D13900C8A004BA536 /* acl_translate.c in Sources */, - C942118613900C8A004BA536 /* mk_pthread_impl.c in Sources */, - C942118713900C8A004BA536 /* pthread.c in Sources */, - C942118813900C8A004BA536 /* pthread_cancelable.c in Sources */, - C942118913900C8A004BA536 /* pthread_cond.c in Sources */, - C942118A13900C8A004BA536 /* pthread_mutex.c in Sources */, - C942118B13900C8A004BA536 /* pthread_rwlock.c in Sources */, - C942118C13900C8A004BA536 /* pthread_tsd.c in Sources */, - C942118D13900C8A004BA536 /* pthread_atfork_test.c in Sources */, - C942118E13900C8A004BA536 /* thread_setup.c in Sources */, C942119113900C8A004BA536 /* regerror.c in Sources */, - C942119413900C8A004BA536 /* chk_fail.c in Sources */, - C942119513900C8A004BA536 /* memcpy_chk.c in Sources */, - C942119613900C8A004BA536 /* memmove_chk.c in Sources */, - C942119713900C8A004BA536 /* memset_chk.c in Sources */, - C942119813900C8A004BA536 /* snprintf_chk.c in Sources */, - C942119913900C8A004BA536 /* sprintf_chk.c in Sources */, - C942119A13900C8A004BA536 /* stpcpy_chk.c in Sources */, - C942119B13900C8A004BA536 /* stpncpy_chk.c in Sources */, - C942119C13900C8A004BA536 /* strcat_chk.c in Sources */, - C942119D13900C8A004BA536 /* strcpy_chk.c in Sources */, - C942119E13900C8A004BA536 /* strncat_chk.c in Sources */, - C942119F13900C8A004BA536 /* strncpy_chk.c in Sources */, - C94211A013900C8A004BA536 /* vsnprintf_chk.c in Sources */, - C94211A113900C8A004BA536 /* vsprintf_chk.c in Sources */, C94211A213900C8A004BA536 /* _flock_stub.c in Sources */, C94211A313900C8A004BA536 /* asprintf.c in Sources */, C94211A413900C8A004BA536 /* clrerr.c in Sources */, @@ -10890,6 +11350,7 @@ C94211CA13900C8A004BA536 /* getchar.c in Sources */, C94211CB13900C8A004BA536 /* getdelim.c in Sources */, C94211CC13900C8A004BA536 /* getline.c in Sources */, + 928BD1001D76072200EC01FC /* timingsafe_bcmp.c in Sources */, C94211CD13900C8A004BA536 /* gets.c in Sources */, C94211CE13900C8A004BA536 /* getw.c in Sources */, C94211CF13900C8A004BA536 /* getwc.c in Sources */, @@ -11012,29 +11473,17 @@ C942124413900C8A004BA536 /* timelocal.c in Sources */, C942124513900C8A004BA536 /* getdate.c in Sources */, C942124613900C8A004BA536 /* timezone_unix03.c in Sources */, - C942124713900C8A004BA536 /* bcmp.c in Sources */, - C942124813900C8A004BA536 /* bcopy.c in Sources */, - C942124913900C8A004BA536 /* bzero.c in Sources */, C942124A13900C8A004BA536 /* index.c in Sources */, - C942124B13900C8A004BA536 /* memccpy.c in Sources */, - C942124C13900C8A004BA536 /* memchr.c in Sources */, - C942124D13900C8A004BA536 /* memcmp.c in Sources */, - C942124E13900C8A004BA536 /* memcpy.c in Sources */, C942124F13900C8A004BA536 /* memmem.c in Sources */, - C942125013900C8A004BA536 /* memmove.c in Sources */, - C942125113900C8A004BA536 /* memset.c in Sources */, C942125213900C8A004BA536 /* rindex.c in Sources */, C942125513900C8A004BA536 /* strcasecmp.c in Sources */, C942125613900C8A004BA536 /* strcasestr.c in Sources */, - C942125813900C8A004BA536 /* strchr.c in Sources */, - C942125913900C8A004BA536 /* strcmp.c in Sources */, C942125A13900C8A004BA536 /* strcoll.c in Sources */, C942125C13900C8A004BA536 /* strcspn.c in Sources */, C942125D13900C8A004BA536 /* strdup.c in Sources */, C942125E13900C8A004BA536 /* strerror.c in Sources */, C942126113900C8A004BA536 /* strlen.c in Sources */, C942126213900C8A004BA536 /* strmode.c in Sources */, - C942126413900C8A004BA536 /* strncmp.c in Sources */, C942126613900C8A004BA536 /* strndup.c in Sources */, C942126713900C8A004BA536 /* strnlen.c in Sources */, C942126813900C8A004BA536 /* strnstr.c in Sources */, @@ -11077,15 +11526,12 @@ C942128D13900C8A004BA536 /* wmemcpy.c in Sources */, C942128E13900C8A004BA536 /* wmemmove.c in Sources */, C942128F13900C8A004BA536 /* wmemset.c in Sources */, - C942129013900C8A004BA536 /* __libc_init.c in Sources */, + C942129013900C8A004BA536 /* _libc_init.c in Sources */, C942129113900C8A004BA536 /* _libc_fork_child.c in Sources */, C942129213900C8A004BA536 /* chmodx_np.c in Sources */, - C942129313900C8A004BA536 /* context-stubs.c in Sources */, C942129413900C8A004BA536 /* crt_externs.c in Sources */, - C942129513900C8A004BA536 /* errno.c in Sources */, C942129613900C8A004BA536 /* fork.c in Sources */, C942129713900C8A004BA536 /* getgroups.c in Sources */, - C942129813900C8A004BA536 /* getiopolicy_np.c in Sources */, C942129913900C8A004BA536 /* gettimeofday.c in Sources */, C942129A13900C8A004BA536 /* msgctl.c in Sources */, C942129B13900C8A004BA536 /* stack_protector.c in Sources */, @@ -11097,14 +11543,8 @@ C94212A113900C8A004BA536 /* settimeofday.c in Sources */, C94212A213900C8A004BA536 /* shmctl.c in Sources */, C94212A313900C8A004BA536 /* sigaction.c in Sources */, - C94212A413900C8A004BA536 /* sigcatch.c in Sources */, - C94212A513900C8A004BA536 /* sigtramp.c in Sources */, - C94212A613900C8A004BA536 /* slot_name.c in Sources */, C94212A713900C8A004BA536 /* statx_np.c in Sources */, C94212A813900C8A004BA536 /* umaskx_np.c in Sources */, - C94212A913900C8A004BA536 /* cprocs.c in Sources */, - C94212AA13900C8A004BA536 /* cthreads.c in Sources */, - C94212AB13900C8A004BA536 /* mig_support.c in Sources */, C94212AC13900C8A004BA536 /* fparseln.c in Sources */, C94212AD13900C8A004BA536 /* login.c in Sources */, C94212AE13900C8A004BA536 /* login_tty.c in Sources */, @@ -11122,22 +11562,13 @@ C94212B913900C8A004BA536 /* parse.c in Sources */, C94212BA13900C8A004BA536 /* unpack.c in Sources */, C94212BB13900C8A004BA536 /* unparse.c in Sources */, - C94212BC13900C8A004BA536 /* getmcontext.c in Sources */, - C94212BD13900C8A004BA536 /* makecontext.c in Sources */, - C94212BE13900C8A004BA536 /* setcontext.c in Sources */, - C94212BF13900C8A004BA536 /* swapcontext.c in Sources */, - C94212C013900C8A004BA536 /* bcopy.c in Sources */, - C94212C113900C8A004BA536 /* bzero.c in Sources */, - C94212C213900C8A004BA536 /* memcpy.c in Sources */, - C94212C313900C8A004BA536 /* memmove.c in Sources */, - C94212C413900C8A004BA536 /* atomic.c in Sources */, - C94212C513900C8A004BA536 /* spinlocks.c in Sources */, C94212C613900C8A004BA536 /* scandir_b.c in Sources */, - C932C2D313AB20C8004EDA12 /* OSAtomicUP.c in Sources */, - C932C2D413AB20C8004EDA12 /* Spinlocks.c in Sources */, - C932C2D513AB20C8004EDA12 /* SpinlocksUP.c in Sources */, - C932C2D613AB20C8004EDA12 /* SpinlocksWFE.c in Sources */, - C9B4E3DE13BBCE5F0008A9BB /* OSAtomic.c in Sources */, + C98E2B4C139851B7002A3ABB /* init_cpu_capabilities.c in Sources */, + C98E2B4D139851B7002A3ABB /* pthread_getspecific.s in Sources */, + C98E2B4E139851B7002A3ABB /* pthread_self.s in Sources */, + C98E2B4F139851B7002A3ABB /* pthread_set_self.s in Sources */, + C98E2B50139851B7002A3ABB /* start_wqthread.s in Sources */, + C98E2B51139851B7002A3ABB /* thread_start.s in Sources */, 6310518713D4D966004F7BA8 /* strcpy.c in Sources */, 6310518C13D4DABD004F7BA8 /* strlcpy.c in Sources */, 6310518F13D4DAEA004F7BA8 /* strncpy.c in Sources */, @@ -11146,9 +11577,13 @@ 63D4060D13DDF26A0094DD56 /* strcat.c in Sources */, 63D4061013DDF4340094DD56 /* strncat.c in Sources */, 63D4061313DDF6A30094DD56 /* strlcat.c in Sources */, - 3F2208E814358B4A00386F5B /* asl_fd.c in Sources */, B19C645C1450F90200032373 /* sync_volume_np.c in Sources */, 3FD4D48E1472F4B200075CCE /* dirfd.c in Sources */, + 63505E3B1548525D00B637D7 /* strnlen.s in Sources */, + 4B2C64A315519BC300342BFA /* assumes.c in Sources */, + FC2ED610157D4BE80098EC69 /* inet_ntop.c in Sources */, + FC2ED619157D4BE80098EC69 /* inet_pton.c in Sources */, + 639D126A15595DDE00D0403A /* strnlen.s in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -11157,11 +11592,6 @@ buildActionMask = 2147483647; files = ( C95B7EDD138F3C55004311DA /* init_cpu_capabilities.c in Sources */, - C95B7EDE138F3C55004311DA /* dyld_resolvers.c in Sources */, - C95B7EDF138F3C55004311DA /* arm_commpage_gettimeofday.c in Sources */, - C95B7EE0138F3C55004311DA /* gcc_atomic.c in Sources */, - C95B7EE1138F3C55004311DA /* OSAtomic-v4.c in Sources */, - C95B7EE2138F3C55004311DA /* OSAtomic_resolvers.c in Sources */, C95B7EE4138F3C55004311DA /* creat.c in Sources */, C95B7EE5138F3C55004311DA /* gethostid.c in Sources */, C95B7EE6138F3C55004311DA /* getwd.c in Sources */, @@ -11174,11 +11604,7 @@ C95B7EED138F3C55004311DA /* setreuid.c in Sources */, C95B7EEE138F3C55004311DA /* sigaltstk.c in Sources */, C95B7EEF138F3C55004311DA /* sigcompat.c in Sources */, - C95B7EF0138F3C55004311DA /* _dirhelper.c in Sources */, C95B7EF1138F3C55004311DA /* kvm.c in Sources */, - C95B7EF2138F3C55004311DA /* libproc.c in Sources */, - C95B7EF3138F3C55004311DA /* MKGetTimeBaseInfo.c in Sources */, - C95B7EF4138F3C55004311DA /* proc_listpidspath.c in Sources */, C95B7EF5138F3C55004311DA /* forceLibcToBuild.c in Sources */, C95B7EF6138F3C55004311DA /* bt_close.c in Sources */, C95B7EF7138F3C55004311DA /* bt_conv.c in Sources */, @@ -11243,24 +11669,15 @@ C95B7F32138F3C55004311DA /* machdep_ldisdd.c in Sources */, C95B7F33138F3C55004311DA /* machdep_ldisQ.c in Sources */, C95B7F34138F3C55004311DA /* machdep_ldisx.c in Sources */, - C95B7F35138F3C55004311DA /* _simple.c in Sources */, - C95B7F36138F3C55004311DA /* asl.c in Sources */, - C95B7F37138F3C55004311DA /* asl_core.c in Sources */, - C95B7F38138F3C55004311DA /* asl_file.c in Sources */, - C95B7F39138F3C55004311DA /* asl_legacy1.c in Sources */, - C95B7F3A138F3C55004311DA /* asl_msg.c in Sources */, - C95B7F3B138F3C55004311DA /* asl_store.c in Sources */, - C95B7F3C138F3C55004311DA /* asl_util.c in Sources */, - C95B7F3D138F3C55004311DA /* assumes.c in Sources */, C95B7F3E138F3C55004311DA /* authentication.c in Sources */, C95B7F3F138F3C55004311DA /* backtrace.c in Sources */, - C95B7F40138F3C55004311DA /* cache.c in Sources */, C95B7F41138F3C55004311DA /* confstr.c in Sources */, C95B7F42138F3C55004311DA /* crypt.c in Sources */, C95B7F43138F3C55004311DA /* devname.c in Sources */, C95B7F44138F3C55004311DA /* disklabel.c in Sources */, C95B7F45138F3C55004311DA /* errlst.c in Sources */, C95B7F46138F3C55004311DA /* filesec.c in Sources */, + 147CDFDD1B7C233000831EC6 /* clock_gettime.c in Sources */, C95B7F47138F3C55004311DA /* _rand48.c in Sources */, C95B7F48138F3C55004311DA /* alarm.c in Sources */, C95B7F49138F3C55004311DA /* arc4random.c in Sources */, @@ -11300,7 +11717,6 @@ C95B7F6B138F3C55004311DA /* opendir.c in Sources */, C95B7F6C138F3C55004311DA /* pause.c in Sources */, C95B7F6D138F3C55004311DA /* popen.c in Sources */, - C95B7F6E138F3C55004311DA /* pselect.c in Sources */, C95B7F6F138F3C55004311DA /* psignal.c in Sources */, C95B7F70138F3C55004311DA /* raise.c in Sources */, C95B7F71138F3C55004311DA /* readdir.c in Sources */, @@ -11344,42 +11760,19 @@ C95B7F97138F3C55004311DA /* getttyent.c in Sources */, C95B7F98138F3C55004311DA /* getusershell.c in Sources */, C95B7F99138F3C55004311DA /* getvfsbyname.c in Sources */, - C95B7F9A138F3C55004311DA /* isinf.c in Sources */, - C95B7F9B138F3C55004311DA /* isnan.c in Sources */, - C95B7F9C138F3C55004311DA /* magazine_malloc.c in Sources */, - C95B7F9D138F3C55004311DA /* malloc.c in Sources */, C95B7F9E138F3C55004311DA /* nanosleep.c in Sources */, C95B7F9F138F3C55004311DA /* utmpx.c in Sources */, C95B7FA0138F3C55004311DA /* nftw.c in Sources */, C95B7FA1138F3C55004311DA /* nlist.c in Sources */, - C95B7FA2138F3C55004311DA /* NSSystemDirectories.c in Sources */, C95B7FA3138F3C55004311DA /* oldsyslog.c in Sources */, - C95B7FA4138F3C55004311DA /* platfunc.c in Sources */, - C95B7FA5138F3C55004311DA /* scalable_malloc.c in Sources */, C95B7FA6138F3C55004311DA /* setlogin.c in Sources */, C95B7FA7138F3C55004311DA /* sigsetops.c in Sources */, - C95B7FA8138F3C55004311DA /* stack_logging.c in Sources */, - C95B7FA9138F3C55004311DA /* stack_logging_disk.c in Sources */, C95B7FAA138F3C55004311DA /* strtofflags.c in Sources */, - C95B7FAB138F3C55004311DA /* syslog.c in Sources */, C95B7FAC138F3C55004311DA /* thread_stack_pcs.c in Sources */, C95B7FAD138F3C55004311DA /* uname.c in Sources */, C95B7FAE138F3C55004311DA /* utmpx-darwin.c in Sources */, C95B7FAF138F3C55004311DA /* wordexp.c in Sources */, C95B7FB1138F3C55004311DA /* gmon.c in Sources */, - C95B7FB2138F3C55004311DA /* getmcontext.c in Sources */, - C95B7FB3138F3C55004311DA /* makecontext.c in Sources */, - C95B7FB4138F3C55004311DA /* setcontext.c in Sources */, - C95B7FB5138F3C55004311DA /* setjmperr.c in Sources */, - C95B7FB6138F3C55004311DA /* swapcontext.c in Sources */, - C95B7FB7138F3C55004311DA /* init_cpu_capabilities.c in Sources */, - C95B7FB8138F3C55004311DA /* bcopy.c in Sources */, - C95B7FB9138F3C55004311DA /* bzero.c in Sources */, - C95B7FBA138F3C55004311DA /* memcpy.c in Sources */, - C95B7FBB138F3C55004311DA /* memmove.c in Sources */, - C95B7FBC138F3C55004311DA /* atomic.c in Sources */, - C95B7FBD138F3C55004311DA /* mach_absolute_time.c in Sources */, - C95B7FBE138F3C55004311DA /* spinlocks.c in Sources */, C95B7FD1138F3C55004311DA /* ascii.c in Sources */, C95B7FD2138F3C55004311DA /* big5.c in Sources */, C95B7FD3138F3C55004311DA /* btowc.c in Sources */, @@ -11468,30 +11861,7 @@ C95B8026138F3C55004311DA /* acl_flag.c in Sources */, C95B8027138F3C55004311DA /* acl_perm.c in Sources */, C95B8028138F3C55004311DA /* acl_translate.c in Sources */, - C95B8031138F3C55004311DA /* mk_pthread_impl.c in Sources */, - C95B8032138F3C55004311DA /* pthread.c in Sources */, - C95B8033138F3C55004311DA /* pthread_cancelable.c in Sources */, - C95B8034138F3C55004311DA /* pthread_cond.c in Sources */, - C95B8035138F3C55004311DA /* pthread_mutex.c in Sources */, - C95B8036138F3C55004311DA /* pthread_rwlock.c in Sources */, - C95B8037138F3C55004311DA /* pthread_tsd.c in Sources */, - C95B8038138F3C55004311DA /* pthread_atfork_test.c in Sources */, - C95B8039138F3C55004311DA /* thread_setup.c in Sources */, C95B803C138F3C55004311DA /* regerror.c in Sources */, - C95B803F138F3C55004311DA /* chk_fail.c in Sources */, - C95B8040138F3C55004311DA /* memcpy_chk.c in Sources */, - C95B8041138F3C55004311DA /* memmove_chk.c in Sources */, - C95B8042138F3C55004311DA /* memset_chk.c in Sources */, - C95B8043138F3C55004311DA /* snprintf_chk.c in Sources */, - C95B8044138F3C55004311DA /* sprintf_chk.c in Sources */, - C95B8045138F3C55004311DA /* stpcpy_chk.c in Sources */, - C95B8046138F3C55004311DA /* stpncpy_chk.c in Sources */, - C95B8047138F3C55004311DA /* strcat_chk.c in Sources */, - C95B8048138F3C55004311DA /* strcpy_chk.c in Sources */, - C95B8049138F3C55004311DA /* strncat_chk.c in Sources */, - C95B804A138F3C55004311DA /* strncpy_chk.c in Sources */, - C95B804B138F3C55004311DA /* vsnprintf_chk.c in Sources */, - C95B804C138F3C55004311DA /* vsprintf_chk.c in Sources */, C95B804D138F3C55004311DA /* _flock_stub.c in Sources */, C95B804E138F3C55004311DA /* asprintf.c in Sources */, C95B804F138F3C55004311DA /* clrerr.c in Sources */, @@ -11535,6 +11905,7 @@ C95B8075138F3C55004311DA /* getchar.c in Sources */, C95B8076138F3C55004311DA /* getdelim.c in Sources */, C95B8077138F3C55004311DA /* getline.c in Sources */, + 928BD1041D76073400EC01FC /* timingsafe_bcmp.c in Sources */, C95B8078138F3C55004311DA /* gets.c in Sources */, C95B8079138F3C55004311DA /* getw.c in Sources */, C95B807A138F3C55004311DA /* getwc.c in Sources */, @@ -11657,29 +12028,17 @@ C95B80EF138F3C55004311DA /* timelocal.c in Sources */, C95B80F0138F3C55004311DA /* getdate.c in Sources */, C95B80F1138F3C55004311DA /* timezone_unix03.c in Sources */, - C95B80F2138F3C55004311DA /* bcmp.c in Sources */, - C95B80F3138F3C55004311DA /* bcopy.c in Sources */, - C95B80F4138F3C55004311DA /* bzero.c in Sources */, C95B80F5138F3C55004311DA /* index.c in Sources */, - C95B80F6138F3C55004311DA /* memccpy.c in Sources */, - C95B80F7138F3C55004311DA /* memchr.c in Sources */, - C95B80F8138F3C55004311DA /* memcmp.c in Sources */, - C95B80F9138F3C55004311DA /* memcpy.c in Sources */, C95B80FA138F3C55004311DA /* memmem.c in Sources */, - C95B80FB138F3C55004311DA /* memmove.c in Sources */, - C95B80FC138F3C55004311DA /* memset.c in Sources */, C95B80FD138F3C55004311DA /* rindex.c in Sources */, C95B8100138F3C55004311DA /* strcasecmp.c in Sources */, C95B8101138F3C55004311DA /* strcasestr.c in Sources */, - C95B8103138F3C55004311DA /* strchr.c in Sources */, - C95B8104138F3C55004311DA /* strcmp.c in Sources */, C95B8105138F3C55004311DA /* strcoll.c in Sources */, C95B8107138F3C55004311DA /* strcspn.c in Sources */, C95B8108138F3C55004311DA /* strdup.c in Sources */, C95B8109138F3C55004311DA /* strerror.c in Sources */, C95B810C138F3C55004311DA /* strlen.c in Sources */, C95B810D138F3C55004311DA /* strmode.c in Sources */, - C95B810F138F3C55004311DA /* strncmp.c in Sources */, C95B8111138F3C55004311DA /* strndup.c in Sources */, C95B8112138F3C55004311DA /* strnlen.c in Sources */, C95B8113138F3C55004311DA /* strnstr.c in Sources */, @@ -11720,17 +12079,15 @@ C95B8136138F3C55004311DA /* wmemchr.c in Sources */, C95B8137138F3C55004311DA /* wmemcmp.c in Sources */, C95B8138138F3C55004311DA /* wmemcpy.c in Sources */, + 2DF67CE2184F9CBE00B83A3D /* debug_private.c in Sources */, C95B8139138F3C55004311DA /* wmemmove.c in Sources */, C95B813A138F3C55004311DA /* wmemset.c in Sources */, - C95B813B138F3C55004311DA /* __libc_init.c in Sources */, + C95B813B138F3C55004311DA /* _libc_init.c in Sources */, C95B813C138F3C55004311DA /* _libc_fork_child.c in Sources */, C95B813D138F3C55004311DA /* chmodx_np.c in Sources */, - C95B813E138F3C55004311DA /* context-stubs.c in Sources */, C95B813F138F3C55004311DA /* crt_externs.c in Sources */, - C95B8140138F3C55004311DA /* errno.c in Sources */, C95B8141138F3C55004311DA /* fork.c in Sources */, C95B8142138F3C55004311DA /* getgroups.c in Sources */, - C95B8143138F3C55004311DA /* getiopolicy_np.c in Sources */, C95B8144138F3C55004311DA /* gettimeofday.c in Sources */, C95B8145138F3C55004311DA /* msgctl.c in Sources */, C95B8146138F3C55004311DA /* stack_protector.c in Sources */, @@ -11742,14 +12099,8 @@ C95B814C138F3C55004311DA /* settimeofday.c in Sources */, C95B814D138F3C55004311DA /* shmctl.c in Sources */, C95B814E138F3C55004311DA /* sigaction.c in Sources */, - C95B814F138F3C55004311DA /* sigcatch.c in Sources */, - C95B8150138F3C55004311DA /* sigtramp.c in Sources */, - C95B8151138F3C55004311DA /* slot_name.c in Sources */, C95B8152138F3C55004311DA /* statx_np.c in Sources */, C95B8153138F3C55004311DA /* umaskx_np.c in Sources */, - C95B8154138F3C55004311DA /* cprocs.c in Sources */, - C95B8155138F3C55004311DA /* cthreads.c in Sources */, - C95B8156138F3C55004311DA /* mig_support.c in Sources */, C95B8157138F3C55004311DA /* fparseln.c in Sources */, C95B8158138F3C55004311DA /* login.c in Sources */, C95B8159138F3C55004311DA /* login_tty.c in Sources */, @@ -11767,19 +12118,11 @@ C95B8164138F3C55004311DA /* parse.c in Sources */, C95B8165138F3C55004311DA /* unpack.c in Sources */, C95B8166138F3C55004311DA /* unparse.c in Sources */, - C95B8167138F3C55004311DA /* getmcontext.c in Sources */, - C95B8168138F3C55004311DA /* makecontext.c in Sources */, - C95B8169138F3C55004311DA /* setcontext.c in Sources */, - C95B816A138F3C55004311DA /* swapcontext.c in Sources */, - C95B816B138F3C55004311DA /* bcopy.c in Sources */, - C95B816C138F3C55004311DA /* bzero.c in Sources */, - C95B816D138F3C55004311DA /* memcpy.c in Sources */, - C95B816E138F3C55004311DA /* memmove.c in Sources */, - C95B816F138F3C55004311DA /* atomic.c in Sources */, - C95B8170138F3C55004311DA /* spinlocks.c in Sources */, - 3F2208EB14358B4A00386F5B /* asl_fd.c in Sources */, B19C645F1450F90200032373 /* sync_volume_np.c in Sources */, 3FB7E1B7146EF2E000843438 /* dirfd.c in Sources */, + 4B2C64A615519BC600342BFA /* assumes.c in Sources */, + FC2ED614157D4BE80098EC69 /* inet_ntop.c in Sources */, + FC2ED61D157D4BE80098EC69 /* inet_pton.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -11788,11 +12131,6 @@ buildActionMask = 2147483647; files = ( C95B8188138F52B0004311DA /* init_cpu_capabilities.c in Sources */, - C95B8189138F52B0004311DA /* dyld_resolvers.c in Sources */, - C95B818A138F52B0004311DA /* arm_commpage_gettimeofday.c in Sources */, - C95B818B138F52B0004311DA /* gcc_atomic.c in Sources */, - C95B818C138F52B0004311DA /* OSAtomic-v4.c in Sources */, - C95B818D138F52B0004311DA /* OSAtomic_resolvers.c in Sources */, C95B818F138F52B0004311DA /* creat.c in Sources */, C95B8190138F52B0004311DA /* gethostid.c in Sources */, C95B8191138F52B0004311DA /* getwd.c in Sources */, @@ -11805,11 +12143,7 @@ C95B8198138F52B0004311DA /* setreuid.c in Sources */, C95B8199138F52B0004311DA /* sigaltstk.c in Sources */, C95B819A138F52B0004311DA /* sigcompat.c in Sources */, - C95B819B138F52B0004311DA /* _dirhelper.c in Sources */, C95B819C138F52B0004311DA /* kvm.c in Sources */, - C95B819D138F52B0004311DA /* libproc.c in Sources */, - C95B819E138F52B0004311DA /* MKGetTimeBaseInfo.c in Sources */, - C95B819F138F52B0004311DA /* proc_listpidspath.c in Sources */, C95B81A0138F52B0004311DA /* forceLibcToBuild.c in Sources */, C95B81A1138F52B0004311DA /* bt_close.c in Sources */, C95B81A2138F52B0004311DA /* bt_conv.c in Sources */, @@ -11874,24 +12208,15 @@ C95B81DD138F52B0004311DA /* machdep_ldisdd.c in Sources */, C95B81DE138F52B0004311DA /* machdep_ldisQ.c in Sources */, C95B81DF138F52B0004311DA /* machdep_ldisx.c in Sources */, - C95B81E0138F52B0004311DA /* _simple.c in Sources */, - C95B81E1138F52B0004311DA /* asl.c in Sources */, - C95B81E2138F52B0004311DA /* asl_core.c in Sources */, - C95B81E3138F52B0004311DA /* asl_file.c in Sources */, - C95B81E4138F52B0004311DA /* asl_legacy1.c in Sources */, - C95B81E5138F52B0004311DA /* asl_msg.c in Sources */, - C95B81E6138F52B0004311DA /* asl_store.c in Sources */, - C95B81E7138F52B0004311DA /* asl_util.c in Sources */, - C95B81E8138F52B0004311DA /* assumes.c in Sources */, C95B81E9138F52B0004311DA /* authentication.c in Sources */, C95B81EA138F52B0004311DA /* backtrace.c in Sources */, - C95B81EB138F52B0004311DA /* cache.c in Sources */, C95B81EC138F52B0004311DA /* confstr.c in Sources */, C95B81ED138F52B0004311DA /* crypt.c in Sources */, C95B81EE138F52B0004311DA /* devname.c in Sources */, C95B81EF138F52B0004311DA /* disklabel.c in Sources */, C95B81F0138F52B0004311DA /* errlst.c in Sources */, C95B81F1138F52B0004311DA /* filesec.c in Sources */, + 147CDFDE1B7C233100831EC6 /* clock_gettime.c in Sources */, C95B81F2138F52B0004311DA /* _rand48.c in Sources */, C95B81F3138F52B0004311DA /* alarm.c in Sources */, C95B81F4138F52B0004311DA /* arc4random.c in Sources */, @@ -11931,7 +12256,6 @@ C95B8216138F52B0004311DA /* opendir.c in Sources */, C95B8217138F52B0004311DA /* pause.c in Sources */, C95B8218138F52B0004311DA /* popen.c in Sources */, - C95B8219138F52B0004311DA /* pselect.c in Sources */, C95B821A138F52B0004311DA /* psignal.c in Sources */, C95B821B138F52B0004311DA /* raise.c in Sources */, C95B821C138F52B0004311DA /* readdir.c in Sources */, @@ -11975,42 +12299,19 @@ C95B8242138F52B0004311DA /* getttyent.c in Sources */, C95B8243138F52B0004311DA /* getusershell.c in Sources */, C95B8244138F52B0004311DA /* getvfsbyname.c in Sources */, - C95B8245138F52B0004311DA /* isinf.c in Sources */, - C95B8246138F52B0004311DA /* isnan.c in Sources */, - C95B8247138F52B0004311DA /* magazine_malloc.c in Sources */, - C95B8248138F52B0004311DA /* malloc.c in Sources */, C95B8249138F52B0004311DA /* nanosleep.c in Sources */, C95B824A138F52B0004311DA /* utmpx.c in Sources */, C95B824B138F52B0004311DA /* nftw.c in Sources */, C95B824C138F52B0004311DA /* nlist.c in Sources */, - C95B824D138F52B0004311DA /* NSSystemDirectories.c in Sources */, C95B824E138F52B0004311DA /* oldsyslog.c in Sources */, - C95B824F138F52B0004311DA /* platfunc.c in Sources */, - C95B8250138F52B0004311DA /* scalable_malloc.c in Sources */, C95B8251138F52B0004311DA /* setlogin.c in Sources */, C95B8252138F52B0004311DA /* sigsetops.c in Sources */, - C95B8253138F52B0004311DA /* stack_logging.c in Sources */, - C95B8254138F52B0004311DA /* stack_logging_disk.c in Sources */, C95B8255138F52B0004311DA /* strtofflags.c in Sources */, - C95B8256138F52B0004311DA /* syslog.c in Sources */, C95B8257138F52B0004311DA /* thread_stack_pcs.c in Sources */, C95B8258138F52B0004311DA /* uname.c in Sources */, C95B8259138F52B0004311DA /* utmpx-darwin.c in Sources */, C95B825A138F52B0004311DA /* wordexp.c in Sources */, C95B825C138F52B0004311DA /* gmon.c in Sources */, - C95B825D138F52B0004311DA /* getmcontext.c in Sources */, - C95B825E138F52B0004311DA /* makecontext.c in Sources */, - C95B825F138F52B0004311DA /* setcontext.c in Sources */, - C95B8260138F52B0004311DA /* setjmperr.c in Sources */, - C95B8261138F52B0004311DA /* swapcontext.c in Sources */, - C95B8262138F52B0004311DA /* init_cpu_capabilities.c in Sources */, - C95B8263138F52B0004311DA /* bcopy.c in Sources */, - C95B8264138F52B0004311DA /* bzero.c in Sources */, - C95B8265138F52B0004311DA /* memcpy.c in Sources */, - C95B8266138F52B0004311DA /* memmove.c in Sources */, - C95B8267138F52B0004311DA /* atomic.c in Sources */, - C95B8268138F52B0004311DA /* mach_absolute_time.c in Sources */, - C95B8269138F52B0004311DA /* spinlocks.c in Sources */, C95B827C138F52B0004311DA /* ascii.c in Sources */, C95B827D138F52B0004311DA /* big5.c in Sources */, C95B827E138F52B0004311DA /* btowc.c in Sources */, @@ -12099,30 +12400,7 @@ C95B82D1138F52B0004311DA /* acl_flag.c in Sources */, C95B82D2138F52B0004311DA /* acl_perm.c in Sources */, C95B82D3138F52B0004311DA /* acl_translate.c in Sources */, - C95B82DC138F52B0004311DA /* mk_pthread_impl.c in Sources */, - C95B82DD138F52B0004311DA /* pthread.c in Sources */, - C95B82DE138F52B0004311DA /* pthread_cancelable.c in Sources */, - C95B82DF138F52B0004311DA /* pthread_cond.c in Sources */, - C95B82E0138F52B0004311DA /* pthread_mutex.c in Sources */, - C95B82E1138F52B0004311DA /* pthread_rwlock.c in Sources */, - C95B82E2138F52B0004311DA /* pthread_tsd.c in Sources */, - C95B82E3138F52B0004311DA /* pthread_atfork_test.c in Sources */, - C95B82E4138F52B0004311DA /* thread_setup.c in Sources */, C95B82E7138F52B0004311DA /* regerror.c in Sources */, - C95B82EA138F52B0004311DA /* chk_fail.c in Sources */, - C95B82EB138F52B0004311DA /* memcpy_chk.c in Sources */, - C95B82EC138F52B0004311DA /* memmove_chk.c in Sources */, - C95B82ED138F52B0004311DA /* memset_chk.c in Sources */, - C95B82EE138F52B0004311DA /* snprintf_chk.c in Sources */, - C95B82EF138F52B0004311DA /* sprintf_chk.c in Sources */, - C95B82F0138F52B0004311DA /* stpcpy_chk.c in Sources */, - C95B82F1138F52B0004311DA /* stpncpy_chk.c in Sources */, - C95B82F2138F52B0004311DA /* strcat_chk.c in Sources */, - C95B82F3138F52B0004311DA /* strcpy_chk.c in Sources */, - C95B82F4138F52B0004311DA /* strncat_chk.c in Sources */, - C95B82F5138F52B0004311DA /* strncpy_chk.c in Sources */, - C95B82F6138F52B0004311DA /* vsnprintf_chk.c in Sources */, - C95B82F7138F52B0004311DA /* vsprintf_chk.c in Sources */, C95B82F8138F52B0004311DA /* _flock_stub.c in Sources */, C95B82F9138F52B0004311DA /* asprintf.c in Sources */, C95B82FA138F52B0004311DA /* clrerr.c in Sources */, @@ -12166,6 +12444,7 @@ C95B8320138F52B0004311DA /* getchar.c in Sources */, C95B8321138F52B0004311DA /* getdelim.c in Sources */, C95B8322138F52B0004311DA /* getline.c in Sources */, + 928BD1051D76073400EC01FC /* timingsafe_bcmp.c in Sources */, C95B8323138F52B0004311DA /* gets.c in Sources */, C95B8324138F52B0004311DA /* getw.c in Sources */, C95B8325138F52B0004311DA /* getwc.c in Sources */, @@ -12288,29 +12567,17 @@ C95B839A138F52B0004311DA /* timelocal.c in Sources */, C95B839B138F52B0004311DA /* getdate.c in Sources */, C95B839C138F52B0004311DA /* timezone_unix03.c in Sources */, - C95B839D138F52B0004311DA /* bcmp.c in Sources */, - C95B839E138F52B0004311DA /* bcopy.c in Sources */, - C95B839F138F52B0004311DA /* bzero.c in Sources */, C95B83A0138F52B0004311DA /* index.c in Sources */, - C95B83A1138F52B0004311DA /* memccpy.c in Sources */, - C95B83A2138F52B0004311DA /* memchr.c in Sources */, - C95B83A3138F52B0004311DA /* memcmp.c in Sources */, - C95B83A4138F52B0004311DA /* memcpy.c in Sources */, C95B83A5138F52B0004311DA /* memmem.c in Sources */, - C95B83A6138F52B0004311DA /* memmove.c in Sources */, - C95B83A7138F52B0004311DA /* memset.c in Sources */, C95B83A8138F52B0004311DA /* rindex.c in Sources */, C95B83AB138F52B0004311DA /* strcasecmp.c in Sources */, C95B83AC138F52B0004311DA /* strcasestr.c in Sources */, - C95B83AE138F52B0004311DA /* strchr.c in Sources */, - C95B83AF138F52B0004311DA /* strcmp.c in Sources */, C95B83B0138F52B0004311DA /* strcoll.c in Sources */, C95B83B2138F52B0004311DA /* strcspn.c in Sources */, C95B83B3138F52B0004311DA /* strdup.c in Sources */, C95B83B4138F52B0004311DA /* strerror.c in Sources */, C95B83B7138F52B0004311DA /* strlen.c in Sources */, C95B83B8138F52B0004311DA /* strmode.c in Sources */, - C95B83BA138F52B0004311DA /* strncmp.c in Sources */, C95B83BC138F52B0004311DA /* strndup.c in Sources */, C95B83BD138F52B0004311DA /* strnlen.c in Sources */, C95B83BE138F52B0004311DA /* strnstr.c in Sources */, @@ -12351,17 +12618,15 @@ C95B83E1138F52B0004311DA /* wmemchr.c in Sources */, C95B83E2138F52B0004311DA /* wmemcmp.c in Sources */, C95B83E3138F52B0004311DA /* wmemcpy.c in Sources */, + 2DF67CE3184F9CBE00B83A3D /* debug_private.c in Sources */, C95B83E4138F52B0004311DA /* wmemmove.c in Sources */, C95B83E5138F52B0004311DA /* wmemset.c in Sources */, - C95B83E6138F52B0004311DA /* __libc_init.c in Sources */, + C95B83E6138F52B0004311DA /* _libc_init.c in Sources */, C95B83E7138F52B0004311DA /* _libc_fork_child.c in Sources */, C95B83E8138F52B0004311DA /* chmodx_np.c in Sources */, - C95B83E9138F52B0004311DA /* context-stubs.c in Sources */, C95B83EA138F52B0004311DA /* crt_externs.c in Sources */, - C95B83EB138F52B0004311DA /* errno.c in Sources */, C95B83EC138F52B0004311DA /* fork.c in Sources */, C95B83ED138F52B0004311DA /* getgroups.c in Sources */, - C95B83EE138F52B0004311DA /* getiopolicy_np.c in Sources */, C95B83EF138F52B0004311DA /* gettimeofday.c in Sources */, C95B83F0138F52B0004311DA /* msgctl.c in Sources */, C95B83F1138F52B0004311DA /* stack_protector.c in Sources */, @@ -12373,14 +12638,8 @@ C95B83F7138F52B0004311DA /* settimeofday.c in Sources */, C95B83F8138F52B0004311DA /* shmctl.c in Sources */, C95B83F9138F52B0004311DA /* sigaction.c in Sources */, - C95B83FA138F52B0004311DA /* sigcatch.c in Sources */, - C95B83FB138F52B0004311DA /* sigtramp.c in Sources */, - C95B83FC138F52B0004311DA /* slot_name.c in Sources */, C95B83FD138F52B0004311DA /* statx_np.c in Sources */, C95B83FE138F52B0004311DA /* umaskx_np.c in Sources */, - C95B83FF138F52B0004311DA /* cprocs.c in Sources */, - C95B8400138F52B0004311DA /* cthreads.c in Sources */, - C95B8401138F52B0004311DA /* mig_support.c in Sources */, C95B8402138F52B0004311DA /* fparseln.c in Sources */, C95B8403138F52B0004311DA /* login.c in Sources */, C95B8404138F52B0004311DA /* login_tty.c in Sources */, @@ -12398,19 +12657,11 @@ C95B840F138F52B0004311DA /* parse.c in Sources */, C95B8410138F52B0004311DA /* unpack.c in Sources */, C95B8411138F52B0004311DA /* unparse.c in Sources */, - C95B8412138F52B0004311DA /* getmcontext.c in Sources */, - C95B8413138F52B0004311DA /* makecontext.c in Sources */, - C95B8414138F52B0004311DA /* setcontext.c in Sources */, - C95B8415138F52B0004311DA /* swapcontext.c in Sources */, - C95B8416138F52B0004311DA /* bcopy.c in Sources */, - C95B8417138F52B0004311DA /* bzero.c in Sources */, - C95B8418138F52B0004311DA /* memcpy.c in Sources */, - C95B8419138F52B0004311DA /* memmove.c in Sources */, - C95B841A138F52B0004311DA /* atomic.c in Sources */, - C95B841B138F52B0004311DA /* spinlocks.c in Sources */, - 3F2208EC14358B4A00386F5B /* asl_fd.c in Sources */, B19C64601450F90200032373 /* sync_volume_np.c in Sources */, 3FB7E1B8146EF2E000843438 /* dirfd.c in Sources */, + 4B2C64A715519BC700342BFA /* assumes.c in Sources */, + FC2ED615157D4BE80098EC69 /* inet_ntop.c in Sources */, + FC2ED61E157D4BE80098EC69 /* inet_pton.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -12419,11 +12670,6 @@ buildActionMask = 2147483647; files = ( C95B842E138F53DB004311DA /* init_cpu_capabilities.c in Sources */, - C95B842F138F53DB004311DA /* dyld_resolvers.c in Sources */, - C95B8430138F53DB004311DA /* arm_commpage_gettimeofday.c in Sources */, - C95B8431138F53DB004311DA /* gcc_atomic.c in Sources */, - C95B8432138F53DB004311DA /* OSAtomic-v4.c in Sources */, - C95B8433138F53DB004311DA /* OSAtomic_resolvers.c in Sources */, C95B8435138F53DB004311DA /* creat.c in Sources */, C95B8436138F53DB004311DA /* gethostid.c in Sources */, C95B8437138F53DB004311DA /* getwd.c in Sources */, @@ -12436,11 +12682,7 @@ C95B843E138F53DB004311DA /* setreuid.c in Sources */, C95B843F138F53DB004311DA /* sigaltstk.c in Sources */, C95B8440138F53DB004311DA /* sigcompat.c in Sources */, - C95B8441138F53DB004311DA /* _dirhelper.c in Sources */, C95B8442138F53DB004311DA /* kvm.c in Sources */, - C95B8443138F53DB004311DA /* libproc.c in Sources */, - C95B8444138F53DB004311DA /* MKGetTimeBaseInfo.c in Sources */, - C95B8445138F53DB004311DA /* proc_listpidspath.c in Sources */, C95B8446138F53DB004311DA /* forceLibcToBuild.c in Sources */, C95B8447138F53DB004311DA /* bt_close.c in Sources */, C95B8448138F53DB004311DA /* bt_conv.c in Sources */, @@ -12505,24 +12747,15 @@ C95B8483138F53DB004311DA /* machdep_ldisdd.c in Sources */, C95B8484138F53DB004311DA /* machdep_ldisQ.c in Sources */, C95B8485138F53DB004311DA /* machdep_ldisx.c in Sources */, - C95B8486138F53DB004311DA /* _simple.c in Sources */, - C95B8487138F53DB004311DA /* asl.c in Sources */, - C95B8488138F53DB004311DA /* asl_core.c in Sources */, - C95B8489138F53DB004311DA /* asl_file.c in Sources */, - C95B848A138F53DB004311DA /* asl_legacy1.c in Sources */, - C95B848B138F53DB004311DA /* asl_msg.c in Sources */, - C95B848C138F53DB004311DA /* asl_store.c in Sources */, - C95B848D138F53DB004311DA /* asl_util.c in Sources */, - C95B848E138F53DB004311DA /* assumes.c in Sources */, C95B848F138F53DB004311DA /* authentication.c in Sources */, C95B8490138F53DB004311DA /* backtrace.c in Sources */, - C95B8491138F53DB004311DA /* cache.c in Sources */, C95B8492138F53DB004311DA /* confstr.c in Sources */, C95B8493138F53DB004311DA /* crypt.c in Sources */, C95B8494138F53DB004311DA /* devname.c in Sources */, C95B8495138F53DB004311DA /* disklabel.c in Sources */, C95B8496138F53DB004311DA /* errlst.c in Sources */, C95B8497138F53DB004311DA /* filesec.c in Sources */, + 147CDFDF1B7C233100831EC6 /* clock_gettime.c in Sources */, C95B8498138F53DB004311DA /* _rand48.c in Sources */, C95B8499138F53DB004311DA /* alarm.c in Sources */, C95B849A138F53DB004311DA /* arc4random.c in Sources */, @@ -12562,7 +12795,6 @@ C95B84BC138F53DB004311DA /* opendir.c in Sources */, C95B84BD138F53DB004311DA /* pause.c in Sources */, C95B84BE138F53DB004311DA /* popen.c in Sources */, - C95B84BF138F53DB004311DA /* pselect.c in Sources */, C95B84C0138F53DB004311DA /* psignal.c in Sources */, C95B84C1138F53DB004311DA /* raise.c in Sources */, C95B84C2138F53DB004311DA /* readdir.c in Sources */, @@ -12606,42 +12838,19 @@ C95B84E8138F53DB004311DA /* getttyent.c in Sources */, C95B84E9138F53DB004311DA /* getusershell.c in Sources */, C95B84EA138F53DB004311DA /* getvfsbyname.c in Sources */, - C95B84EB138F53DB004311DA /* isinf.c in Sources */, - C95B84EC138F53DB004311DA /* isnan.c in Sources */, - C95B84ED138F53DB004311DA /* magazine_malloc.c in Sources */, - C95B84EE138F53DB004311DA /* malloc.c in Sources */, C95B84EF138F53DB004311DA /* nanosleep.c in Sources */, C95B84F0138F53DB004311DA /* utmpx.c in Sources */, C95B84F1138F53DB004311DA /* nftw.c in Sources */, C95B84F2138F53DB004311DA /* nlist.c in Sources */, - C95B84F3138F53DB004311DA /* NSSystemDirectories.c in Sources */, C95B84F4138F53DB004311DA /* oldsyslog.c in Sources */, - C95B84F5138F53DB004311DA /* platfunc.c in Sources */, - C95B84F6138F53DB004311DA /* scalable_malloc.c in Sources */, C95B84F7138F53DB004311DA /* setlogin.c in Sources */, C95B84F8138F53DB004311DA /* sigsetops.c in Sources */, - C95B84F9138F53DB004311DA /* stack_logging.c in Sources */, - C95B84FA138F53DB004311DA /* stack_logging_disk.c in Sources */, C95B84FB138F53DB004311DA /* strtofflags.c in Sources */, - C95B84FC138F53DB004311DA /* syslog.c in Sources */, C95B84FD138F53DB004311DA /* thread_stack_pcs.c in Sources */, C95B84FE138F53DB004311DA /* uname.c in Sources */, C95B84FF138F53DB004311DA /* utmpx-darwin.c in Sources */, C95B8500138F53DB004311DA /* wordexp.c in Sources */, C95B8502138F53DB004311DA /* gmon.c in Sources */, - C95B8503138F53DB004311DA /* getmcontext.c in Sources */, - C95B8504138F53DB004311DA /* makecontext.c in Sources */, - C95B8505138F53DB004311DA /* setcontext.c in Sources */, - C95B8506138F53DB004311DA /* setjmperr.c in Sources */, - C95B8507138F53DB004311DA /* swapcontext.c in Sources */, - C95B8508138F53DB004311DA /* init_cpu_capabilities.c in Sources */, - C95B8509138F53DB004311DA /* bcopy.c in Sources */, - C95B850A138F53DB004311DA /* bzero.c in Sources */, - C95B850B138F53DB004311DA /* memcpy.c in Sources */, - C95B850C138F53DB004311DA /* memmove.c in Sources */, - C95B850D138F53DB004311DA /* atomic.c in Sources */, - C95B850E138F53DB004311DA /* mach_absolute_time.c in Sources */, - C95B850F138F53DB004311DA /* spinlocks.c in Sources */, C95B8522138F53DB004311DA /* ascii.c in Sources */, C95B8523138F53DB004311DA /* big5.c in Sources */, C95B8524138F53DB004311DA /* btowc.c in Sources */, @@ -12730,30 +12939,7 @@ C95B8577138F53DB004311DA /* acl_flag.c in Sources */, C95B8578138F53DB004311DA /* acl_perm.c in Sources */, C95B8579138F53DB004311DA /* acl_translate.c in Sources */, - C95B8582138F53DB004311DA /* mk_pthread_impl.c in Sources */, - C95B8583138F53DB004311DA /* pthread.c in Sources */, - C95B8584138F53DB004311DA /* pthread_cancelable.c in Sources */, - C95B8585138F53DB004311DA /* pthread_cond.c in Sources */, - C95B8586138F53DB004311DA /* pthread_mutex.c in Sources */, - C95B8587138F53DB004311DA /* pthread_rwlock.c in Sources */, - C95B8588138F53DB004311DA /* pthread_tsd.c in Sources */, - C95B8589138F53DB004311DA /* pthread_atfork_test.c in Sources */, - C95B858A138F53DB004311DA /* thread_setup.c in Sources */, C95B858D138F53DB004311DA /* regerror.c in Sources */, - C95B8590138F53DB004311DA /* chk_fail.c in Sources */, - C95B8591138F53DB004311DA /* memcpy_chk.c in Sources */, - C95B8592138F53DB004311DA /* memmove_chk.c in Sources */, - C95B8593138F53DB004311DA /* memset_chk.c in Sources */, - C95B8594138F53DB004311DA /* snprintf_chk.c in Sources */, - C95B8595138F53DB004311DA /* sprintf_chk.c in Sources */, - C95B8596138F53DB004311DA /* stpcpy_chk.c in Sources */, - C95B8597138F53DB004311DA /* stpncpy_chk.c in Sources */, - C95B8598138F53DB004311DA /* strcat_chk.c in Sources */, - C95B8599138F53DB004311DA /* strcpy_chk.c in Sources */, - C95B859A138F53DB004311DA /* strncat_chk.c in Sources */, - C95B859B138F53DB004311DA /* strncpy_chk.c in Sources */, - C95B859C138F53DB004311DA /* vsnprintf_chk.c in Sources */, - C95B859D138F53DB004311DA /* vsprintf_chk.c in Sources */, C95B859E138F53DB004311DA /* _flock_stub.c in Sources */, C95B859F138F53DB004311DA /* asprintf.c in Sources */, C95B85A0138F53DB004311DA /* clrerr.c in Sources */, @@ -12797,6 +12983,7 @@ C95B85C6138F53DB004311DA /* getchar.c in Sources */, C95B85C7138F53DB004311DA /* getdelim.c in Sources */, C95B85C8138F53DB004311DA /* getline.c in Sources */, + 928BD1061D76073500EC01FC /* timingsafe_bcmp.c in Sources */, C95B85C9138F53DB004311DA /* gets.c in Sources */, C95B85CA138F53DB004311DA /* getw.c in Sources */, C95B85CB138F53DB004311DA /* getwc.c in Sources */, @@ -12919,29 +13106,17 @@ C95B8640138F53DB004311DA /* timelocal.c in Sources */, C95B8641138F53DB004311DA /* getdate.c in Sources */, C95B8642138F53DB004311DA /* timezone_unix03.c in Sources */, - C95B8643138F53DB004311DA /* bcmp.c in Sources */, - C95B8644138F53DB004311DA /* bcopy.c in Sources */, - C95B8645138F53DB004311DA /* bzero.c in Sources */, C95B8646138F53DB004311DA /* index.c in Sources */, - C95B8647138F53DB004311DA /* memccpy.c in Sources */, - C95B8648138F53DB004311DA /* memchr.c in Sources */, - C95B8649138F53DB004311DA /* memcmp.c in Sources */, - C95B864A138F53DB004311DA /* memcpy.c in Sources */, C95B864B138F53DB004311DA /* memmem.c in Sources */, - C95B864C138F53DB004311DA /* memmove.c in Sources */, - C95B864D138F53DB004311DA /* memset.c in Sources */, C95B864E138F53DB004311DA /* rindex.c in Sources */, C95B8651138F53DB004311DA /* strcasecmp.c in Sources */, C95B8652138F53DB004311DA /* strcasestr.c in Sources */, - C95B8654138F53DB004311DA /* strchr.c in Sources */, - C95B8655138F53DB004311DA /* strcmp.c in Sources */, C95B8656138F53DB004311DA /* strcoll.c in Sources */, C95B8658138F53DB004311DA /* strcspn.c in Sources */, C95B8659138F53DB004311DA /* strdup.c in Sources */, C95B865A138F53DB004311DA /* strerror.c in Sources */, C95B865D138F53DB004311DA /* strlen.c in Sources */, C95B865E138F53DB004311DA /* strmode.c in Sources */, - C95B8660138F53DB004311DA /* strncmp.c in Sources */, C95B8662138F53DB004311DA /* strndup.c in Sources */, C95B8663138F53DB004311DA /* strnlen.c in Sources */, C95B8664138F53DB004311DA /* strnstr.c in Sources */, @@ -12982,17 +13157,15 @@ C95B8687138F53DB004311DA /* wmemchr.c in Sources */, C95B8688138F53DB004311DA /* wmemcmp.c in Sources */, C95B8689138F53DB004311DA /* wmemcpy.c in Sources */, + 2DF67CE4184F9CBE00B83A3D /* debug_private.c in Sources */, C95B868A138F53DB004311DA /* wmemmove.c in Sources */, C95B868B138F53DB004311DA /* wmemset.c in Sources */, - C95B868C138F53DB004311DA /* __libc_init.c in Sources */, + C95B868C138F53DB004311DA /* _libc_init.c in Sources */, C95B868D138F53DB004311DA /* _libc_fork_child.c in Sources */, C95B868E138F53DB004311DA /* chmodx_np.c in Sources */, - C95B868F138F53DB004311DA /* context-stubs.c in Sources */, C95B8690138F53DB004311DA /* crt_externs.c in Sources */, - C95B8691138F53DB004311DA /* errno.c in Sources */, C95B8692138F53DB004311DA /* fork.c in Sources */, C95B8693138F53DB004311DA /* getgroups.c in Sources */, - C95B8694138F53DB004311DA /* getiopolicy_np.c in Sources */, C95B8695138F53DB004311DA /* gettimeofday.c in Sources */, C95B8696138F53DB004311DA /* msgctl.c in Sources */, C95B8697138F53DB004311DA /* stack_protector.c in Sources */, @@ -13004,14 +13177,8 @@ C95B869D138F53DB004311DA /* settimeofday.c in Sources */, C95B869E138F53DB004311DA /* shmctl.c in Sources */, C95B869F138F53DB004311DA /* sigaction.c in Sources */, - C95B86A0138F53DB004311DA /* sigcatch.c in Sources */, - C95B86A1138F53DB004311DA /* sigtramp.c in Sources */, - C95B86A2138F53DB004311DA /* slot_name.c in Sources */, C95B86A3138F53DB004311DA /* statx_np.c in Sources */, C95B86A4138F53DB004311DA /* umaskx_np.c in Sources */, - C95B86A5138F53DB004311DA /* cprocs.c in Sources */, - C95B86A6138F53DB004311DA /* cthreads.c in Sources */, - C95B86A7138F53DB004311DA /* mig_support.c in Sources */, C95B86A8138F53DB004311DA /* fparseln.c in Sources */, C95B86A9138F53DB004311DA /* login.c in Sources */, C95B86AA138F53DB004311DA /* login_tty.c in Sources */, @@ -13029,19 +13196,603 @@ C95B86B5138F53DB004311DA /* parse.c in Sources */, C95B86B6138F53DB004311DA /* unpack.c in Sources */, C95B86B7138F53DB004311DA /* unparse.c in Sources */, - C95B86B8138F53DB004311DA /* getmcontext.c in Sources */, - C95B86B9138F53DB004311DA /* makecontext.c in Sources */, - C95B86BA138F53DB004311DA /* setcontext.c in Sources */, - C95B86BB138F53DB004311DA /* swapcontext.c in Sources */, - C95B86BC138F53DB004311DA /* bcopy.c in Sources */, - C95B86BD138F53DB004311DA /* bzero.c in Sources */, - C95B86BE138F53DB004311DA /* memcpy.c in Sources */, - C95B86BF138F53DB004311DA /* memmove.c in Sources */, - C95B86C0138F53DB004311DA /* atomic.c in Sources */, - C95B86C1138F53DB004311DA /* spinlocks.c in Sources */, - 3F2208ED14358B4A00386F5B /* asl_fd.c in Sources */, B19C64611450F90200032373 /* sync_volume_np.c in Sources */, 3FB7E1B9146EF2E000843438 /* dirfd.c in Sources */, + 4B2C64A815519BC700342BFA /* assumes.c in Sources */, + FC2ED616157D4BE80098EC69 /* inet_ntop.c in Sources */, + FC2ED61F157D4BE80098EC69 /* inet_pton.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C97A6F231517AF53005E1998 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C97A6F291517AF53005E1998 /* mcount.s in Sources */, + C97A6F3F1517AF53005E1998 /* strcpy.s in Sources */, + C97A6F401517AF53005E1998 /* strlcat.s in Sources */, + C97A6F411517AF53005E1998 /* strlcpy.s in Sources */, + C97A6F421517AF53005E1998 /* strlen.s in Sources */, + C97A6F441517AF53005E1998 /* strncpy.s in Sources */, + C97A6F5A1517AF53005E1998 /* strlen.s in Sources */, + C97A6F5C1517AF53005E1998 /* strnlen.s in Sources */, + C97A6F5D1517AF53005E1998 /* strstr.s in Sources */, + C97A6F6D1517AF53005E1998 /* mcount.s in Sources */, + C97A6F761517AF53005E1998 /* (null) in Sources */, + C97A6F791517AF53005E1998 /* (null) in Sources */, + C97A6F7A1517AF53005E1998 /* (null) in Sources */, + C97A6F7E1517AF53005E1998 /* (null) in Sources */, + C97A6F8F1517AF53005E1998 /* init_cpu_capabilities.c in Sources */, + C97A6F961517AF53005E1998 /* creat.c in Sources */, + C97A6F971517AF53005E1998 /* gethostid.c in Sources */, + C97A6F981517AF53005E1998 /* getwd.c in Sources */, + C97A6F991517AF53005E1998 /* killpg.c in Sources */, + C97A6F9A1517AF53005E1998 /* sethostid.c in Sources */, + C97A6F9B1517AF53005E1998 /* setpgrp.c in Sources */, + C97A6F9C1517AF53005E1998 /* setrgid.c in Sources */, + C97A6F9D1517AF53005E1998 /* setruid.c in Sources */, + C97A6F9E1517AF53005E1998 /* setregid.c in Sources */, + C97A6F9F1517AF53005E1998 /* setreuid.c in Sources */, + C97A6FA01517AF53005E1998 /* sigaltstk.c in Sources */, + C97A6FA11517AF53005E1998 /* sigcompat.c in Sources */, + C97A6FA31517AF53005E1998 /* kvm.c in Sources */, + C97A6FA71517AF53005E1998 /* forceLibcToBuild.c in Sources */, + C97A6FA81517AF53005E1998 /* bt_close.c in Sources */, + C97A6FA91517AF53005E1998 /* bt_conv.c in Sources */, + C97A6FAA1517AF53005E1998 /* bt_debug.c in Sources */, + C97A6FAB1517AF53005E1998 /* bt_delete.c in Sources */, + C97A6FAC1517AF53005E1998 /* bt_get.c in Sources */, + C97A6FAD1517AF53005E1998 /* bt_open.c in Sources */, + C97A6FAE1517AF53005E1998 /* bt_overflow.c in Sources */, + C97A6FAF1517AF53005E1998 /* bt_page.c in Sources */, + C97A6FB01517AF53005E1998 /* bt_put.c in Sources */, + C97A6FB11517AF53005E1998 /* bt_search.c in Sources */, + C97A6FB21517AF53005E1998 /* bt_seq.c in Sources */, + C97A6FB31517AF53005E1998 /* bt_split.c in Sources */, + C97A6FB41517AF53005E1998 /* bt_utils.c in Sources */, + C97A6FB51517AF53005E1998 /* db.c in Sources */, + C97A6FB61517AF53005E1998 /* hash.c in Sources */, + C97A6FB71517AF53005E1998 /* hash_bigkey.c in Sources */, + C97A6FB81517AF53005E1998 /* hash_buf.c in Sources */, + C97A6FB91517AF53005E1998 /* hash_func.c in Sources */, + C97A6FBA1517AF53005E1998 /* hash_log2.c in Sources */, + C97A6FBB1517AF53005E1998 /* hash_page.c in Sources */, + C97A6FBC1517AF53005E1998 /* ndbm.c in Sources */, + C97A6FBD1517AF53005E1998 /* mpool.c in Sources */, + C97A6FBE1517AF53005E1998 /* rec_close.c in Sources */, + C97A6FBF1517AF53005E1998 /* rec_delete.c in Sources */, + C97A6FC01517AF53005E1998 /* rec_get.c in Sources */, + C97A6FC11517AF53005E1998 /* rec_open.c in Sources */, + C97A6FC21517AF53005E1998 /* rec_put.c in Sources */, + C97A6FC31517AF53005E1998 /* rec_search.c in Sources */, + C97A6FC41517AF53005E1998 /* rec_seq.c in Sources */, + C97A6FC51517AF53005E1998 /* rec_utils.c in Sources */, + C97A6FC61517AF53005E1998 /* brk.c in Sources */, + C97A6FC71517AF53005E1998 /* bsd_signal.c in Sources */, + C97A6FC81517AF53005E1998 /* lchflags.c in Sources */, + C97A6FC91517AF53005E1998 /* lchmod.c in Sources */, + C97A6FCA1517AF53005E1998 /* lutimes.c in Sources */, + C97A6FCB1517AF53005E1998 /* statvfs.c in Sources */, + C97A6FCC1517AF53005E1998 /* tcgetsid.c in Sources */, + C97A6FCD1517AF53005E1998 /* _ldbl_util.c in Sources */, + C97A6FCE1517AF53005E1998 /* _hdtoa.c in Sources */, + C97A6FCF1517AF53005E1998 /* _ldtoa.c in Sources */, + C97A6FD01517AF53005E1998 /* gdtoa-dmisc.c in Sources */, + C97A6FD11517AF53005E1998 /* gdtoa-dtoa.c in Sources */, + C97A6FD21517AF53005E1998 /* gdtoa-gdtoa.c in Sources */, + C97A6FD31517AF53005E1998 /* gdtoa-gethex.c in Sources */, + C97A6FD41517AF53005E1998 /* gdtoa-gmisc.c in Sources */, + C97A6FD51517AF53005E1998 /* gdtoa-hd_init.c in Sources */, + C97A6FD61517AF53005E1998 /* gdtoa-hexnan.c in Sources */, + C97A6FD71517AF53005E1998 /* gdtoa-misc.c in Sources */, + C97A6FD81517AF53005E1998 /* gdtoa-smisc.c in Sources */, + C97A6FD91517AF53005E1998 /* gdtoa-strtod.c in Sources */, + C97A6FDA1517AF53005E1998 /* gdtoa-strtodg.c in Sources */, + C97A6FDB1517AF53005E1998 /* gdtoa-strtof.c in Sources */, + C97A6FDC1517AF53005E1998 /* gdtoa-strtoIg.c in Sources */, + C97A6FDD1517AF53005E1998 /* gdtoa-strtopdd.c in Sources */, + C97A6FDE1517AF53005E1998 /* gdtoa-strtopx.c in Sources */, + C97A6FDF1517AF53005E1998 /* gdtoa-strtord.c in Sources */, + C97A6FE01517AF53005E1998 /* gdtoa-sum.c in Sources */, + C97A6FE11517AF53005E1998 /* gdtoa-ulp.c in Sources */, + C97A6FE21517AF53005E1998 /* glue.c in Sources */, + C97A6FE31517AF53005E1998 /* machdep_ldisd.c in Sources */, + C97A6FE41517AF53005E1998 /* machdep_ldisdd.c in Sources */, + C97A6FE51517AF53005E1998 /* machdep_ldisQ.c in Sources */, + C97A6FE61517AF53005E1998 /* machdep_ldisx.c in Sources */, + C97A6FF01517AF53005E1998 /* authentication.c in Sources */, + C97A6FF11517AF53005E1998 /* backtrace.c in Sources */, + C97A6FF31517AF53005E1998 /* confstr.c in Sources */, + C97A6FF41517AF53005E1998 /* crypt.c in Sources */, + C97A6FF51517AF53005E1998 /* devname.c in Sources */, + C97A6FF61517AF53005E1998 /* disklabel.c in Sources */, + C97A6FF71517AF53005E1998 /* errlst.c in Sources */, + C97A6FF81517AF53005E1998 /* filesec.c in Sources */, + C97A6FF91517AF53005E1998 /* _rand48.c in Sources */, + C97A6FFA1517AF53005E1998 /* alarm.c in Sources */, + C97A6FFB1517AF53005E1998 /* arc4random.c in Sources */, + C97A6FFC1517AF53005E1998 /* assert.c in Sources */, + C97A6FFD1517AF53005E1998 /* basename.c in Sources */, + C97A6FFE1517AF53005E1998 /* clock.c in Sources */, + C97A6FFF1517AF53005E1998 /* closedir.c in Sources */, + C97A70001517AF53005E1998 /* ctermid.c in Sources */, + C97A70011517AF53005E1998 /* daemon.c in Sources */, + C97A70021517AF53005E1998 /* dirname.c in Sources */, + C97A70031517AF53005E1998 /* drand48.c in Sources */, + C97A70041517AF53005E1998 /* erand48.c in Sources */, + C97A70051517AF53005E1998 /* err.c in Sources */, + C97A70061517AF53005E1998 /* exec.c in Sources */, + C97A70071517AF53005E1998 /* fmtcheck.c in Sources */, + C97A70081517AF53005E1998 /* fmtmsg.c in Sources */, + C97A70091517AF53005E1998 /* fnmatch.c in Sources */, + C97A700A1517AF53005E1998 /* ftok.c in Sources */, + C97A700B1517AF53005E1998 /* getbsize.c in Sources */, + C97A700C1517AF53005E1998 /* getcap.c in Sources */, + C97A700D1517AF53005E1998 /* getcwd.c in Sources */, + C97A700E1517AF53005E1998 /* gethostname.c in Sources */, + C97A700F1517AF53005E1998 /* getlogin.c in Sources */, + C97A70101517AF53005E1998 /* getmntinfo.c in Sources */, + C97A70111517AF53005E1998 /* getpagesize.c in Sources */, + C97A70121517AF53005E1998 /* getpeereid.c in Sources */, + C97A70131517AF53005E1998 /* getprogname.c in Sources */, + C97A70141517AF53005E1998 /* glob.c in Sources */, + C97A70151517AF53005E1998 /* isatty.c in Sources */, + C97A70161517AF53005E1998 /* jrand48.c in Sources */, + C97A70171517AF53005E1998 /* lcong48.c in Sources */, + C97A70181517AF53005E1998 /* lockf.c in Sources */, + C97A70191517AF53005E1998 /* lrand48.c in Sources */, + C97A701A1517AF53005E1998 /* mrand48.c in Sources */, + C97A701B1517AF53005E1998 /* nice.c in Sources */, + C97A701C1517AF53005E1998 /* nrand48.c in Sources */, + C97A701D1517AF53005E1998 /* opendir.c in Sources */, + C97A701E1517AF53005E1998 /* pause.c in Sources */, + C97A701F1517AF53005E1998 /* popen.c in Sources */, + C97A70211517AF53005E1998 /* psignal.c in Sources */, + C97A70221517AF53005E1998 /* raise.c in Sources */, + C97A70231517AF53005E1998 /* readdir.c in Sources */, + C97A70241517AF53005E1998 /* readpassphrase.c in Sources */, + C97A70251517AF53005E1998 /* rewinddir.c in Sources */, + C97A70261517AF53005E1998 /* scandir.c in Sources */, + C97A70271517AF53005E1998 /* seed48.c in Sources */, + C97A70281517AF53005E1998 /* seekdir.c in Sources */, + C97A70291517AF53005E1998 /* sethostname.c in Sources */, + C97A702A1517AF53005E1998 /* setmode.c in Sources */, + C97A702B1517AF53005E1998 /* setprogname.c in Sources */, + C97A702C1517AF53005E1998 /* siginterrupt.c in Sources */, + C97A702D1517AF53005E1998 /* siglist.c in Sources */, + C97A702E1517AF53005E1998 /* signal.c in Sources */, + C97A702F1517AF53005E1998 /* sleep.c in Sources */, + C97A70301517AF53005E1998 /* srand48.c in Sources */, + C97A70311517AF53005E1998 /* stringlist.c in Sources */, + C97A70321517AF53005E1998 /* sysconf.c in Sources */, + C97A70331517AF53005E1998 /* sysctl.c in Sources */, + C97A70341517AF53005E1998 /* sysctlbyname.c in Sources */, + C97A70351517AF53005E1998 /* sysctlnametomib.c in Sources */, + C97A70361517AF53005E1998 /* telldir.c in Sources */, + C97A70371517AF53005E1998 /* termios.c in Sources */, + C97A70381517AF53005E1998 /* time.c in Sources */, + C97A70391517AF53005E1998 /* times.c in Sources */, + C97A703A1517AF53005E1998 /* timezone.c in Sources */, + C97A703B1517AF53005E1998 /* ttyname.c in Sources */, + C97A703C1517AF53005E1998 /* ttyslot.c in Sources */, + C97A703D1517AF53005E1998 /* ualarm.c in Sources */, + C97A703E1517AF53005E1998 /* ulimit.c in Sources */, + C97A703F1517AF53005E1998 /* unvis.c in Sources */, + C97A70401517AF53005E1998 /* usleep.c in Sources */, + C97A70411517AF53005E1998 /* utime.c in Sources */, + C97A70421517AF53005E1998 /* vis.c in Sources */, + C97A70431517AF53005E1998 /* wait.c in Sources */, + C97A70441517AF53005E1998 /* wait3.c in Sources */, + C97A70451517AF53005E1998 /* waitpid.c in Sources */, + C97A70461517AF53005E1998 /* fts.c in Sources */, + C97A70471517AF53005E1998 /* get_compat.c in Sources */, + C97A70481517AF53005E1998 /* getloadavg.c in Sources */, + C97A70491517AF53005E1998 /* getttyent.c in Sources */, + C97A704A1517AF53005E1998 /* getusershell.c in Sources */, + C97A704B1517AF53005E1998 /* getvfsbyname.c in Sources */, + C97A70501517AF53005E1998 /* nanosleep.c in Sources */, + C97A70511517AF53005E1998 /* utmpx.c in Sources */, + C97A70521517AF53005E1998 /* nftw.c in Sources */, + C97A70531517AF53005E1998 /* nlist.c in Sources */, + C97A70551517AF53005E1998 /* oldsyslog.c in Sources */, + C97A70581517AF53005E1998 /* setlogin.c in Sources */, + C97A70591517AF53005E1998 /* sigsetops.c in Sources */, + C97A705C1517AF53005E1998 /* strtofflags.c in Sources */, + C97A705E1517AF53005E1998 /* thread_stack_pcs.c in Sources */, + C97A705F1517AF53005E1998 /* uname.c in Sources */, + C97A70601517AF53005E1998 /* utmpx-darwin.c in Sources */, + C97A70611517AF53005E1998 /* wordexp.c in Sources */, + C97A70621517AF53005E1998 /* gmon.c in Sources */, + C97A70701517AF53005E1998 /* ascii.c in Sources */, + C97A70711517AF53005E1998 /* big5.c in Sources */, + C97A70721517AF53005E1998 /* btowc.c in Sources */, + C97A70731517AF53005E1998 /* collate.c in Sources */, + C97A70741517AF53005E1998 /* collcmp.c in Sources */, + C97A70751517AF53005E1998 /* euc.c in Sources */, + C97A70761517AF53005E1998 /* fix_grouping.c in Sources */, + C97A70771517AF53005E1998 /* gb18030.c in Sources */, + C97A70781517AF53005E1998 /* gb2312.c in Sources */, + C97A70791517AF53005E1998 /* gbk.c in Sources */, + C97A707A1517AF53005E1998 /* ldpart.c in Sources */, + C97A707B1517AF53005E1998 /* lmessages.c in Sources */, + C97A707C1517AF53005E1998 /* lmonetary.c in Sources */, + C97A707D1517AF53005E1998 /* lnumeric.c in Sources */, + C97A707E1517AF53005E1998 /* localeconv.c in Sources */, + C97A707F1517AF53005E1998 /* mblen.c in Sources */, + C97A70801517AF53005E1998 /* mbrlen.c in Sources */, + C97A70811517AF53005E1998 /* mbrtowc.c in Sources */, + C97A70821517AF53005E1998 /* mbsinit.c in Sources */, + C97A70831517AF53005E1998 /* mbsnrtowcs.c in Sources */, + C97A70841517AF53005E1998 /* mbsrtowcs.c in Sources */, + C97A70851517AF53005E1998 /* mbstowcs.c in Sources */, + C97A70861517AF53005E1998 /* mbtowc.c in Sources */, + C97A70871517AF53005E1998 /* mskanji.c in Sources */, + C97A70881517AF53005E1998 /* nextwctype.c in Sources */, + C97A70891517AF53005E1998 /* nl_langinfo.c in Sources */, + C97A708A1517AF53005E1998 /* nomacros.c in Sources */, + C97A708B1517AF53005E1998 /* none.c in Sources */, + C97A708C1517AF53005E1998 /* rune.c in Sources */, + C97A708D1517AF53005E1998 /* runetype.c in Sources */, + C97A708E1517AF53005E1998 /* setlocale.c in Sources */, + 2DF67CDF184F9CBE00B83A3D /* debug_private.c in Sources */, + C97A708F1517AF53005E1998 /* setrunelocale.c in Sources */, + C97A70901517AF53005E1998 /* table.c in Sources */, + C97A70911517AF53005E1998 /* tolower.c in Sources */, + C97A70921517AF53005E1998 /* toupper.c in Sources */, + C97A70931517AF53005E1998 /* utf2.c in Sources */, + C97A70941517AF53005E1998 /* utf8.c in Sources */, + C97A70951517AF53005E1998 /* wcrtomb.c in Sources */, + C97A70961517AF53005E1998 /* wcsftime.c in Sources */, + C97A70971517AF53005E1998 /* wcsnrtombs.c in Sources */, + C97A70981517AF53005E1998 /* wcsrtombs.c in Sources */, + C97A70991517AF53005E1998 /* wcstod.c in Sources */, + C97A709A1517AF53005E1998 /* wcstof.c in Sources */, + C97A709B1517AF53005E1998 /* wcstoimax.c in Sources */, + C97A709C1517AF53005E1998 /* wcstol.c in Sources */, + C97A709D1517AF53005E1998 /* wcstold.c in Sources */, + C97A709E1517AF53005E1998 /* wcstoll.c in Sources */, + C97A709F1517AF53005E1998 /* wcstombs.c in Sources */, + C97A70A01517AF53005E1998 /* wcstoul.c in Sources */, + C97A70A11517AF53005E1998 /* wcstoull.c in Sources */, + C97A70A21517AF53005E1998 /* wcstoumax.c in Sources */, + C97A70A31517AF53005E1998 /* wctob.c in Sources */, + C97A70A41517AF53005E1998 /* wctomb.c in Sources */, + C97A70A51517AF53005E1998 /* wctrans.c in Sources */, + C97A70A61517AF53005E1998 /* wctype.c in Sources */, + C97A70A71517AF53005E1998 /* wcwidth.c in Sources */, + C97A70A81517AF53005E1998 /* frune.c in Sources */, + C97A70A91517AF53005E1998 /* isctype.c in Sources */, + C97A70AA1517AF53005E1998 /* iswctype.c in Sources */, + C97A70AB1517AF53005E1998 /* lconv.c in Sources */, + C97A70AC1517AF53005E1998 /* mbrune.c in Sources */, + C97A70AD1517AF53005E1998 /* runedepreciated.c in Sources */, + C97A70AE1517AF53005E1998 /* setinvalidrune.c in Sources */, + C97A70AF1517AF53005E1998 /* xlocale.c in Sources */, + C97A70B01517AF53005E1998 /* addr2ascii.c in Sources */, + C97A70B11517AF53005E1998 /* ascii2addr.c in Sources */, + C97A70B21517AF53005E1998 /* inet_addr.c in Sources */, + C97A70B31517AF53005E1998 /* inet_lnaof.c in Sources */, + C97A70B41517AF53005E1998 /* inet_makeaddr.c in Sources */, + C97A70B51517AF53005E1998 /* inet_net_ntop.c in Sources */, + C97A70B61517AF53005E1998 /* inet_net_pton.c in Sources */, + C97A70B71517AF53005E1998 /* inet_neta.c in Sources */, + C97A70B81517AF53005E1998 /* inet_netof.c in Sources */, + C97A70B91517AF53005E1998 /* inet_network.c in Sources */, + C97A70BA1517AF53005E1998 /* inet_ntoa.c in Sources */, + C97A70BB1517AF53005E1998 /* linkaddr.c in Sources */, + C97A70BC1517AF53005E1998 /* nsap_addr.c in Sources */, + C97A70BD1517AF53005E1998 /* recv.c in Sources */, + C97A70BE1517AF53005E1998 /* send.c in Sources */, + C97A70BF1517AF53005E1998 /* sockatmark.c in Sources */, + C97A70C01517AF53005E1998 /* sourcefilter.c in Sources */, + C97A70C11517AF53005E1998 /* msgcat.c in Sources */, + C97A70C21517AF53005E1998 /* acl.c in Sources */, + C97A70C31517AF53005E1998 /* acl_entry.c in Sources */, + C97A70C41517AF53005E1998 /* acl_file.c in Sources */, + C97A70C51517AF53005E1998 /* acl_flag.c in Sources */, + C97A70C61517AF53005E1998 /* acl_perm.c in Sources */, + C97A70C71517AF53005E1998 /* acl_translate.c in Sources */, + C97A70D11517AF53005E1998 /* regerror.c in Sources */, + C97A70D21517AF53005E1998 /* chk_fail.c in Sources */, + C97A70D31517AF53005E1998 /* memcpy_chk.c in Sources */, + C97A70D41517AF53005E1998 /* memmove_chk.c in Sources */, + C97A70D51517AF53005E1998 /* memset_chk.c in Sources */, + C97A70D61517AF53005E1998 /* snprintf_chk.c in Sources */, + C97A70D71517AF53005E1998 /* sprintf_chk.c in Sources */, + C97A70D81517AF53005E1998 /* stpcpy_chk.c in Sources */, + C97A70D91517AF53005E1998 /* stpncpy_chk.c in Sources */, + C97A70DA1517AF53005E1998 /* strcat_chk.c in Sources */, + C97A70DB1517AF53005E1998 /* strcpy_chk.c in Sources */, + 3FA8F3251643AB8100D37078 /* strlcat_chk.c in Sources */, + 3FA8F3261643AB8100D37078 /* strlcpy_chk.c in Sources */, + C97A70DC1517AF53005E1998 /* strncat_chk.c in Sources */, + C97A70DD1517AF53005E1998 /* strncpy_chk.c in Sources */, + C97A70DE1517AF53005E1998 /* vsnprintf_chk.c in Sources */, + C97A70DF1517AF53005E1998 /* vsprintf_chk.c in Sources */, + C97A70E01517AF53005E1998 /* _flock_stub.c in Sources */, + C97A70E11517AF53005E1998 /* asprintf.c in Sources */, + C97A70E21517AF53005E1998 /* clrerr.c in Sources */, + C97A70E31517AF53005E1998 /* dprintf.c in Sources */, + C97A70E41517AF53005E1998 /* fclose.c in Sources */, + C97A70E51517AF53005E1998 /* fdopen.c in Sources */, + C97A70E61517AF53005E1998 /* feof.c in Sources */, + C97A70E71517AF53005E1998 /* ferror.c in Sources */, + C97A70E81517AF53005E1998 /* fflush.c in Sources */, + C97A70E91517AF53005E1998 /* fgetc.c in Sources */, + C97A70EA1517AF53005E1998 /* fgetln.c in Sources */, + C97A70EB1517AF53005E1998 /* fgetpos.c in Sources */, + C97A70EC1517AF53005E1998 /* fgets.c in Sources */, + C97A70ED1517AF53005E1998 /* fgetwc.c in Sources */, + C97A70EE1517AF53005E1998 /* fgetwln.c in Sources */, + C97A70EF1517AF53005E1998 /* fgetws.c in Sources */, + C97A70F01517AF53005E1998 /* fileno.c in Sources */, + C97A70F11517AF53005E1998 /* findfp.c in Sources */, + C97A70F21517AF53005E1998 /* flags.c in Sources */, + 3FD14575171D42B300B7BAF5 /* bcopy.c in Sources */, + C97A70F31517AF53005E1998 /* fopen.c in Sources */, + C97A70F41517AF53005E1998 /* fprintf.c in Sources */, + C97A70F51517AF53005E1998 /* fpurge.c in Sources */, + C97A70F61517AF53005E1998 /* fputc.c in Sources */, + C97A70F71517AF53005E1998 /* fputs.c in Sources */, + C97A70F81517AF53005E1998 /* fputwc.c in Sources */, + C97A70F91517AF53005E1998 /* fputws.c in Sources */, + C97A70FA1517AF53005E1998 /* fread.c in Sources */, + C97A70FB1517AF53005E1998 /* freopen.c in Sources */, + C97A70FC1517AF53005E1998 /* fscanf.c in Sources */, + C97A70FD1517AF53005E1998 /* fseek.c in Sources */, + C97A70FE1517AF53005E1998 /* fsetpos.c in Sources */, + C97A70FF1517AF53005E1998 /* ftell.c in Sources */, + C97A71001517AF53005E1998 /* funopen.c in Sources */, + C97A71011517AF53005E1998 /* fvwrite.c in Sources */, + C97A71021517AF53005E1998 /* fwalk.c in Sources */, + C97A71031517AF53005E1998 /* fwide.c in Sources */, + C97A71041517AF53005E1998 /* fwprintf.c in Sources */, + C97A71051517AF53005E1998 /* fwrite.c in Sources */, + C97A71061517AF53005E1998 /* fwscanf.c in Sources */, + C97A71071517AF53005E1998 /* getc.c in Sources */, + C97A71081517AF53005E1998 /* getchar.c in Sources */, + C97A71091517AF53005E1998 /* getdelim.c in Sources */, + C97A710A1517AF53005E1998 /* getline.c in Sources */, + C97A710B1517AF53005E1998 /* gets.c in Sources */, + C97A710C1517AF53005E1998 /* getw.c in Sources */, + C97A710D1517AF53005E1998 /* getwc.c in Sources */, + C97A710E1517AF53005E1998 /* getwchar.c in Sources */, + C97A710F1517AF53005E1998 /* makebuf.c in Sources */, + C97A71101517AF53005E1998 /* mktemp.c in Sources */, + C97A71111517AF53005E1998 /* perror.c in Sources */, + C97A71121517AF53005E1998 /* printf-pos.c in Sources */, + C97A71131517AF53005E1998 /* printf.c in Sources */, + C97A71141517AF53005E1998 /* putc.c in Sources */, + C97A71151517AF53005E1998 /* putchar.c in Sources */, + C97A71161517AF53005E1998 /* puts.c in Sources */, + C97A71171517AF53005E1998 /* putw.c in Sources */, + C97A71181517AF53005E1998 /* putwc.c in Sources */, + C97A71191517AF53005E1998 /* putwchar.c in Sources */, + C97A711A1517AF53005E1998 /* refill.c in Sources */, + C97A711B1517AF53005E1998 /* remove.c in Sources */, + C97A711C1517AF53005E1998 /* rewind.c in Sources */, + C97A711D1517AF53005E1998 /* rget.c in Sources */, + C97A711E1517AF53005E1998 /* scanf.c in Sources */, + C97A711F1517AF53005E1998 /* setbuf.c in Sources */, + C97A71201517AF53005E1998 /* setbuffer.c in Sources */, + C97A71211517AF53005E1998 /* setvbuf.c in Sources */, + C97A71221517AF53005E1998 /* snprintf.c in Sources */, + C97A71231517AF53005E1998 /* sprintf.c in Sources */, + C97A71241517AF53005E1998 /* sscanf.c in Sources */, + C97A71251517AF53005E1998 /* stdio.c in Sources */, + C97A71261517AF53005E1998 /* swprintf.c in Sources */, + C97A71271517AF53005E1998 /* swscanf.c in Sources */, + C97A71281517AF53005E1998 /* tempnam.c in Sources */, + C97A71291517AF53005E1998 /* tmpfile.c in Sources */, + C97A712A1517AF53005E1998 /* tmpnam.c in Sources */, + C97A712B1517AF53005E1998 /* ungetc.c in Sources */, + C97A712C1517AF53005E1998 /* ungetwc.c in Sources */, + C97A712D1517AF53005E1998 /* vasprintf.c in Sources */, + C97A712E1517AF53005E1998 /* vdprintf.c in Sources */, + C97A712F1517AF53005E1998 /* vfprintf.c in Sources */, + C97A71301517AF53005E1998 /* vfscanf.c in Sources */, + C97A71311517AF53005E1998 /* vfwprintf.c in Sources */, + C97A71321517AF53005E1998 /* vfwscanf.c in Sources */, + C97A71331517AF53005E1998 /* vprintf.c in Sources */, + C97A71341517AF53005E1998 /* vscanf.c in Sources */, + C97A71351517AF53005E1998 /* vsnprintf.c in Sources */, + C97A71361517AF53005E1998 /* vsprintf.c in Sources */, + C97A71371517AF53005E1998 /* vsscanf.c in Sources */, + C97A71381517AF53005E1998 /* vswprintf.c in Sources */, + C97A71391517AF53005E1998 /* vswscanf.c in Sources */, + C97A713A1517AF53005E1998 /* vwprintf.c in Sources */, + C97A713B1517AF53005E1998 /* vwscanf.c in Sources */, + C97A713C1517AF53005E1998 /* wbuf.c in Sources */, + C97A713D1517AF53005E1998 /* wprintf.c in Sources */, + C97A713E1517AF53005E1998 /* wscanf.c in Sources */, + 147CDFDA1B7C232900831EC6 /* clock_gettime.c in Sources */, + C97A713F1517AF53005E1998 /* wsetup.c in Sources */, + C97A71401517AF53005E1998 /* a64l.c in Sources */, + C97A71411517AF53005E1998 /* _Exit_.c in Sources */, + C97A71421517AF53005E1998 /* abort.c in Sources */, + C97A71431517AF53005E1998 /* abs.c in Sources */, + C97A71441517AF53005E1998 /* atexit.c in Sources */, + C97A71451517AF53005E1998 /* atof.c in Sources */, + C97A71461517AF53005E1998 /* atoi.c in Sources */, + C97A71471517AF53005E1998 /* atol.c in Sources */, + C97A71481517AF53005E1998 /* atoll.c in Sources */, + C97A71491517AF53005E1998 /* bsearch.c in Sources */, + C97A714A1517AF53005E1998 /* div.c in Sources */, + C97A714B1517AF53005E1998 /* exit.c in Sources */, + C97A714C1517AF53005E1998 /* getenv.c in Sources */, + C97A714D1517AF53005E1998 /* getopt.c in Sources */, + C97A714E1517AF53005E1998 /* getopt_long.c in Sources */, + C97A714F1517AF53005E1998 /* getsubopt.c in Sources */, + C97A71501517AF53005E1998 /* hcreate.c in Sources */, + C97A71511517AF53005E1998 /* heapsort.c in Sources */, + C97A71521517AF53005E1998 /* heapsort_b.c in Sources */, + C97A71531517AF53005E1998 /* heapsort_r.c in Sources */, + C97A71541517AF53005E1998 /* imaxabs.c in Sources */, + C97A71551517AF53005E1998 /* imaxdiv.c in Sources */, + C97A71561517AF53005E1998 /* insque.c in Sources */, + C97A71571517AF53005E1998 /* labs.c in Sources */, + C97A71581517AF53005E1998 /* ldiv.c in Sources */, + C97A71591517AF53005E1998 /* llabs.c in Sources */, + C97A715A1517AF53005E1998 /* lldiv.c in Sources */, + C97A715B1517AF53005E1998 /* lsearch.c in Sources */, + C97A715C1517AF53005E1998 /* merge.c in Sources */, + C97A715D1517AF53005E1998 /* putenv.c in Sources */, + C97A715E1517AF53005E1998 /* qsort.c in Sources */, + C97A715F1517AF53005E1998 /* qsort_r.c in Sources */, + C97A71601517AF53005E1998 /* radixsort.c in Sources */, + C97A71611517AF53005E1998 /* rand.c in Sources */, + C97A71621517AF53005E1998 /* random.c in Sources */, + C97A71631517AF53005E1998 /* reallocf.c in Sources */, + C97A71641517AF53005E1998 /* realpath.c in Sources */, + C97A71651517AF53005E1998 /* remque.c in Sources */, + C97A71661517AF53005E1998 /* setenv.c in Sources */, + C97A71671517AF53005E1998 /* strhash.c in Sources */, + C97A71681517AF53005E1998 /* strtoimax.c in Sources */, + C97A71691517AF53005E1998 /* strtol.c in Sources */, + C97A716A1517AF53005E1998 /* strtoll.c in Sources */, + C97A716B1517AF53005E1998 /* strtoq.c in Sources */, + C97A716C1517AF53005E1998 /* strtoul.c in Sources */, + C97A716D1517AF53005E1998 /* strtoull.c in Sources */, + C97A716E1517AF53005E1998 /* strtoumax.c in Sources */, + C97A716F1517AF53005E1998 /* strtouq.c in Sources */, + C97A71701517AF53005E1998 /* system.c in Sources */, + C97A71711517AF53005E1998 /* tdelete.c in Sources */, + C97A71721517AF53005E1998 /* tfind.c in Sources */, + C97A71731517AF53005E1998 /* tsearch.c in Sources */, + C97A71741517AF53005E1998 /* twalk.c in Sources */, + C97A71751517AF53005E1998 /* grantpt.c in Sources */, + C97A71761517AF53005E1998 /* l64a.c in Sources */, + C97A71771517AF53005E1998 /* strfmon.c in Sources */, + C97A71781517AF53005E1998 /* ecvt.c in Sources */, + C97A71791517AF53005E1998 /* gcvt.c in Sources */, + C97A717A1517AF53005E1998 /* qsort_b-fbsd.c in Sources */, + C97A717B1517AF53005E1998 /* asctime.c in Sources */, + C97A717C1517AF53005E1998 /* difftime.c in Sources */, + C97A717D1517AF53005E1998 /* ftime.c in Sources */, + C97A717E1517AF53005E1998 /* localtime.c in Sources */, + C97A717F1517AF53005E1998 /* strftime.c in Sources */, + C97A71801517AF53005E1998 /* strptime.c in Sources */, + C97A71811517AF53005E1998 /* time32.c in Sources */, + C97A71821517AF53005E1998 /* timelocal.c in Sources */, + C97A71831517AF53005E1998 /* getdate.c in Sources */, + C97A71841517AF53005E1998 /* timezone_unix03.c in Sources */, + C97A71881517AF53005E1998 /* index.c in Sources */, + C97A718D1517AF53005E1998 /* memmem.c in Sources */, + C97A71901517AF53005E1998 /* rindex.c in Sources */, + C97A71911517AF53005E1998 /* strcasecmp.c in Sources */, + C97A71921517AF53005E1998 /* strcasestr.c in Sources */, + C97A71951517AF53005E1998 /* strcoll.c in Sources */, + C97A71961517AF53005E1998 /* strcspn.c in Sources */, + C97A71971517AF53005E1998 /* strdup.c in Sources */, + C97A71981517AF53005E1998 /* strerror.c in Sources */, + C97A71991517AF53005E1998 /* strlen.c in Sources */, + C97A719A1517AF53005E1998 /* strmode.c in Sources */, + C97A719C1517AF53005E1998 /* strndup.c in Sources */, + C97A719D1517AF53005E1998 /* strnlen.c in Sources */, + C97A719E1517AF53005E1998 /* strnstr.c in Sources */, + C97A719F1517AF53005E1998 /* strpbrk.c in Sources */, + C97A71A01517AF53005E1998 /* strrchr.c in Sources */, + C97A71A11517AF53005E1998 /* strsep.c in Sources */, + C97A71A21517AF53005E1998 /* strsignal.c in Sources */, + C97A71A31517AF53005E1998 /* strspn.c in Sources */, + C97A71A41517AF53005E1998 /* strstr.c in Sources */, + C97A71A51517AF53005E1998 /* strtok.c in Sources */, + C97A71A61517AF53005E1998 /* strxfrm.c in Sources */, + C97A71A71517AF53005E1998 /* swab.c in Sources */, + C97A71A81517AF53005E1998 /* wcpcpy.c in Sources */, + C97A71A91517AF53005E1998 /* wcpncpy.c in Sources */, + C97A71AA1517AF53005E1998 /* wcscasecmp.c in Sources */, + C97A71AB1517AF53005E1998 /* wcscat.c in Sources */, + C97A71AC1517AF53005E1998 /* wcschr.c in Sources */, + C97A71AD1517AF53005E1998 /* wcscmp.c in Sources */, + C97A71AE1517AF53005E1998 /* wcscoll.c in Sources */, + C97A71AF1517AF53005E1998 /* wcscpy.c in Sources */, + C97A71B01517AF53005E1998 /* wcscspn.c in Sources */, + C97A71B11517AF53005E1998 /* wcsdup.c in Sources */, + C97A71B21517AF53005E1998 /* wcslcat.c in Sources */, + C97A71B31517AF53005E1998 /* wcslcpy.c in Sources */, + C97A71B41517AF53005E1998 /* wcslen.c in Sources */, + C97A71B51517AF53005E1998 /* wcsncasecmp.c in Sources */, + C97A71B61517AF53005E1998 /* wcsncat.c in Sources */, + C97A71B71517AF53005E1998 /* wcsncmp.c in Sources */, + C97A71B81517AF53005E1998 /* wcsncpy.c in Sources */, + C97A71B91517AF53005E1998 /* wcsnlen.c in Sources */, + C97A71BA1517AF53005E1998 /* wcspbrk.c in Sources */, + C97A71BB1517AF53005E1998 /* wcsrchr.c in Sources */, + C97A71BC1517AF53005E1998 /* wcsspn.c in Sources */, + C97A71BD1517AF53005E1998 /* wcsstr.c in Sources */, + C97A71BE1517AF53005E1998 /* wcstok.c in Sources */, + C97A71BF1517AF53005E1998 /* wcswidth.c in Sources */, + C97A71C01517AF53005E1998 /* wcsxfrm.c in Sources */, + C97A71C11517AF53005E1998 /* wmemchr.c in Sources */, + C97A71C21517AF53005E1998 /* wmemcmp.c in Sources */, + C97A71C31517AF53005E1998 /* wmemcpy.c in Sources */, + C97A71C41517AF53005E1998 /* wmemmove.c in Sources */, + C97A71C51517AF53005E1998 /* wmemset.c in Sources */, + C97A71C61517AF53005E1998 /* _libc_init.c in Sources */, + C97A71C71517AF53005E1998 /* _libc_fork_child.c in Sources */, + C97A71C81517AF53005E1998 /* chmodx_np.c in Sources */, + C97A71CA1517AF53005E1998 /* crt_externs.c in Sources */, + C97A71CC1517AF53005E1998 /* fork.c in Sources */, + C97A71CD1517AF53005E1998 /* getgroups.c in Sources */, + C97A71CF1517AF53005E1998 /* gettimeofday.c in Sources */, + C97A71D01517AF53005E1998 /* msgctl.c in Sources */, + C97A71D11517AF53005E1998 /* stack_protector.c in Sources */, + C97A71D21517AF53005E1998 /* openx_np.c in Sources */, + C97A71D31517AF53005E1998 /* OSMemoryNotification.c in Sources */, + C97A71D41517AF53005E1998 /* OSThermalNotification.c in Sources */, + C97A71D51517AF53005E1998 /* posix_spawn.c in Sources */, + C97A71D61517AF53005E1998 /* semctl.c in Sources */, + C97A71D71517AF53005E1998 /* settimeofday.c in Sources */, + C97A71D81517AF53005E1998 /* shmctl.c in Sources */, + C97A71D91517AF53005E1998 /* sigaction.c in Sources */, + C97A71DA1517AF53005E1998 /* (null) in Sources */, + C97A71DD1517AF53005E1998 /* statx_np.c in Sources */, + C97A71DE1517AF53005E1998 /* umaskx_np.c in Sources */, + C97A71E21517AF53005E1998 /* fparseln.c in Sources */, + C97A71E31517AF53005E1998 /* login.c in Sources */, + C97A71E41517AF53005E1998 /* login_tty.c in Sources */, + C97A71E51517AF53005E1998 /* logout.c in Sources */, + C97A71E61517AF53005E1998 /* logwtmp.c in Sources */, + C97A71E71517AF53005E1998 /* mkpath_np.c in Sources */, + C97A71E81517AF53005E1998 /* opendev.c in Sources */, + C97A71E91517AF53005E1998 /* pty.c in Sources */, + C97A71EA1517AF53005E1998 /* clear.c in Sources */, + C97A71EB1517AF53005E1998 /* compare.c in Sources */, + C97A71EC1517AF53005E1998 /* copy.c in Sources */, + C97A71ED1517AF53005E1998 /* gen_uuid.c in Sources */, + C97A71EE1517AF53005E1998 /* isnull.c in Sources */, + C97A71EF1517AF53005E1998 /* pack.c in Sources */, + C97A71F01517AF53005E1998 /* parse.c in Sources */, + C97A71F11517AF53005E1998 /* unpack.c in Sources */, + C97A71F21517AF53005E1998 /* unparse.c in Sources */, + C97A71F71517AF53005E1998 /* (null) in Sources */, + C97A71F81517AF53005E1998 /* (null) in Sources */, + C97A71F91517AF53005E1998 /* (null) in Sources */, + C97A71FA1517AF53005E1998 /* (null) in Sources */, + C97A71FD1517AF53005E1998 /* scandir_b.c in Sources */, + C97A71FF1517AF53005E1998 /* init_cpu_capabilities.c in Sources */, + C97A72001517AF53005E1998 /* pthread_getspecific.s in Sources */, + C97A72011517AF53005E1998 /* pthread_self.s in Sources */, + C97A72021517AF53005E1998 /* pthread_set_self.s in Sources */, + C97A72031517AF53005E1998 /* start_wqthread.s in Sources */, + C97A72041517AF53005E1998 /* thread_start.s in Sources */, + C97A720D1517AF53005E1998 /* strcpy.c in Sources */, + C97A720E1517AF53005E1998 /* strlcpy.c in Sources */, + C97A720F1517AF53005E1998 /* strncpy.c in Sources */, + C97A72101517AF53005E1998 /* stpcpy.c in Sources */, + C97A72111517AF53005E1998 /* stpncpy.c in Sources */, + C97A72121517AF53005E1998 /* strcat.c in Sources */, + C97A72131517AF53005E1998 /* strncat.c in Sources */, + C97A72141517AF53005E1998 /* strlcat.c in Sources */, + C97A72161517AF53005E1998 /* sync_volume_np.c in Sources */, + C97A72171517AF53005E1998 /* dirfd.c in Sources */, + C925D1FD1518F4A2003D315B /* eos_stubs.c in Sources */, + 63505E3C1548525D00B637D7 /* strnlen.s in Sources */, + 4B2C64A415519BC400342BFA /* assumes.c in Sources */, + FC2ED611157D4BE80098EC69 /* inet_ntop.c in Sources */, + FC2ED61A157D4BE80098EC69 /* inet_pton.c in Sources */, + 3F169A3E1643B7BA0029E851 /* memccpy_chk.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -13049,147 +13800,28 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C9EB2F82138F68CB0075BB52 /* cpu_number.s in Sources */, - C9EB2F83138F68CB0075BB52 /* icacheinval.s in Sources */, C9EB2F84138F68CB0075BB52 /* init_cpu_capabilities.c in Sources */, - C9EB2F85138F68CB0075BB52 /* pthread_getspecific.s in Sources */, - C9EB2F86138F68CB0075BB52 /* pthread_self.s in Sources */, - C9EB2F87138F68CB0075BB52 /* pthread_set_self.s in Sources */, - C9EB2F88138F68CB0075BB52 /* start_wqthread.s in Sources */, - C9EB2F89138F68CB0075BB52 /* thread_start.s in Sources */, - C9EB2F8B138F68CB0075BB52 /* bcopy_CortexA8.s in Sources */, - C9EB2F8C138F68CB0075BB52 /* bcopy_CortexA9.s in Sources */, - C9EB2F8D138F68CB0075BB52 /* bcopy_Generic.s in Sources */, - C9EB2F8E138F68CB0075BB52 /* bzero_CortexA8.s in Sources */, - C9EB2F8F138F68CB0075BB52 /* bzero_CortexA9.s in Sources */, - C9EB2F90138F68CB0075BB52 /* bzero_Generic.s in Sources */, - C9EB2F91138F68CB0075BB52 /* dyld_resolvers.c in Sources */, - C9EB2F92138F68CB0075BB52 /* ffs.s in Sources */, - C9EB2F93138F68CB0075BB52 /* memcmp.s in Sources */, - C9EB2F94138F68CB0075BB52 /* memset_pattern.s in Sources */, - C9EB2F95138F68CB0075BB52 /* strchr.s in Sources */, - C9EB2F96138F68CB0075BB52 /* strcmp.s in Sources */, C9EB2F99138F68CB0075BB52 /* strlen.s in Sources */, - C9EB2F9A138F68CB0075BB52 /* strncmp.s in Sources */, C9EB2F9C138F68CB0075BB52 /* strnlen.s in Sources */, C9EB2F9D138F68CB0075BB52 /* strstr.s in Sources */, - C9EB2F9E138F68CB0075BB52 /* _longjmp.s in Sources */, - C9EB2FA0138F68CB0075BB52 /* _setjmp.s in Sources */, - C9EB2FA1138F68CB0075BB52 /* arm_commpage_gettimeofday.c in Sources */, - C9EB2FA2138F68CB0075BB52 /* gcc_atomic.c in Sources */, - C9EB2FA3138F68CB0075BB52 /* longjmp.s in Sources */, - C9EB2FA4138F68CB0075BB52 /* mach_absolute_time.s in Sources */, - C9EB2FA5138F68CB0075BB52 /* OSAtomic-v4.c in Sources */, - C9EB2FA7138F68CB0075BB52 /* OSAtomic_resolvers.c in Sources */, - C9EB2FA9138F68CB0075BB52 /* setjmp.s in Sources */, - C9EB2F4C138F68A80075BB52 /* _ctx_start.S in Sources */, - C9EB2F4D138F68A80075BB52 /* _setcontext.S in Sources */, - C9EB2F4E138F68A80075BB52 /* cpu_number.s in Sources */, - C9EB2F4F138F68A80075BB52 /* getcontext.S in Sources */, - C9EB2F50138F68A80075BB52 /* getmcontext.c in Sources */, - C9EB2F51138F68A80075BB52 /* icacheinval.s in Sources */, - C9EB2F52138F68A80075BB52 /* makecontext.c in Sources */, C9EB2F53138F68A80075BB52 /* mcount.s in Sources */, - C9EB2F54138F68A80075BB52 /* setcontext.c in Sources */, - C9EB2F55138F68A80075BB52 /* setjmperr.c in Sources */, - C9EB2F56138F68A80075BB52 /* swapcontext.c in Sources */, - C9EB2F57138F68A80075BB52 /* init_cpu_capabilities.c in Sources */, - C9EB2F58138F68A80075BB52 /* preempt.s in Sources */, - C9EB2F59138F68A80075BB52 /* pthread_getspecific.s in Sources */, - C9EB2F5A138F68A80075BB52 /* pthread_mutex_lock.s in Sources */, - C9EB2F5B138F68A80075BB52 /* pthread_self.s in Sources */, - C9EB2F5C138F68A80075BB52 /* pthread_set_self.s in Sources */, - C9EB2F5D138F68A80075BB52 /* start_wqthread.s in Sources */, - C9EB2F5E138F68A80075BB52 /* thread_start.s in Sources */, - C9EB2F60138F68A80075BB52 /* __bzero.s in Sources */, - C9EB2F61138F68A80075BB52 /* bcopy.c in Sources */, - C9EB2F62138F68A80075BB52 /* bcopy_scalar.s in Sources */, - C9EB2F63138F68A80075BB52 /* bcopy_sse2.s in Sources */, - C9EB2F64138F68A80075BB52 /* bcopy_sse3x.s in Sources */, - C9EB2F65138F68A80075BB52 /* bcopy_sse42.s in Sources */, - C9EB2F66138F68A80075BB52 /* bzero.c in Sources */, - C9EB2F67138F68A80075BB52 /* bzero_scalar.s in Sources */, - C9EB2F68138F68A80075BB52 /* bzero_sse2.s in Sources */, - C9EB2F69138F68A80075BB52 /* bzero_sse42.s in Sources */, - C9EB2F6A138F68A80075BB52 /* ffs.s in Sources */, - C9EB2F6B138F68A80075BB52 /* longcopy_sse3x.s in Sources */, - C9EB2F6C138F68A80075BB52 /* memcmp.s in Sources */, - C9EB2F6D138F68A80075BB52 /* memcpy.c in Sources */, - C9EB2F6E138F68A80075BB52 /* memmove.c in Sources */, - C9EB2F6F138F68A80075BB52 /* memset.s in Sources */, - C9EB2F70138F68A80075BB52 /* memset_pattern_sse2.s in Sources */, - C9EB2F71138F68A80075BB52 /* strcmp.s in Sources */, C9EB2F72138F68A80075BB52 /* strcpy.s in Sources */, C9EB2F73138F68A80075BB52 /* strlcat.s in Sources */, C9EB2F74138F68A80075BB52 /* strlcpy.s in Sources */, C9EB2F75138F68A80075BB52 /* strlen.s in Sources */, - C9EB2F76138F68A80075BB52 /* strncmp.s in Sources */, C9EB2F77138F68A80075BB52 /* strncpy.s in Sources */, - C9EB2F78138F68A80075BB52 /* _setjmp.s in Sources */, - C9EB2F79138F68A80075BB52 /* _sigtramp.s in Sources */, - C9EB2F7A138F68A80075BB52 /* atomic.c in Sources */, - C9EB2F7B138F68A80075BB52 /* i386_gettimeofday_asm.s in Sources */, - C9EB2F7C138F68A80075BB52 /* mach_absolute_time.c in Sources */, - C9EB2F7D138F68A80075BB52 /* mach_absolute_time_asm.s in Sources */, - C9EB2F7E138F68A80075BB52 /* OSAtomic.s in Sources */, - C9EB2F7F138F68A80075BB52 /* setjmp.s in Sources */, - C9EB2F80138F68A80075BB52 /* spinlocks.c in Sources */, - C9EB2F81138F68A80075BB52 /* spinlocks_asm.s in Sources */, - C9B53E57138DA5910028D27C /* _ctx_start.S in Sources */, - C9B53E58138DA5910028D27C /* _setcontext.S in Sources */, - C9B53E59138DA5910028D27C /* cpu_number.s in Sources */, - C9B53E5A138DA5910028D27C /* getcontext.S in Sources */, - C9B53E5B138DA5910028D27C /* getmcontext.c in Sources */, - C9B53E5C138DA5910028D27C /* icacheinval.s in Sources */, - C9B53E5D138DA5910028D27C /* makecontext.c in Sources */, C9B53E5E138DA5910028D27C /* mcount.s in Sources */, - C9B53E5F138DA5910028D27C /* setcontext.c in Sources */, - C9B53E60138DA5910028D27C /* swapcontext.c in Sources */, - C9B53E62138DA5950028D27C /* preempt.s in Sources */, - C9B53E63138DA5950028D27C /* pthread_getspecific.s in Sources */, - C9B53E64138DA5950028D27C /* pthread_mutex_lock.s in Sources */, - C9B53E65138DA5950028D27C /* pthread_self.s in Sources */, - C9B53E66138DA5950028D27C /* pthread_set_self.s in Sources */, - C9B53E67138DA5950028D27C /* start_wqthread.s in Sources */, - C9B53E68138DA5950028D27C /* thread_start.s in Sources */, - C9B53E69138DA59F0028D27C /* __bzero.s in Sources */, - C9B53E6A138DA59F0028D27C /* bcopy.c in Sources */, - C9B53E6B138DA59F0028D27C /* bcopy_sse3x.s in Sources */, - C9B53E6C138DA59F0028D27C /* bcopy_sse42.s in Sources */, - C9B53E6D138DA59F0028D27C /* bzero.c in Sources */, - C9B53E6E138DA59F0028D27C /* bzero_sse2.s in Sources */, - C9B53E6F138DA59F0028D27C /* bzero_sse42.s in Sources */, - C9B53E70138DA59F0028D27C /* ffs.s in Sources */, - C9B53E71138DA59F0028D27C /* longcopy_sse3x.s in Sources */, - C9B53E72138DA59F0028D27C /* memcmp.s in Sources */, - C9B53E73138DA59F0028D27C /* memcpy.c in Sources */, - C9B53E74138DA59F0028D27C /* memmove.c in Sources */, - C9B53E75138DA59F0028D27C /* memset.s in Sources */, - C9B53E76138DA59F0028D27C /* strcmp.s in Sources */, C9B53E77138DA59F0028D27C /* strcpy.s in Sources */, - C9B53E78138DA59F0028D27C /* strlcat.s in Sources */, - C9B53E79138DA59F0028D27C /* strlcpy.s in Sources */, C9B53E7A138DA59F0028D27C /* strlen.s in Sources */, - C9B53E7B138DA59F0028D27C /* strncmp.s in Sources */, C9B53E7C138DA59F0028D27C /* strncpy.s in Sources */, - C9B53E7D138DA5A30028D27C /* _setjmp.s in Sources */, - C9B53E7E138DA5A30028D27C /* _sigtramp.s in Sources */, - C9B53E7F138DA5A30028D27C /* atomic.c in Sources */, - C9B53E80138DA5A30028D27C /* i386_gettimeofday_asm.s in Sources */, - C9B53E81138DA5A30028D27C /* nanotime.s in Sources */, - C9B53E82138DA5A30028D27C /* OSAtomic.s in Sources */, - C9B53E83138DA5A30028D27C /* setjmp.s in Sources */, - C9B53E84138DA5A30028D27C /* spinlocks.c in Sources */, - C9B53E85138DA5A30028D27C /* spinlocks_asm.s in Sources */, - C9EB3556138F7F6A0075BB52 /* setjmperr.c in Sources */, - 6358199113B53DD800CDF61C /* bzero_Swift.s in Sources */, - 6358199313B53ECC00CDF61C /* bcopy_Swift.s in Sources */, - 634C4C3813BCEADC008CA66D /* memset_pattern_Swift.s in Sources */, - C995462813AAA25000A531B4 /* OSAtomicUP.c in Sources */, - C97C344113AB0E1B00713550 /* Spinlocks.c in Sources */, - C980F8EC13AB168D0069AB06 /* SpinlocksUP.c in Sources */, - C932C2D013AB1C73004EDA12 /* SpinlocksWFE.c in Sources */, - C9B4E3D813BBBF2D0008A9BB /* OSAtomic.c in Sources */, + C921D3891395B7DD001CE070 /* init_cpu_capabilities.c in Sources */, + C921D38A1395B7DD001CE070 /* pthread_getspecific.s in Sources */, + C921D38B1395B7DD001CE070 /* pthread_self.s in Sources */, + C921D38C1395B7DD001CE070 /* pthread_set_self.s in Sources */, + C921D38D1395B7DD001CE070 /* start_wqthread.s in Sources */, + C921D38E1395B7DD001CE070 /* thread_start.s in Sources */, + 63505E3D1548525D00B637D7 /* strnlen.s in Sources */, + 639D126C15595DDE00D0403A /* strnlen.s in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -13197,22 +13829,16 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C9258122138E3CA100B3107C /* magmallocProvider.d in Sources */, - C9C2A95C138E03C700287F00 /* dirhelper.defs in Sources */, - C9C2A99C138E06D900287F00 /* asl_ipc.defs in Sources */, C9C2A959138E025700287F00 /* sigaltstk.c in Sources */, C9C2A95A138E025700287F00 /* sigcompat.c in Sources */, - C9C2A95D138E03C700287F00 /* libproc.c in Sources */, - C9C2A95E138E03C700287F00 /* proc_listpidspath.c in Sources */, + 147CDFDB1B7C232A00831EC6 /* clock_gettime.c in Sources */, C9C2A97D138E058200287F00 /* brk.c in Sources */, C9C2A97E138E058200287F00 /* bsd_signal.c in Sources */, C9C2A97F138E058200287F00 /* lchflags.c in Sources */, C9C2A980138E058200287F00 /* lchmod.c in Sources */, C9C2A981138E058200287F00 /* lutimes.c in Sources */, C9C2A982138E058200287F00 /* statvfs.c in Sources */, - C9C2A9A1138E06D900287F00 /* assumes.c in Sources */, C9C2A9A2138E06D900287F00 /* backtrace.c in Sources */, - C9C2A9A3138E06D900287F00 /* cache.c in Sources */, C9C2A9A4138E06D900287F00 /* confstr.c in Sources */, C9C2A9A5138E06D900287F00 /* crypt.c in Sources */, C9C2A9A6138E06D900287F00 /* devname.c in Sources */, @@ -13225,23 +13851,19 @@ C9C2A9AD138E072500287F00 /* getttyent.c in Sources */, C9C2A9AE138E072500287F00 /* getusershell.c in Sources */, C9C2A9AF138E072500287F00 /* getvfsbyname.c in Sources */, - C9C2A9B0138E072500287F00 /* isinf.c in Sources */, - C9C2A9B1138E072500287F00 /* isnan.c in Sources */, + C9ECE2771950E384008E8672 /* atexit_receipt.c in Sources */, C9C2A9B5138E072500287F00 /* nanosleep.c in Sources */, C9C2A9B6138E072500287F00 /* nftw.c in Sources */, - C9C2A9B7138E072500287F00 /* platfunc.c in Sources */, C9C2A9B8138E072500287F00 /* setlogin.c in Sources */, C9C2A9B9138E072600287F00 /* sigsetops.c in Sources */, - C9C2A9BA138E072600287F00 /* stack_logging.c in Sources */, - C9C2A9BB138E072600287F00 /* stack_logging_disk.c in Sources */, C9C2A9BC138E072600287F00 /* strtofflags.c in Sources */, - C9C2A9BD138E072600287F00 /* syslog.c in Sources */, C9C2A9BE138E072600287F00 /* thread_stack_pcs.c in Sources */, C9C2A9BF138E072600287F00 /* uname.c in Sources */, C9C2A9C0138E072600287F00 /* utmpx-darwin.c in Sources */, - C9C2A9C1138E072600287F00 /* wordexp.c in Sources */, + 2DF67CE0184F9CBE00B83A3D /* debug_private.c in Sources */, C9A12853138E0BE00003880A /* gmon.c in Sources */, C9A12854138E0C1C0003880A /* isctype.c in Sources */, + 3FD14576171D42B300B7BAF5 /* bcopy.c in Sources */, C9A12855138E0C1C0003880A /* iswctype.c in Sources */, C9A12856138E0C1C0003880A /* xlocale.c in Sources */, C9A128A0138E0CD10003880A /* acl.c in Sources */, @@ -13250,37 +13872,17 @@ C9A128A3138E0CD10003880A /* acl_flag.c in Sources */, C9A128A4138E0CD10003880A /* acl_perm.c in Sources */, C9A128A5138E0CD10003880A /* acl_translate.c in Sources */, - C9A128A6138E0D0B0003880A /* pthread.c in Sources */, - C9A128A7138E0D0B0003880A /* pthread_cancelable.c in Sources */, - C9A128A8138E0D0B0003880A /* pthread_cond.c in Sources */, - C9A128A9138E0D0B0003880A /* pthread_mutex.c in Sources */, - C9A128AA138E0D0B0003880A /* pthread_rwlock.c in Sources */, - C9A128AB138E0D0B0003880A /* pthread_tsd.c in Sources */, - C9A128AC138E0D0B0003880A /* stack.s in Sources */, - C9A128AD138E0D0B0003880A /* thread_setup.c in Sources */, - C9A128B3138E0D950003880A /* chk_fail.c in Sources */, - C9A128B4138E0D950003880A /* memcpy_chk.c in Sources */, - C9A128B5138E0D950003880A /* memmove_chk.c in Sources */, - C9A128B6138E0D950003880A /* memset_chk.c in Sources */, - C9A128B7138E0D950003880A /* snprintf_chk.c in Sources */, - C9A128B8138E0D950003880A /* sprintf_chk.c in Sources */, - C9A128B9138E0D950003880A /* stpcpy_chk.c in Sources */, - C9A128BA138E0D950003880A /* stpncpy_chk.c in Sources */, - C9A128BB138E0D950003880A /* strcat_chk.c in Sources */, - C9A128BC138E0D950003880A /* strcpy_chk.c in Sources */, - C9A128BD138E0D950003880A /* strncat_chk.c in Sources */, - C9A128BE138E0D950003880A /* strncpy_chk.c in Sources */, - C9A128BF138E0D950003880A /* vsnprintf_chk.c in Sources */, - C9A128C0138E0D950003880A /* vsprintf_chk.c in Sources */, C9A12929138E0EF00003880A /* getdate.c in Sources */, C9A1292A138E0EF00003880A /* timezone_unix03.c in Sources */, - C9A12974138E10AB0003880A /* cprocs.c in Sources */, - C9A12975138E10AB0003880A /* cthreads.c in Sources */, - C9A12976138E10AB0003880A /* mig_support.c in Sources */, + B1795373158B0E35008990E8 /* xprintf_all_in_one.c in Sources */, + B126140515881A000077E3CC /* xprintf_comp.c in Sources */, + B126140615881A000077E3CC /* xprintf_domain.c in Sources */, + B1795374158B0E35008990E8 /* xprintf_exec.c in Sources */, C9A12977138E10C40003880A /* fparseln.c in Sources */, C9A12978138E10C40003880A /* login_tty.c in Sources */, C9A12979138E10C40003880A /* logwtmp.c in Sources */, 3F76864713E91CBC00C94D25 /* mkpath_np.c in Sources */, + 3F34A15D1C4AA80B000D4A82 /* raise.c in Sources */, C9A1297A138E10C40003880A /* opendev.c in Sources */, C9A1297B138E10C40003880A /* pty.c in Sources */, C9A1297C138E10FB0003880A /* clear.c in Sources */, @@ -13292,49 +13894,29 @@ C9A12982138E10FB0003880A /* parse.c in Sources */, C9A12983138E10FB0003880A /* unpack.c in Sources */, C9A12984138E10FB0003880A /* unparse.c in Sources */, - C9C2A95B138E03C700287F00 /* _dirhelper.c in Sources */, C9C2A983138E058200287F00 /* tcgetsid.c in Sources */, - C9C2A998138E06D900287F00 /* _simple.c in Sources */, - C9C2A999138E06D900287F00 /* asl.c in Sources */, - C9C2A99A138E06D900287F00 /* asl_core.c in Sources */, - C9C2A99B138E06D900287F00 /* asl_file.c in Sources */, - C9C2A99D138E06D900287F00 /* asl_legacy1.c in Sources */, - C9C2A99E138E06D900287F00 /* asl_msg.c in Sources */, - C9C2A99F138E06D900287F00 /* asl_store.c in Sources */, - C9C2A9A0138E06D900287F00 /* asl_util.c in Sources */, - C9C2A9B4138E072500287F00 /* malloc.c in Sources */, - C9C2A9B2138E072500287F00 /* magazine_malloc.c in Sources */, - C9FA32FB138E4BD00089A94B /* __libc_init.c in Sources */, + C9FA32FB138E4BD00089A94B /* _libc_init.c in Sources */, C9FA32FC138E4BD00089A94B /* _libc_fork_child.c in Sources */, C9FA32FD138E4BD00089A94B /* chmodx_np.c in Sources */, - C9FA32FE138E4BD00089A94B /* context-stubs.c in Sources */, C9FA32FF138E4BD00089A94B /* crt_externs.c in Sources */, - C9FA3300138E4BD00089A94B /* errno.c in Sources */, C9FA3301138E4BD00089A94B /* fork.c in Sources */, - C9FA3302138E4BD00089A94B /* getiopolicy_np.c in Sources */, C9FA3303138E4BD00089A94B /* gettimeofday.c in Sources */, C9FA3304138E4BD00089A94B /* openx_np.c in Sources */, C9FA3307138E4BD00089A94B /* posix_spawn.c in Sources */, C9FA3308138E4BD00089A94B /* settimeofday.c in Sources */, C9FA3309138E4BD00089A94B /* sigaction.c in Sources */, - C9FA330A138E4BD00089A94B /* sigcatch.c in Sources */, - C9FA330B138E4BD00089A94B /* sigtramp.c in Sources */, - C9FA330C138E4BD00089A94B /* slot_name.c in Sources */, C9FA330D138E4BD00089A94B /* statx_np.c in Sources */, C9FA330E138E4BD00089A94B /* umaskx_np.c in Sources */, C9421014138F23CA004BA536 /* frune.c in Sources */, C9421015138F23CA004BA536 /* mbrune.c in Sources */, C9421016138F23CA004BA536 /* runedepreciated.c in Sources */, C9421017138F23CA004BA536 /* setinvalidrune.c in Sources */, - C9EB2FBB138F6A920075BB52 /* NSSystemDirectories.c in Sources */, C9EB3542138F7D0A0075BB52 /* login.c in Sources */, C9EB3543138F7D0A0075BB52 /* logout.c in Sources */, C9EB3558138F7FF40075BB52 /* nlist.c in Sources */, C9EB355C138F81A40075BB52 /* kvm.c in Sources */, - C9EB355E138F81AB0075BB52 /* MKGetTimeBaseInfo.c in Sources */, C98373971395989E00E5C052 /* OSMemoryNotification.c in Sources */, C98373981395989E00E5C052 /* OSThermalNotification.c in Sources */, - C9CF595A13CD0B9600674871 /* memset_pattern.c in Sources */, 6310518A13D4D9E9004F7BA8 /* strcpy.c in Sources */, 6310518D13D4DABD004F7BA8 /* strlcpy.c in Sources */, 6310519013D4DAEA004F7BA8 /* strncpy.c in Sources */, @@ -13343,9 +13925,9 @@ 63D4060E13DDF26A0094DD56 /* strcat.c in Sources */, 63D4061113DDF4340094DD56 /* strncat.c in Sources */, 63D4061413DDF6A30094DD56 /* strlcat.c in Sources */, - 3F2208E914358B4A00386F5B /* asl_fd.c in Sources */, B19C645D1450F90200032373 /* sync_volume_np.c in Sources */, 3FB7E1B5146EF2E000843438 /* dirfd.c in Sources */, + 4B2C64BA1551B03700342BFA /* assumes.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -13354,7 +13936,7 @@ buildActionMask = 2147483647; files = ( C9D94333138DB75B00FB7ACC /* forceLibcToBuild.c in Sources */, - C965CBF2143BBEC7003912CE /* deps.c in Sources */, + 92ABC7E91D375FC2000DF880 /* compatibility_hacks.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -13363,11 +13945,6 @@ buildActionMask = 2147483647; files = ( C9765EB2138EC61900741512 /* init_cpu_capabilities.c in Sources */, - C9765EB3138EC61900741512 /* dyld_resolvers.c in Sources */, - C9765EB4138EC61900741512 /* arm_commpage_gettimeofday.c in Sources */, - C9765EB5138EC61900741512 /* gcc_atomic.c in Sources */, - C9765EB6138EC61900741512 /* OSAtomic-v4.c in Sources */, - C9765EB7138EC61900741512 /* OSAtomic_resolvers.c in Sources */, C9765EB9138EC61900741512 /* creat.c in Sources */, C9765EBA138EC61900741512 /* gethostid.c in Sources */, C9765EBB138EC61900741512 /* getwd.c in Sources */, @@ -13380,11 +13957,7 @@ C9765EC2138EC61900741512 /* setreuid.c in Sources */, C9765EC3138EC61900741512 /* sigaltstk.c in Sources */, C9765EC4138EC61900741512 /* sigcompat.c in Sources */, - C9765EC5138EC61900741512 /* _dirhelper.c in Sources */, - C9765EC7138EC61900741512 /* libproc.c in Sources */, C9765EC6138EC61900741512 /* kvm.c in Sources */, - C9765EC8138EC61900741512 /* MKGetTimeBaseInfo.c in Sources */, - C9765EC9138EC61900741512 /* proc_listpidspath.c in Sources */, C9765ECA138EC61900741512 /* forceLibcToBuild.c in Sources */, C9765ECB138EC61900741512 /* bt_close.c in Sources */, C9765ECC138EC61900741512 /* bt_conv.c in Sources */, @@ -13449,24 +14022,15 @@ C9765F07138EC61900741512 /* machdep_ldisdd.c in Sources */, C9765F08138EC61900741512 /* machdep_ldisQ.c in Sources */, C9765F09138EC61900741512 /* machdep_ldisx.c in Sources */, - C9765F0A138EC61900741512 /* _simple.c in Sources */, - C9765F0B138EC61900741512 /* asl.c in Sources */, - C9765F0C138EC61900741512 /* asl_core.c in Sources */, - C9765F0D138EC61900741512 /* asl_file.c in Sources */, - C9765F0E138EC61900741512 /* asl_legacy1.c in Sources */, - C9765F0F138EC61900741512 /* asl_msg.c in Sources */, - C9765F10138EC61900741512 /* asl_store.c in Sources */, - C9765F11138EC61900741512 /* asl_util.c in Sources */, - C9765F12138EC61900741512 /* assumes.c in Sources */, C9765F13138EC61900741512 /* authentication.c in Sources */, C9765F14138EC61900741512 /* backtrace.c in Sources */, - C9765F15138EC61900741512 /* cache.c in Sources */, C9765F16138EC61900741512 /* confstr.c in Sources */, C9765F17138EC61900741512 /* crypt.c in Sources */, C9765F18138EC61900741512 /* devname.c in Sources */, C9765F19138EC61900741512 /* disklabel.c in Sources */, C9765F1A138EC61900741512 /* errlst.c in Sources */, C9765F1B138EC61900741512 /* filesec.c in Sources */, + 147CDFDC1B7C232F00831EC6 /* clock_gettime.c in Sources */, C9765F1C138EC61900741512 /* _rand48.c in Sources */, C9765F1D138EC61900741512 /* alarm.c in Sources */, C9765F1E138EC61900741512 /* arc4random.c in Sources */, @@ -13506,7 +14070,6 @@ C9765F40138EC61900741512 /* opendir.c in Sources */, C9765F41138EC61900741512 /* pause.c in Sources */, C9765F42138EC61900741512 /* popen.c in Sources */, - C9765F43138EC61900741512 /* pselect.c in Sources */, C9765F44138EC61900741512 /* psignal.c in Sources */, C9765F45138EC61900741512 /* raise.c in Sources */, C9765F46138EC61900741512 /* readdir.c in Sources */, @@ -13550,42 +14113,19 @@ C9765F6C138EC61900741512 /* getttyent.c in Sources */, C9765F6D138EC61900741512 /* getusershell.c in Sources */, C9765F6E138EC61900741512 /* getvfsbyname.c in Sources */, - C9765F6F138EC61900741512 /* isinf.c in Sources */, - C9765F70138EC61900741512 /* isnan.c in Sources */, - C9765F71138EC61900741512 /* magazine_malloc.c in Sources */, - C9765F72138EC61900741512 /* malloc.c in Sources */, C9765F73138EC61900741512 /* nanosleep.c in Sources */, C9765F74138EC61900741512 /* utmpx.c in Sources */, C9765F75138EC61900741512 /* nftw.c in Sources */, C9765F76138EC61900741512 /* nlist.c in Sources */, - C9765F77138EC61900741512 /* NSSystemDirectories.c in Sources */, C9765F78138EC61900741512 /* oldsyslog.c in Sources */, - C9765F79138EC61900741512 /* platfunc.c in Sources */, - C9765F7A138EC61900741512 /* scalable_malloc.c in Sources */, C9765F7B138EC61900741512 /* setlogin.c in Sources */, C9765F7C138EC61900741512 /* sigsetops.c in Sources */, - C9765F7D138EC61900741512 /* stack_logging.c in Sources */, - C9765F7E138EC61900741512 /* stack_logging_disk.c in Sources */, C9765F7F138EC61900741512 /* strtofflags.c in Sources */, - C9765F80138EC61900741512 /* syslog.c in Sources */, C9765F81138EC61900741512 /* thread_stack_pcs.c in Sources */, C9765F82138EC61900741512 /* uname.c in Sources */, C9765F83138EC61900741512 /* utmpx-darwin.c in Sources */, C9765F84138EC61900741512 /* wordexp.c in Sources */, C9765F86138EC61900741512 /* gmon.c in Sources */, - C9765F87138EC61900741512 /* getmcontext.c in Sources */, - C9765F88138EC61900741512 /* makecontext.c in Sources */, - C9765F89138EC61900741512 /* setcontext.c in Sources */, - C9765F8A138EC61900741512 /* setjmperr.c in Sources */, - C9765F8B138EC61900741512 /* swapcontext.c in Sources */, - C9765F8C138EC61900741512 /* init_cpu_capabilities.c in Sources */, - C9765F8D138EC61900741512 /* bcopy.c in Sources */, - C9765F8E138EC61900741512 /* bzero.c in Sources */, - C9765F8F138EC61900741512 /* memcpy.c in Sources */, - C9765F90138EC61900741512 /* memmove.c in Sources */, - C9765F91138EC61900741512 /* atomic.c in Sources */, - C9765F92138EC61900741512 /* mach_absolute_time.c in Sources */, - C9765F93138EC61900741512 /* spinlocks.c in Sources */, C9765FA6138EC61900741512 /* ascii.c in Sources */, C9765FA7138EC61900741512 /* big5.c in Sources */, C9765FA8138EC61900741512 /* btowc.c in Sources */, @@ -13674,30 +14214,7 @@ C9765FFB138EC61900741512 /* acl_flag.c in Sources */, C9765FFC138EC61900741512 /* acl_perm.c in Sources */, C9765FFD138EC61900741512 /* acl_translate.c in Sources */, - C9766006138EC61900741512 /* mk_pthread_impl.c in Sources */, - C9766007138EC61900741512 /* pthread.c in Sources */, - C9766008138EC61900741512 /* pthread_cancelable.c in Sources */, - C9766009138EC61900741512 /* pthread_cond.c in Sources */, - C976600A138EC61900741512 /* pthread_mutex.c in Sources */, - C976600B138EC61900741512 /* pthread_rwlock.c in Sources */, - C976600C138EC61900741512 /* pthread_tsd.c in Sources */, - C976600D138EC61900741512 /* pthread_atfork_test.c in Sources */, - C976600E138EC61900741512 /* thread_setup.c in Sources */, C9766011138EC61900741512 /* regerror.c in Sources */, - C9766014138EC61900741512 /* chk_fail.c in Sources */, - C9766015138EC61900741512 /* memcpy_chk.c in Sources */, - C9766016138EC61900741512 /* memmove_chk.c in Sources */, - C9766017138EC61900741512 /* memset_chk.c in Sources */, - C9766018138EC61900741512 /* snprintf_chk.c in Sources */, - C9766019138EC61900741512 /* sprintf_chk.c in Sources */, - C976601A138EC61A00741512 /* stpcpy_chk.c in Sources */, - C976601B138EC61A00741512 /* stpncpy_chk.c in Sources */, - C976601C138EC61A00741512 /* strcat_chk.c in Sources */, - C976601D138EC61A00741512 /* strcpy_chk.c in Sources */, - C976601E138EC61A00741512 /* strncat_chk.c in Sources */, - C976601F138EC61A00741512 /* strncpy_chk.c in Sources */, - C9766020138EC61A00741512 /* vsnprintf_chk.c in Sources */, - C9766021138EC61A00741512 /* vsprintf_chk.c in Sources */, C9766022138EC61A00741512 /* _flock_stub.c in Sources */, C9766023138EC61A00741512 /* asprintf.c in Sources */, C9766024138EC61A00741512 /* clrerr.c in Sources */, @@ -13741,6 +14258,7 @@ C976604A138EC61A00741512 /* getchar.c in Sources */, C976604B138EC61A00741512 /* getdelim.c in Sources */, C976604C138EC61A00741512 /* getline.c in Sources */, + 928BD1031D76073300EC01FC /* timingsafe_bcmp.c in Sources */, C976604D138EC61A00741512 /* gets.c in Sources */, C976604E138EC61A00741512 /* getw.c in Sources */, C976604F138EC61A00741512 /* getwc.c in Sources */, @@ -13863,29 +14381,17 @@ C97660C4138EC61A00741512 /* timelocal.c in Sources */, C97660C5138EC61A00741512 /* getdate.c in Sources */, C97660C6138EC61A00741512 /* timezone_unix03.c in Sources */, - C97660C7138EC61A00741512 /* bcmp.c in Sources */, - C97660C8138EC61A00741512 /* bcopy.c in Sources */, - C97660C9138EC61A00741512 /* bzero.c in Sources */, C97660CA138EC61A00741512 /* index.c in Sources */, - C97660CB138EC61A00741512 /* memccpy.c in Sources */, - C97660CC138EC61A00741512 /* memchr.c in Sources */, - C97660CD138EC61A00741512 /* memcmp.c in Sources */, - C97660CE138EC61A00741512 /* memcpy.c in Sources */, C97660CF138EC61A00741512 /* memmem.c in Sources */, - C97660D0138EC61A00741512 /* memmove.c in Sources */, - C97660D1138EC61A00741512 /* memset.c in Sources */, C97660D2138EC61A00741512 /* rindex.c in Sources */, C97660D5138EC61A00741512 /* strcasecmp.c in Sources */, C97660D6138EC61A00741512 /* strcasestr.c in Sources */, - C97660D8138EC61A00741512 /* strchr.c in Sources */, - C97660D9138EC61A00741512 /* strcmp.c in Sources */, C97660DA138EC61A00741512 /* strcoll.c in Sources */, C97660DC138EC61A00741512 /* strcspn.c in Sources */, C97660DD138EC61A00741512 /* strdup.c in Sources */, C97660DE138EC61A00741512 /* strerror.c in Sources */, C97660E1138EC61A00741512 /* strlen.c in Sources */, C97660E2138EC61A00741512 /* strmode.c in Sources */, - C97660E4138EC61A00741512 /* strncmp.c in Sources */, C97660E6138EC61A00741512 /* strndup.c in Sources */, C97660E7138EC61A00741512 /* strnlen.c in Sources */, C97660E8138EC61A00741512 /* strnstr.c in Sources */, @@ -13926,17 +14432,15 @@ C976610B138EC61A00741512 /* wmemchr.c in Sources */, C976610C138EC61A00741512 /* wmemcmp.c in Sources */, C976610D138EC61A00741512 /* wmemcpy.c in Sources */, + 2DF67CE1184F9CBE00B83A3D /* debug_private.c in Sources */, C976610E138EC61A00741512 /* wmemmove.c in Sources */, C976610F138EC61A00741512 /* wmemset.c in Sources */, - C9766110138EC61A00741512 /* __libc_init.c in Sources */, + C9766110138EC61A00741512 /* _libc_init.c in Sources */, C9766111138EC61A00741512 /* _libc_fork_child.c in Sources */, C9766112138EC61A00741512 /* chmodx_np.c in Sources */, - C9766113138EC61A00741512 /* context-stubs.c in Sources */, C9766114138EC61A00741512 /* crt_externs.c in Sources */, - C9766115138EC61A00741512 /* errno.c in Sources */, C9766116138EC61A00741512 /* fork.c in Sources */, C9766117138EC61A00741512 /* getgroups.c in Sources */, - C9766118138EC61A00741512 /* getiopolicy_np.c in Sources */, C9766119138EC61A00741512 /* gettimeofday.c in Sources */, C976611A138EC61A00741512 /* msgctl.c in Sources */, C976611B138EC61A00741512 /* stack_protector.c in Sources */, @@ -13948,14 +14452,8 @@ C9766121138EC61A00741512 /* settimeofday.c in Sources */, C9766122138EC61A00741512 /* shmctl.c in Sources */, C9766123138EC61A00741512 /* sigaction.c in Sources */, - C9766124138EC61A00741512 /* sigcatch.c in Sources */, - C9766125138EC61A00741512 /* sigtramp.c in Sources */, - C9766126138EC61A00741512 /* slot_name.c in Sources */, C9766127138EC61A00741512 /* statx_np.c in Sources */, C9766128138EC61A00741512 /* umaskx_np.c in Sources */, - C9766129138EC61A00741512 /* cprocs.c in Sources */, - C976612A138EC61A00741512 /* cthreads.c in Sources */, - C976612B138EC61A00741512 /* mig_support.c in Sources */, C976612C138EC61A00741512 /* fparseln.c in Sources */, C976612D138EC61A00741512 /* login.c in Sources */, C976612E138EC61A00741512 /* login_tty.c in Sources */, @@ -13973,19 +14471,11 @@ C9766139138EC61A00741512 /* parse.c in Sources */, C976613A138EC61A00741512 /* unpack.c in Sources */, C976613B138EC61A00741512 /* unparse.c in Sources */, - C976613C138EC61A00741512 /* getmcontext.c in Sources */, - C976613D138EC61A00741512 /* makecontext.c in Sources */, - C976613E138EC61A00741512 /* setcontext.c in Sources */, - C976613F138EC61A00741512 /* swapcontext.c in Sources */, - C9766140138EC61A00741512 /* bcopy.c in Sources */, - C9766141138EC61A00741512 /* bzero.c in Sources */, - C9766142138EC61A00741512 /* memcpy.c in Sources */, - C9766143138EC61A00741512 /* memmove.c in Sources */, - C9766144138EC61A00741512 /* atomic.c in Sources */, - C9766145138EC61A00741512 /* spinlocks.c in Sources */, - 3F2208EA14358B4A00386F5B /* asl_fd.c in Sources */, B19C645E1450F90200032373 /* sync_volume_np.c in Sources */, 3FB7E1B6146EF2E000843438 /* dirfd.c in Sources */, + 4B2C64A515519BC600342BFA /* assumes.c in Sources */, + FC2ED613157D4BE80098EC69 /* inet_ntop.c in Sources */, + FC2ED61C157D4BE80098EC69 /* inet_pton.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -13994,11 +14484,6 @@ buildActionMask = 2147483647; files = ( C9EB2FCD138F6D880075BB52 /* init_cpu_capabilities.c in Sources */, - C9EB2FCE138F6D880075BB52 /* dyld_resolvers.c in Sources */, - C9EB2FCF138F6D880075BB52 /* arm_commpage_gettimeofday.c in Sources */, - C9EB2FD0138F6D880075BB52 /* gcc_atomic.c in Sources */, - C9EB2FD1138F6D880075BB52 /* OSAtomic-v4.c in Sources */, - C9EB2FD2138F6D880075BB52 /* OSAtomic_resolvers.c in Sources */, C9EB2FD4138F6D880075BB52 /* creat.c in Sources */, C9EB2FD5138F6D880075BB52 /* gethostid.c in Sources */, C9EB2FD6138F6D880075BB52 /* getwd.c in Sources */, @@ -14011,11 +14496,7 @@ C9EB2FDD138F6D880075BB52 /* setreuid.c in Sources */, C9EB2FDE138F6D880075BB52 /* sigaltstk.c in Sources */, C9EB2FDF138F6D880075BB52 /* sigcompat.c in Sources */, - C9EB2FE0138F6D880075BB52 /* _dirhelper.c in Sources */, C9EB2FE1138F6D880075BB52 /* kvm.c in Sources */, - C9EB2FE2138F6D880075BB52 /* libproc.c in Sources */, - C9EB2FE3138F6D880075BB52 /* MKGetTimeBaseInfo.c in Sources */, - C9EB2FE4138F6D880075BB52 /* proc_listpidspath.c in Sources */, C9EB2FE5138F6D880075BB52 /* forceLibcToBuild.c in Sources */, C9EB2FE6138F6D880075BB52 /* bt_close.c in Sources */, C9EB2FE7138F6D880075BB52 /* bt_conv.c in Sources */, @@ -14080,18 +14561,8 @@ C9EB3022138F6D880075BB52 /* machdep_ldisdd.c in Sources */, C9EB3023138F6D880075BB52 /* machdep_ldisQ.c in Sources */, C9EB3024138F6D880075BB52 /* machdep_ldisx.c in Sources */, - C9EB3025138F6D880075BB52 /* _simple.c in Sources */, - C9EB3026138F6D880075BB52 /* asl.c in Sources */, - C9EB3027138F6D880075BB52 /* asl_core.c in Sources */, - C9EB3028138F6D880075BB52 /* asl_file.c in Sources */, - C9EB3029138F6D880075BB52 /* asl_legacy1.c in Sources */, - C9EB302A138F6D880075BB52 /* asl_msg.c in Sources */, - C9EB302B138F6D880075BB52 /* asl_store.c in Sources */, - C9EB302C138F6D880075BB52 /* asl_util.c in Sources */, - C9EB302D138F6D880075BB52 /* assumes.c in Sources */, C9EB302E138F6D880075BB52 /* authentication.c in Sources */, C9EB302F138F6D880075BB52 /* backtrace.c in Sources */, - C9EB3030138F6D880075BB52 /* cache.c in Sources */, C9EB3031138F6D880075BB52 /* confstr.c in Sources */, C9EB3032138F6D880075BB52 /* crypt.c in Sources */, C9EB3033138F6D880075BB52 /* devname.c in Sources */, @@ -14137,7 +14608,6 @@ C9EB305B138F6D880075BB52 /* opendir.c in Sources */, C9EB305C138F6D880075BB52 /* pause.c in Sources */, C9EB305D138F6D880075BB52 /* popen.c in Sources */, - C9EB305E138F6D880075BB52 /* pselect.c in Sources */, C9EB305F138F6D880075BB52 /* psignal.c in Sources */, C9EB3060138F6D880075BB52 /* raise.c in Sources */, C9EB3061138F6D880075BB52 /* readdir.c in Sources */, @@ -14181,42 +14651,20 @@ C9EB3087138F6D880075BB52 /* getttyent.c in Sources */, C9EB3088138F6D880075BB52 /* getusershell.c in Sources */, C9EB3089138F6D880075BB52 /* getvfsbyname.c in Sources */, - C9EB308A138F6D880075BB52 /* isinf.c in Sources */, - C9EB308B138F6D880075BB52 /* isnan.c in Sources */, - C9EB308C138F6D880075BB52 /* magazine_malloc.c in Sources */, - C9EB308D138F6D880075BB52 /* malloc.c in Sources */, C9EB308E138F6D880075BB52 /* nanosleep.c in Sources */, C9EB308F138F6D880075BB52 /* utmpx.c in Sources */, C9EB3090138F6D880075BB52 /* nftw.c in Sources */, C9EB3091138F6D880075BB52 /* nlist.c in Sources */, - C9EB3092138F6D880075BB52 /* NSSystemDirectories.c in Sources */, C9EB3093138F6D880075BB52 /* oldsyslog.c in Sources */, - C9EB3094138F6D880075BB52 /* platfunc.c in Sources */, - C9EB3095138F6D880075BB52 /* scalable_malloc.c in Sources */, + 928BD1071D76073600EC01FC /* timingsafe_bcmp.c in Sources */, C9EB3096138F6D880075BB52 /* setlogin.c in Sources */, C9EB3097138F6D880075BB52 /* sigsetops.c in Sources */, - C9EB3098138F6D880075BB52 /* stack_logging.c in Sources */, - C9EB3099138F6D880075BB52 /* stack_logging_disk.c in Sources */, C9EB309A138F6D880075BB52 /* strtofflags.c in Sources */, - C9EB309B138F6D880075BB52 /* syslog.c in Sources */, C9EB309C138F6D880075BB52 /* thread_stack_pcs.c in Sources */, C9EB309D138F6D880075BB52 /* uname.c in Sources */, C9EB309E138F6D880075BB52 /* utmpx-darwin.c in Sources */, C9EB309F138F6D880075BB52 /* wordexp.c in Sources */, C9EB30A1138F6D880075BB52 /* gmon.c in Sources */, - C9EB30A2138F6D880075BB52 /* getmcontext.c in Sources */, - C9EB30A3138F6D880075BB52 /* makecontext.c in Sources */, - C9EB30A4138F6D880075BB52 /* setcontext.c in Sources */, - C9EB30A5138F6D880075BB52 /* setjmperr.c in Sources */, - C9EB30A6138F6D880075BB52 /* swapcontext.c in Sources */, - C9EB30A7138F6D880075BB52 /* init_cpu_capabilities.c in Sources */, - C9EB30A8138F6D880075BB52 /* bcopy.c in Sources */, - C9EB30A9138F6D880075BB52 /* bzero.c in Sources */, - C9EB30AA138F6D880075BB52 /* memcpy.c in Sources */, - C9EB30AB138F6D880075BB52 /* memmove.c in Sources */, - C9EB30AC138F6D880075BB52 /* atomic.c in Sources */, - C9EB30AD138F6D880075BB52 /* mach_absolute_time.c in Sources */, - C9EB30AE138F6D880075BB52 /* spinlocks.c in Sources */, C9EB30C1138F6D880075BB52 /* ascii.c in Sources */, C9EB30C2138F6D880075BB52 /* big5.c in Sources */, C9EB30C3138F6D880075BB52 /* btowc.c in Sources */, @@ -14305,30 +14753,7 @@ C9EB3116138F6D880075BB52 /* acl_flag.c in Sources */, C9EB3117138F6D880075BB52 /* acl_perm.c in Sources */, C9EB3118138F6D880075BB52 /* acl_translate.c in Sources */, - C9EB3121138F6D880075BB52 /* mk_pthread_impl.c in Sources */, - C9EB3122138F6D880075BB52 /* pthread.c in Sources */, - C9EB3123138F6D880075BB52 /* pthread_cancelable.c in Sources */, - C9EB3124138F6D880075BB52 /* pthread_cond.c in Sources */, - C9EB3125138F6D880075BB52 /* pthread_mutex.c in Sources */, - C9EB3126138F6D880075BB52 /* pthread_rwlock.c in Sources */, - C9EB3127138F6D880075BB52 /* pthread_tsd.c in Sources */, - C9EB3128138F6D880075BB52 /* pthread_atfork_test.c in Sources */, - C9EB3129138F6D880075BB52 /* thread_setup.c in Sources */, C9EB312C138F6D880075BB52 /* regerror.c in Sources */, - C9EB312F138F6D880075BB52 /* chk_fail.c in Sources */, - C9EB3130138F6D880075BB52 /* memcpy_chk.c in Sources */, - C9EB3131138F6D880075BB52 /* memmove_chk.c in Sources */, - C9EB3132138F6D880075BB52 /* memset_chk.c in Sources */, - C9EB3133138F6D880075BB52 /* snprintf_chk.c in Sources */, - C9EB3134138F6D880075BB52 /* sprintf_chk.c in Sources */, - C9EB3135138F6D880075BB52 /* stpcpy_chk.c in Sources */, - C9EB3136138F6D880075BB52 /* stpncpy_chk.c in Sources */, - C9EB3137138F6D880075BB52 /* strcat_chk.c in Sources */, - C9EB3138138F6D880075BB52 /* strcpy_chk.c in Sources */, - C9EB3139138F6D880075BB52 /* strncat_chk.c in Sources */, - C9EB313A138F6D880075BB52 /* strncpy_chk.c in Sources */, - C9EB313B138F6D880075BB52 /* vsnprintf_chk.c in Sources */, - C9EB313C138F6D880075BB52 /* vsprintf_chk.c in Sources */, C9EB313D138F6D880075BB52 /* _flock_stub.c in Sources */, C9EB313E138F6D880075BB52 /* asprintf.c in Sources */, C9EB313F138F6D880075BB52 /* clrerr.c in Sources */, @@ -14346,6 +14771,7 @@ C9EB314B138F6D880075BB52 /* fgetwln.c in Sources */, C9EB314C138F6D880075BB52 /* fgetws.c in Sources */, C9EB314D138F6D880075BB52 /* fileno.c in Sources */, + 147CDFE01B7C233200831EC6 /* clock_gettime.c in Sources */, C9EB314E138F6D880075BB52 /* findfp.c in Sources */, C9EB314F138F6D880075BB52 /* flags.c in Sources */, C9EB3150138F6D880075BB52 /* fopen.c in Sources */, @@ -14494,29 +14920,17 @@ C9EB31DF138F6D880075BB52 /* timelocal.c in Sources */, C9EB31E0138F6D880075BB52 /* getdate.c in Sources */, C9EB31E1138F6D880075BB52 /* timezone_unix03.c in Sources */, - C9EB31E2138F6D880075BB52 /* bcmp.c in Sources */, - C9EB31E3138F6D880075BB52 /* bcopy.c in Sources */, - C9EB31E4138F6D880075BB52 /* bzero.c in Sources */, C9EB31E5138F6D880075BB52 /* index.c in Sources */, - C9EB31E6138F6D880075BB52 /* memccpy.c in Sources */, - C9EB31E7138F6D880075BB52 /* memchr.c in Sources */, - C9EB31E8138F6D880075BB52 /* memcmp.c in Sources */, - C9EB31E9138F6D880075BB52 /* memcpy.c in Sources */, C9EB31EA138F6D880075BB52 /* memmem.c in Sources */, - C9EB31EB138F6D880075BB52 /* memmove.c in Sources */, - C9EB31EC138F6D880075BB52 /* memset.c in Sources */, C9EB31ED138F6D880075BB52 /* rindex.c in Sources */, C9EB31F0138F6D880075BB52 /* strcasecmp.c in Sources */, C9EB31F1138F6D880075BB52 /* strcasestr.c in Sources */, - C9EB31F3138F6D880075BB52 /* strchr.c in Sources */, - C9EB31F4138F6D880075BB52 /* strcmp.c in Sources */, C9EB31F5138F6D880075BB52 /* strcoll.c in Sources */, C9EB31F7138F6D880075BB52 /* strcspn.c in Sources */, C9EB31F8138F6D880075BB52 /* strdup.c in Sources */, C9EB31F9138F6D880075BB52 /* strerror.c in Sources */, C9EB31FC138F6D880075BB52 /* strlen.c in Sources */, C9EB31FD138F6D880075BB52 /* strmode.c in Sources */, - C9EB31FF138F6D880075BB52 /* strncmp.c in Sources */, C9EB3201138F6D880075BB52 /* strndup.c in Sources */, C9EB3202138F6D880075BB52 /* strnlen.c in Sources */, C9EB3203138F6D880075BB52 /* strnstr.c in Sources */, @@ -14548,6 +14962,7 @@ C9EB321D138F6D880075BB52 /* wcsncpy.c in Sources */, C9EB321E138F6D880075BB52 /* wcsnlen.c in Sources */, C9EB321F138F6D880075BB52 /* wcspbrk.c in Sources */, + 2DF67CE5184F9CBE00B83A3D /* debug_private.c in Sources */, C9EB3220138F6D880075BB52 /* wcsrchr.c in Sources */, C9EB3221138F6D880075BB52 /* wcsspn.c in Sources */, C9EB3222138F6D880075BB52 /* wcsstr.c in Sources */, @@ -14559,15 +14974,12 @@ C9EB3228138F6D880075BB52 /* wmemcpy.c in Sources */, C9EB3229138F6D880075BB52 /* wmemmove.c in Sources */, C9EB322A138F6D880075BB52 /* wmemset.c in Sources */, - C9EB322B138F6D880075BB52 /* __libc_init.c in Sources */, + C9EB322B138F6D880075BB52 /* _libc_init.c in Sources */, C9EB322C138F6D880075BB52 /* _libc_fork_child.c in Sources */, C9EB322D138F6D880075BB52 /* chmodx_np.c in Sources */, - C9EB322E138F6D880075BB52 /* context-stubs.c in Sources */, C9EB322F138F6D880075BB52 /* crt_externs.c in Sources */, - C9EB3230138F6D880075BB52 /* errno.c in Sources */, C9EB3231138F6D880075BB52 /* fork.c in Sources */, C9EB3232138F6D880075BB52 /* getgroups.c in Sources */, - C9EB3233138F6D880075BB52 /* getiopolicy_np.c in Sources */, C9EB3234138F6D880075BB52 /* gettimeofday.c in Sources */, C9EB3235138F6D880075BB52 /* msgctl.c in Sources */, C9EB3236138F6D880075BB52 /* stack_protector.c in Sources */, @@ -14579,14 +14991,8 @@ C9EB323C138F6D880075BB52 /* settimeofday.c in Sources */, C9EB323D138F6D880075BB52 /* shmctl.c in Sources */, C9EB323E138F6D880075BB52 /* sigaction.c in Sources */, - C9EB323F138F6D880075BB52 /* sigcatch.c in Sources */, - C9EB3240138F6D880075BB52 /* sigtramp.c in Sources */, - C9EB3241138F6D880075BB52 /* slot_name.c in Sources */, C9EB3242138F6D880075BB52 /* statx_np.c in Sources */, C9EB3243138F6D880075BB52 /* umaskx_np.c in Sources */, - C9EB3244138F6D880075BB52 /* cprocs.c in Sources */, - C9EB3245138F6D880075BB52 /* cthreads.c in Sources */, - C9EB3246138F6D880075BB52 /* mig_support.c in Sources */, C9EB3247138F6D880075BB52 /* fparseln.c in Sources */, C9EB3248138F6D880075BB52 /* login.c in Sources */, C9EB3249138F6D880075BB52 /* login_tty.c in Sources */, @@ -14604,20 +15010,12 @@ C9EB3254138F6D880075BB52 /* parse.c in Sources */, C9EB3255138F6D880075BB52 /* unpack.c in Sources */, C9EB3256138F6D880075BB52 /* unparse.c in Sources */, - C9EB3257138F6D880075BB52 /* getmcontext.c in Sources */, - C9EB3258138F6D880075BB52 /* makecontext.c in Sources */, - C9EB3259138F6D880075BB52 /* setcontext.c in Sources */, - C9EB325A138F6D880075BB52 /* swapcontext.c in Sources */, - C9EB325B138F6D880075BB52 /* bcopy.c in Sources */, - C9EB325C138F6D880075BB52 /* bzero.c in Sources */, - C9EB325D138F6D880075BB52 /* memcpy.c in Sources */, - C9EB325E138F6D880075BB52 /* memmove.c in Sources */, - C9EB325F138F6D880075BB52 /* atomic.c in Sources */, - C9EB3260138F6D880075BB52 /* spinlocks.c in Sources */, B10BC41C14338AEB005E4366 /* regcomp.c in Sources */, - 3F2208EE14358B4A00386F5B /* asl_fd.c in Sources */, B19C64621450F90200032373 /* sync_volume_np.c in Sources */, 3FB7E1BA146EF2E000843438 /* dirfd.c in Sources */, + 4B2C64A915519BC800342BFA /* assumes.c in Sources */, + FC2ED617157D4BE80098EC69 /* inet_ntop.c in Sources */, + FC2ED620157D4BE80098EC69 /* inet_pton.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14626,11 +15024,6 @@ buildActionMask = 2147483647; files = ( C9EB3274138F75580075BB52 /* init_cpu_capabilities.c in Sources */, - C9EB3275138F75580075BB52 /* dyld_resolvers.c in Sources */, - C9EB3276138F75580075BB52 /* arm_commpage_gettimeofday.c in Sources */, - C9EB3277138F75580075BB52 /* gcc_atomic.c in Sources */, - C9EB3278138F75580075BB52 /* OSAtomic-v4.c in Sources */, - C9EB3279138F75580075BB52 /* OSAtomic_resolvers.c in Sources */, C9EB327B138F75580075BB52 /* creat.c in Sources */, C9EB327C138F75580075BB52 /* gethostid.c in Sources */, C9EB327D138F75580075BB52 /* getwd.c in Sources */, @@ -14643,11 +15036,7 @@ C9EB3284138F75580075BB52 /* setreuid.c in Sources */, C9EB3285138F75580075BB52 /* sigaltstk.c in Sources */, C9EB3286138F75580075BB52 /* sigcompat.c in Sources */, - C9EB3287138F75580075BB52 /* _dirhelper.c in Sources */, C9EB3288138F75580075BB52 /* kvm.c in Sources */, - C9EB3289138F75580075BB52 /* libproc.c in Sources */, - C9EB328A138F75580075BB52 /* MKGetTimeBaseInfo.c in Sources */, - C9EB328B138F75580075BB52 /* proc_listpidspath.c in Sources */, C9EB328C138F75580075BB52 /* forceLibcToBuild.c in Sources */, C9EB328D138F75580075BB52 /* bt_close.c in Sources */, C9EB328E138F75580075BB52 /* bt_conv.c in Sources */, @@ -14712,18 +15101,8 @@ C9EB32C9138F75580075BB52 /* machdep_ldisdd.c in Sources */, C9EB32CA138F75580075BB52 /* machdep_ldisQ.c in Sources */, C9EB32CB138F75580075BB52 /* machdep_ldisx.c in Sources */, - C9EB32CC138F75580075BB52 /* _simple.c in Sources */, - C9EB32CD138F75580075BB52 /* asl.c in Sources */, - C9EB32CE138F75580075BB52 /* asl_core.c in Sources */, - C9EB32CF138F75580075BB52 /* asl_file.c in Sources */, - C9EB32D0138F75580075BB52 /* asl_legacy1.c in Sources */, - C9EB32D1138F75580075BB52 /* asl_msg.c in Sources */, - C9EB32D2138F75580075BB52 /* asl_store.c in Sources */, - C9EB32D3138F75580075BB52 /* asl_util.c in Sources */, - C9EB32D4138F75580075BB52 /* assumes.c in Sources */, C9EB32D5138F75580075BB52 /* authentication.c in Sources */, C9EB32D6138F75580075BB52 /* backtrace.c in Sources */, - C9EB32D7138F75580075BB52 /* cache.c in Sources */, C9EB32D8138F75580075BB52 /* confstr.c in Sources */, C9EB32D9138F75580075BB52 /* crypt.c in Sources */, C9EB32DA138F75580075BB52 /* devname.c in Sources */, @@ -14769,7 +15148,6 @@ C9EB3302138F75580075BB52 /* opendir.c in Sources */, C9EB3303138F75580075BB52 /* pause.c in Sources */, C9EB3304138F75580075BB52 /* popen.c in Sources */, - C9EB3305138F75580075BB52 /* pselect.c in Sources */, C9EB3306138F75580075BB52 /* psignal.c in Sources */, C9EB3307138F75580075BB52 /* raise.c in Sources */, C9EB3308138F75580075BB52 /* readdir.c in Sources */, @@ -14813,42 +15191,20 @@ C9EB332E138F75580075BB52 /* getttyent.c in Sources */, C9EB332F138F75580075BB52 /* getusershell.c in Sources */, C9EB3330138F75580075BB52 /* getvfsbyname.c in Sources */, - C9EB3331138F75580075BB52 /* isinf.c in Sources */, - C9EB3332138F75580075BB52 /* isnan.c in Sources */, - C9EB3333138F75580075BB52 /* magazine_malloc.c in Sources */, - C9EB3334138F75580075BB52 /* malloc.c in Sources */, C9EB3335138F75580075BB52 /* nanosleep.c in Sources */, C9EB3336138F75580075BB52 /* utmpx.c in Sources */, C9EB3337138F75580075BB52 /* nftw.c in Sources */, C9EB3338138F75580075BB52 /* nlist.c in Sources */, - C9EB3339138F75580075BB52 /* NSSystemDirectories.c in Sources */, C9EB333A138F75580075BB52 /* oldsyslog.c in Sources */, - C9EB333B138F75580075BB52 /* platfunc.c in Sources */, - C9EB333C138F75580075BB52 /* scalable_malloc.c in Sources */, + 928BD1081D76073600EC01FC /* timingsafe_bcmp.c in Sources */, C9EB333D138F75580075BB52 /* setlogin.c in Sources */, C9EB333E138F75580075BB52 /* sigsetops.c in Sources */, - C9EB333F138F75580075BB52 /* stack_logging.c in Sources */, - C9EB3340138F75580075BB52 /* stack_logging_disk.c in Sources */, C9EB3341138F75580075BB52 /* strtofflags.c in Sources */, - C9EB3342138F75580075BB52 /* syslog.c in Sources */, C9EB3343138F75580075BB52 /* thread_stack_pcs.c in Sources */, C9EB3344138F75580075BB52 /* uname.c in Sources */, C9EB3345138F75580075BB52 /* utmpx-darwin.c in Sources */, C9EB3346138F75580075BB52 /* wordexp.c in Sources */, C9EB3348138F75580075BB52 /* gmon.c in Sources */, - C9EB3349138F75580075BB52 /* getmcontext.c in Sources */, - C9EB334A138F75580075BB52 /* makecontext.c in Sources */, - C9EB334B138F75580075BB52 /* setcontext.c in Sources */, - C9EB334C138F75580075BB52 /* setjmperr.c in Sources */, - C9EB334D138F75580075BB52 /* swapcontext.c in Sources */, - C9EB334E138F75580075BB52 /* init_cpu_capabilities.c in Sources */, - C9EB334F138F75580075BB52 /* bcopy.c in Sources */, - C9EB3350138F75580075BB52 /* bzero.c in Sources */, - C9EB3351138F75580075BB52 /* memcpy.c in Sources */, - C9EB3352138F75580075BB52 /* memmove.c in Sources */, - C9EB3353138F75580075BB52 /* atomic.c in Sources */, - C9EB3354138F75580075BB52 /* mach_absolute_time.c in Sources */, - C9EB3355138F75580075BB52 /* spinlocks.c in Sources */, C9EB3368138F75580075BB52 /* ascii.c in Sources */, C9EB3369138F75580075BB52 /* big5.c in Sources */, C9EB336A138F75580075BB52 /* btowc.c in Sources */, @@ -14937,30 +15293,7 @@ C9EB33BD138F75580075BB52 /* acl_flag.c in Sources */, C9EB33BE138F75580075BB52 /* acl_perm.c in Sources */, C9EB33BF138F75580075BB52 /* acl_translate.c in Sources */, - C9EB33C8138F75580075BB52 /* mk_pthread_impl.c in Sources */, - C9EB33C9138F75580075BB52 /* pthread.c in Sources */, - C9EB33CA138F75580075BB52 /* pthread_cancelable.c in Sources */, - C9EB33CB138F75580075BB52 /* pthread_cond.c in Sources */, - C9EB33CC138F75580075BB52 /* pthread_mutex.c in Sources */, - C9EB33CD138F75580075BB52 /* pthread_rwlock.c in Sources */, - C9EB33CE138F75580075BB52 /* pthread_tsd.c in Sources */, - C9EB33CF138F75580075BB52 /* pthread_atfork_test.c in Sources */, - C9EB33D0138F75580075BB52 /* thread_setup.c in Sources */, C9EB33D3138F75580075BB52 /* regerror.c in Sources */, - C9EB33D6138F75580075BB52 /* chk_fail.c in Sources */, - C9EB33D7138F75580075BB52 /* memcpy_chk.c in Sources */, - C9EB33D8138F75580075BB52 /* memmove_chk.c in Sources */, - C9EB33D9138F75580075BB52 /* memset_chk.c in Sources */, - C9EB33DA138F75580075BB52 /* snprintf_chk.c in Sources */, - C9EB33DB138F75580075BB52 /* sprintf_chk.c in Sources */, - C9EB33DC138F75580075BB52 /* stpcpy_chk.c in Sources */, - C9EB33DD138F75580075BB52 /* stpncpy_chk.c in Sources */, - C9EB33DE138F75580075BB52 /* strcat_chk.c in Sources */, - C9EB33DF138F75580075BB52 /* strcpy_chk.c in Sources */, - C9EB33E0138F75580075BB52 /* strncat_chk.c in Sources */, - C9EB33E1138F75580075BB52 /* strncpy_chk.c in Sources */, - C9EB33E2138F75580075BB52 /* vsnprintf_chk.c in Sources */, - C9EB33E3138F75580075BB52 /* vsprintf_chk.c in Sources */, C9EB33E4138F75580075BB52 /* _flock_stub.c in Sources */, C9EB33E5138F75580075BB52 /* asprintf.c in Sources */, C9EB33E6138F75580075BB52 /* clrerr.c in Sources */, @@ -14978,6 +15311,7 @@ C9EB33F2138F75580075BB52 /* fgetwln.c in Sources */, C9EB33F3138F75580075BB52 /* fgetws.c in Sources */, C9EB33F4138F75580075BB52 /* fileno.c in Sources */, + 147CDFE11B7C233300831EC6 /* clock_gettime.c in Sources */, C9EB33F5138F75580075BB52 /* findfp.c in Sources */, C9EB33F6138F75580075BB52 /* flags.c in Sources */, C9EB33F7138F75580075BB52 /* fopen.c in Sources */, @@ -15126,29 +15460,17 @@ C9EB3486138F75580075BB52 /* timelocal.c in Sources */, C9EB3487138F75580075BB52 /* getdate.c in Sources */, C9EB3488138F75580075BB52 /* timezone_unix03.c in Sources */, - C9EB3489138F75580075BB52 /* bcmp.c in Sources */, - C9EB348A138F75580075BB52 /* bcopy.c in Sources */, - C9EB348B138F75580075BB52 /* bzero.c in Sources */, C9EB348C138F75580075BB52 /* index.c in Sources */, - C9EB348D138F75580075BB52 /* memccpy.c in Sources */, - C9EB348E138F75580075BB52 /* memchr.c in Sources */, - C9EB348F138F75580075BB52 /* memcmp.c in Sources */, - C9EB3490138F75580075BB52 /* memcpy.c in Sources */, C9EB3491138F75580075BB52 /* memmem.c in Sources */, - C9EB3492138F75580075BB52 /* memmove.c in Sources */, - C9EB3493138F75580075BB52 /* memset.c in Sources */, C9EB3494138F75580075BB52 /* rindex.c in Sources */, C9EB3497138F75580075BB52 /* strcasecmp.c in Sources */, C9EB3498138F75580075BB52 /* strcasestr.c in Sources */, - C9EB349A138F75580075BB52 /* strchr.c in Sources */, - C9EB349B138F75580075BB52 /* strcmp.c in Sources */, C9EB349C138F75580075BB52 /* strcoll.c in Sources */, C9EB349E138F75580075BB52 /* strcspn.c in Sources */, C9EB349F138F75580075BB52 /* strdup.c in Sources */, C9EB34A0138F75580075BB52 /* strerror.c in Sources */, C9EB34A3138F75580075BB52 /* strlen.c in Sources */, C9EB34A4138F75580075BB52 /* strmode.c in Sources */, - C9EB34A6138F75580075BB52 /* strncmp.c in Sources */, C9EB34A8138F75580075BB52 /* strndup.c in Sources */, C9EB34A9138F75580075BB52 /* strnlen.c in Sources */, C9EB34AA138F75580075BB52 /* strnstr.c in Sources */, @@ -15180,6 +15502,7 @@ C9EB34C4138F75580075BB52 /* wcsncpy.c in Sources */, C9EB34C5138F75580075BB52 /* wcsnlen.c in Sources */, C9EB34C6138F75580075BB52 /* wcspbrk.c in Sources */, + 2DF67CE6184F9CBE00B83A3D /* debug_private.c in Sources */, C9EB34C7138F75580075BB52 /* wcsrchr.c in Sources */, C9EB34C8138F75580075BB52 /* wcsspn.c in Sources */, C9EB34C9138F75580075BB52 /* wcsstr.c in Sources */, @@ -15191,15 +15514,12 @@ C9EB34CF138F75580075BB52 /* wmemcpy.c in Sources */, C9EB34D0138F75580075BB52 /* wmemmove.c in Sources */, C9EB34D1138F75580075BB52 /* wmemset.c in Sources */, - C9EB34D2138F75580075BB52 /* __libc_init.c in Sources */, + C9EB34D2138F75580075BB52 /* _libc_init.c in Sources */, C9EB34D3138F75580075BB52 /* _libc_fork_child.c in Sources */, C9EB34D4138F75580075BB52 /* chmodx_np.c in Sources */, - C9EB34D5138F75580075BB52 /* context-stubs.c in Sources */, C9EB34D6138F75580075BB52 /* crt_externs.c in Sources */, - C9EB34D7138F75580075BB52 /* errno.c in Sources */, C9EB34D8138F75580075BB52 /* fork.c in Sources */, C9EB34D9138F75580075BB52 /* getgroups.c in Sources */, - C9EB34DA138F75580075BB52 /* getiopolicy_np.c in Sources */, C9EB34DB138F75580075BB52 /* gettimeofday.c in Sources */, C9EB34DC138F75580075BB52 /* msgctl.c in Sources */, C9EB34DD138F75580075BB52 /* stack_protector.c in Sources */, @@ -15211,14 +15531,8 @@ C9EB34E3138F75580075BB52 /* settimeofday.c in Sources */, C9EB34E4138F75580075BB52 /* shmctl.c in Sources */, C9EB34E5138F75580075BB52 /* sigaction.c in Sources */, - C9EB34E6138F75580075BB52 /* sigcatch.c in Sources */, - C9EB34E7138F75580075BB52 /* sigtramp.c in Sources */, - C9EB34E8138F75580075BB52 /* slot_name.c in Sources */, C9EB34E9138F75580075BB52 /* statx_np.c in Sources */, C9EB34EA138F75580075BB52 /* umaskx_np.c in Sources */, - C9EB34EB138F75580075BB52 /* cprocs.c in Sources */, - C9EB34EC138F75580075BB52 /* cthreads.c in Sources */, - C9EB34ED138F75580075BB52 /* mig_support.c in Sources */, C9EB34EE138F75580075BB52 /* fparseln.c in Sources */, C9EB34EF138F75580075BB52 /* login.c in Sources */, C9EB34F0138F75580075BB52 /* login_tty.c in Sources */, @@ -15236,39 +15550,76 @@ C9EB34FB138F75580075BB52 /* parse.c in Sources */, C9EB34FC138F75580075BB52 /* unpack.c in Sources */, C9EB34FD138F75580075BB52 /* unparse.c in Sources */, - C9EB34FE138F75580075BB52 /* getmcontext.c in Sources */, - C9EB34FF138F75580075BB52 /* makecontext.c in Sources */, - C9EB3500138F75580075BB52 /* setcontext.c in Sources */, - C9EB3501138F75580075BB52 /* swapcontext.c in Sources */, - C9EB3502138F75580075BB52 /* bcopy.c in Sources */, - C9EB3503138F75580075BB52 /* bzero.c in Sources */, - C9EB3504138F75580075BB52 /* memcpy.c in Sources */, - C9EB3505138F75580075BB52 /* memmove.c in Sources */, - C9EB3506138F75580075BB52 /* atomic.c in Sources */, - C9EB3507138F75580075BB52 /* spinlocks.c in Sources */, C9EB3510138F76A10075BB52 /* scandir_b.c in Sources */, - 3F2208EF14358B4A00386F5B /* asl_fd.c in Sources */, B19C64631450F90200032373 /* sync_volume_np.c in Sources */, 3FB7E1BB146EF2E000843438 /* dirfd.c in Sources */, + 4B2C64AA15519BCB00342BFA /* assumes.c in Sources */, + FC2ED618157D4BE80098EC69 /* inet_ntop.c in Sources */, + FC2ED621157D4BE80098EC69 /* inet_pton.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 3F51211716C318EB00AFB431 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3F51206A16C3174300AFB431 /* FortifySource */; + targetProxy = 3F51211616C318EB00AFB431 /* PBXContainerItemProxy */; + }; + 928F25D51BEAD2AE007B13C7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 928F25D01BEACED7007B13C7 /* darwintests */; + targetProxy = 928F25D41BEAD2AE007B13C7 /* PBXContainerItemProxy */; + }; B122F2D91432BA8700AF95D0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B122F0E71432B8E600AF95D0 /* TRE */; targetProxy = B122F2D81432BA8700AF95D0 /* PBXContainerItemProxy */; }; - B1E96509157E749200FCCEE7 /* PBXTargetDependency */ = { + C0E343841C582ECB00E749C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C9C2A94C138DFFD900287F00 /* Base */; + targetProxy = C0E343851C582ECB00E749C2 /* PBXContainerItemProxy */; + }; + C0E343861C582ECB00E749C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C9257ECF138E1B5000B3107C /* FreeBSD */; + targetProxy = C0E343871C582ECB00E749C2 /* PBXContainerItemProxy */; + }; + C0E343881C582ECB00E749C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B122F0E71432B8E600AF95D0 /* TRE */; + targetProxy = C0E343891C582ECB00E749C2 /* PBXContainerItemProxy */; + }; + C0E3438A1C582ECB00E749C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C9D9435F138EC3E300FB7ACC /* Variant_Cancelable */; + targetProxy = C0E3438B1C582ECB00E749C2 /* PBXContainerItemProxy */; + }; + C0E3438C1C582ECB00E749C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C95B7ED9138F3C55004311DA /* Variant_DarwinExtsn */; + targetProxy = C0E3438D1C582ECB00E749C2 /* PBXContainerItemProxy */; + }; + C0E345E61C58323000E749C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C0E343831C582ECB00E749C2 /* libc_static */; + targetProxy = C0E345E51C58323000E749C2 /* PBXContainerItemProxy */; + }; + C925D2011518FA5D003D315B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = B1E96340157E722200FCCEE7 /* FreeBSD_gcc */; - targetProxy = B1E96508157E749200FCCEE7 /* PBXContainerItemProxy */; + target = C95B7ED9138F3C55004311DA /* Variant_DarwinExtsn */; + targetProxy = C925D2001518FA5D003D315B /* PBXContainerItemProxy */; + }; + C925D2031518FEBE003D315B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C97A6F1E1517AF53005E1998 /* libc_eOS.a */; + targetProxy = C925D2021518FEBE003D315B /* PBXContainerItemProxy */; }; C942130913901709004BA536 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = C942102D13900C8A004BA536 /* libc.a */; + target = C942102D13900C8A004BA536 /* libc_dyld */; targetProxy = C942130813901709004BA536 /* PBXContainerItemProxy */; }; C95B817D138F3F72004311DA /* PBXTargetDependency */ = { @@ -15286,6 +15637,26 @@ target = C95B842A138F53DB004311DA /* Variant_Pre1050 */; targetProxy = C95B86CB138F546E004311DA /* PBXContainerItemProxy */; }; + C9AE91BB1517D33100A2626C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C9C2A94C138DFFD900287F00 /* Base */; + targetProxy = C9AE91BA1517D33100A2626C /* PBXContainerItemProxy */; + }; + C9AE91BD1517D33100A2626C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C9257ECF138E1B5000B3107C /* FreeBSD */; + targetProxy = C9AE91BC1517D33100A2626C /* PBXContainerItemProxy */; + }; + C9AE91BF1517D33100A2626C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B122F0E71432B8E600AF95D0 /* TRE */; + targetProxy = C9AE91BE1517D33100A2626C /* PBXContainerItemProxy */; + }; + C9AE91C11517D33100A2626C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C9D9435F138EC3E300FB7ACC /* Variant_Cancelable */; + targetProxy = C9AE91C01517D33100A2626C /* PBXContainerItemProxy */; + }; C9BD3C39138F16EE00B389FD /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = C9D9435F138EC3E300FB7ACC /* Variant_Cancelable */; @@ -15324,9 +15695,58 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 3F5120EF16C3174300AFB431 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)"; + EXECUTABLE_PREFIX = lib; + INCLUDED_SOURCE_FILE_NAMES = "$(BASE_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 3F5120F016C3174300AFB431 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)"; + EXECUTABLE_PREFIX = lib; + INCLUDED_SOURCE_FILE_NAMES = "$(BASE_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 925E7FE719E8945A00AC7889 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 925E7FE819E8945A00AC7889 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 928F25D21BEACED7007B13C7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 928F25D31BEACED7007B13C7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; B122F2AB1432B8E600AF95D0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = ( "$(FreeBSD_EXCLUDED_SOURCE_GDTOA)", "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)", @@ -15345,6 +15765,7 @@ B122F2AC1432B8E600AF95D0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = ( "$(FreeBSD_EXCLUDED_SOURCE_GDTOA)", "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)", @@ -15357,44 +15778,26 @@ }; name = Release; }; - B1E96504157E722200FCCEE7 /* Debug */ = { + C0E345E01C582ECB00E749C2 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = C0E345E31C58300F00E749C2 /* libc_static.xcconfig */; buildSettings = { - EXCLUDED_SOURCE_FILE_NAMES = ( - "$(FreeBSD_EXCLUDED_SOURCE_GDTOA)", - "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)", - ); - EXECUTABLE_PREFIX = lib; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_VERSION = com.apple.compilers.llvmgcc42; - INCLUDED_SOURCE_FILE_NAMES = "$(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; - PRODUCT_NAME = FreeBSD_gcc; + PRODUCT_NAME = "$(PRODUCT_NAME)"; }; name = Debug; }; - B1E96505157E722200FCCEE7 /* Release */ = { + C0E345E11C582ECB00E749C2 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = C0E345E31C58300F00E749C2 /* libc_static.xcconfig */; buildSettings = { - EXCLUDED_SOURCE_FILE_NAMES = ( - "$(FreeBSD_EXCLUDED_SOURCE_GDTOA)", - "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)", - ); - EXECUTABLE_PREFIX = lib; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_VERSION = com.apple.compilers.llvmgcc42; - INCLUDED_SOURCE_FILE_NAMES = "$(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; - PRODUCT_NAME = FreeBSD_gcc; + PRODUCT_NAME = "$(PRODUCT_NAME)"; }; name = Release; }; C9257ED1138E1B5000B3107C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = ( "$(FreeBSD_EXCLUDED_SOURCE_GDTOA)", "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)", @@ -15413,6 +15816,7 @@ C9257ED2138E1B5000B3107C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = ( "$(FreeBSD_EXCLUDED_SOURCE_GDTOA)", "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)", @@ -15428,7 +15832,7 @@ C9258103138E2D3100B3107C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; + EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; @@ -15442,7 +15846,7 @@ C9258104138E2D3100B3107C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; + EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; @@ -15454,11 +15858,17 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + BUILD_VARIANTS = normal; + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; INSTALL_PATH = /usr/local/lib/dyld; - PRODUCT_NAME = c; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + /usr/lib/system, + ); + PRODUCT_NAME = c_dyld; SKIP_INSTALL = NO; STRIP_INSTALLED_PRODUCT = NO; VARIANT = DYLD; @@ -15469,11 +15879,17 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + BUILD_VARIANTS = normal; + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; INSTALL_PATH = /usr/local/lib/dyld; - PRODUCT_NAME = c; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + /usr/lib/system, + ); + PRODUCT_NAME = c_dyld; SKIP_INSTALL = NO; STRIP_INSTALLED_PRODUCT = NO; VARIANT = DYLD; @@ -15484,6 +15900,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15496,6 +15913,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15508,6 +15926,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15520,6 +15939,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15532,6 +15952,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15544,6 +15965,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15552,6 +15974,20 @@ }; name = Release; }; + C97A721A1517AF53005E1998 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C9AE91AE1517CDAC00A2626C /* eos.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + C97A721B1517AF53005E1998 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C9AE91AE1517CDAC00A2626C /* eos.xcconfig */; + buildSettings = { + }; + name = Release; + }; C9B5359C138D9A690028D27C /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = C9C2A948138DF7DD00287F00 /* libc.xcconfig */; @@ -15569,19 +16005,10 @@ C9B53E2E138DA0610028D27C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - EXCLUDED_SOURCE_FILE_NAMES = ( - "*/*/*.c", - "*/*/*.s", - "*/*/*.S", - ); + EXCLUDED_SOURCE_FILE_NAMES = "*"; EXECUTABLE_PREFIX = lib; GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_UNUSED_VARIABLE = YES; - INCLUDED_SOURCE_FILE_NAMES = ( - "$(ARCH_FAMILY)/*/*.c", - "$(ARCH_FAMILY)/*/*.s", - "$(ARCH_FAMILY)/*/*.S", - ); + INCLUDED_SOURCE_FILE_NAMES = "$(Platform_INCLUDED_SOURCE_FILE_NAMES)"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; @@ -15590,18 +16017,9 @@ C9B53E2F138DA0610028D27C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - EXCLUDED_SOURCE_FILE_NAMES = ( - "*/*/*.c", - "*/*/*.s", - "*/*/*.S", - ); + EXCLUDED_SOURCE_FILE_NAMES = "*"; EXECUTABLE_PREFIX = lib; - GCC_WARN_UNUSED_VARIABLE = YES; - INCLUDED_SOURCE_FILE_NAMES = ( - "$(ARCH_FAMILY)/*/*.c", - "$(ARCH_FAMILY)/*/*.s", - "$(ARCH_FAMILY)/*/*.S", - ); + INCLUDED_SOURCE_FILE_NAMES = "$(Platform_INCLUDED_SOURCE_FILE_NAMES)"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; @@ -15610,6 +16028,7 @@ C9C2A94F138DFFDA00287F00 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(BASE_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; @@ -15620,6 +16039,7 @@ C9C2A950138DFFDA00287F00 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(BASE_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))"; @@ -15630,12 +16050,14 @@ C9D94331138DB73300FB7ACC /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", /usr/lib/system, ); + "ORDER_FILE[sdk=iphoneos*]" = "$(SDKROOT)/AppleInternal/OrderFiles/libsystem_c.order"; OTHER_LDFLAGS = "$(LIBSYSTEM_C_LDFLAGS)"; PRODUCT_NAME = c; SKIP_INSTALL = NO; @@ -15647,12 +16069,14 @@ C9D94332138DB73300FB7ACC /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", /usr/lib/system, ); + "ORDER_FILE[sdk=iphoneos*]" = "$(SDKROOT)/AppleInternal/OrderFiles/libsystem_c.order"; OTHER_LDFLAGS = "$(LIBSYSTEM_C_LDFLAGS)"; PRODUCT_NAME = c; SKIP_INSTALL = NO; @@ -15665,6 +16089,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15677,6 +16102,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15689,6 +16115,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15701,6 +16128,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15713,6 +16141,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15725,6 +16154,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */; buildSettings = { + COMBINE_HIDPI_IMAGES = YES; EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)"; EXECUTABLE_PREFIX = lib; INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)"; @@ -15736,6 +16166,33 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 3F5120EE16C3174300AFB431 /* Build configuration list for PBXNativeTarget "FortifySource" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3F5120EF16C3174300AFB431 /* Debug */, + 3F5120F016C3174300AFB431 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 925E7FF919E8945A00AC7889 /* Build configuration list for PBXAggregateTarget "Libc_tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 925E7FE719E8945A00AC7889 /* Debug */, + 925E7FE819E8945A00AC7889 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 928F25D11BEACED7007B13C7 /* Build configuration list for PBXLegacyTarget "darwintests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 928F25D21BEACED7007B13C7 /* Debug */, + 928F25D31BEACED7007B13C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; B122F2AA1432B8E600AF95D0 /* Build configuration list for PBXNativeTarget "TRE" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -15745,11 +16202,11 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - B1E96503157E722200FCCEE7 /* Build configuration list for PBXNativeTarget "FreeBSD_gcc" */ = { + C0E345DF1C582ECB00E749C2 /* Build configuration list for PBXNativeTarget "libc_static" */ = { isa = XCConfigurationList; buildConfigurations = ( - B1E96504157E722200FCCEE7 /* Debug */, - B1E96505157E722200FCCEE7 /* Release */, + C0E345E01C582ECB00E749C2 /* Debug */, + C0E345E11C582ECB00E749C2 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -15772,7 +16229,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C94212C913900C8A004BA536 /* Build configuration list for PBXNativeTarget "libc.a" */ = { + C94212C913900C8A004BA536 /* Build configuration list for PBXNativeTarget "libc_dyld" */ = { isa = XCConfigurationList; buildConfigurations = ( C94212CA13900C8A004BA536 /* Debug */, @@ -15808,6 +16265,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + C97A72191517AF53005E1998 /* Build configuration list for PBXNativeTarget "libc_eOS.a" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C97A721A1517AF53005E1998 /* Debug */, + C97A721B1517AF53005E1998 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; C9B5359A138D9A690028D27C /* Build configuration list for PBXProject "Libc" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/src/libc/Libc.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/src/libc/Libc.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 77138ed8f..000000000 --- a/src/libc/Libc.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/src/libc/Platforms/appletvos/Makefile.inc b/src/libc/Platforms/appletvos/Makefile.inc new file mode 100644 index 000000000..7b485b2ba --- /dev/null +++ b/src/libc/Platforms/appletvos/Makefile.inc @@ -0,0 +1,56 @@ +# +# Selectable features for AppleTV +# + +# Legacy *64 APIs +#FEATURE_LEGACY_64_APIS = 1 + +# Legacy crt1.o environ support +#FEATURE_LEGACY_CRT1_ENVIRON = 1 + +# Legacy rune APIs +#FEATURE_LEGACY_RUNE_APIS = 1 + +# Legacy utmp APIs +#FEATURE_LEGACY_UTMP_APIS = 1 + +# OSThermalNotification APIs +FEATURE_THERM_NOTIFICATION_APIS = 1 + +# Move localtime to /var/db/timezone +FEATURE_MOVE_LOCALTIME = 1 + +# Use TZDIR symlink in /var/db +FEATURE_TZDIR_SYMLINK = 1 + +.if RC_ProjectName _Sim$ +FEATURE_MOVE_LOCALTIME = 0 +FEATURE_TZDIR_SYMLINK = 0 +.endif + +# No pre-1050 variants (should match sys/cdefs.h) +FEATURE_ONLY_1050_VARIANTS = 1 + +# No legacy variants (should match sys/cdefs.h) +FEATURE_ONLY_UNIX_CONFORMANCE = 1 + +# Only 64-bit ino_t (should match sys/cdefs.h) +FEATURE_ONLY_64_BIT_INO_T = 1 + +# Patch 3333969 +#FEATURE_PATCH_3333969 = 1 + +# Patch 3417676 +#FEATURE_PATCH_3417676 = 1 + +# plockstat dtrace support +#FEATURE_PLOCKSTAT = 1 + +# Timezone change notification +FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1 + +# Smaller stdio buffers +FEATURE_SMALL_STDIOBUF = 1 + +# Disable registration of specific signals () +FEATURE_SIGNAL_RESTRICTION = 1 diff --git a/src/libc/Platforms/bridgeos/Makefile.inc b/src/libc/Platforms/bridgeos/Makefile.inc new file mode 100644 index 000000000..dcb0cc6b8 --- /dev/null +++ b/src/libc/Platforms/bridgeos/Makefile.inc @@ -0,0 +1,51 @@ +# +# Selectable features for Apple Watch +# + +# Legacy *64 APIs +#FEATURE_LEGACY_64_APIS = 1 + +# Legacy crt1.o environ support +#FEATURE_LEGACY_CRT1_ENVIRON = 1 + +# Legacy rune APIs +#FEATURE_LEGACY_RUNE_APIS = 1 + +# Legacy utmp APIs +#FEATURE_LEGACY_UTMP_APIS = 1 + +# OSThermalNotification APIs +FEATURE_THERM_NOTIFICATION_APIS = 1 + +# Move localtime to /var/db/timezone +FEATURE_MOVE_LOCALTIME = 0 + +# Use TZDIR symlink in /var/db +FEATURE_TZDIR_SYMLINK = 0 + +# No pre-1050 variants (should match sys/cdefs.h) +FEATURE_ONLY_1050_VARIANTS = 1 + +# No legacy variants (should match sys/cdefs.h) +FEATURE_ONLY_UNIX_CONFORMANCE = 1 + +# Only 64-bit ino_t (should match sys/cdefs.h) +FEATURE_ONLY_64_BIT_INO_T = 1 + +# Patch 3333969 +#FEATURE_PATCH_3333969 = 1 + +# Patch 3417676 +#FEATURE_PATCH_3417676 = 1 + +# plockstat dtrace support +#FEATURE_PLOCKSTAT = 1 + +# Timezone change notification +FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1 + +# Smaller stdio buffers +FEATURE_SMALL_STDIOBUF = 1 + +# Disable registration of specific signals () +FEATURE_SIGNAL_RESTRICTION = 1 diff --git a/src/libc/Platforms/iphoneos/Makefile.inc b/src/libc/Platforms/iphoneos/Makefile.inc index 4708e557f..df326716c 100644 --- a/src/libc/Platforms/iphoneos/Makefile.inc +++ b/src/libc/Platforms/iphoneos/Makefile.inc @@ -14,14 +14,18 @@ # Legacy utmp APIs #FEATURE_LEGACY_UTMP_APIS = 1 -# New OSMemoryNotification and OSThermalNotification APIs -FEATURE_MEM_THERM_NOTIFICATION_APIS = 1 +# OSThermalNotification APIs +FEATURE_THERM_NOTIFICATION_APIS = 1 # Move localtime to /var/db/timezone FEATURE_MOVE_LOCALTIME = 1 +# Use TZDIR symlink in /var/db +FEATURE_TZDIR_SYMLINK = 1 + .if RC_ProjectName _Sim$ FEATURE_MOVE_LOCALTIME = 0 +FEATURE_TZDIR_SYMLINK = 0 .endif # No pre-1050 variants (should match sys/cdefs.h) @@ -39,14 +43,14 @@ FEATURE_ONLY_64_BIT_INO_T = 1 # Patch 3417676 #FEATURE_PATCH_3417676 = 1 -# Patch 5243343 -FEATURE_PATCH_5243343 = 1 - # plockstat dtrace support #FEATURE_PLOCKSTAT = 1 # Timezone change notification FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1 -# Memorystatus support for posix_spawn() -FEATURE_MEMORYSTATUS = 1 +# Smaller stdio buffers +FEATURE_SMALL_STDIOBUF = 1 + +# Disable registration of specific signals () +# FEATURE_SIGNAL_RESTRICTION = 0 diff --git a/src/libc/Platforms/macosx/Makefile.inc b/src/libc/Platforms/macosx/Makefile.inc index ff3617f49..f48843d08 100644 --- a/src/libc/Platforms/macosx/Makefile.inc +++ b/src/libc/Platforms/macosx/Makefile.inc @@ -14,12 +14,15 @@ FEATURE_LEGACY_RUNE_APIS = 1 # Legacy utmp APIs FEATURE_LEGACY_UTMP_APIS = 1 -# New OSMemoryNotification and OSThermalNotification APIs -#FEATURE_MEM_THERM_NOTIFICATION_APIS = 1 +# OSThermalNotification APIs +FEATURE_THERM_NOTIFICATION_APIS = 1 # Move localtime to /var/db/timezone #FEATURE_MOVE_LOCALTIME = 1 +# Use TZDIR symlink in /var/db +#FEATURE_TZDIR_SYMLINK = 1 + # No pre-1050 variants (should match sys/cdefs.h) #FEATURE_ONLY_1050_VARIANTS = 1 @@ -37,14 +40,14 @@ FEATURE_PATCH_3333969 = 1 # Patch 3417676 FEATURE_PATCH_3417676 = 1 -# Patch 5243343 -FEATURE_PATCH_5243343 = 1 - # plockstat dtrace support FEATURE_PLOCKSTAT = 1 # Timezone change notification FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1 -# Memorystatus support for posix_spawn() -FEATURE_MEMORYSTATUS = 1 +# Extensible printf performance enhancement (uses more memory) +FEATURE_XPRINTF_PERF = 1 + +# Disable registration of specific signals () +# FEATURE_SIGNAL_RESTRICTION = 0 diff --git a/src/libc/Platforms/watchos/Makefile.inc b/src/libc/Platforms/watchos/Makefile.inc new file mode 100644 index 000000000..2253e33b2 --- /dev/null +++ b/src/libc/Platforms/watchos/Makefile.inc @@ -0,0 +1,56 @@ +# +# Selectable features for Apple Watch +# + +# Legacy *64 APIs +#FEATURE_LEGACY_64_APIS = 1 + +# Legacy crt1.o environ support +#FEATURE_LEGACY_CRT1_ENVIRON = 1 + +# Legacy rune APIs +#FEATURE_LEGACY_RUNE_APIS = 1 + +# Legacy utmp APIs +#FEATURE_LEGACY_UTMP_APIS = 1 + +# OSThermalNotification APIs +FEATURE_THERM_NOTIFICATION_APIS = 1 + +# Move localtime to /var/db/timezone +FEATURE_MOVE_LOCALTIME = 1 + +# Use TZDIR symlink in /var/db +FEATURE_TZDIR_SYMLINK = 1 + +.if RC_ProjectName _Sim$ +FEATURE_MOVE_LOCALTIME = 0 +FEATURE_TZDIR_SYMLINK = 0 +.endif + +# No pre-1050 variants (should match sys/cdefs.h) +FEATURE_ONLY_1050_VARIANTS = 1 + +# No legacy variants (should match sys/cdefs.h) +FEATURE_ONLY_UNIX_CONFORMANCE = 1 + +# Only 64-bit ino_t (should match sys/cdefs.h) +FEATURE_ONLY_64_BIT_INO_T = 1 + +# Patch 3333969 +#FEATURE_PATCH_3333969 = 1 + +# Patch 3417676 +#FEATURE_PATCH_3417676 = 1 + +# plockstat dtrace support +#FEATURE_PLOCKSTAT = 1 + +# Timezone change notification +FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1 + +# Smaller stdio buffers +FEATURE_SMALL_STDIOBUF = 1 + +# Disable registration of specific signals () +FEATURE_SIGNAL_RESTRICTION = 1 diff --git a/src/libc/arm/gen/cpu_number.s b/src/libc/arm/gen/cpu_number.s deleted file mode 100644 index a46623857..000000000 --- a/src/libc/arm/gen/cpu_number.s +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include - -#define __APPLE_API_PRIVATE -#include -#undef __APPLE_API_PRIVATE - - .text - .align 2 - .globl _cpu_number -_cpu_number: -#ifdef _ARM_ARCH_7 - mrc p15, 0, r0, c13, c0, 3 - and r0, r0, #3 -#else - mov r0, #0 -#endif - bx lr diff --git a/src/libc/arm/pthreads/init_cpu_capabilities.c b/src/libc/arm/pthreads/init_cpu_capabilities.c deleted file mode 100644 index 476c0178b..000000000 --- a/src/libc/arm/pthreads/init_cpu_capabilities.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* Initialize the "_cpu_capabilities" vector on ARM processors. */ - -#define __APPLE_API_PRIVATE -#include -#undef __APPLE_API_PRIVATE - -extern int _get_cpu_capabilities(void); - -int _cpu_capabilities = 0; -int _cpu_has_altivec = 0; // DEPRECATED: use _cpu_capabilities instead - -__private_extern__ void -_init_cpu_capabilities( void ) -{ -} diff --git a/src/libc/arm/pthreads/pthread_getspecific.s b/src/libc/arm/pthreads/pthread_getspecific.s deleted file mode 100644 index 90e0e9818..000000000 --- a/src/libc/arm/pthreads/pthread_getspecific.s +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include "pthread_machdep.h" -#include - -#define __APPLE_API_PRIVATE -#include -#undef __APPLE_API_PRIVATE - - .text - .align 4 - .globl _pthread_getspecific -_pthread_getspecific: -#ifdef _ARM_ARCH_6 - mrc p15, 0, r1, c13, c0, 3 - bic r1, r1, #3 - add r0, r1, r0, lsl #2 -#else - add r0, r9, r0, lsl #2 -#endif - ldr r0, [r0, #0] - bx lr diff --git a/src/libc/arm/pthreads/pthread_self.s b/src/libc/arm/pthreads/pthread_self.s deleted file mode 100644 index 0e84b6d24..000000000 --- a/src/libc/arm/pthreads/pthread_self.s +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include - -#define __APPLE_API_PRIVATE -#include -#undef __APPLE_API_PRIVATE - - .text - .align 2 - .globl _pthread_self -_pthread_self: -#ifdef _ARM_ARCH_6 - mrc p15, 0, r0, c13, c0, 3 - bic r0, r0, #3 -#else - mov r0, r9 -#endif - ldr r0, [r0, #0] - bx lr diff --git a/src/libc/arm/pthreads/pthread_set_self.s b/src/libc/arm/pthreads/pthread_set_self.s deleted file mode 100644 index 13ef35b4f..000000000 --- a/src/libc/arm/pthreads/pthread_set_self.s +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - - .text - .align 2 - .globl ___pthread_set_self -___pthread_set_self: -#ifndef _ARM_ARCH_6 - mov r9, r0 -#endif - /* fast trap for thread_set_cthread */ - mov r3, #2 - mov r12, #0x80000000 - swi #SWI_SYSCALL - bx lr diff --git a/src/libc/arm/pthreads/start_wqthread.s b/src/libc/arm/pthreads/start_wqthread.s deleted file mode 100644 index 79bb28e14..000000000 --- a/src/libc/arm/pthreads/start_wqthread.s +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2009, 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include - -#define __APPLE_API_PRIVATE -#include -#undef __APPLE_API_PRIVATE - -// This routine is never called directly by user code, jumped from kernel -// args 0 to 3 are already in the regs 0 to 3 -// should set stack with the 2 extra args before calling pthread_wqthread() -// arg4 is in r[4] -// arg5 is in r[5] - - .text - .align 2 - .globl _start_wqthread -_start_wqthread: - stmfd sp!, {r4, r5} - bl __pthread_wqthread - -// Stackshots will show the routine that happens to link immediately following -// _start_wqthread. So we add an extra instruction (nop) to make stackshots -// more readable. - nop diff --git a/src/libc/arm/pthreads/thread_start.s b/src/libc/arm/pthreads/thread_start.s deleted file mode 100644 index 5bf4bf616..000000000 --- a/src/libc/arm/pthreads/thread_start.s +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2009, 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include - -#define __APPLE_API_PRIVATE -#include -#undef __APPLE_API_PRIVATE - -// This routine is never called directly by user code, jumped from kernel -// args 0 to 3 are already in the regs 0 to 3 -// should set stack with the 2 extra args before calling pthread_wqthread() -// arg4 is in r[4] -// arg5 is in r[5] - - .text - .align 2 - .globl _thread_start -_thread_start: - stmfd sp!, {r4, r5} - bl __pthread_start - -// Stackshots will show the routine that happens to link immediately following -// _thread_start. So we add an extra instruction (nop) to make stackshots -// more readable. - nop diff --git a/src/libc/arm/string/bcopy_CortexA8.s b/src/libc/arm/string/bcopy_CortexA8.s deleted file mode 100644 index 89ae1a73d..000000000 --- a/src/libc/arm/string/bcopy_CortexA8.s +++ /dev/null @@ -1,863 +0,0 @@ -/* - * Copyright (c) 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD - -/***************************************************************************** - * Cortex-A8 implementation * - *****************************************************************************/ - -// Cortex-A8 implementations of memcpy( ), memmove( ) and bcopy( ). -// -// Our tests have shown that NEON is always a performance win for memcpy( ). -// However, for the specific case of copies from a warm source to a cold -// destination when the buffer size is between 1k and 32k, it is not enough -// of a performance win to offset the increased power footprint, resulting -// in an energy usage regression. Thus, we detect that particular case, and -// pass those copies through the ARM core registers. All other copies larger -// than 8 bytes are handled on NEON. -// -// Stephen Canon, August 2009 - -.text -.code 16 -.syntax unified - -// void bcopy(const void * source, -// void * destination, -// size_t length); -// -// void *memmove(void * destination, -// const void * source, -// size_t n); -// -// void *memcpy(void * restrict destination, -// const void * restrict source, -// size_t n); -// -// all copy n successive bytes from source to destination. memmove and memcpy -// returns destination, whereas bcopy has no return value. copying takes place -// as if it were through a temporary buffer -- after return destination contains -// exactly the bytes from source, even if the buffers overlap. - -.thumb_func _bcopy$VARIANT$CortexA8 -.thumb_func _memmove$VARIANT$CortexA8 -.thumb_func _memcpy$VARIANT$CortexA8 -.globl _bcopy$VARIANT$CortexA8 -.globl _memmove$VARIANT$CortexA8 -.globl _memcpy$VARIANT$CortexA8 - -#define SAVE_REGISTERS {r4,r5,r6,r8,r10,r11} -#define COPY_REGISTERS {r3,r4,r5,r6,r8,r9,r10,r11} - -/***************************************************************************** - * entry points * - *****************************************************************************/ - -.align 2 -_bcopy$VARIANT$CortexA8: - -// bcopy has the first and second arguments in the opposite order as the C -// library functions memmove and memcpy. If bcopy is called, we swap these -// two arguments and then fall into memmove. - - mov r3, r0 - mov r0, r1 - mov r1, r3 - -.align 2 -_memmove$VARIANT$CortexA8: -_memcpy$VARIANT$CortexA8: - -// At entry to memmove/memcpy, registers contain the following values: -// -// r0 pointer to the first byte of the destination buffer -// r1 pointer to the first byte of the source buffer -// r2 number of bytes to copy -// -// Our preference is to use a (faster and easier to understand) front-to-back -// copy of the buffer. However, memmove requires that copies take place as -// though through a temporary buffer. This means that if the buffers overlap, -// it may be necessary to copy the buffer in reverse order. -// -// To properly detect such overlap, we begin by computing the offset between -// the source and destination pointers. If the offset happens to be zero, -// then there is no work to be done, so we can early out. - - subs r3, r0, r1 - it eq - bxeq lr - -// r3 now contains the offset between the buffers, (destination - source). If -// 0 < offset < length, then the high-addressed bits of the source alias the -// low addressed bytes of the destination. Thus, if we were to perform the -// copy in ascending address order, we would overwrite the high-addressed -// source bytes before we had a chance to copy them, and the data would be lost. -// -// Thus, we can use the front-to-back copy only if offset is negative or -// greater than the length. This is the case precisely if offset compares -// unsigned higher than length. - - cmp r3, r2 - bhs L_copyFrontToBack - -/***************************************************************************** - * back to front copy * - *****************************************************************************/ - -// Here we have fallen through into the back-to-front copy. We preserve the -// original destination pointer in r0 because it is the return value for the -// routine, and update the other registers as follows: -// -// r1 one byte beyond the end of the destination buffer -// r2 number of bytes to copy -// ip one byte beyond the end of the destination buffer - - mov ip, r0 - add r1, r2 - add ip, r2 - -// Subtract 8 from the buffer length; if this is negative, then we will use -// only single-byte copies, and we jump directly to a scalar copy loop. - - subs r2, $8 - blt L_scalarReverseCopy - -// If the destination pointer is 8-byte aligned we can use 8-byte NEON copies -// to move the data. - - tst ip, $7 - beq L_vectorReverseCopy - -// Otherwise, we copy a single byte at a time, in order of descending memory -// address, until the destination is 8 byte aligned. Within this loop, -// registers are used as follows: -// -// r0 original destination pointer -// r1 pointer to one byte past the next element to be copied -// r2 (bytes remaining to be copied) - 8 -// r3 temporary to hold the byte that is being copied -// ip pointer one byte past the destination of the next byte to be copied -// -// byte that will be copied in this iteration -// | byte that was copied in the previous iteration -// Source buffer: v v -// ------------------------+---+---+------------------------- -// bytes still to copy ... | | | ... bytes already copied -// ------------------------+---+---+------------------------- -// ^ -// r1 holds the address of this byte - -0: ldrb r3, [r1, $-1]! - sub r2, $1 - strb r3, [ip, $-1]! - tst ip, $7 - bne 0b - -// At this point, the destination pointer is 8 byte aligned. Check again that -// there are at least 8 bytes remaining to copy by comparing the remaining -// length minus 8 to zero. If fewer than 8 bytes remain, jump to the cleanup -// path. - - cmp r2, $0 - blt L_scalarReverseCopy - -/***************************************************************************** - * destination is 8 byte aligned * - *****************************************************************************/ - -L_vectorReverseCopy: - -// At this point, registers contain the following values: -// -// r0 original destination pointer -// r1 pointer to one byte past the next element to be copied -// r2 (bytes remaining to copy) - 8 -// ip pointer one byte past the destination of the next byte to be copied -// -// Furthermore, it is known that ip is 8 byte aligned, and that r2 is positive. -// NEON has really excellent alignment handling in hardware, so we would like -// to use that to handle cases where the source is not similarly aligned to the -// destination (it supports even single-byte misalignment at speed). However, -// on some SoC designs, not all of the DMA busses support such access. Thus, -// we must unfortunately use a software workaround in those cases. -// -// Fortunately, 4-byte aligned loads are supported even on the DMA busses, so -// we only need to handle the different possible source alignments modulo 4. -// Here we have a dispatch table to jump to the correct copy implementation -// for the given source alignment. -// -// The tbh instruction loads the address offset of the correct implementation -// from the data table that immediately follows it and adds it to the pc to -// jump to the correct branch. - - ands r3, r1, $3 - tbh [pc, r3, lsl $1] -0: -.short (L_reverseAligned0-0b)/2 -.short (L_reverseAligned1-0b)/2 -.short (L_reverseAligned2-0b)/2 -.short (L_reverseAligned3-0b)/2 - -/***************************************************************************** - * source is also at least word aligned * - *****************************************************************************/ - -L_reverseAligned0: - -// Subtract 56 from r2, so that it contains the number of bytes remaining to -// copy minus 64. If this result is negative, then we jump into a loop that -// copies 8 bytes at a time. - - subs r2, $0x38 - blt L_reverseVectorCleanup - -// Check if the destination pointer is 64-byte aligned. If so, jump to a loop -// that copies whole cachelines. - - tst ip, $0x38 - beq L_reverseCachelineAligned - -// Otherwise, we copy a 8 bytes at a time, in order of descending memory -// address, until the destination is 64 byte aligned. Within this loop, -// registers are used as follows: -// -// r0 original destination pointer -// r1 pointer to one byte past the next element to be copied -// r2 (bytes remaining to be copied) - 64 -// ip pointer one byte past the destination of the next byte to be copied -// d0 temporary storage for copy -// -// bytes that will be copied after this iteration -// | 8 byte block that will be copied in this iteration -// v v -// --------------+-------------------------------+--------------------- -// | 0 1 2 3 4 5 6 7 | bytes already copied -// --------------+-------------------------------+--------------------- -// ^ -// r1 points here - -0: sub r1, $8 - vld1.32 {d0}, [r1] - sub ip, $8 - sub r2, $8 - tst ip, $0x38 - vst1.64 {d0}, [ip,:64] - bne 0b - -// At this point, the destination pointer is 64 byte aligned. Check again that -// there are at least 64 bytes remaining to copy by comparing the remaining -// length minus 64 to zero. If fewer than 64 bytes remain, skip over the main -// copy loop. - - cmp r2, $0 - blt L_reverseVectorCleanup - -/***************************************************************************** - * destination is cacheline aligned * - *****************************************************************************/ - -L_reverseCachelineAligned: - -// In the special case that we are copying a buffer of between 1k and 32k bytes -// we do not use a NEON copy for the main loop. This is because if we happen -// to be doing a copy from a source in cache to a destination that is not in -// cache, this will result in an increase in energy usage. In all other cases, -// NEON gives superior energy conservation. - - sub r3, r2, $0x3c0 - cmp r3, $0x7c00 - blo L_useSTMDB - -// Pre-decrement the source (r1) and destination (ip) pointers so that they -// point to the first byte of the trailing 32-byte window of each buffer. -// Additionally, load the address increment of -32 into r3. - - sub r1, $32 - sub ip, $32 - mov r3, $-32 - -// The destination pointer is known to be 64-byte aligned, so we can use the -// maximal alignment hint (:256) for our vector stores. Detect if the source -// is also at least 32-byte aligned and jump to a loop that uses maximal -// alignment hints for the loads as well if possible. - - tst r1, $0x1f - beq L_reverseSourceAligned - -// This loop copies 64 bytes per iteration, from a 4-byte aligned source to a -// 64-byte aligned destination, in order of descending memory address. Within -// this loop, registers are used as follows: -// -// r0 original destination pointer (unmodified) -// r1 pointer to the next 32-byte block to load -// r2 (number of bytes remaining to copy) - 64 -// r3 address increment of -32. -// ip pointer to which the next 32-byte block is to be stored -// q0-q3 temporary registers used for copies -// -// Note that the loop is arrange in such a way that a single cleanup store is -// necessary after the final loop iteration. This occurs at label (1), and is -// shared between the unaligned and aligned loops. - - vld1.32 {q2,q3}, [r1], r3 - vld1.32 {q0,q1}, [r1], r3 - subs r2, $64 - vst1.64 {q2,q3}, [ip,:256], r3 - blt 1f -.align 3 -0: vld1.32 {q2,q3}, [r1], r3 - vst1.64 {q0,q1}, [ip,:256], r3 - vld1.32 {q0,q1}, [r1], r3 - subs r2, $64 - vst1.64 {q2,q3}, [ip,:256], r3 - bge 0b - b 1f - -L_reverseSourceAligned: - -// This loop is identical to the immediately preceeding loop, except that it -// uses the additional alignment hint that the source pointer (r1) is 32-byte -// aligned. The two loops share cleanup code for the final iteration. - - vld1.64 {q2,q3}, [r1,:256], r3 - vld1.64 {q0,q1}, [r1,:256], r3 - subs r2, $64 - vst1.64 {q2,q3}, [ip,:256], r3 - blt 1f -.align 3 -0: vld1.64 {q2,q3}, [r1,:256], r3 - vst1.64 {q0,q1}, [ip,:256], r3 - vld1.64 {q0,q1}, [r1,:256], r3 - subs r2, $64 - vst1.64 {q2,q3}, [ip,:256], r3 - bge 0b - -// Final vector store for both of the above loops. - -1: vst1.64 {q0,q1}, [ip,:256], r3 - -// Adjust the source and destination pointers so that they once again point to -// the last byte that we used (which is one byte higher than the address that -// we will use next for any required cleanup). - - add r1, $32 - add ip, $32 - -L_reverseVectorCleanup: - -// Add 56 to r2, so that it contains the number of bytes remaing to copy minus -// 8. A comparison of this value with zero tells us if any more whole 8-byte -// blocks need to be copied. - - adds r2, r2, $0x38 - blt L_scalarReverseCopy - -// This loop copies 8 bytes at a time in order of descending memory address, -// until fewer than 8 bytes remain to be copied. Within this loop, registers -// are used as follows: -// -// r0 original destination pointer -// r1 pointer to one byte past the next element to be copied -// r2 (bytes remaining to be copied) - 64 -// ip pointer one byte past the destination of the next byte to be copied -// d0 temporary storage for copy - -0: sub r1, $8 - vld1.32 {d0}, [r1] - sub ip, $8 - subs r2, $8 - vst1.64 {d0}, [ip,:64] - bge 0b - -/***************************************************************************** - * sub-doubleword cleanup copies * - *****************************************************************************/ - -L_scalarReverseCopy: - -// Add 8 to r2, so that it contains the number of bytes remaining to copy, and -// return to the calling routine if zero bytes remain. - - adds r2, $8 - it eq - bxeq lr - -// Copy one byte at a time in descending address order until we reach the front -// of the buffer. Within this loop, registers are used as follows: -// -// r0 original destination pointer -// r1 pointer to one byte past the next element to be copied -// r2 (bytes remaining to be copied) - 8 -// r3 temporary to hold the byte that is being copied -// ip pointer one byte past the destination of the next byte to be copied - -0: ldrb r3, [r1, $-1]! - subs r2, $1 - strb r3, [ip, $-1]! - bne 0b - bx lr - -/***************************************************************************** - * STMDB loop for 1k-32k buffers * - *****************************************************************************/ - -// This loop copies 64 bytes each iteration in order of descending memory -// address, using the GPRs instead of NEON. -// -// r0 original destination pointer -// r1 pointer to one byte past the next element to be copied -// r2 (bytes remaining to be copied) - 64 -// r3-6,r8-11 (COPY_REGISTERS) temporary registers used for moving data -// ip pointer to one byte past the next location to store to - -L_useSTMDB: - push SAVE_REGISTERS -.align 3 -0: ldmdb r1!, COPY_REGISTERS - subs r2, r2, $64 - stmdb ip!, COPY_REGISTERS - ldmdb r1!, COPY_REGISTERS - pld [r1, $-64] - stmdb ip!, COPY_REGISTERS - bge 0b - pop SAVE_REGISTERS - b L_reverseVectorCleanup - -/***************************************************************************** - * Misaligned reverse vld1 loop * - *****************************************************************************/ - -// Software alignment fixup to handle source and dest that are relatively -// misaligned mod 4 bytes. -// -// The basic idea is to use 4-byte aligned loads to load 8 bytes per iteration, -// which we combine with the 8 bytes loaded in the previous iteration to get a -// 16 byte field; the next 8 bytes to be stored to the destination buffer are -// somewhere in that field, and we get them using the VEXT instruction: -// -// | 8 bytes from this iteration | 8 bytes from last iteration | -// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ -// | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | -// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ -// ^8 bytes to store this iteration^ | -// could be a page boundary -// -// We need to be a little bit careful, however. Because the loads only have 4 -// byte alignment, the very first load could slop over into a page that is not -// mapped readable. In order to prevent this scenario, we copy eight bytes -// using byte-by-byte before beginning the main loop. -// -// At the beginning of each iteration through this loop, registers are used -// as follows: -// -// r0 original destination pointer -// r1 pointer to the next block of 8 bytes to load -// r2 (bytes remaining to copy) - 8 -// ip pointer to the next block of 8 bytes to store -// d0 next 8 bytes to store -// d2 8 bytes loaded in the previous iteration -// d3 8 bytes loaded two iterations ago - -#define RCOPY_UNALIGNED(offset) \ -0: ldrb r3, [r1,$-1]! ;\ - strb r3, [ip,$-1]! ;\ - subs r2, $1 ;\ - blt L_scalarReverseCopy ;\ - tst ip, $7 ;\ - bne 0b ;\ - bic r1, $3 ;\ - sub r1, $8 ;\ - sub ip, $8 ;\ - mov r3, $-8 ;\ - vld1.32 {d2,d3}, [r1], r3 ;\ - subs r2, $8 ;\ - blt 1f ;\ -0: vext.8 d0, d2, d3, $(offset);\ - vmov d3, d2 ;\ - vld1.32 {d2}, [r1], r3 ;\ - subs r2, $8 ;\ - vst1.64 {d0}, [ip, :64], r3 ;\ - bge 0b ;\ -1: vext.8 d0, d2, d3, $(offset);\ - add r1, $8 ;\ - vst1.64 {d0}, [ip, :64] ;\ -2: add r1, $(offset);\ - b L_scalarReverseCopy - -L_reverseAligned1: - RCOPY_UNALIGNED(1) -L_reverseAligned2: - RCOPY_UNALIGNED(2) -L_reverseAligned3: - RCOPY_UNALIGNED(3) - -/***************************************************************************** - * front to back copy * - *****************************************************************************/ - -L_copyFrontToBack: - -// Here the pointers are laid out such that we can use our preferred -// front-to-back copy. We preserve original destination pointer in r0 because -// it is the return value for the routine, and copy it to ip to use in this -// routine. - - mov ip, r0 - -// Subtract 8 from the buffer length; if this is negative, then we will use -// only single-byte copies, and we jump directly to a scalar copy loop. - - subs r2, $8 - blt L_scalarCopy - -// If the destination pointer is 8-byte aligned we can use 8-byte NEON copies -// to move the data. - - tst ip, $7 - beq L_vectorCopy - -// Otherwise, we copy a single byte at a time, in order of ascending memory -// address, until the destination is 8 byte aligned. Within this loop, -// registers are used as follows: -// -// r0 original destination pointer -// r1 pointer to the next byte to copy -// r2 (bytes remaining to be copied) - 8 -// r3 temporary to hold the byte that is being copied -// ip pointer to the next byte to store to - -0: ldrb r3, [r1], $1 - sub r2, $1 - strb r3, [ip], $1 - tst ip, $7 - bne 0b - -// At this point, the destination pointer is 8 byte aligned. Check again that -// there are at least 8 bytes remaining to copy by comparing the remaining -// length minus 8 to zero. If fewer than 8 bytes remain, jump to the cleanup -// path. - - cmp r2, $0 - blt L_scalarCopy - -/***************************************************************************** - * destination is doubleword aligned * - *****************************************************************************/ - -L_vectorCopy: - -// At this point, registers contain the following values: -// -// r0 original destination pointer -// r1 pointer to the next element to be copied -// r2 (bytes remaining to copy) - 8 -// ip pointer to the destination of the next byte to be copied -// -// Furthermore, it is known that ip is 8 byte aligned, and that r2 is positive. -// NEON has really excellent alignment handling in hardware, so we would like -// to use that to handle cases where the source is not similarly aligned to the -// destination (it supports even single-byte misalignment at speed). However, -// on some SoC designs, not all of the DMA busses support such access. Thus, -// we must unfortunately use a software workaround in those cases. -// -// Fortunately, 4-byte aligned loads are supported even on the DMA busses, so -// we only need to handle the different possible source alignments modulo 4. -// Here we have a dispatch table to jump to the correct copy implementation -// for the given source alignment. -// -// The tbh instruction loads the address offset of the correct implementation -// from the data table that immediately follows it and adds it to the pc to -// jump to the correct branch. - - ands r3, r1, $3 - bic r1, $3 - tbh [pc, r3, lsl $1] -0: -.short (L_sourceAligned0-0b)/2 -.short (L_sourceAligned1-0b)/2 -.short (L_sourceAligned2-0b)/2 -.short (L_sourceAligned3-0b)/2 - -/***************************************************************************** - * source is also at least word aligned * - *****************************************************************************/ - -L_sourceAligned0: - -// Subtract 56 from r2, so that it contains the number of bytes remaining to -// copy minus 64. If this result is negative, then we jump into a loop that -// copies 8 bytes at a time. - - subs r2, $0x38 - blt L_vectorCleanup - -// Check if the destination pointer is 64-byte aligned. If so, jump to a loop -// that copies whole cachelines. - - tst ip, $0x38 - beq L_cachelineAligned - -// Otherwise, we copy a 8 bytes at a time, in order of ascending memory -// address, until the destination is 64 byte aligned. Within this loop, -// registers are used as follows: -// -// r0 original destination pointer -// r1 pointer to the next element to be copied -// r2 (bytes remaining to be copied) - 64 -// ip pointer to the destination of the next byte to be copied -// d0 temporary storage for copy - -0: vld1.32 {d0}, [r1]! - sub r2, $8 - vst1.64 {d0}, [ip,:64]! - tst ip, $0x38 - bne 0b - -// At this point, the destination pointer is 64 byte aligned. Check again that -// there are at least 64 bytes remaining to copy by comparing the remaining -// length minus 64 to zero. If fewer than 64 bytes remain, skip over the main -// copy loop. - - cmp r2, $0 - blt L_vectorCleanup - -/***************************************************************************** - * destination is cacheline aligned * - *****************************************************************************/ - -// In the special case that we are copying a buffer of between 1k and 32k bytes -// we do not use a NEON copy for the main loop. This is because if we happen -// to be doing a copy from a source in cache to a destination that is not in -// cache, this will result in an increase in energy usage. In all other cases, -// NEON gives superior energy conservation. - -L_cachelineAligned: - sub r3, r2, $0x3c0 - cmp r3, $0x7c00 - blo L_useSTMIA - -// The destination pointer is known to be 64-byte aligned, so we can use the -// maximal alignment hint (:256) for our vector stores. Detect if the source -// is also at least 32-byte aligned and jump to a loop that uses maximal -// alignment hints for the loads as well if possible. - - tst r1, $0x1f - beq L_sourceAligned32 - -// This loop copies 64 bytes per iteration, from a 4-byte aligned source to a -// 64-byte aligned destination, in order of ascending memory address. Within -// this loop, registers are used as follows: -// -// r0 original destination pointer (unmodified) -// r1 pointer to the next 32-byte block to load -// r2 (number of bytes remaining to copy) - 64 -// ip pointer to which the next 32-byte block is to be stored -// q0-q3 temporary registers used for copies -// -// Note that the loop is arrange in such a way that a single cleanup store is -// necessary after the final loop iteration. This occurs at label (1), and is -// shared between the unaligned and aligned loops. - - vld1.32 {q2,q3}, [r1]! - vld1.32 {q0,q1}, [r1]! - subs r2, $64 - vst1.64 {q2,q3}, [ip,:256]! - blt 1f -.align 3 -0: vld1.32 {q2,q3}, [r1]! - vst1.64 {q0,q1}, [ip,:256]! - vld1.32 {q0,q1}, [r1]! - subs r2, $64 - vst1.64 {q2,q3}, [ip,:256]! - bge 0b - b 1f - -L_sourceAligned32: - -// This loop is identical to the immediately preceeding loop, except that it -// uses the additional alignment hint that the source pointer (r1) is 32-byte -// aligned. The two loops share cleanup code for the final iteration. - - vld1.64 {q2,q3}, [r1,:256]! - vld1.64 {q0,q1}, [r1,:256]! - subs r2, $64 - vst1.64 {q2,q3}, [ip,:256]! - blt 1f -.align 3 -0: vld1.64 {q2,q3}, [r1,:256]! - vst1.64 {q0,q1}, [ip,:256]! - vld1.64 {q0,q1}, [r1,:256]! - subs r2, $64 - vst1.64 {q2,q3}, [ip,:256]! - bge 0b - -// Final vector store for both of the above loops. - -1: vst1.64 {q0,q1}, [ip,:256]! - -L_vectorCleanup: - -// Add 56 to r2, so that it contains the number of bytes remaing to copy minus -// 8. A comparison of this value with zero tells us if any more whole 8-byte -// blocks need to be copied. - - adds r2, $0x38 - blt L_scalarCopy - -// This loop copies 8 bytes at a time in order of descending memory address, -// until fewer than 8 bytes remain to be copied. Within this loop, registers -// are used as follows: -// -// r0 original destination pointer -// r1 pointer to the next element to be copied -// r2 (bytes remaining to be copied) - 64 -// ip pointer to the destination of the next byte to be copied -// d0 temporary storage for copy - -0: vld1.32 {d0}, [r1]! - subs r2, $8 - vst1.64 {d0}, [ip,:64]! - bge 0b - -/***************************************************************************** - * sub-doubleword cleanup copies * - *****************************************************************************/ - -L_scalarCopy: - -// Add 8 to r2, so that it contains the number of bytes remaining to copy, and -// return to the calling routine if zero bytes remain. - - adds r2, $8 - it eq - bxeq lr - -// Copy one byte at a time in descending address order until we reach the front -// of the buffer. Within this loop, registers are used as follows: -// -// r0 original destination pointer -// r1 pointer to one byte past the next element to be copied -// r2 (bytes remaining to be copied) - 8 -// r3 temporary to hold the byte that is being copied -// ip pointer one byte past the destination of the next byte to be copied - -0: ldrb r3, [r1], $1 - strb r3, [ip], $1 - subs r2, $1 - bne 0b - bx lr - -/***************************************************************************** - * STMIA loop for 1k-32k buffers * - *****************************************************************************/ - -// This loop copies 64 bytes each iteration in order of ascending memory -// address, using the GPRs instead of NEON. -// -// r0 original destination pointer -// r1 pointer to the next element to be copied -// r2 (bytes remaining to be copied) - 64 -// r3-6,r8-11 (COPY_REGISTERS) temporary registers used for moving data -// ip pointer to the next location to store to - -L_useSTMIA: - push SAVE_REGISTERS -.align 3 -0: ldmia r1!, COPY_REGISTERS - subs r2, r2, $64 - stmia ip!, COPY_REGISTERS - ldmia r1!, COPY_REGISTERS - pld [r1, $64] - stmia ip!, COPY_REGISTERS - bge 0b - pop SAVE_REGISTERS - b L_vectorCleanup - -/***************************************************************************** - * Misaligned forward vld1 loop * - *****************************************************************************/ - -// Software alignment fixup to handle source and dest that are relatively -// misaligned mod 4 bytes. -// -// The basic idea is to use 4-byte aligned loads to load 8 bytes per iteration, -// which we combine with the 8 bytes loaded in the previous iteration to get a -// 16 byte field; the next 8 bytes to be stored to the destination buffer are -// somewhere in that field, and we get them using the VEXT instruction: -// -// | 8 bytes from last iteration | 8 bytes from this iteration | -// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ -// | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | -// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ -// ^8 bytes to store this iteration^ | -// could be a page boundary -// -// We need to be a little bit careful, however. Because the loads only have 4 -// byte alignment, if we used this approach all the way to the end of the -// buffer, the very last 8 byte load might slop over onto a new page by 4 -// bytes, and that new page might not be mapped into our process. Thus, we -// terminate this copy loop when fewer than 12 bytes remain to be copied, -// instead of the more natural-seeming termination condition of "8 bytes -// remaining" (the illustration above shows the worst case and demonstrates -// why 12 is a sufficiently safe condition). -// -// At the beginning of each iteration through this loop, registers are used -// as follows: -// -// r0 original destination pointer -// r1 pointer to the next block of 8 bytes to load -// r2 (bytes remaining to copy) - 12 -// ip pointer to the next block of 8 bytes to store -// d0 next 8 bytes to store -// d2 8 bytes loaded in the previous iteration -// d3 8 bytes loaded two iterations ago - -#define COPY_UNALIGNED(offset) \ - subs r2, $4 ;\ - blt 2f ;\ - vld1.32 {d2,d3}, [r1]! ;\ - subs r2, $8 ;\ - blt 1f ;\ -0: vext.8 d0, d2, d3, $(offset);\ - vmov d2, d3 ;\ - vld1.32 {d3}, [r1]! ;\ - subs r2, $8 ;\ - vst1.64 {d0}, [ip, :64]! ;\ - bge 0b ;\ -1: vext.8 d0, d2, d3, $(offset);\ - sub r1, $8 ;\ - vst1.64 {d0}, [ip, :64]! ;\ -2: add r1, $(offset);\ - add r2, $4 ;\ - b L_scalarCopy - -L_sourceAligned1: - COPY_UNALIGNED(1) -L_sourceAligned2: - COPY_UNALIGNED(2) -L_sourceAligned3: - COPY_UNALIGNED(3) - -#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD diff --git a/src/libc/arm/string/bcopy_CortexA9.s b/src/libc/arm/string/bcopy_CortexA9.s deleted file mode 100644 index 45f0e2b64..000000000 --- a/src/libc/arm/string/bcopy_CortexA9.s +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright (c) 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * This file implements the following functions for the Cortex-A9 processor: - * - * void bcopy(const void * source, - * void * destination, - * size_t length); - * - * void *memmove(void * destination, - * const void * source, - * size_t n); - * - * void *memcpy(void * restrict destination, - * const void * restrict source, - * size_t n); - * - * All copy n successive bytes from source to destination. Memmove and memcpy - * return destination, whereas bcopy has no return value. Copying takes place - * as if it were through a temporary buffer -- after return destination - * contains exactly the bytes from source, even if the buffers overlap (this is - * not required of memcpy by the C standard; its behavior is undefined if the - * buffers overlap, but we are holding ourselves to the historical behavior of - * this function on OS X and iOS). - */ - -#include -#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD - -/***************************************************************************** - * Macros * - *****************************************************************************/ - -#define A9_ENTRY(name) \ - .align 2;\ - .globl _ ## name ## $VARIANT$CortexA9;\ - _ ## name ## $VARIANT$CortexA9: - -#define ESTABLISH_FRAME \ - push {r0,r4,r7,lr};\ - add r7, sp, #8 - -#define CLEAR_FRAME_AND_RETURN \ - pop {r0,r4,r7,pc} - -#define ADDITIONAL_CALLEE_SAVE_REGISTERS {r5,r6,r8,r10} - -#define COPY_REGISTERS {r3,r4,r5,r6,r8,r9,r10,r12} - -/***************************************************************************** - * entry points * - *****************************************************************************/ - -.text -.syntax unified -.code 32 - -A9_ENTRY(bcopy) -// Translate bcopy calls into memcpy calls by swapping the first and second -// arguments. - mov r3, r0 - mov r0, r1 - mov r1, r3 - -A9_ENTRY(memcpy) -A9_ENTRY(memmove) -// Our preference is to copy the data in ascending address order, but if the -// buffers overlap such that the beginning of the destination buffer aliases -// the end of the source buffer, we need to copy in descending address order -// instead to preserve the memmove semantics. We detect this case with the -// test: -// -// destination - source < length (unsigned compare) -// -// If the address of the source buffer is higher than the address of the -// destination buffer, this arithmetic can overflow, but the overflowed value -// can only be smaller than length if the buffers do not overlap, so we don't -// need to worry about false positives due to the overflow (they happen, but -// only in cases where copying in either order is correct). - subs r3, r0, r1 - bxeq lr - ESTABLISH_FRAME - cmp r3, r2 - blo L_descendingCopy - -/***************************************************************************** - * ascending copy * - *****************************************************************************/ - -// The layout of the two buffers is such that we can use our preferred -// (ascending address order) copy implementation. Throughout this copy, -// registers are used as follows: -// -// r0 lowest unwritten address in the destination buffer. -// r1 lowest unread address in the source buffer. -// r2 number of bytes remaining to copy less an offset that varies -// with the size of the copies that are being made. -// r3, r4, r5, r6, r8, r9, r10, r12 -// temporary registers used to hold the data during copies. -// r12 also used as a scratch register for alignment / length calculations - -L_ascendingCopy: -// We begin by checking if less than four bytes are to be copied; if so, we -// branch directly to a small-buffer copy and return. Otherwise, we copy up -// to three bytes if needed to make the destination pointer have word (four -// byte) alignment. - subs r2, #4 - blo L_ascendingLengthLessThanFour - ands ip, r0, #0x3 - beq L_ascendingDestinationWordAligned - ldrb r3, [r1],#1 - cmp ip, #2 - ldrbls r4, [r1],#1 - strb r3, [r0],#1 - ldrblo r3, [r1],#1 - add r2, ip - strbls r4, [r0],#1 - strblo r3, [r0],#1 - subs r2, #4 - bhs L_ascendingDestinationWordAligned - -L_ascendingLengthLessThanFour: -// Conditionally copies up to three bytes, assuming no alignment. This is -// only used if the original length of the buffer is smaller than four. - lsls ip, r2, #31 - ldrbcs r3, [r1],#1 - ldrbcs ip, [r1],#1 - ldrbmi r4, [r1] - strbcs r3, [r0],#1 - strbcs ip, [r0],#1 - strbmi r4, [r0] - CLEAR_FRAME_AND_RETURN - -L_ascendingDestinationWordAligned: -// We know that the destination has word alignment. If the source is not -// similarly aligned, jump to an unaligned copy loop. - tst r1, #0x3 - bne L_ascendingUnalignedCopy - -/***************************************************************************** - * ascending copy, both buffers have word alignment * - *****************************************************************************/ - -// If less than sixty-four bytes remain to be copied, jump directly to the -// word-aligned cleanup path. Otherwise, we copy up to 28 bytes as needed -// to make the destination pointer have cacheline alignment. - subs r2, r2, #0x3c - blo L_ascendingLengthLessThanSixtyFour -0: tst r0, #0x1c - beq L_ascendingDestinationCachelineAligned - ldr r3, [r1],#4 - subs r2, #4 - str r3, [r0],#4 - bhs 0b - b L_ascendingLengthLessThanSixtyFour - -L_ascendingDestinationCachelineAligned: -// Unrolled main copy loop; copies two cachelines (64 bytes) per iteration. -// Empirical testing suggests that 0x60 is the optimal lookahead for preload, -// though anything between 0x40 and 0x100 seems to be "acceptable". - push ADDITIONAL_CALLEE_SAVE_REGISTERS -0: ldm r1!, COPY_REGISTERS - subs r2, r2, #0x40 - stm r0!, COPY_REGISTERS - pld [r1, #0x60] - ldm r1!, COPY_REGISTERS - pld [r1, #0x60] - stm r0!, COPY_REGISTERS - bhs 0b - pop ADDITIONAL_CALLEE_SAVE_REGISTERS - -L_ascendingLengthLessThanSixtyFour: -// Cleanup copy of up to 63 bytes. We can assume that both the source and -// destination addresses have word alignment here. - tst r2, #0x30 - beq 1f -0: ldm r1!, {r3,r4,r9,ip} - sub r2, r2, #0x10 - stm r0!, {r3,r4,r9,ip} - tst r2, #0x30 - bne 0b -1: tst r2, #0xf - beq 2f - lsls ip, r2, #29 - ldmcs r1!, {r3,ip} - stmcs r0!, {r3,ip} - ldrmi r3, [r1],#4 - strmi r3, [r0],#4 - lsls ip, r2, #31 - ldrhcs r3, [r1],#2 - strhcs r3, [r0],#2 - ldrbmi ip, [r1] - strbmi ip, [r0] -2: CLEAR_FRAME_AND_RETURN - -/***************************************************************************** - * ascending copy, source buffer is not word aligned * - *****************************************************************************/ - -L_ascendingUnalignedCopy: -// Destination buffer is word aligned, but source buffer is not. Copy -// byte-by-byte until the destination buffer has eightbyte alignment. - subs r2, #4 - blo L_ascendingUnalignedByteCleanup -0: tst r0, #0x7 - beq L_ascendingUnalignedVectorCopy - ldrb r3, [r1],#1 - subs r2, #1 - strb r3, [r0],#1 - bhs 0b -L_ascendingUnalignedByteCleanup: - adds r2, #8 - beq 1f -0: ldrb r3, [r1],#1 - subs r2, #1 - strb r3, [r0],#1 - bne 0b -1: CLEAR_FRAME_AND_RETURN - -L_ascendingUnalignedVectorCopy: -// Destination buffer is eightbyte aligned. Source buffer has unknown -// alignment. Use NEON to handle the misaligned copies. We begin by copying -// up to 24 bytes to get cacheline alignment of the destination buffer. - subs r2, #0x18 - blo L_ascendingUnalignedVectorCleanup -0: tst r0, #0x18 - beq L_ascendingUnalignedCachelineCopy - vld1.8 {d0}, [r1]! - subs r2, #8 - vst1.8 {d0}, [r0,:64]! - bhs 0b -L_ascendingUnalignedVectorCleanup: - adds r2, #0x18 - blo L_ascendingUnalignedByteCleanup -0: vld1.8 {d0}, [r1]! - subs r2, #8 - vst1.8 {d0}, [r0,:64]! - bhs 0b - b L_ascendingUnalignedByteCleanup - -L_ascendingUnalignedCachelineCopy: -// Main copy loop; moves 32 bytes per iteration. Requires only byte alignment -// of the source address. - vld1.8 {q0,q1},[r1]! - pld [r1, #0x60] - vst1.8 {q0,q1},[r0,:256]! - subs r2, #0x20 - bhs L_ascendingUnalignedCachelineCopy - b L_ascendingUnalignedVectorCleanup - -/***************************************************************************** - * descending copy * - *****************************************************************************/ - -// The layout of the two buffers is such that we must copy in descending- -// address order. Throughout this copy, registers are used as follows: -// -// r0 lowest address in the destination buffer that has been written to. -// r1 lowest address in the source buffer that has been read from. -// r2 number of bytes remaining to copy less an offset that varies -// with the size of the copies that are being made. -// r3, r4, r5, r6, r8, r9, r10, r12 -// temporary registers used to hold the data during copies. -// r12 also used as a scratch register for alignment / length calculations - -L_descendingCopy: -// We begin by checking if less than four bytes are to be copied; if so, we -// branch directly to a small-buffer copy and return. Otherwise, we copy up -// to three bytes if needed to make the destination pointer have word (four -// byte) alignment. - add r1, r2 - add r0, r2 - subs r2, #4 - blo L_descendingLengthLessThanFour - ands ip, r0, #0x3 - beq L_descendingDestinationWordAligned - ldrb r3, [r1, #-1]! - cmp ip, #2 - ldrbhs r4, [r1, #-1]! - strb r3, [r0, #-1]! - ldrbhi r3, [r1, #-1]! - strbhs r4, [r0, #-1]! - strbhi r3, [r0, #-1]! - subs r2, ip - bhs L_descendingDestinationWordAligned - -L_descendingLengthLessThanFour: -// Conditionally copies up to three bytes, assuming no alignment. This is -// only used if the original length of the buffer is smaller than four. - lsls ip, r2, #31 - ldrbcs r3, [r1, #-1]! - ldrbcs ip, [r1, #-1]! - ldrbmi r4, [r1, #-1] - strbcs r3, [r0, #-1]! - strbcs ip, [r0, #-1]! - strbmi r4, [r0, #-1] - CLEAR_FRAME_AND_RETURN - -L_descendingDestinationWordAligned: -// We know that the destination has word alignment. If the source is not -// similarly aligned, jump to an unaligned copy loop. - tst r1, #0x3 - bne L_descendingUnalignedCopy - -/***************************************************************************** - * descending copy, both buffers have word alignment * - *****************************************************************************/ - -// If less than sixty-four bytes remain to be copied, jump directly to the -// word-aligned cleanup path. Otherwise, we copy up to 28 bytes as needed -// to make the destination pointer have cacheline alignment. - subs r2, r2, #0x3c - blo L_descendingLengthLessThanSixtyFour -0: tst r0, #0x1c - beq L_descendingDestinationCachelineAligned - ldr r3, [r1, #-4]! - subs r2, #4 - str r3, [r0, #-4]! - bhs 0b - b L_descendingLengthLessThanSixtyFour - -L_descendingDestinationCachelineAligned: -// Unrolled main copy loop; copies two cachelines (64 bytes) per iteration. -// Empirical testing suggests that -0x80 is the optimal lookahead for preload, -// though anything between -0x40 and -0x100 seems to be "acceptable". - push ADDITIONAL_CALLEE_SAVE_REGISTERS -0: ldmdb r1!, COPY_REGISTERS - subs r2, r2, #0x40 - stmdb r0!, COPY_REGISTERS - pld [r1, #-0x80] - ldmdb r1!, COPY_REGISTERS - pld [r1, #-0x80] - stmdb r0!, COPY_REGISTERS - bhs 0b - pop ADDITIONAL_CALLEE_SAVE_REGISTERS - -L_descendingLengthLessThanSixtyFour: -// Cleanup copy of up to 63 bytes. We can assume that both the source and -// destination addresses have word alignment here. - tst r2, #0x30 - beq 1f -0: ldmdb r1!, {r3,r4,r9,ip} - sub r2, r2, #0x10 - stmdb r0!, {r3,r4,r9,ip} - tst r2, #0x30 - bne 0b -1: tst r2, #0xf - beq 2f - lsls ip, r2, #29 - ldmdbcs r1!, {r3,ip} - stmdbcs r0!, {r3,ip} - ldrmi r3, [r1, #-4]! - strmi r3, [r0, #-4]! - lsls ip, r2, #31 - ldrhcs r3, [r1, #-2]! - strhcs r3, [r0, #-2]! - ldrbmi ip, [r1, #-1] - strbmi ip, [r0, #-1] -2: CLEAR_FRAME_AND_RETURN - -/***************************************************************************** - * descending copy, source buffer is not word aligned * - *****************************************************************************/ - -L_descendingUnalignedCopy: -// Destination buffer is word aligned, but source buffer is not. Copy -// byte-by-byte until the destination buffer has eightbyte alignment. - subs r2, #4 - blo L_descendingUnalignedByteCleanup -0: tst r0, #0x7 - beq L_descendingUnalignedVectorCopy - ldrb r3, [r1, #-1]! - subs r2, #1 - strb r3, [r0, #-1]! - bhs 0b -L_descendingUnalignedByteCleanup: - adds r2, #8 - beq 1f -0: ldrb r3, [r1, #-1]! - subs r2, #1 - strb r3, [r0, #-1]! - bne 0b -1: CLEAR_FRAME_AND_RETURN - -L_descendingUnalignedVectorCopy: -// Destination buffer is eightbyte aligned. Source buffer has unknown -// alignment. Use NEON to handle the misaligned copies. We begin by copying -// up to 24 bytes to get cacheline alignment of the destination buffer. - subs r2, #0x18 - blo L_descendingUnalignedVectorCleanup -0: tst r0, #0x18 - beq L_descendingUnalignedCachelineCopy - sub r1, #8 - vld1.8 {d0}, [r1] - sub r0, #8 - vst1.8 {d0}, [r0,:64] - subs r2, #8 - bhs 0b -L_descendingUnalignedVectorCleanup: - adds r2, #0x18 - blo L_descendingUnalignedByteCleanup -0: sub r1, #8 - vld1.8 {d0}, [r1] - sub r0, #8 - vst1.8 {d0}, [r0,:64] - subs r2, #8 - bhs 0b - b L_descendingUnalignedByteCleanup - -L_descendingUnalignedCachelineCopy: -// Main copy loop; moves 32 bytes per iteration. Requires only byte alignment -// of the source address. - sub r1, #32 - sub r0, #32 - mov r4, #-32 -0: vld1.8 {q0,q1},[r1], r4 - pld [r1, #-0x60] - vst1.8 {q0,q1},[r0,:256], r4 - subs r2, #0x20 - bhs 0b - add r1, #32 - add r0, #32 - b L_descendingUnalignedVectorCleanup - -#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD diff --git a/src/libc/arm/string/bcopy_Generic.s b/src/libc/arm/string/bcopy_Generic.s deleted file mode 100644 index 4d5fc22ea..000000000 --- a/src/libc/arm/string/bcopy_Generic.s +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2006, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/***************************************************************************** - * ARMv5 and ARMv6 implementation, also used in dyld on later archs * - *****************************************************************************/ - -#include -#if !defined _ARM_ARCH_7 || defined VARIANT_DYLD - -.text -.align 2 - - .globl _memcpy - .globl _bcopy - .globl _memmove - -_bcopy: /* void bcopy(const void *src, void *dest, size_t len); */ - mov r3, r0 - mov r0, r1 - mov r1, r3 - -_memcpy: /* void *memcpy(void *dest, const void *src, size_t len); */ -_memmove: /* void *memmove(void *dest, const void *src, size_t len); */ - /* check for zero len or if the pointers are the same */ - cmp r2, #0 - cmpne r0, r1 - bxeq lr - - /* save r0 (return value), r4 (scratch), and r5 (scratch) */ - stmfd sp!, { r0, r4, r5, r7, lr } - add r7, sp, #12 - - /* check for overlap. r3 <- distance between src & dest */ - subhs r3, r0, r1 - sublo r3, r1, r0 - cmp r3, r2 /* if distance(src, dest) < len, we have overlap */ - blo Loverlap - -Lnormalforwardcopy: - /* are src and dest dissimilarly word aligned? */ - mov r12, r0, lsl #30 - cmp r12, r1, lsl #30 - bne Lnonwordaligned_forward - - /* if len < 64, do a quick forward copy */ - cmp r2, #64 - blt Lsmallforwardcopy - - /* check for 16 byte src/dest unalignment */ - tst r0, #0xf - bne Lsimilarlyunaligned - - /* check for 32 byte dest unalignment */ - tst r0, #(1<<4) - bne Lunaligned_32 - -Lmorethan64_aligned: - /* save some more registers to use in the copy */ - stmfd sp!, { r6, r8, r10, r11 } - - /* pre-subtract 64 from the len counter to avoid an extra compare in the loop */ - sub r2, r2, #64 - -L64loop: - /* copy 64 bytes at a time */ - ldmia r1!, { r3, r4, r5, r6, r8, r10, r11, r12 } -#ifdef _ARM_ARCH_6 - pld [r1, #32] -#endif - stmia r0!, { r3, r4, r5, r6, r8, r10, r11, r12 } - ldmia r1!, { r3, r4, r5, r6, r8, r10, r11, r12 } - subs r2, r2, #64 -#ifdef _ARM_ARCH_6 - pld [r1, #32] -#endif - stmia r0!, { r3, r4, r5, r6, r8, r10, r11, r12 } - bge L64loop - - /* restore the scratch registers we just saved */ - ldmfd sp!, { r6, r8, r10, r11 } - - /* fix up the len counter (previously subtracted an extra 64 from it) and test for completion */ - adds r2, r2, #64 - beq Lexit - -Llessthan64_aligned: - /* copy 16 bytes at a time until we have < 16 bytes */ - cmp r2, #16 - ldmgeia r1!, { r3, r4, r5, r12 } - stmgeia r0!, { r3, r4, r5, r12 } - subges r2, r2, #16 - bgt Llessthan64_aligned - beq Lexit - -Llessthan16_aligned: - mov r2, r2, lsl #28 - msr cpsr_f, r2 - - ldmmiia r1!, { r2, r3 } - ldreq r4, [r1], #4 - ldrcsh r5, [r1], #2 - ldrvsb r12, [r1], #1 - - stmmiia r0!, { r2, r3 } - streq r4, [r0], #4 - strcsh r5, [r0], #2 - strvsb r12, [r0], #1 - b Lexit - -Lsimilarlyunaligned: - /* both src and dest are unaligned in similar ways, align to dest on 32 byte boundary */ - mov r12, r0, lsl #28 - rsb r12, r12, #0 - msr cpsr_f, r12 - - ldrvsb r3, [r1], #1 - ldrcsh r4, [r1], #2 - ldreq r5, [r1], #4 - - strvsb r3, [r0], #1 - strcsh r4, [r0], #2 - streq r5, [r0], #4 - - ldmmiia r1!, { r3, r4 } - stmmiia r0!, { r3, r4 } - - subs r2, r2, r12, lsr #28 - beq Lexit - -Lunaligned_32: - /* bring up to dest 32 byte alignment */ - tst r0, #(1 << 4) - ldmneia r1!, { r3, r4, r5, r12 } - stmneia r0!, { r3, r4, r5, r12 } - subne r2, r2, #16 - - /* we should now be aligned, see what copy method we should use */ - cmp r2, #64 - bge Lmorethan64_aligned - b Llessthan64_aligned - -Lbytewise2: - /* copy 2 bytes at a time */ - subs r2, r2, #2 - - ldrb r3, [r1], #1 - ldrplb r4, [r1], #1 - - strb r3, [r0], #1 - strplb r4, [r0], #1 - - bhi Lbytewise2 - b Lexit - -Lbytewise: - /* simple bytewise forward copy */ - ldrb r3, [r1], #1 - subs r2, r2, #1 - strb r3, [r0], #1 - bne Lbytewise - b Lexit - -Lsmallforwardcopy: - /* src and dest are word aligned similarly, less than 64 bytes to copy */ - cmp r2, #4 - blt Lbytewise2 - - /* bytewise copy until word aligned */ - tst r1, #3 -Lwordalignloop: - ldrneb r3, [r1], #1 - strneb r3, [r0], #1 - subne r2, r2, #1 - tstne r1, #3 - bne Lwordalignloop - - cmp r2, #16 - bge Llessthan64_aligned - blt Llessthan16_aligned - -Loverlap: - /* src and dest overlap in some way, len > 0 */ - cmp r0, r1 /* if dest > src */ - bhi Loverlap_srclower - -Loverlap_destlower: - /* dest < src, see if we can still do a fast forward copy or fallback to slow forward copy */ - cmp r3, #64 - bge Lnormalforwardcopy /* overlap is greater than one stride of the copy, use normal copy */ - - cmp r3, #2 - bge Lbytewise2 - b Lbytewise - - /* the following routines deal with having to copy in the reverse direction */ -Loverlap_srclower: - /* src < dest, with overlap */ - - /* src += len; dest += len; */ - add r0, r0, r2 - add r1, r1, r2 - - /* we have to copy in reverse no matter what, test if we can we use a large block reverse copy */ - cmp r2, #64 /* less than 64 bytes to copy? */ - cmpgt r3, #64 /* less than 64 bytes of nonoverlap? */ - blt Lbytewise_reverse - - /* test of src and dest are nonword aligned differently */ - mov r3, r0, lsl #30 - cmp r3, r1, lsl #30 - bne Lbytewise_reverse - - /* test if src and dest are non word aligned or dest is non 16 byte aligned */ - tst r0, #0xf - bne Lunaligned_reverse_similarly - - /* test for dest 32 byte alignment */ - tst r0, #(1<<4) - bne Lunaligned_32_reverse_similarly - - /* 64 byte reverse block copy, src and dest aligned */ -Lmorethan64_aligned_reverse: - /* save some more registers to use in the copy */ - stmfd sp!, { r6, r8, r10, r11 } - - /* pre-subtract 64 from the len counter to avoid an extra compare in the loop */ - sub r2, r2, #64 - -L64loop_reverse: - /* copy 64 bytes at a time */ - ldmdb r1!, { r3, r4, r5, r6, r8, r10, r11, r12 } -#ifdef _ARM_ARCH_6 - pld [r1, #-32] -#endif - stmdb r0!, { r3, r4, r5, r6, r8, r10, r11, r12 } - ldmdb r1!, { r3, r4, r5, r6, r8, r10, r11, r12 } - subs r2, r2, #64 -#ifdef _ARM_ARCH_6 - pld [r1, #-32] -#endif - stmdb r0!, { r3, r4, r5, r6, r8, r10, r11, r12 } - bge L64loop_reverse - - /* restore the scratch registers we just saved */ - ldmfd sp!, { r6, r8, r10, r11 } - - /* fix up the len counter (previously subtracted an extra 64 from it) and test for completion */ - adds r2, r2, #64 - beq Lexit - -Lbytewise_reverse: - ldrb r3, [r1, #-1]! - strb r3, [r0, #-1]! - subs r2, r2, #1 - bne Lbytewise_reverse - b Lexit - -Lunaligned_reverse_similarly: - /* both src and dest are unaligned in similar ways, align to dest on 32 byte boundary */ - mov r12, r0, lsl #28 - msr cpsr_f, r12 - - ldrvsb r3, [r1, #-1]! - ldrcsh r4, [r1, #-2]! - ldreq r5, [r1, #-4]! - - strvsb r3, [r0, #-1]! - strcsh r4, [r0, #-2]! - streq r5, [r0, #-4]! - - ldmmidb r1!, { r3, r4 } - stmmidb r0!, { r3, r4 } - - subs r2, r2, r12, lsr #28 - beq Lexit - -Lunaligned_32_reverse_similarly: - /* bring up to dest 32 byte alignment */ - tst r0, #(1 << 4) - ldmnedb r1!, { r3, r4, r5, r12 } - stmnedb r0!, { r3, r4, r5, r12 } - subne r2, r2, #16 - - /* we should now be aligned, see what copy method we should use */ - cmp r2, #64 - bge Lmorethan64_aligned_reverse - b Lbytewise_reverse - - /* the following routines deal with non word aligned copies */ -Lnonwordaligned_forward: - cmp r2, #8 - blt Lbytewise2 /* not worth the effort with less than 24 bytes total */ - - /* bytewise copy until src word aligned */ - tst r1, #3 -Lwordalignloop2: - ldrneb r3, [r1], #1 - strneb r3, [r0], #1 - subne r2, r2, #1 - tstne r1, #3 - bne Lwordalignloop2 - - /* figure out how the src and dest are unaligned */ - and r3, r0, #3 - cmp r3, #2 - blt Lalign1_forward - beq Lalign2_forward - bgt Lalign3_forward - -Lalign1_forward: - /* the dest pointer is 1 byte off from src */ - mov r12, r2, lsr #2 /* number of words we should copy */ - sub r0, r0, #1 - - /* prime the copy */ - ldrb r4, [r0] /* load D[7:0] */ - -Lalign1_forward_loop: - ldr r3, [r1], #4 /* load S */ - orr r4, r4, r3, lsl #8 /* D[31:8] = S[24:0] */ - str r4, [r0], #4 /* save D */ - mov r4, r3, lsr #24 /* D[7:0] = S[31:25] */ - subs r12, r12, #1 - bne Lalign1_forward_loop - - /* finish the copy off */ - strb r4, [r0], #1 /* save D[7:0] */ - - ands r2, r2, #3 - beq Lexit - b Lbytewise2 - -Lalign2_forward: - /* the dest pointer is 2 bytes off from src */ - mov r12, r2, lsr #2 /* number of words we should copy */ - sub r0, r0, #2 - - /* prime the copy */ - ldrh r4, [r0] /* load D[15:0] */ - -Lalign2_forward_loop: - ldr r3, [r1], #4 /* load S */ - orr r4, r4, r3, lsl #16 /* D[31:16] = S[15:0] */ - str r4, [r0], #4 /* save D */ - mov r4, r3, lsr #16 /* D[15:0] = S[31:15] */ - subs r12, r12, #1 - bne Lalign2_forward_loop - - /* finish the copy off */ - strh r4, [r0], #2 /* save D[15:0] */ - - ands r2, r2, #3 - beq Lexit - b Lbytewise2 - -Lalign3_forward: - /* the dest pointer is 3 bytes off from src */ - mov r12, r2, lsr #2 /* number of words we should copy */ - sub r0, r0, #3 - - /* prime the copy */ - ldr r4, [r0] - and r4, r4, #0x00ffffff /* load D[24:0] */ - -Lalign3_forward_loop: - ldr r3, [r1], #4 /* load S */ - orr r4, r4, r3, lsl #24 /* D[31:25] = S[7:0] */ - str r4, [r0], #4 /* save D */ - mov r4, r3, lsr #8 /* D[24:0] = S[31:8] */ - subs r12, r12, #1 - bne Lalign3_forward_loop - - /* finish the copy off */ - strh r4, [r0], #2 /* save D[15:0] */ - mov r4, r4, lsr #16 - strb r4, [r0], #1 /* save D[23:16] */ - - ands r2, r2, #3 - beq Lexit - b Lbytewise2 - -Lexit: - ldmfd sp!, {r0, r4, r5, r7, pc} - -#endif // !defined _ARM_ARCH_7 || defined VARIANT_DYLD - diff --git a/src/libc/arm/string/bcopy_Swift.s b/src/libc/arm/string/bcopy_Swift.s deleted file mode 100644 index e5188b18d..000000000 --- a/src/libc/arm/string/bcopy_Swift.s +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * This file implements the following functions for the Swift micro-arch: - * - * void bcopy(const void * source, - * void * destination, - * size_t length); - * - * void *memmove(void * destination, - * const void * source, - * size_t n); - * - * void *memcpy(void * restrict destination, - * const void * restrict source, - * size_t n); - * - * All copy n successive bytes from source to destination. Memmove and memcpy - * return destination, whereas bcopy has no return value. Copying takes place - * as if it were through a temporary buffer -- after return destination - * contains exactly the bytes from source, even if the buffers overlap (this is - * not required of memcpy by the C standard; its behavior is undefined if the - * buffers overlap, but we are holding ourselves to the historical behavior of - * this function on OS X and iOS). - */ - -#include -#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD - -.syntax unified -.code 16 -.globl _bcopy$VARIANT$Swift -.thumb_func _bcopy$VARIANT$Swift -.globl _memmove$VARIANT$Swift -.thumb_func _memmove$VARIANT$Swift -.globl _memcpy$VARIANT$Swift -.thumb_func _memcpy$VARIANT$Swift - -.text -.align 4 -_bcopy$VARIANT$Swift: -// Translate bcopy calls into memcpy calls by swapping the first and second -// arguments. - mov r3, r0 - mov r0, r1 - mov r1, r3 - -_memmove$VARIANT$Swift: -_memcpy$VARIANT$Swift: -// Our preference is to copy the data in ascending address order, but if the -// buffers overlap such that the beginning of the destination buffer aliases -// the end of the source buffer, we need to copy in descending address order -// instead to preserve the memmove semantics. We detect this case with the -// test: -// -// destination - source < length (unsigned compare) -// -// If the address of the source buffer is higher than the address of the -// destination buffer, this arithmetic can overflow, but the overflowed value -// can only be smaller than length if the buffers do not overlap, so we don't -// need to worry about false positives due to the overflow (they happen, but -// only in cases where copying in either order is correct). - push {r7,lr} - mov r7, sp - subs r3, r0, r1 - beq L_exit - mov ip, r0 - cmp r3, r2 - blo L_descendingCopy - -/***************************************************************************** - * Ascending copy * - *****************************************************************************/ - - subs r3, r2, #32 // If length < 32, jump to a dedicated code - blo L_ascendingShort // path for short buffers. - - orr lr, r0, r1 // If the length is not a multiple of 16, or - orr lr, r2 // either buffer is not 16-byte aligned, then - ands lr, #0xf // some edging is needed; jump to a separate - bne L_ascendingEdging // branch to handle it. - -/***************************************************************************** - * Ascending vector aligned copy * - *****************************************************************************/ - -0: subs r3, #32 // Copy 32 bytes at a time from src to dst, - vld1.8 {q0,q1}, [r1,:128]! // both of which have 16-byte alignment. - vst1.8 {q0,q1}, [ip,:128]! // Terminate this loop when 32 or fewer bytes - bhi 0b // remain to be copied. - - add r1, r3 // Backtrack both pointers by 32 - remaining - vld1.8 {q0,q1}, [r1,:128] // and copy 32 bytes from src to dst. This - add ip, r3 // copy may overlap the previous copy, and - vst1.8 {q0,q1}, [ip,:128] // takes us precisely to the end of the - pop {r7,pc} // buffer. - -/***************************************************************************** - * Ascending vector misaligned copy * - *****************************************************************************/ - -L_ascendingEdging: - tst ip, #0xf // Copy one byte at a time until the - itttt ne // destination pointer has 16 byte alignment. - ldrbne r3, [r1],#1 - strbne r3, [ip],#1 - subne r2, #1 - bne L_ascendingEdging - - and lr, r1, #0xf // Back the source pointer up to a 16-byte - bic r1, #0xf // aligned location, and check if length > 32. - subs r3, r2, #32 - blo L_ascendingEdgingExit - tbh [pc, lr, lsl #1] // Otherwise, we have a jump table based on -0: // the relative alignment of the buffers. -.short (L_ascendingExtract0x0-0b)/2 -.short (L_ascendingExtract0x1-0b)/2 -.short (L_ascendingExtract0x2-0b)/2 -.short (L_ascendingExtract0x3-0b)/2 -.short (L_ascendingExtract0x4-0b)/2 -.short (L_ascendingExtract0x5-0b)/2 -.short (L_ascendingExtract0x6-0b)/2 -.short (L_ascendingExtract0x7-0b)/2 -.short (L_ascendingExtract0x8-0b)/2 -.short (L_ascendingExtract0x9-0b)/2 -.short (L_ascendingExtract0xa-0b)/2 -.short (L_ascendingExtract0xb-0b)/2 -.short (L_ascendingExtract0xc-0b)/2 -.short (L_ascendingExtract0xd-0b)/2 -.short (L_ascendingExtract0xe-0b)/2 -.short (L_ascendingExtract0xf-0b)/2 - -L_ascendingExtract0x0: // If the two buffers are similarly aligned, - subs r3, #32 // we use a slightly simpler loop that just - vld1.8 {q0,q1}, [r1,:128]! // copies 32 bytes at a time. - vst1.8 {q0,q1}, [ip,:128]! - bhs L_ascendingExtract0x0 - b L_ascendingEdgingExit - -#define ASCENDING_EXTRACT(shift)\ -L_ascendingExtract ## shift:\ - vld1.8 {q8}, [r1,:128]!;\ -0: vld1.8 {q9,q10},[r1,:128]!;\ - vext.8 q0, q8, q9, $(shift);\ - vext.8 q1, q9, q10,$(shift);\ - vmov q8, q10;\ - vst1.8 {q0,q1}, [ip,:128]!;\ - subs r3, $32;\ - bhs 0b;\ - sub r1, $16;\ - b L_ascendingEdgingExit - -ASCENDING_EXTRACT(0x1) // Otherwise, we use the loop implemented in -ASCENDING_EXTRACT(0x2) // the above macro. It loads 32 bytes per -ASCENDING_EXTRACT(0x3) // iteration combines it with the residual -ASCENDING_EXTRACT(0x4) // bytes from the previous iteration, and -ASCENDING_EXTRACT(0x5) // uses the VEXT instruction to extract 32 -ASCENDING_EXTRACT(0x6) // bytes that can be stored to a 16-byte -ASCENDING_EXTRACT(0x7) // aligned location in the destination buffer. -ASCENDING_EXTRACT(0x8) // This continues until 32 or fewer bytes -ASCENDING_EXTRACT(0x9) // remain to be copied. This is significantly -ASCENDING_EXTRACT(0xa) // faster than using misaligned loads and -ASCENDING_EXTRACT(0xb) // stores, which are very inefficient on -ASCENDING_EXTRACT(0xc) // Swift. -ASCENDING_EXTRACT(0xd) -ASCENDING_EXTRACT(0xe) -ASCENDING_EXTRACT(0xf) - -L_ascendingEdgingExit: - add r1, lr // Restore the source pointer - add r2, r3, #32 // Restore the length -L_ascendingShort: - subs r2, #1 // Copy one byte at a time until the buffer - itt hs // is exhausted, then return. - ldrbhs r3, [r1],#1 - strbhs r3, [ip],#1 - bhi L_ascendingShort -L_exit: - pop {r7,pc} - -/***************************************************************************** - * Descending copy * - *****************************************************************************/ - -L_descendingCopy: - add r1, r2 // Advance source and destination pointers to - add ip, r2 // the end of the buffer. - - subs r3, r2, #32 // If length < 32, jump to a dedicated code - blo L_descendingShort // path for short buffers. - - orr lr, r0, r1 // If the length is not a multiple of 16, or - orr lr, r2 // either buffer is not 16-byte aligned, then - ands lr, #0xf // some edging is needed; jump to a separate - bne L_descendingEdging // branch to handle it. - -/***************************************************************************** - * Descending vector aligned copy * - *****************************************************************************/ - -0: sub r1, #32 // Copies 32 bytes (16-byte aligned) from - vld1.8 {q0,q1}, [r1,:128] // source to destination on each pass through - sub ip, #32 // the loop. The loop ends when 32 or fewer - vst1.8 {q0,q1}, [ip,:128] // bytes remain to be copied. - subs r3, #32 - bhi 0b - add r3, #32 // Copy the remaining up-to-32 bytes. - sub r1, r3 // This copy may overlap the copy performed - vld1.8 {q0,q1}, [r1,:128] // in the final iteration through the - sub ip, r3 // previous loop, but this is more efficient - vst1.8 {q0,q1}, [ip,:128] // than figuring out exactly which bytes - pop {r7,pc} // need to be copied. - -/***************************************************************************** - * Descending vector misaligned copy * - *****************************************************************************/ - -L_descendingEdging: - tst ip, #0xf // Identical to how we handle misalignment for - itttt ne // ascending copies. First we move one byte - ldrbne r3, [r1,#-1]! // at a time until the destination has 16 - strbne r3, [ip,#-1]! // byte alignment. - subne r2, #1 - bne L_descendingEdging - - and lr, r1, #0xf // Then we extract the alignment of the source - bic r1, #0xf // buffer and use a jump table to dispatch - subs r3, r2, #32 // into code that does the appropriate - blo L_descendingEdgingExit // software alignment fixup. - tbh [pc, lr, lsl #1] -0: -.short (L_descendingExtract0x0-0b)/2 -.short (L_descendingExtract0x1-0b)/2 -.short (L_descendingExtract0x2-0b)/2 -.short (L_descendingExtract0x3-0b)/2 -.short (L_descendingExtract0x4-0b)/2 -.short (L_descendingExtract0x5-0b)/2 -.short (L_descendingExtract0x6-0b)/2 -.short (L_descendingExtract0x7-0b)/2 -.short (L_descendingExtract0x8-0b)/2 -.short (L_descendingExtract0x9-0b)/2 -.short (L_descendingExtract0xa-0b)/2 -.short (L_descendingExtract0xb-0b)/2 -.short (L_descendingExtract0xc-0b)/2 -.short (L_descendingExtract0xd-0b)/2 -.short (L_descendingExtract0xe-0b)/2 -.short (L_descendingExtract0xf-0b)/2 - -L_descendingExtract0x0: // For relative alignment, we have a fast - sub r1, #32 // path identical to the aligned copy loop. - vld1.8 {q0,q1}, [r1,:128] - sub ip, #32 - vst1.8 {q0,q1}, [ip,:128] - subs r3, #32 - bhs L_descendingExtract0x0 - b L_descendingEdgingExit - -#define DESCENDING_EXTRACT(shift)\ -L_descendingExtract ## shift:\ - vld1.8 {q10}, [r1,:128];\ -0: sub r1, #32;\ - vld1.8 {q8,q9}, [r1,:128];\ - vext.8 q1, q9, q10,$(shift);\ - vext.8 q0, q8, q9, $(shift);\ - vmov q10, q8;\ - sub ip, #32;\ - vst1.8 {q0,q1}, [ip,:128];\ - subs r3, $32;\ - bhs 0b;\ - b L_descendingEdgingExit - -DESCENDING_EXTRACT(0x1) // Otherwise, we use the loop above (almost -DESCENDING_EXTRACT(0x2) // identical to the one we use in the -DESCENDING_EXTRACT(0x3) // ascending copy case). -DESCENDING_EXTRACT(0x4) -DESCENDING_EXTRACT(0x5) -DESCENDING_EXTRACT(0x6) -DESCENDING_EXTRACT(0x7) -DESCENDING_EXTRACT(0x8) -DESCENDING_EXTRACT(0x9) -DESCENDING_EXTRACT(0xa) -DESCENDING_EXTRACT(0xb) -DESCENDING_EXTRACT(0xc) -DESCENDING_EXTRACT(0xd) -DESCENDING_EXTRACT(0xe) -DESCENDING_EXTRACT(0xf) - -L_descendingEdgingExit: - add r1, lr // Restore source pointer - add r2, r3, #32 // Restore length -L_descendingShort: - subs r2, #1 // Byte-by-byte copy loop for short overlapping - itt hs // buffers. - ldrbhs r3, [r1,#-1]! - strbhs r3, [ip,#-1]! - bhi L_descendingShort - pop {r7,pc} - -#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD \ No newline at end of file diff --git a/src/libc/arm/string/bzero_CortexA8.s b/src/libc/arm/string/bzero_CortexA8.s deleted file mode 100644 index bcbfea042..000000000 --- a/src/libc/arm/string/bzero_CortexA8.s +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD - -/********************************************************************** - * Cortex-A8 implementation * - **********************************************************************/ - -// Cortex-A8 implementations of memset( ) and bzero( ). Main loop is 64-byte -// NEON stores, unless the buffer length is > 1k. Beyond that point, there is -// little to no speed advantage with NEON (and a slight regression in some -// measured cases), so we switch to the GPRs. -// -// The crossover point should be reevaluated for future architectures. -// -// -- Stephen Canon, August 2009 - -.text -.syntax unified -.code 16 - -// void bzero(void * destination, -// size_t length); -// -// zeros out a buffer length bytes long, beginning at the address destination. -.thumb_func ___bzero$VARIANT$CortexA8 -.globl ___bzero$VARIANT$CortexA8 -.thumb_func _bzero$VARIANT$CortexA8 -.globl _bzero$VARIANT$CortexA8 -.align 2 -___bzero$VARIANT$CortexA8: -_bzero$VARIANT$CortexA8: - mov r2, r1 // match the API to memset(dest, 0, length) - eor r1, r1 // and fall through into memset - -// void *memset(void * destination, -// int value, size_t n); -// -// writes value converted to an unsigned char to n successive bytes, beginning -// at destination. - -// Notes on register usage: -// -// Throughout this function, registers have nearly constant usage; the pattern -// is: -// -// r0 holds the original destination pointer, unmodified. This value -// must be returned by the routine, so it is easiest to just leave it -// in place. -// r1 holds the value that is being copied into the buffer, in some stage -// of splattedness. The low byte is guaranteed to always have the value -// but the higher bytes may or may not contain copies of it. -// r2 holds the length minus some offset, where the offset is always the -// number of bytes that the current loop stores per iteration. -// r3-r6,r8,r10,r11 are used with stmia, and will only ever contain splatted -// copies of the value to be stored. -// ip holds a pointer to the lowest byte in the array that has not yet been -// set to hold value. -// q0 and q1 hold splatted copies of the value in the vector path, and are -// otherwise unused. - -.thumb_func _memset$VARIANT$CortexA8 -.globl _memset$VARIANT$CortexA8 -.align 2 -_memset$VARIANT$CortexA8: - mov ip, r0 // copy destination pointer. - subs r2, #0x8 // if length - 8 is negative (i.e. length - and r1, #0xff // is less than 8), jump to cleanup path. - blt L_scalarCleanup // - - tst ip, #0x7 // if the destination is doubleword - beq L_vectorCopy // aligned, jump to fast path. - -0: strb r1, [ip], #1 // store one byte at a time until - sub r2, #1 // destination pointer is 8 byte aligned. - tst ip, #7 // - bne 0b // - - cmp r2, #0x0 // if length - 8 is negative, - blt L_scalarCleanup // jump to the cleanup code - -L_vectorCopy: - vdup.8 q0, r1 // splat the byte to be stored across - subs r2, #0x38 // q0 and q1, and check if length - 64 - vmov q1, q0 // is negative; if so, jump to the - blt L_vectorCleanup // cleanup code. - - tst ip, #0x38 // if the destination is cacheline - beq L_cachelineAligned // aligned, jump to the fast path. - -0: vst1.64 {d0}, [ip, :64]! // store one double word at a time until - sub r2, #8 // the destination is 64-byte aligned - tst ip, #0x38 // - bne 0b - - cmp r2, #0x0 // if length - 64 is negative, - blt L_vectorCleanup // jump to the cleanup code - -L_cachelineAligned: - cmp r2, #0x3c0 // if length > 1024 - bge L_useSTMIA // we use stmia instead - -.align 4 // main loop -0: vst1.64 {q0,q1}, [ip, :256]! // store 32 bytes - subs r2, #0x40 // decrement length by 64 - vst1.64 {q0,q1}, [ip, :256]! // store 32 bytes - bge 0b // if length - 64 >= 0, continue - -L_vectorCleanup: - adds r2, #0x38 // if (length - 8) < 0, goto scalar cleanup - blt L_scalarCleanup // - -0: subs r2, #8 // store one double word at a time until - vst1.64 {d0}, [ip, :64]! // (length - 8) < 0. - bge 0b - -L_scalarCleanup: - adds r2, #8 // restore length - beq 1f // early out if zero. - -0: strb r1, [ip], #1 // store one byte at a time until length - subs r2, #1 // is zero. - bne 0b // -1: bx lr // return. - -// STMIA loop for large buffers -// -// For stores larger than 1024 bytes, we use STMIA because we can't get enough -// of a speedup from NEON to offset the higher power draw of the NEON unit. -// -// This crossover should be reevaluated on future architectures. -// -// We avoid using r7 and r9 even though it's not strictly necessary. - -L_useSTMIA: - push {r4,r5,r6,r8,r10,r11} - orr r1, r1, r1, lsl #8 - orr r1, r1, r1, lsl #16 - mov r3, r1 - mov r4, r1 - mov r5, r1 - mov r6, r1 - mov r8, r1 - mov r10, r1 - mov r11, r1 -.align 4 -0: stmia ip!, {r1,r3,r4,r5,r6,r8,r10,r11} - subs r2, #0x40 - stmia ip!, {r1,r3,r4,r5,r6,r8,r10,r11} - bge 0b - pop {r4,r5,r6,r8,r10,r11} - b L_vectorCleanup - -#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD - diff --git a/src/libc/arm/string/bzero_CortexA9.s b/src/libc/arm/string/bzero_CortexA9.s deleted file mode 100644 index 9ab178b75..000000000 --- a/src/libc/arm/string/bzero_CortexA9.s +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * This file implements the following functions for the Cortex-A9 processor: - * - * void bzero(void * destination, - * size_t length); - * - * void __bzero(void * destination, - * size_t length); - * - * zeros out a buffer length bytes long, beginning at the address destination. - * - * void *memset(void * destination, - * int value, - * size_t n); - * - * writes value converted to an unsigned char to n successive bytes, beginning - * at destination. - */ - -#include -#if defined _ARM_ARCH_7 - -/***************************************************************************** - * Macros * - *****************************************************************************/ - -#define A9_ENTRY(name) \ - .align 2;\ - .globl _ ## name ## $VARIANT$CortexA9;\ - _ ## name ## $VARIANT$CortexA9: - -#define ESTABLISH_FRAME \ - push {r0,r4,r7,lr};\ - add r7, sp, #8 - -#define CLEAR_FRAME_AND_RETURN \ - pop {r0,r4,r7,pc} - -#define ADDITIONAL_CALLEE_SAVE_REGISTERS {r5,r6,r8} - -#define STORE_REGISTERS {r1,r3,r4,r5,r6,r8,r9,ip} - -/***************************************************************************** - * entry points * - *****************************************************************************/ - -.text -.syntax unified -.code 32 - -A9_ENTRY(__bzero) -A9_ENTRY(bzero) - mov r2, r1 - eor r1, r1 - -A9_ENTRY(memset) -// Early out if fewer than four bytes are to be set. Otherwise, store up to -// three bytes to align the destination pointer to a word boundary. - ESTABLISH_FRAME - and r1, #0xff - subs r2, #4 - orr r1, r1, r1, lsl #8 - blo L_lengthLessThanFour - orr r1, r1, r1, lsl #16 -0: tst r0, #0x3 - beq L_wordAligned - strb r1, [r0],#1 - subs r2, #1 - bhs 0b -L_lengthLessThanFour: - adds r2, #4 - beq 1f -0: strb r1, [r0],#1 - subs r2, #1 - bne 0b -1: CLEAR_FRAME_AND_RETURN - -L_wordAligned: -// Destination pointer has word alignment. Early out if fewer than 64 bytes -// are to be set. Otherwise, store up to 28 bytes to align the destination -// pointer to a cacheline boundary. - mov r3, r1 - mov r4, r1 - subs r2, #0x3c - mov r9, r1 - blo L_lengthLessThanSixtyFour -0: tst r0, #0x1c - beq L_cachelineAligned - str r1, [r0],#4 - subs r2, #4 - bhs 0b -L_lengthLessThanSixtyFour: - tst r2, #0x30 - beq 1f -0: stm r0!, {r1,r3,r4,r9} - sub r2, #0x10 - tst r2, #0x30 - bne 0b -1: tst r2, #0xf - beq 2f - lsls ip, r2, #29 - stmcs r0!, {r1,r3} - strmi r1, [r0],#4 - lsls ip, r2, #31 - strhcs r1, [r0],#2 - strbmi r1, [r0] -2: CLEAR_FRAME_AND_RETURN - -L_cachelineAligned: -// Main unrolled loop; stores two complete cachelines per iteration. - push ADDITIONAL_CALLEE_SAVE_REGISTERS - mov r5, r1 - mov r6, r1 - mov r8, r1 - mov ip, r1 -.align 4 -0: stm r0!, STORE_REGISTERS - subs r2, #0x40 - stm r0!, STORE_REGISTERS - bhs 0b - pop ADDITIONAL_CALLEE_SAVE_REGISTERS - b L_lengthLessThanSixtyFour - -#endif // defined _ARM_ARCH_7 diff --git a/src/libc/arm/string/bzero_Generic.s b/src/libc/arm/string/bzero_Generic.s deleted file mode 100644 index c3c24582f..000000000 --- a/src/libc/arm/string/bzero_Generic.s +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2006, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#if !defined _ARM_ARCH_7 || defined VARIANT_DYLD - -#include -#include - -/* - * A reasonably well-optimized bzero/memset. Should work equally well on arm11 and arm9 based - * cores. - * - * The algorithm is to align the destination pointer on a 32 byte boundary and then - * blast data 64 bytes at a time, in two stores of 32 bytes per loop. - */ - .text - .align 2 - - .globl _memset -/* void *memset(void *ptr, int c, size_t len); */ -_memset: - /* move len into r1, unpack c into r2 */ - mov r3, r2 - and r1, r1, #0xff - orr r1, r1, r1, lsl #8 - orr r2, r1, r1, lsl #16 - mov r1, r3 - b Lbzeroengine - - .globl _bzero -/* void bzero(void *ptr, size_t len); */ -_bzero: - /* zero out r2 so we can be just like memset(0) */ - mov r2, #0 - -Lbzeroengine: - /* move the base pointer into r12 and leave r0 alone so that we return the original pointer */ - mov r12, r0 - - /* copy r2 into r3 for 64-bit stores */ - mov r3, r2 - - /* check for zero len */ - cmp r1, #0 - bxeq lr - - /* fall back to a bytewise store for less than 32 bytes */ - cmp r1, #32 - blt L_bytewise - - /* check for 32 byte unaligned ptr */ - tst r12, #0x1f - bne L_unaligned - - /* make sure we have more than 64 bytes to zero */ - cmp r1, #64 - blt L_lessthan64aligned - - /* >= 64 bytes of len, 32 byte aligned */ -L_64ormorealigned: - - /* we need some registers, avoid r7 (frame pointer) and r9 (thread register) */ - stmfd sp!, { r4-r6, r8, r10-r11 } - mov r4, r2 - mov r5, r2 - mov r6, r2 - mov r8, r2 - mov r10, r2 - mov r11, r2 - - /* pre-subtract 64 from the len to avoid an extra compare in the loop */ - sub r1, r1, #64 - -L_64loop: - stmia r12!, { r2-r6, r8, r10-r11 } - subs r1, r1, #64 - stmia r12!, { r2-r6, r8, r10-r11 } - bge L_64loop - - /* restore the saved regs */ - ldmfd sp!, { r4-r6, r8, r10-r11 } - - /* check for completion (had previously subtracted an extra 64 from len) */ - adds r1, r1, #64 - bxeq lr - -L_lessthan64aligned: - /* do we have 16 or more bytes left */ - cmp r1, #16 - stmgeia r12!, { r2-r3 } - stmgeia r12!, { r2-r3 } - subges r1, r1, #16 - bgt L_lessthan64aligned - bxeq lr - -L_lessthan16aligned: - /* store 0 to 15 bytes */ - mov r1, r1, lsl #28 /* move the remaining len bits [3:0] to the flags area of cpsr */ - msr cpsr_f, r1 - - stmmiia r12!, { r2-r3 } /* n is set, store 8 bytes */ - streq r2, [r12], #4 /* z is set, store 4 bytes */ - strcsh r2, [r12], #2 /* c is set, store 2 bytes */ - strvsb r2, [r12], #1 /* v is set, store 1 byte */ - bx lr - -L_bytewise: - /* bytewise copy, 2 bytes at a time, alignment not guaranteed */ - subs r1, r1, #2 - strb r2, [r12], #1 - strplb r2, [r12], #1 - bhi L_bytewise - bx lr - -L_unaligned: - /* unaligned on 32 byte boundary, store 1-15 bytes until we're 16 byte aligned */ - mov r3, r12, lsl #28 - rsb r3, r3, #0x00000000 - msr cpsr_f, r3 - - strvsb r2, [r12], #1 /* v is set, unaligned in the 1s column */ - strcsh r2, [r12], #2 /* c is set, unaligned in the 2s column */ - streq r2, [r12], #4 /* z is set, unaligned in the 4s column */ - strmi r2, [r12], #4 /* n is set, unaligned in the 8s column */ - strmi r2, [r12], #4 - - subs r1, r1, r3, lsr #28 - bxeq lr - - /* we had previously trashed r3, restore it */ - mov r3, r2 - - /* now make sure we're 32 byte aligned */ - tst r12, #(1 << 4) - stmneia r12!, { r2-r3 } - stmneia r12!, { r2-r3 } - subnes r1, r1, #16 - - /* we're now aligned, check for >= 64 bytes left */ - cmp r1, #64 - bge L_64ormorealigned - b L_lessthan64aligned - -X_LEAF(___bzero, _bzero) - -#endif // !defined _ARM_ARCH_7 || defined VARIANT_DYLD diff --git a/src/libc/arm/string/bzero_Swift.s b/src/libc/arm/string/bzero_Swift.s deleted file mode 100644 index 9c0d1af53..000000000 --- a/src/libc/arm/string/bzero_Swift.s +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * This file implements the following functions for the Swift micro-arch: - * - * void bzero(void * destination, - * size_t length); - * - * void __bzero(void * destination, - * size_t length); - * - * zeros out a buffer length bytes long, beginning at the address destination. - * - * void *memset(void * destination, - * int value, - * size_t n); - * - * writes value converted to an unsigned char to n successive bytes, beginning - * at destination. - */ - -#include -#if defined _ARM_ARCH_7 - -.syntax unified -.code 32 -.globl ___bzero$VARIANT$Swift -.globl _bzero$VARIANT$Swift -.globl _memset$VARIANT$Swift - -.text -.align 4 -___bzero$VARIANT$Swift: -_bzero$VARIANT$Swift: - mov r2, r1 // Set value to zero and move length to the - eor r1, r1 // correct register to match the memset API. -_memset$VARIANT$Swift: - push {r7,lr} // Establish a frame, and make a copy of the - mov r7, sp // pointer to increment so that we can - mov ip, r0 // return the original pointer unmodified. - - vdup.8 q0, r1 // Splat the low byte of value across q0. - subs r3, r2, #64 // If length < 64, jump to a dedicated - blo L_lengthLessThan64 // code path to handle small buffers. - - vmov q1, q0 // Copy the splatted value to q1. - orr lr, r2, r0 // If the length is not a multiple of 16 or - ands lr, #0xf // the buffer is not 16-byte aligned, then - bne L_edgingNeeded // some edging is needed; branch. - -0: subs r3, #64 // Write 64 bytes at a time to the 16-byte - vst1.8 {q0,q1}, [ip,:128]! // aligned buffer. Terminate this loop when - vst1.8 {q0,q1}, [ip,:128]! // 64 or fewer bytes remain to be written. - bhi 0b - - add ip, r3 // Backtrack the destination pointer by - vst1.8 {q0,q1}, [ip,:128]! // 64 - remaining bytes, and write 64 bytes - vst1.8 {q0,q1}, [ip,:128] // to that address. This takes us precisely - pop {r7,pc} // to the end of the buffer. - -L_edgingNeeded: - vst1.8 {q0}, [ip] // Write 16 bytes to the [possibly unaligned] - and lr, ip, #0xf // buffer, then advance the pointer to the - bic ip, #0xf // next aligned location, and adjust the - add r3, lr // length accordingly. Note that this means - add ip, #16 // that the first write in the loop may - subs r3, #16 // overlap with the write we just performed; - blo 1f // this is the fastest way to get alignment - nop // on Swift. - -0: subs r3, #64 // Write 64 bytes at a time to the 16-byte - vst1.8 {q0,q1}, [ip,:128]! // aligned buffer. Terminate this loop when - vst1.8 {q0,q1}, [ip,:128]! // 64 or fewer bytes remain to be written. - bhi 0b - -1: add ip, r3 // Backtrack the destination pointer by - vst1.8 {q0,q1}, [ip]! // 64 - remaining bytes, and write 64 bytes - vst1.8 {q0,q1}, [ip] // to that address. This takes us precisely - pop {r7,pc} // to the end of the buffer. - -L_lengthLessThan64: - subs r3, r2, #8 // If the length is smaller than eight, jump - blo 1f // into a dedicated byte store loop. - -0: subs r3, #8 // Write 8 bytes at a time to the destination - vst1.8 {d0}, [ip]! // buffer, terminating when eight or fewer - bhi 0b // bytes remain to be written. - - add ip, r3 // Backtrack the destination pointer by - vst1.8 {d0}, [ip] // 8 - remaining bytes, and write 8 bytes - pop {r7,pc} // to that address, then return. - -1: subs r2, #1 // Store one byte at a time to the destination - strbhs r1, [ip], #1 // buffer, until we exhaust the length. - bhi 1b - pop {r7,pc} - -#endif // defined _ARM_ARCH_7 diff --git a/src/libc/arm/string/dyld_resolvers.c b/src/libc/arm/string/dyld_resolvers.c deleted file mode 100644 index 1c53fff38..000000000 --- a/src/libc/arm/string/dyld_resolvers.c +++ /dev/null @@ -1,98 +0,0 @@ -// This file implements resolvers to assist dyld in choosing the correct -// implementation of routines on ARMv7 processors. The -// micro-architectural differences between Cortex-A8 and Cortex-A9 are such -// that optimal write loops are quite different on the two processors. - -#include -#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD - -#include -#include -#include - -// The MakeResolver(name) macro creates a function that dyld calls to -// pick an implementation of the name function. It does a check to determine -// if it is running on a8 or a9 hardware, and returns a pointer to either -// -// name$VARIANT$CortexA8 -// or -// name$VARIANT$CortexA9 -// or -// name$VARIANT$Swift -// -// This resolution only occurs once per process; once a symbol is bound to an -// implementation in dyld, no further calls to the resolver occur. -// -// On unknown implementations of the ARMv7 architecture, the Swift variant -// is returned by these resolvers. -#define MakeResolver(name) \ - void * name ## Resolver(void) __asm__("_" #name); \ - void * name ## Resolver(void) { \ - __asm__(".symbol_resolver _" #name); \ - switch (*(int *)_COMM_PAGE_CPUFAMILY) { \ - case CPUFAMILY_ARM_13: return name ## $VARIANT$CortexA8; \ - case CPUFAMILY_ARM_14: return name ## $VARIANT$CortexA9; \ - default: return name ## $VARIANT$Swift; \ - } \ - } - -void bzero$VARIANT$CortexA8(void *, size_t); -void bzero$VARIANT$CortexA9(void *, size_t); -void bzero$VARIANT$Swift(void *, size_t); -MakeResolver(bzero) - -void __bzero$VARIANT$CortexA8(void *, size_t); -void __bzero$VARIANT$CortexA9(void *, size_t); -void __bzero$VARIANT$Swift(void *, size_t); -MakeResolver(__bzero) - -void *memset$VARIANT$CortexA8(void *, int, size_t); -void *memset$VARIANT$CortexA9(void *, int, size_t); -void *memset$VARIANT$Swift(void *, int, size_t); -MakeResolver(memset) - -void bcopy$VARIANT$CortexA8(const void *, void *, size_t); -void bcopy$VARIANT$CortexA9(const void *, void *, size_t); -void bcopy$VARIANT$Swift(const void *, void *, size_t); -MakeResolver(bcopy) - -void *memmove$VARIANT$CortexA8(void *, const void *, size_t); -void *memmove$VARIANT$CortexA9(void *, const void *, size_t); -void *memmove$VARIANT$Swift(void *, const void *, size_t); -MakeResolver(memmove) - -void *memcpy$VARIANT$CortexA8(void *, const void *, size_t); -void *memcpy$VARIANT$CortexA9(void *, const void *, size_t); -void *memcpy$VARIANT$Swift(void *, const void *, size_t); -MakeResolver(memcpy) - -// The memset_patternx resolvers are a little different, because we only have -// a generic implementation and a Swift implementation. -#define MakeResolver_Swift(name) \ - void * name ## Resolver(void) __asm__("_" #name); \ - void * name ## Resolver(void) { \ - __asm__(".symbol_resolver _" #name); \ - switch (*(int *)_COMM_PAGE_CPUFAMILY) { \ - case CPUFAMILY_ARM_13: return name ## $VARIANT$Generic; \ - case CPUFAMILY_ARM_14: return name ## $VARIANT$Generic; \ - default: return name ## $VARIANT$Swift; \ - } \ - } - -void memset_pattern4$VARIANT$Generic(void *b, const void *c4, size_t len); -void memset_pattern4$VARIANT$Swift(void *b, const void *c4, size_t len); -MakeResolver_Swift(memset_pattern4); - -void memset_pattern8$VARIANT$Generic(void *b, const void *c8, size_t len); -void memset_pattern8$VARIANT$Swift(void *b, const void *c8, size_t len); -MakeResolver_Swift(memset_pattern8); - -void memset_pattern16$VARIANT$Generic(void *b, const void *c16, size_t len); -void memset_pattern16$VARIANT$Swift(void *b, const void *c16, size_t len); -MakeResolver_Swift(memset_pattern16); - -#else // defined _ARM_ARCH_7 && !defined VARIANT_DYLD - -typedef int emptyFilesArentCFiles; - -#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD diff --git a/src/libc/arm/string/ffs.s b/src/libc/arm/string/ffs.s deleted file mode 100644 index 62e492a0b..000000000 --- a/src/libc/arm/string/ffs.s +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#ifdef _ARM_ARCH_5 - .text - - .align 2 - .globl _ffs -_ffs: - .globl _ffsl -_ffsl: - rsb r3, r0, #0 - and r0, r0, r3 - clz r0, r0 - rsb r0, r0, #32 - bx lr - - .align 2 - .globl _fls -_fls: - .globl _flsl -_flsl: - clz r0, r0 - rsb r0, r0, #32 - bx lr -#else -#error need to define ffs for this architecture -#endif diff --git a/src/libc/arm/string/memcmp.s b/src/libc/arm/string/memcmp.s deleted file mode 100644 index 2cdd5a32a..000000000 --- a/src/libc/arm/string/memcmp.s +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -// ARM Assembly implementation of memcmp( ) from -// Uses Thumb2 if it is available, otherwise generates ARM code. -// -// -- Stephen Canon, August 2009 -// -// The basic idea is to use word compares instead of byte compares as long as -// at least four bytes remain to be compared. However, because memcmp( ) -// compares the buffers as though they were big-endian unsigned integers, we -// need to byte-reverse each word before comparing them. -// -// If the buffers are not word aligned, or they are shorter than four bytes, -// we just use a simple byte comparison loop instead. -// -// int bcmp(void *src1, void *src2, size_t length); -// int memcmp(void *src1, void *src2, size_t length); - -.text -.syntax unified -#if defined __thumb2__ - .code 16 - .thumb_func _bcmp - .thumb_func _memcmp -#else - .code 32 -#endif - -#define ESTABLISH_FRAME \ - push {r7,lr};\ - mov r7, sp -#define CLEAR_FRAME_AND_RETURN \ - pop {r7,pc} - -#include - -#if defined _ARM_ARCH_6 - #define BYTE_REVERSE(reg,tmp) \ - rev reg, reg -#else // defined _ARM_ARCH_6 -// Prior to ARMv6, the REV instruction is not available. We use a very cute -// software workaround instead, which needs only a single scratch register. - #define BYTE_REVERSE(reg,tmp) \ - eor tmp, reg, reg, ror #16;\ - bic tmp, tmp, #0xff0000 ;\ - mov tmp, tmp, lsr #8 ;\ - eor reg, tmp, reg, ror #8 -#endif // defined _ARM_ARCH_6 - -.globl _bcmp -.globl _memcmp -.align 2 -_bcmp: -_memcmp: - // If both buffers are not word aligned, jump to a byte-comparison loop. - ESTABLISH_FRAME - orr ip, r0, r1 - tst ip, #3 - bne L_useByteComparisons - - // As long as at least four bytes of length remain, load one word from each - // buffer and check if they are equal. -0: subs r2, #4 - blo L_lessThanFourBytesRemain - ldr r3, [r0],#4 - ldr ip, [r1],#4 - cmp r3, ip - beq 0b - - // If words from the two buffers compared unequal, we end up here. We need - // to byte-swap both words, then subtract to determine the result (+/-1). - BYTE_REVERSE(r3,r1) - BYTE_REVERSE(ip,r2) - mov r0, #1 - subs r3, ip - it lo - movlo r0, #-1 - CLEAR_FRAME_AND_RETURN - -L_lessThanFourBytesRemain: - adds r2, #4 -L_useByteComparisons: - mov r3, r0 - // If no bytes remain to compare, the buffers are equal and we return zero. - // Otherwise, load one byte from each buffer and check if they are equal. -0: subs r2, #1 - blo L_buffersAreEqual - ldrb r0, [r3],#1 - ldrb ip, [r1],#1 - subs r0, ip - beq 0b - CLEAR_FRAME_AND_RETURN - -L_buffersAreEqual: - mov r0, #0 - CLEAR_FRAME_AND_RETURN diff --git a/src/libc/arm/string/memset_pattern.s b/src/libc/arm/string/memset_pattern.s deleted file mode 100755 index b569484ce..000000000 --- a/src/libc/arm/string/memset_pattern.s +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -// Only built for armv6 and higher. -#if defined _ARM_ARCH_6 - -// If we're building for armv7, and not for DYLD, then we have a symbol -// resolver so we need to rename these implementations. -#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD -#define _memset_pattern4 _memset_pattern4$VARIANT$Generic -#define _memset_pattern8 _memset_pattern8$VARIANT$Generic -#define _memset_pattern16 _memset_pattern16$VARIANT$Generic -#endif - -#include - -/* - * This file contains the following functions: - * - * void memset_pattern4(void *b, const void *c4, size_t len) - * void memset_pattern8(void *b, const void *c8, size_t len) - * void memset_pattern16(void *b, const void *c16, size_t len) - * - * The memset() is implemented in the bzero.s file. - * - * This is a reasonably well optimized version of memset_pattern* routines - * implemented for the ARM9 and ARM11 processors using the ARMv6 instruction - * set. These routines use the ARM's core registers. - * - * The algorithm is to align the destination pointer on a 16 byte boundary - * and then blast data 64 bytes at a time, in two stores of 32 bytes per loop. - * - */ - .text - .align 2 - .syntax unified - -/*----------------------------------------------------------------------------*/ -/* void memset_pattern4(void *ptr, const void *pattern4, size_t len); */ -/* */ -/* r0 << destination pointer */ -/* r1 << pointer to 4-byte pattern */ -/* r2 << 'len' (length of destination buffer in bytes) */ -/*----------------------------------------------------------------------------*/ - .globl _memset_pattern4 -_memset_pattern4: - cmp r2, #0 /* check if len is zero */ - bxeq lr /* return if length is zero */ - - /* We need some registers, so save volatiles on stack */ - /* Avoid r7 (frame pointer) and r9 (thread register) */ - stmfd sp!, {r4-r7, lr} - add r7, sp, #12 /* establish frame */ - stmfd sp!, {r8, r10-r11} - - /* copy destination base pointer r0 to r12 and leave r0 alone */ - /* so that we return original pointer back to the caller */ - mov r12, r0 - - /* Check if 'len' is long enough to bother alignment of destination */ - /* pointer */ - cmp r2, #32 /* long enough to bother aligning? */ - movlt r3, #4 /* move pattern length into r3 */ - movlt r10, #4 /* pattern index */ - movlt r11, r1 /* move pattern pointer into r11 */ - blt L_Short /* no */ - - /* move 'len' into r1, get 4-byte pattern in r2 */ - mov r6, r2 /* temporarily move 'len' in to r6 */ - ldr r2, [r1]/* load 4-byte pattern into r2 */ - mov r1, r6 /* move 'len' from r6 to r1 */ - - mov r3, r2 /* copy 4-byte pattern into r3, r4 and r5 registers */ - mov r4, r2 - mov r5, r2 - -L_NotShort: - - /* Check for 16 or 32 byte aligned destination pointer */ - tst r12, #0x1F /* check for 32 byte aligned */ - beq L_Aligned - tst r12, #0xF /* check for 16 byte aligned */ - beq L_16ByteAligned - b L_Unaligned /* yes */ - -L_Bytewise: - ldrb r4, [r11], #1 - strb r4, [r12], #1 - subs r10, #1 - moveq r10, r3 - moveq r11, r1 - sub r2, #1 - -L_Short: - cmp r2, #0 /* more bytes left? */ - bne L_Bytewise - ldm sp!, {r8, r10-r11} /* restores registers from stack */ - ldm sp!, {r4-r7, pc} /* restore & return from subroutine */ - -/* 'len' is long enough to justify aligning the destination pointer */ -/* */ -/* By the time we reach here, data is stored in registers as follows: */ -/* r1 << 'len' (length of destination buffer in bytes) */ -/* r2-r5 << pattern; either 4x4byte OR 2x8byte OR 1x16-byte */ -/* r12 << destination pointer copy (scratch register) */ -/* r0 << destination pointer original */ -/* */ -/* Use r11 as scratch register to store the #bytes offset to 16-byte align */ -/* */ -/* Unaligned on 32-byte boundary, store 1-15 bytes until 16-byte aligned */ -/* As we store these bytes, we rotate the pattern stored in r2-r5 to reflect */ -/* the alignment. */ - -L_Unaligned: - mov r11, r12, lsl #28 - rsb r11, r11, #0 - msr cpsr_f, r11 /* Bits[31:28] of cpsr now contain #bytes to align*/ - -L_Store15BytesAndRotatePattern: - strbvs r2, [r12], #1 /* v is set, unaligned in the 1s column */ - andvs r6, r2, #0xFF /* Rotate pattern right in r2-r5 by 1-byte */ - andvs r8, r3, #0xFF /* Consider register r2-r5 and a contiguous */ - andvs r10, r4, #0xFF /* 16-byte register with r2 containing LSB */ - andvs r11, r5, #0xFF /* and r5 containing MSB */ - lsrvs r2, r2, #8 - lsrvs r3, r3, #8 - lsrvs r4, r4, #8 - lsrvs r5, r5, #8 - orrvs r2, r2, r8, lsl #24 - orrvs r3, r3, r10, lsl #24 - orrvs r4, r4, r11, lsl #24 - orrvs r5, r5, r6, lsl #24 - - strhcs r2, [r12], #2 /* c is set, unaligned in the 2s column */ - movcs r6, r2, lsl #16 /* Rotate pattern right in r2-r5 by 2-bytes */ - movcs r8, r3, lsl #16 - movcs r10, r4, lsl #16 - movcs r11, r5, lsl #16 - lsrcs r2, r2, #16 - lsrcs r3, r3, #16 - lsrcs r4, r4, #16 - lsrcs r5, r5, #16 - orrcs r2, r2, r8 - orrcs r3, r3, r10 - orrcs r4, r4, r11 - orrcs r5, r5, r6 - - streq r2, [r12], #4 /* z is set, unaligned in the 4s column */ - moveq r6, r2 /* Rotate pattern right in r2-r5 by 4-bytes */ - moveq r2, r3 - moveq r3, r4 - moveq r4, r5 - moveq r5, r6 - - stmmi r12!, {r2-r3} /* n is set, unaligned in the 8s column */ - movmi r6, r2 /* Rotate pattern right in r2-r5 by 4-bytes */ - movmi r8, r3 - movmi r2, r4 - movmi r3, r5 - movmi r4, r6 - movmi r5, r8 - - mrs r11, cpsr /*copy cpsr in to r11 */ - subs r1, r1, r11, lsr #28 - ldmeq sp!, {r8, r10-r11} /* restores registers from stack */ - ldmeq sp!, {r4-r7, pc} /* restore & return from subroutine */ - -/* By the time we reach here, we are 16-byte aligned and r2-r5 contains */ -/* rotated pattern. Now lets make sure we are 32-byte aligned. */ -L_16ByteAligned: - tst r12, #(1 << 4) - stmne r12!, {r2-r5} - subsne r1, r1, #16 - -/* By the time we reach here, data is stored in registers as follows: */ -/* r1 << 'len' (remaining length of destination buffer in bytes) */ -/* r2-r5 << rotated pattern; either 4x4byte OR 2x8byte OR 1x16-byte */ -/* r12 << aligned destination pointer copy (scratch register) */ -L_Aligned: - cmp r1, #64 - blt L_AlignedLessThan64 - -/* Copy pattern in four more registers so that we can do 64 byte transfers */ - mov r6, r2 - mov r8, r3 - mov r10, r4 - mov r11, r5 - -/* At this point, we are 16-byte aligned and 'len' is greater than 64 bytes */ -/* Lets transfer 64 bytes at a time until len becomes less than 64 bytes */ - sub r1, r1, #64 /* pre-subtract to avoid extra compare in loop */ -L_Loop64: - stm r12!, {r2-r6, r8, r10-r11} - subs r1, r1, #64 - stm r12!, {r2-r6, r8, r10-r11} - bge L_Loop64 - - /* return if 'len' is zero */ - adds r1, r1, #64 /* readjust length; previously subtracted extra 64*/ - ldmeq sp!, {r8, r10-r11} /* restores registers from stack */ - ldmeq sp!, {r4-r7, pc} /* restore & return from subroutine */ - -L_AlignedLessThan64: - /* do we have 16 or more bytes left */ - cmp r1, #16 - stmge r12!, {r2-r5} - subsge r1, r1, #16 - bgt L_AlignedLessThan64 - ldmeq sp!, {r8, r10-r11} /* restores registers from stack */ - ldmeq sp!, {r4-r7, pc} /* restore & return from subroutine */ - -L_AlignedLessThan16: - /* store last up-to 15 bytes */ - /* move the remaining len bits [3:0] to the flags area of cpsr */ - mov r1, r1, lsl #28 - msr cpsr_f, r1 - - stmmi r12!, {r2-r3} /* n is set, store 8 bytes */ - movmi r2, r4 /* shift vector down 8 bytes */ - movmi r3, r5 - - streq r2, [r12], #4 /* z is set, store 4 bytes */ - moveq r2, r3 /* shift vector down 4 bytes */ - - strhcs r2, [r12], #2 /* c is set, store 2 bytes */ - lsrcs r2, #16 /* shift register right 2 bytes */ - - strbvs r2, [r12], #1 /* v is set, store 1 byte */ - ldm sp!, {r8, r10-r11} /* restores registers from stack */ - ldm sp!, {r4-r7, pc} /* restore & return from subroutine */ - -/*----------------------------------------------------------------------------*/ -/* void memset_pattern8(void *ptr, const void *pattern8, size_t len); */ -/* */ -/* r0 << destination pointer */ -/* r1 << pointer to 8-byte pattern */ -/* r2 << 'len' (length of destination buffer in bytes) */ -/*----------------------------------------------------------------------------*/ - .globl _memset_pattern8 -_memset_pattern8: - cmp r2, #0 /* check if len is zero */ - bxeq lr /* return if length is zero */ - - /* We need some registers, so save volatiles on stack */ - /* Avoid r7 (frame pointer) and r9 (thread register) */ - stmfd sp!, {r4-r7, lr} - add r7, sp, #12 /* establish frame */ - stmfd sp!, {r8, r10-r11} - - /* copy destination base pointer r0 to r12 and leave r0 alone */ - /* so that we return original pointer back to the caller */ - mov r12, r0 - - /* Check if 'len' is long enough to bother alignment of destination */ - /* pointer */ - cmp r2, #32 /* long enough to bother aligning? */ - movlt r3, #8 /* move pattern length into r3 */ - movlt r10, #8 /* pattern index */ - movlt r11, r1 /* move pattern pointer into r11 */ - blt L_Short /* no */ - - /* move 'len' into r1, get 8-byte pattern in r2-r3 */ - mov r6, r2 /* temporarily move 'len' in to r6 */ - ldr r2, [r1], #4 /* load 8-byte pattern into r2-r3 */ - ldr r3, [r1], #4 - mov r1, r6 /* move 'len' from r6 to r1 */ - - mov r4, r2 /* copy 8-byte pattern into r4-r5 registers */ - mov r5, r3 - b L_NotShort /* yes */ - - -/*----------------------------------------------------------------------------*/ -/* void memset_pattern16(void *ptr, const void *pattern16, size_t len); */ -/* */ -/* r0 << destination pointer */ -/* r1 << pointer to 16-byte pattern */ -/* r2 << 'len' (length of destination buffer in bytes) */ -/*----------------------------------------------------------------------------*/ - .globl _memset_pattern16 -_memset_pattern16: - cmp r2, #0 /* check if len is zero */ - bxeq lr /* return if length is zero */ - - /* We need some registers, so save volatiles on stack */ - /* Avoid r7 (frame pointer) and r9 (thread register) */ - stmfd sp!, {r4-r7, lr} - add r7, sp, #12 /* establish frame */ - stmfd sp!, {r8, r10-r11} - - /* copy destination base pointer r0 to r12 and leave r0 alone */ - /* so that we return original pointer back to the caller */ - mov r12, r0 - - /* Check if 'len' is long enough to bother alignment of destination */ - /* pointer */ - cmp r2, #32 /* long enough to bother aligning? */ - movlt r3, #16 /* move pattern length into r3 */ - movlt r10, #16 /* pattern index */ - movlt r11, r1 /* move pattern pointer into r11 */ - blt L_Short /* no */ - - /* move 'len' into r1, get 16-byte pattern in r2-r5 */ - mov r6, r2 /* temporarily move 'len' in to r6 */ - ldr r2, [r1], #4 /* load 16-byte pattern into r2-r5 */ - ldr r3, [r1], #4 - ldr r4, [r1], #4 - ldr r5, [r1], #4 - mov r1, r6 /* move 'len' from r6 to r1 */ - - b L_NotShort /* yes */ - - -#endif /* _ARM_ARCH_6 */ diff --git a/src/libc/arm/string/memset_pattern_Swift.s b/src/libc/arm/string/memset_pattern_Swift.s deleted file mode 100644 index 2f843a0b4..000000000 --- a/src/libc/arm/string/memset_pattern_Swift.s +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * This file implements the following functions for the Swift micro-arch: - * - * void memset_pattern4(void *b, const void *pattern4, size_t len); - * void memset_pattern8(void *b, const void *pattern8, size_t len); - * void memset_pattern16(void *b, const void *pattern16, size_t len); - * - * The implementation of all three functions is fundamentally the same. - * memset_pattern4 is extensively commented to explain, reference that - * if you have any questions about the other two. - */ - -#include -#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD - -.syntax unified -.code 32 -.text -.globl _memset_pattern4$VARIANT$Swift -.globl _memset_pattern8$VARIANT$Swift -.globl _memset_pattern16$VARIANT$Swift - -/******************************************************************************/ - -.align 4 -_memset_pattern4$VARIANT$Swift: - push {r7,lr} - mov r7, sp - -// Load the pattern and splat it to q0, then check if the buffer is at least -// 64 bytes long. If not, branch to a short-buffer implementation. - ldr r1, [r1] - vdup.32 q0, r1 - subs r3, r2, #64 - blo L_short4 - -// We want to use aligned vector stores to fill the bulk of the buffer. In -// order to make that work, we need to rotate the pattern as necessary to -// match up with aligned locations, and we also need to extract the alignment -// of the destination pointer mod 16. - lsl ip, r0, #3 - and lr, r0, #0xf // alignment of destination pointer mod 16 - rsb ip, ip, #32 // low five bits contain 32 - 8*(address%4). - -// Before we start the aligned stores, we do a single unaligned store of -// 16 bytes of the pattern to the start of the buffer. Since the buffer is -// at least 64 bytes long, this store is known to lie entirely inside the -// buffer: -// first aligned address in buffer -// v -// ---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--- -// ... | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | 0 | 1 | 2 | ... -// ---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--- -// ^ -// unaligned store starts here: -// [ 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 ] - vst1.8 {q0}, [r0]! - -// Subsequent stores will be aligned, and will start at the first aligned -// address in the buffer. We apply the rotation that we calculated before -// the vector store (in the low five bits of ip) to get the pattern that -// is to be stored starting at the aligned location. For example, in the -// picture above, the buffer had alignment of 3 mod 4, so the rotation to -// be applied is 32 - 8*3 = 8. Rotating the pattern right by 8 bits gives -// us [ 1 2 3 0 ] (remember, we're little-endian), which we see is what -// needs to be stored starting at the first aligned location. -// -// Besides rotating the pattern, we also need to adjust the length (by -// subtracting 16 - alignment mod 16), and to advance the pointer to the -// first aligned location. - ror r1, ip // Pattern to use for aligned memory - add r3, lr - bic r0, #0xf // destination for first aligned store - subs r3, #16 // updated length - blo 1f - -// Splat the rotated value across q1 and q2 - vdup.32 q1, r1 - vmov q2, q1 - -// Main store loop. We write the splatted aligned pattern across 64 bytes -// per iteration, terminating the loop when the remaining length of the -// buffer is 64 bytes or less. -0: subs r3, #64 - vst1.32 {q1,q2}, [r0,:128]! - vst1.32 {q1,q2}, [r0,:128]! - bhi 0b - -// The remaining length of the buffer is 64 bytes or less (but the total -// length of the buffer is at least 64 bytes; otherwise we would have -// branched to the "short" path). Thus, we can handle the entirety of the -// remaining buffer with two 32-byte unaligned stores. -// -// Again, we need to rotate the pattern to match the alignment, this time -// by 8*(length%4), and we also need to back up the destination pointer -// so that it points to precisely 64 bytes before the end of the buffer. -// We accomplish this by adding r3, which contains the remaining length of -// the buffer minus 64. -1: lsl ip, r3, #3 - ror r1, ip - vdup.32 q8, r1 - vmov q9, q8 - add r0, r3 - vst1.32 {q8,q9}, [r0]! - vst1.32 {q8,q9}, [r0] - pop {r7,pc} - -L_short4: -// If we branch here, the buffer is less than 64 bytes long. At this point, -// register contents are as follows: -// -// r0 pointer to the buffer -// r1 pattern -// r2 buffer length -// q0 splatted pattern -// -// To begin, we store eight bytes at a time until the remaining length is -// less than eight bytes. - subs r3, r2, #8 - blo 1f -0: subs r3, #8 - vst1.32 {d0}, [r0]! - bhs 0b - -// Then we store one byte at a time, rotating the pattern to get the next -// byte, until we reach the end of the buffer. - add r2, r3, #8 -1: subs r2, #1 - strbhs r1, [r0],#1 - ror r1, #8 - bhi 1b - pop {r7,pc} - -/******************************************************************************/ - -.align 4 -_memset_pattern8$VARIANT$Swift: -// The implementation of this function is substantially identical to that of -// memset_pattern4. The only differences are in how we rotate the pattern for -// the purposes of extracting the bytes to store. For clarity, only those -// differences are commented here; consult memset_pattern4 (above) for -// a detailed description of the algorithm used. - push {r7,lr} - mov r7, sp - vld1.8 {d0}, [r1] - vmov d1, d0 - subs r3, r2, #64 - blo L_short8 - - bic sp, #0xf // Align stack to 16 bytes and write 32 bytes - sub sp, #16 // of pattern to the stack. We will use - vst1.8 {q0}, [sp,:128] // unaligned loads from this scratch buffer - sub sp, #16 // to get rotated forms of the pattern. - vst1.8 {q0}, [sp,:128] - and ip, r0, #0x7 // Now generate an unaligned pointer to the - rsb ip, ip, #8 // rotated pattern that we need to use for - add ip, sp // aligned stores in the main loop. - and lr, r0, #0xf - vst1.8 {q0}, [r0]! - add r3, lr - bic r0, #0xf - subs r3, #16 - blo 1f - vld1.8 {q1}, [ip] - vmov q2, q1 -0: subs r3, #64 - vst1.32 {q1,q2}, [r0,:128]! - vst1.32 {q1,q2}, [r0,:128]! - bhi 0b -1: and lr, r3, #0x7 // Generate an unaligned pointer to the - add ip, lr // rotated pattern to use for cleanup. - vld1.8 {q8}, [ip] - vmov q9, q8 - add r0, r3 - vst1.32 {q8,q9}, [r0]! - vst1.32 {q8,q9}, [r0] - mov sp, r7 // Restore stack pointer - pop {r7,pc} - -L_short8: - subs r2, #8 - blo 1f -0: subs r2, #8 - vst1.32 {d0}, [r0]! - bhs 0b -1: adds r2, #8 - beq 3f -2: vst1.8 {d0[0]}, [r0]! // Store one byte from NEON - vext.8 d0, d0, d0, #1 // Use VEXT to rotate pattern - subs r2, #1 - bhi 2b -3: pop {r7,pc} - -/******************************************************************************/ - -.align 4 -_memset_pattern16$VARIANT$Swift: -// The implementation of this function is substantially identical to that of -// memset_pattern4. The only differences are in how we rotate the pattern for -// the purposes of extracting the bytes to store. For clarity, only those -// differences are commented here; consult memset_pattern4 (above) for -// a detailed description of the algorithm used. - push {r7,lr} - mov r7, sp - vld1.8 {q0}, [r1] - subs r3, r2, #64 - blo L_short16 - - bic sp, #0xf // Align stack to 16 bytes and write 48 bytes - sub sp, #16 // of pattern to the stack. We will use - vst1.8 {q0}, [sp,:128] // unaligned loads from this scratch buffer - sub sp, #16 // to get rotated forms of the pattern. - vst1.8 {q0}, [sp,:128] - sub sp, #16 - vst1.8 {q0}, [sp,:128] - and lr, r0, #0xf // Now generate an unaligned pointer to the - rsb ip, lr, #16 // rotated pattern that we need to use for - add ip, sp // aligned stores in the main loop. - vst1.8 {q0}, [r0]! - add r3, lr - bic r0, #0xf - subs r3, #16 - blo 1f - vld1.8 {q1}, [ip] - vmov q2, q1 -0: subs r3, #64 - vst1.32 {q1,q2}, [r0,:128]! - vst1.32 {q1,q2}, [r0,:128]! - bhi 0b -1: and lr, r3, #0xf // Generate an unaligned pointer to the - add ip, lr // rotated pattern to use for cleanup. - vld1.8 {q8}, [ip] - vmov q9, q8 - add r0, r3 - vst1.32 {q8,q9}, [r0]! - vst1.32 {q8,q9}, [r0] - mov sp, r7 // Restore stack pointer - pop {r7,pc} - -L_short16: - subs r2, #16 - blo 1f -0: subs r2, #16 - vst1.32 {q0}, [r0]! - bhs 0b -1: adds r2, #16 - beq 3f -2: vst1.8 {d0[0]}, [r0]! // Store one byte from NEON - vext.8 q0, q0, q0, #1 // Use VEXT to rotate pattern - subs r2, #1 - bhi 2b -3: pop {r7,pc} - -#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD diff --git a/src/libc/arm/string/strchr.s b/src/libc/arm/string/strchr.s deleted file mode 100644 index 229db7bad..000000000 --- a/src/libc/arm/string/strchr.s +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2010 Apple, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -// char * strchr(const char *s, int c); -// -// The strchr( ) function locates the first occurence of c (converted to a -// char) in the string s. If c is '\0', the function locates the terminating -// '\0' byte. - -.text -.syntax unified -.code 32 -.globl _strchr - -.align 3 -_strchr: -// Setup a frame and convert c to a char. - push {r7,lr} - mov r7, sp - and r1, r1, #0xff - -// Basic character-by-character search for c; on each pass through the loop -// we load a byte from s and increment s. We then check if this byte is equal -// to either c or to '\0'; if not, we continue the loop. -0: ldrb r2, [r0],#1 - cmp r2, r1 - tstne r2, r2 - bne 0b - -// Either we have found a match, or we have reached the end of the string (or -// both, if c == '\0'). Because we incremented s after loading the last -// character, we need to decrement the pointer by one to get a pointer to -// either the matching or terminating character. - sub r0, r0, #1 - -// Now compare the last character we loaded to the character that we're -// searching for. If they don't match, the character was not found in the -// string, so return NULL. - cmp r2, r1 - movne r0, #0 - pop {r7,pc} diff --git a/src/libc/arm/string/strcmp.s b/src/libc/arm/string/strcmp.s deleted file mode 100644 index e214c3f66..000000000 --- a/src/libc/arm/string/strcmp.s +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2011 Apple, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -.text -.syntax unified -.code 32 -.globl _strcmp -// int strcmp(const char *s1, const char *s2); -// -// Returns zero if the two NUL-terminated strings s1 and s2 are equal. -// Otherwise, returns the difference between the first two -// characters that do not match, interpreted as unsigned integers. - -#define ESTABLISH_FRAME \ - push {r4-r7,lr} ;\ - add r7, sp, #12 ;\ - push {r8} -#define CLEAR_FRAME \ - pop {r8} ;\ - pop {r4-r7,lr} - -.align 3 -.long 0, 0x01010101 -_strcmp: -// Load a character from each string and advance the pointers. If the loaded -// characters are unequal or NUL, return their difference. -0: ldrb r2, [r0],#1 - ldrb ip, [r1],#1 - cmp r2, #1 - cmphs r2, ip - bne L_earlyReturn -// If the address of the next character from s1 does not have word alignment, -// continue with the character-by-character comparison. Otherwise, fall -// through into the word-by-word comparison path. - tst r0, #3 - bne 0b - -// We have not encountered a NUL or a mismatch, and s1 has word alignment. -// Establish a frame, since we're going to need additional registers anyway. - ESTABLISH_FRAME - ldr lr, (_strcmp-4) - -// Word align s2, and place the remainder in r8. Compute the right- and -// left-shifts to extract each word that we will compare to the other source -// from the aligned words that we load: -// -// aligned s2 to be loaded on next iteration -// | "true" s2 | -// v v v -// +---+---+---+---+ +---+---+---+---+ -// | 0 | 1 | 2 | 3 | | 4 | 5 | 6 | 7 | -// +---+---+---+---+ +---+---+---+---+ -// ^-----------------^ -// to be compared on next iteration - and r8, r1, #3 - bic r1, r1, #3 - mov r8, r8, lsl #3 - rsb r5, r8, #32 - -// Load the first aligned word of s2. OR 0x01 into any bytes that preceed the -// "true s2", to prevent our check for NUL from generating a false positive. -// Then check for NUL, and jump to the byte-by-byte comparison loop after -// unwinding the pointers if we enounter one. - ldr r6, [r1],#4 - orr r6, r6, lr, lsr r5 - sub r2, r6, lr - bic r2, r2, r6 - tst r2, lr, lsl #7 - mov r4, r6, lsr r8 - bne L_unwindLoopPreload - -.align 3 -L_wordCompareLoop: - // Load the next aligned word of s2 and check if it contains any NUL bytes. - // Load the next aligned word of s1, and extract the corresponding bytes from - // the two words of s2 loaded in this and the previous iteration of the loop. - // Compare these two words. - // If no NUL or mismatched words have been encountered, continue the loop. - ldr r6, [r1],#4 -#if defined _ARM_ARCH_6 - uqsub8 r2, lr, r6 - tst r2, r2 - ldr ip, [r0],#4 -#else - sub r2, r6, lr - bic r2, r2, r6 - ldr ip, [r0],#4 - tst r2, lr, lsl #7 -#endif - orr r3, r4, r6, lsl r5 - cmpeq ip, r3 - mov r4, r6, lsr r8 - beq L_wordCompareLoop - -// Either we have encountered a NUL, or we have found a mismatch between s1 -// and s2. Unwind the pointers and use a byte-by-byte comparison loop. - sub r0, r0, #4 - sub r1, r1, #4 -L_unwindLoopPreload: - sub r1, r1, r5, lsr #3 - CLEAR_FRAME - -L_byteCompareLoop: -// Load a character from each string and advance the pointers. If the loaded -// characters are unequal or NUL, return their difference. - ldrb r2, [r0],#1 - ldrb ip, [r1],#1 - cmp r2, #1 - cmpcs r2, ip - beq L_byteCompareLoop - -L_earlyReturn: -// Return the difference between the last two characters loaded. - sub r0, r2, ip - bx lr diff --git a/src/libc/arm/string/strlen.s b/src/libc/arm/string/strlen.s deleted file mode 100644 index d7b261d38..000000000 --- a/src/libc/arm/string/strlen.s +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2011 Apple, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -.syntax unified -.code 32 -.globl _strlen - -#define addr r0 -#define word r1 -#define temp r2 -#define mask r3 -#define save ip -#define indx r0 - -.macro IfWordDoesntContainNUL_SetZ -#if defined _ARM_ARCH_6 -// In each word of the string, we check for NUL bytes via a saturating -// unsigned subtraction of each byte from 0x1. The result of this is -// non-zero if and only if the corresponding byte in the string is NUL. -// Simply using a TST instruction checks all four bytes for NULs in one -// go. - uqsub8 temp, mask, word - tst temp, temp -#else -// If we're on armv5, we do not have the uqsub8 instruction, so we need -// to use a different test for NUL. Instead, we compute: -// -// byte - 0x1 & ~byte -// -// and test the high-order bit. If it is set, then byte is NUL. Just -// as with the other test, this can be applied simultaneously to all -// bytes in a word. - sub temp, word, mask - bic temp, temp, word - tst temp, mask, lsl #7 -#endif -.endm - -.text -.align 4 -.long 0x0 // padding -.long 0x01010101 // mask for use in finding NULs -_strlen: -// Establish stack frame, load mask that we will use to find NUL bytes, -// and set aside a copy of the pointer to the string. - push {r7,lr} - mov r7, sp - ldr mask, (_strlen-4) - add save, addr, #4 - -// Load the aligned word that contains the start of the string, then OR -// 0x01 into any bytes that preceed the start of the string to prevent -// false positives when we check for NUL bytes. - and temp, addr, #3 - bic addr, addr, #3 - lsl temp, temp, #3 - ldr word, [addr], #4 - rsb temp, temp, #32 - orr word, word, mask, lsr temp - -// Check if the string ends in the first word. If so, don't load any -// more of the string; instead jump directly to the cleanup code. - IfWordDoesntContainNUL_SetZ - bne 1f - -.align 4 -// Load one word of the string on each iteration, and check it for NUL -// bytes. If a NUL is found, fall through into the cleanup code. -0: ldr word, [addr], #4 - IfWordDoesntContainNUL_SetZ - beq 0b - -// The last word that we loaded contained a NUL. Subtracting the saved -// pointer from the current pointer gives us the number of bytes from -// the start of the string to the word containing the NUL. -1: sub indx, addr, save -#if defined _ARM_ARCH_6 -// To that we add the index of the first NUL byte in the word, computed -// using REV and CLZ followed by a shift. - rev temp, temp - clz temp, temp - add indx, indx, temp, lsr #3 -#else -// armv5 does not have the REV instruction, so instead we find the -// index of the NUL byte in word with a linear search. - tst word, #0x000000ff - addne indx, #1 - tstne word, #0x0000ff00 - addne indx, #1 - tstne word, #0x00ff0000 - addne indx, #1 -#endif - pop {r7,pc} - diff --git a/src/libc/arm/string/strncmp.s b/src/libc/arm/string/strncmp.s deleted file mode 100644 index 450aa44fc..000000000 --- a/src/libc/arm/string/strncmp.s +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2010, 2011 Apple, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -.text -.syntax unified -.code 32 -.globl _strncmp -// int strncmp(const char *s1, const char *s2, size_t n); -// -// Returns zero if the two NUL-terminated strings s1 and s2 are equal up to -// n characters. Otherwise, returns the difference between the first two -// characters that do not match, interpreted as unsigned integers. - -#define ESTABLISH_FRAME \ - push {r4-r7,lr} ;\ - add r7, sp, #12 ;\ - push {r8,r10} -#define CLEAR_FRAME \ - pop {r8,r10} ;\ - pop {r4-r7,lr} - -.align 3 -.long 0, 0x01010101 -_strncmp: -// If n < 16, jump straight to the byte-by-byte comparison loop. - cmp r2, #16 - blo L_byteCompareLoop -// Load a character from each string and advance the pointers. If the loaded -// characters are unequal or NUL, return their difference. -0: ldrb r3, [r0],#1 - ldrb ip, [r1],#1 - sub r2, #1 - cmp r3, #1 - cmphs r3, ip - bne L_earlyReturn -// If the address of the next character from s1 does not have word alignment, -// continue with the character-by-character comparison. Otherwise, fall -// through into the word-by-word comparison path. - tst r0, #3 - bne 0b - -// We have not encountered a NUL or a mismatch, and s1 has word alignment. -// Establish a frame, since we're going to need additional registers anyway. - ESTABLISH_FRAME - ldr lr, (_strncmp-4) - -// Word align s2, and place the remainder in r10. Compute the right- and -// left-shifts to extract each word that we will compare to the other source -// from the aligned words that we load: -// -// aligned s2 to be loaded on next iteration -// | "true" s2 | -// v v v -// +---+---+---+---+ +---+---+---+---+ -// | 0 | 1 | 2 | 3 | | 4 | 5 | 6 | 7 | -// +---+---+---+---+ +---+---+---+---+ -// ^-----------------^ -// to be compared on next iteration - and r10, r1, #3 - bic r1, r1, #3 - mov r10, r10, lsl #3 - rsb r6, r10,#32 - -// Subtract the number of bytes of the initial word load from s2 that will -// actually be used from n. - sub r2, r2, r6, lsr #3 - -// Load the first aligned word of s2. OR 0x01 into any bytes that preceed the -// "true s2", to prevent our check for NUL from generating a false positive. -// Then check for NUL, and jump to the byte-by-byte comparison loop after -// unwinding the pointers if we enounter one. - ldr r8, [r1],#4 - orr r8, r8, lr, lsr r6 - sub r3, r8, lr - bic r3, r3, r8 - tst r3, lr, lsl #7 - mov r5, r8, lsr r10 - bne L_unwindLoopPreload - -.align 3 -L_wordCompareLoop: -// If n < 4, abort the word compare loop before we load any more data. - subs r2, r2, #4 - blo L_nIsLessThanFour -// Load the next aligned word of s2 and check if it contains any NUL bytes. -// Load the next aligned word of s1, and extract the corresponding bytes from -// the two words of s2 loaded in this and the previous iteration of the loop. -// Compare these two words. -// If no NUL or mismatched words have been encountered, continue the loop. - ldr r8, [r1],#4 -#if defined _ARM_ARCH_6 - uqsub8 r3, lr, r8 - tst r3, r3 - ldr ip, [r0],#4 -#else - sub r3, r8, lr - bic r3, r3, r8 - ldr ip, [r0],#4 - tst r3, lr, lsl #7 -#endif - orr r4, r5, r8, lsl r6 - cmpeq ip, r4 - mov r5, r8, lsr r10 - beq L_wordCompareLoop - -// Either we have encountered a NUL, or we have found a mismatch between s1 -// and s2. Unwind the pointers and use a byte-by-byte comparison loop. - sub r0, r0, #4 - sub r1, r1, #4 -L_nIsLessThanFour: - add r2, r2, #4 -L_unwindLoopPreload: - sub r1, r1, r6, lsr #3 - add r2, r2, r6, lsr #3 - CLEAR_FRAME - -L_byteCompareLoop: -// If n-- == 0, we have exhausted the allowed number of comparisons, and need -// to return zero without additional loads. - subs r2, r2, #1 - movlo r0, #0 - bxlo lr -// Load a character from each string and advance the pointers. If the loaded -// characters are unequal or NUL, return their difference. - ldrb r3, [r0],#1 - ldrb ip, [r1],#1 - cmp r3, #1 - cmpcs r3, ip - beq L_byteCompareLoop - -L_earlyReturn: -// Return the difference between the last two characters loaded. - sub r0, r3, ip - bx lr diff --git a/src/libc/arm/string/strnlen.s b/src/libc/arm/string/strnlen.s deleted file mode 100644 index 33535fd1f..000000000 --- a/src/libc/arm/string/strnlen.s +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2011 Apple, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -.syntax unified -.code 32 -.globl _strnlen - -#define addr r0 -#define maxl r1 -#define temp r2 -#define mask r3 -#define save ip -#define word lr -#define byte lr -#define indx r0 - -.macro IfHS_and_WordDoesntContainNUL_SetZ -#if defined _ARM_ARCH_6 -// In each word of the string, we check for NUL bytes via a saturating -// unsigned subtraction of each byte from 0x1. The result of this is -// non-zero if and only if the corresponding byte in the string is NUL. -// Simply using a TST instruction checks all four bytes for NULs in one -// go. - uqsub8 temp, mask, word - tsths temp, temp -#else -// If we're on armv5, we do not have the uqsub8 instruction, so we need -// to use a different test for NUL. Instead, we compute: -// -// byte - 0x1 & ~byte -// -// and test the high-order bit. If it is set, then byte is NUL. Just -// as with the other test, this can be applied simultaneously to all -// bytes in a word. - sub temp, word, mask - bic temp, temp, word - tsths temp, mask, lsl #7 -#endif -.endm - -.text -.align 3 -.long 0x0 // padding -.long 0x01010101 // mask for use in finding NULs -_strnlen: -// Establish stack frame, load mask that we will use to find NUL bytes, -// and set aside a copy of the pointer to the string. Subtract 4 from -// the maxlen, and jump into a byte-by-byte search if this requires a -// borrow, as we cannot use a word-by-word search in that case. - push {r7,lr} - mov r7, sp - ldr mask, (_strnlen-4) - add save, addr, #4 - subs maxl, maxl, #4 - blo L_bytewiseSearch - -// Load the aligned word that contains the start of the string, then OR -// 0x01 into any bytes that preceed the start to prevent false positives -// when we check for NUL bytes. Additionally, add the number of unused -// bytes to maxlen. - and temp, addr, #3 - bic addr, addr, #3 - add maxl, maxl, temp - lsl temp, temp, #3 - ldr word, [addr], #4 - rsb temp, temp, #32 - orr word, word, mask, lsr temp - - subs maxl, maxl, #4 - IfHS_and_WordDoesntContainNUL_SetZ - bne 1f - -.align 4 -0: ldr word, [addr], #4 - subs maxl, maxl, #4 - IfHS_and_WordDoesntContainNUL_SetZ - beq 0b - -.align 4 -// Either the last word that we loaded contained a NUL, or we will -// exceed maxlen before we finish the next word in the string. Determine -// which case we are in by repeating the check for NUL, and branch if -// there was not a NUL byte. Padding ensures that we don't have two -// branches in a single 16-byte fetch group, as this interferes with -// branch prediction on Swift. -1: tst temp, temp - beq L_bytewiseSearch - -// The last word that we loaded contained a NUL. Subtracting the saved -// pointer from the current pointer gives us the number of bytes from -// the start of the string to the word containing the NUL. - sub indx, addr, save -#if defined _ARM_ARCH_6 -// To that we add the index of the first NUL byte in the word, computed -// using REV and CLZ followed by a shift. - rev temp, temp - clz temp, temp - add indx, indx, temp, lsr #3 -#else -// armv5 does not have the REV instruction, so instead we find the -// index of the NUL byte in word with a linear search. - tst word, #0x000000ff - addne indx, #1 - tstne word, #0x0000ff00 - addne indx, #1 - tstne word, #0x00ff0000 - addne indx, #1 -#endif - pop {r7,pc} - -.align 4 -L_bytewiseSearch: -// Restore maxlen (the last thing that happened before we branched here -// was that we subtracted 4 from maxlen), and adjust the saved string -// pointer. Then we do a simple byte-by-byte search until we either -// reach the end of the string or maxlen reaches zero, at which point -// the length to return is simply the difference between the current -// and saved pointers. - adds maxl, maxl, #4 - sub save, save, #4 - beq 1f -0: ldrb byte, [addr] - cmp byte, #0 - addhi addr, #1 - subshi maxl, #1 - bhi 0b -1: sub indx, addr, save - pop {r7,pc} diff --git a/src/libc/arm/string/strstr.s b/src/libc/arm/string/strstr.s deleted file mode 100644 index a44087e83..000000000 --- a/src/libc/arm/string/strstr.s +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2010, Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -// char * strstr(const char *s1, const char *s2); -// -// If s2 is empty, s1 is returned. -// If s2 does not occur in s1, NULL is returned. -// Otherwise, a pointer to the first character of the first occurrence of s2 -// in s1 is returned. -// -// We use a hand-tuned version of the naive quadratic time algorithm; we have -// experimented with more sophisticated algorithms, however they have been -// found wanting. The increased startup cost combines with the frequency of -// calls to strstr with small strings to swamp the gains from improved -// asymptotic complexity. - -#define CLEAR_FRAME_AND_RETURN \ - pop {r4,r5,r6,r7,pc} - -.text -.syntax unified -.code 32 -.globl _strstr -.align 2 -_strstr: - push {r4,r5,r6,r7,lr} - add r7, sp, #12 - -// Throughout this function, I will refer to the string in which we are -// searching as "string" and the string for which we are searching as "word". -// Using s1 and s2 is too confusing. Thus, we want to return a pointer to -// the first occurrence of "word" in "string". - mov r5, r1 - mov r4, r0 - -// We begin by calling strlen to find the length of "word". We also handle -// two special cases here: we early-out if word is an empty string (length -// zero), and we call strchr if word is only a single character. - mov r0, r5 - bl _strlen - subs r0, r0, #1 - ble L_tinyWord - -// Load the first character of word - ldrb ip, [r5] - -L_lookForFirstCharacter: -// Load the first character from string. If it is equal to the first -// character of word, or is a zero byte, then we do more processing; -// otherwise, proceed to the next character. - ldrb r1, [r4],#1 - cmp r1, ip - tstne r1, r1 - bne L_lookForFirstCharacter - -// The byte that we loaded from string either matched the first character -// of word, or was a zero byte. If it was a zero byte, then we have reached -// the end of string without finding a match of word. Otherwise, we fall -// into a loop that checks additional characters to see if we have a match. - tst r1, r1 - beq L_noMatch - -// We have found a match for the first character of word; we want to read -// characters from this point on to see if we have a match for the entirety -// of word. We want to be sure to preserve the state of the outside loop, -// however: -// -// r0: length(word) - 1 -// r4: pointer to the next character in string -// r5: pointer to the first character in word -// ip: first character in word -// -// The registers r1-r3, r6, and lr are available as scratch. We set them up -// for the inner loop as follows: -// -// r1: remaining length to be matched -// r2: pointer to next character of string to match -// r3: pointer to next character of word to match -// r6: current character from string -// lr: current character from word - mov r2, r4 - add r3, r5, #1 - mov r1, r0 - -L_checkMatch: -// Load the next byte from both the candidate match and from word. If they -// are not equal, jump back to the outer loop. If they are equal, decrement -// the length, and continue the inner loop if we have not yet found a -// complete match. -// -// We don't need to worry about looking for null bytes in this loop; we know -// that we won't load a null byte from word, because we computed it's length -// earlier, and are using that as a termination condition. If we hit a null -// byte in string, the comparison will fail (because the corresponding byte -// in word is non-null), and we will return to the outer loop, where the -// null byte will be detected and handled properly. - ldrb r6, [r2],#1 - ldrb lr, [r3],#1 - cmp r6, lr - bne L_lookForFirstCharacter - subs r1, r1, #1 - bne L_checkMatch - -// We have exhausted the length of word without finding a mismatched character -// so we have found a match. Return a pointer to the beginning of the match -// string. (This pointer is r4 - 1 because r4 was auto-incremented when we -// loaded the first character). - sub r0, r4, #1 - CLEAR_FRAME_AND_RETURN - -L_noMatch: -// No match was found; return NULL. - mov r0, #0 - CLEAR_FRAME_AND_RETURN - -L_tinyWord: -// "word" is either empty or a single character. If it is a single character, -// translate strstr into a call to the (more efficient) strchr. - blt L_emptyWord - ldrb r1, [r5] - mov r0, r4 - bl _strchr - CLEAR_FRAME_AND_RETURN - -L_emptyWord: -// "word" is empty; return "string". - movlt r0, r4 - CLEAR_FRAME_AND_RETURN - \ No newline at end of file diff --git a/src/libc/arm/sys/OSAtomic-v4.c b/src/libc/arm/sys/OSAtomic-v4.c deleted file mode 100644 index 8f794204d..000000000 --- a/src/libc/arm/sys/OSAtomic-v4.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2004, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - - -#if !defined(_ARM_ARCH_6) - -/* - * The only atomic operation ARMv4T provides (atomic swap) is not - * sufficient for the general 32-bit arithmetic and compare-and-swap - * operations OSAtomic is supposed to provide. So we use a global - * spin lock around all operations. - * - * Since we have only a single, in-order, CPU, we do not need - * memory barriers for data. - */ - -static OSSpinLock _atomic_lock = OS_SPINLOCK_INIT; - -int32_t OSAtomicAdd32( int32_t theAmount, volatile int32_t *theValue ) -{ - int32_t result; - - OSSpinLockLock(&_atomic_lock); - result = (*theValue += theAmount); - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -int32_t OSAtomicAdd32Barrier( int32_t theAmount, volatile int32_t *theValue ) -{ - return OSAtomicAdd32(theAmount, theValue); -} - -int64_t OSAtomicAdd64( int64_t theAmount, volatile int64_t *theValue ) -{ - int64_t result; - - OSSpinLockLock(&_atomic_lock); - result = (*theValue += theAmount); - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -int64_t OSAtomicAdd64Barrier( int64_t theAmount, volatile int64_t *theValue ) -{ - return OSAtomicAdd64(theAmount, theValue); -} - -int32_t OSAtomicOr32( uint32_t theMask, volatile uint32_t *theValue ) -{ - int32_t result; - - OSSpinLockLock(&_atomic_lock); - result = (*theValue |= theMask); - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -int32_t OSAtomicOr32Barrier( uint32_t theMask, volatile uint32_t *theValue ) -{ - return OSAtomicOr32(theMask, theValue); -} - -int32_t OSAtomicOr32Orig( uint32_t theMask, volatile uint32_t *theValue ) -{ - int32_t result; - - OSSpinLockLock(&_atomic_lock); - result = *theValue; - *theValue |= theMask; - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -int32_t OSAtomicOr32OrigBarrier( uint32_t theMask, volatile uint32_t *theValue ) -{ - return OSAtomicOr32Orig(theMask, theValue); -} - -int32_t OSAtomicAnd32( uint32_t theMask, volatile uint32_t *theValue ) -{ - int32_t result; - - OSSpinLockLock(&_atomic_lock); - result = (*theValue &= theMask); - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -int32_t OSAtomicAnd32Barrier( uint32_t theMask, volatile uint32_t *theValue ) -{ - return OSAtomicAnd32(theMask, theValue); -} - -int32_t OSAtomicAnd32Orig( uint32_t theMask, volatile uint32_t *theValue ) -{ - int32_t result; - - OSSpinLockLock(&_atomic_lock); - result = *theValue; - *theValue &= theMask; - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -int32_t OSAtomicAnd32OrigBarrier( uint32_t theMask, volatile uint32_t *theValue ) -{ - return OSAtomicAnd32Orig(theMask, theValue); -} - -int32_t OSAtomicXor32( uint32_t theMask, volatile uint32_t *theValue ) -{ - int32_t result; - - OSSpinLockLock(&_atomic_lock); - result = (*theValue ^= theMask); - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -int32_t OSAtomicXor32Barrier( uint32_t theMask, volatile uint32_t *theValue ) -{ - return OSAtomicXor32(theMask, theValue); -} - -int32_t OSAtomicXor32Orig( uint32_t theMask, volatile uint32_t *theValue ) -{ - int32_t result; - - OSSpinLockLock(&_atomic_lock); - result = *theValue; - *theValue ^= theMask; - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -int32_t OSAtomicXor32OrigBarrier( uint32_t theMask, volatile uint32_t *theValue ) -{ - return OSAtomicXor32Orig(theMask, theValue); -} - -bool OSAtomicCompareAndSwap32( int32_t oldValue, int32_t newValue, volatile int32_t *theValue ) -{ - bool result; - - OSSpinLockLock(&_atomic_lock); - result = (*theValue == oldValue); - if (result) *theValue = newValue; - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, volatile int32_t *theValue ) -{ - return OSAtomicCompareAndSwap32(oldValue, newValue, theValue); -} - -bool -OSAtomicCompareAndSwapInt(int oldValue, int newValue, volatile int *theValue) -{ - return OSAtomicCompareAndSwap32(oldValue, newValue, theValue); -} - -bool -OSAtomicCompareAndSwapIntBarrier(int oldValue, int newValue, volatile int *theValue) -{ - return OSAtomicCompareAndSwap32(oldValue, newValue, theValue); -} - -bool -OSAtomicCompareAndSwapLong(long oldValue, long newValue, volatile long *theValue) -{ - return OSAtomicCompareAndSwap32(oldValue, newValue, (volatile int32_t *)theValue); -} - -bool -OSAtomicCompareAndSwapLongBarrier(long oldValue, long newValue, volatile long *theValue) -{ - return OSAtomicCompareAndSwap32(oldValue, newValue, (volatile int32_t *)theValue); -} - -bool OSAtomicCompareAndSwap64( int64_t oldValue, int64_t newValue, volatile int64_t *theValue ) -{ - bool result; - - OSSpinLockLock(&_atomic_lock); - result = (*theValue == oldValue); - if (result) *theValue = newValue; - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -bool OSAtomicCompareAndSwap64Barrier( int64_t oldValue, int64_t newValue, volatile int64_t *theValue ) -{ - return OSAtomicCompareAndSwap64(oldValue, newValue, theValue); -} - -bool OSAtomicTestAndSet( uint32_t n, volatile void *theAddress ) -{ - char *byteAddress = ((char*)theAddress + (n>>3)); - uint32_t byteBit = (0x80>>(n&7)); - bool result; - - OSSpinLockLock(&_atomic_lock); - result = *byteAddress & byteBit; - *byteAddress |= byteBit; - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -bool OSAtomicTestAndSetBarrier( uint32_t n, volatile void *theAddress ) -{ - return OSAtomicTestAndSet(n, theAddress); -} - -bool OSAtomicTestAndClear( uint32_t n, volatile void *theAddress ) -{ - char *byteAddress = ((char*)theAddress + (n>>3)); - uint32_t byteBit = (0x80>>(n&7)); - bool result; - - OSSpinLockLock(&_atomic_lock); - result = *byteAddress & byteBit; - *byteAddress &= (~byteBit); - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -bool OSAtomicTestAndClearBarrier( uint32_t n, volatile void *theAddress ) -{ - return OSAtomicTestAndClear(n, theAddress); -} - -void OSMemoryBarrier( void ) -{ - return; -} - - -bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue ) -{ - return OSAtomicCompareAndSwapPtr(__oldValue, __newValue, __theValue); -} - -bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ) -{ - bool result; - - OSSpinLockLock(&_atomic_lock); - result = (*__theValue == __oldValue); - if (result) *__theValue = __newValue; - OSSpinLockUnlock(&_atomic_lock); - - return result; -} - -void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset ) -{ - OSSpinLockLock(&_atomic_lock); - *((void **)((char *)__new + __offset)) = __list->opaque1; - __list->opaque1 = __new; - OSSpinLockUnlock(&_atomic_lock); -} - -void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset ) -{ - void *head; - - OSSpinLockLock(&_atomic_lock); - head = __list->opaque1; - if (head != NULL) { - void **next = (void **)((char *)head + __offset); - __list->opaque1 = *next; - } - OSSpinLockUnlock(&_atomic_lock); - - return head; -} - -#endif /* !defined(_ARM_ARCH_6) */ diff --git a/src/libc/arm/sys/OSAtomic.c b/src/libc/arm/sys/OSAtomic.c deleted file mode 100644 index 41c328b9a..000000000 --- a/src/libc/arm/sys/OSAtomic.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "OSAtomic.h" -#include "../../darwin/OSAtomicLoadStoreEx.c" diff --git a/src/libc/arm/sys/OSAtomic.h b/src/libc/arm/sys/OSAtomic.h deleted file mode 100644 index 77454035c..000000000 --- a/src/libc/arm/sys/OSAtomic.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __ARM_OSATOMIC_SHIMS__ -#define __ARM_OSATOMIC_SHIMS__ - -#include -#include -#include -#include -#include - -#define fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l)) -#define slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l)) - -#if defined(__arm__) -#include - -#define _osatomic_load_exclusive(p, r) \ - __asm__ __volatile__( \ - "ldrex %[_r], %[_p]" \ - : [_r] "=&r" (r) \ - : [_p] "m" (*(p)) : "memory") - -#define _osatomic_load_exclusive64(p, r) \ - do { \ - register uint32_t rl asm("r4"), rh asm("r5"); \ - __asm__ __volatile__( \ - "ldrexd %[_rl], %[_rh], %[_p]" \ - : [_rl] "=r" (rl), [_rh] "=r" (rh) \ - : [_p] "m" (*(p)) : "memory"); \ - r = (typeof(r))(((uint64_t)rh << 32) | (uint64_t)rl); \ - } while (0); - -#define _osatomic_store_exclusive(p, r, t) \ - __asm__ __volatile__( \ - "strex %[_t], %[_r], %[_p]" \ - : [_t] "=&r" (t) \ - : [_p] "m" (*(p)), [_r] "r" (r) : "memory") - -#define _osatomic_store_exclusive64(p, r, t) \ - do { \ - register uint32_t rl asm("r4"), rh asm("r5"); \ - rh = (uint32_t)(r >> 32); \ - rl = (uint32_t)(r); \ - __asm__ __volatile__( \ - "strexd %[_t], %[_rl], %[_rh], %[_p]" \ - : [_t] "=&r" (t) \ - : [_p] "m" (*(p)), [_rl] "r" (rl), [_rh] "r" (rh) : "memory"); \ - } while (0); - -#if defined(_ARM_ARCH_7) - -#ifdef _OSATOMIC_WFE -# define MP_SPIN_TRIES 10 -# define _osatomic_pause() __asm__ __volatile__("wfe") -#else -# define MP_SPIN_TRIES 1000 -# define _osatomic_pause() __asm__ __volatile__("yield") -#endif // _OSATOMIC_WFE - -#define _osatomic_barrier() \ - __asm__ __volatile__( \ - "dmb ish" \ - : : : "memory") - -#define _osatomic_store_barrier() \ - __asm__ __volatile__( \ - "dmb ishst" \ - : : : "memory") - -#elif defined(_ARM_ARCH_6) && !defined(__thumb__) // _ARM_ARCH_7 - -#define _osatomic_barrier() \ - __asm__ __volatile__( \ - "mcr p15, 0, %0, c7, c10, 5" \ - : : "r" (0) : "memory") - -#define _osatomic_store_barrier() _osatomic_barrier() -#define _osatomic_pause() - -#elif defined(_ARM_ARCH_6) && defined(__thumb__) -#error Atomic operations not available on ARMv6 Thumb -#endif // _ARM_ARCH_7 - -#if !defined(_ARM_ARCH_7) -# ifndef _OSATOMIC_NO_BARRIERS -# define __OSATOMIC_SUFFIX "" -# define __OSATOMIC_BARRIER "Barrier" -# define _OSATOMIC_ALIAS_NB(x) -# else -# define _OSATOMIC_EXTRAS 1 -# define __OSATOMIC_SUFFIX "" -# define __OSATOMIC_BARRIER "" -# define _OSATOMIC_ALIAS_NB(x) -# endif // _OSATOMIC_NO_BARRIERS -#else -# define _OSATOMIC_EXTRAS 1 -# ifndef _OSATOMIC_NO_BARRIERS -# ifdef _OSATOMIC_WFE -# define __OSATOMIC_SUFFIX "$VARIANT$wfe" -# else -# define __OSATOMIC_SUFFIX "$VARIANT$mp" -# endif // _OSATOMIC_ONLY_WFE -# define __OSATOMIC_BARRIER "Barrier" __OSATOMIC_SUFFIX -# define _OSATOMIC_ALIAS_NB(x) -# else -# define __OSATOMIC_SUFFIX "$VARIANT$up" -# define __OSATOMIC_BARRIER "Barrier" __OSATOMIC_SUFFIX -// Undefine the barrier operations -# undef _osatomic_barrier -# define _osatomic_barrier() -# undef _osatomic_store_barrier -# define _osatomic_store_barrier() -// Aliases to alias non-barrier operations to UP variant names -# if defined(__thumb__) -# define _OSATOMIC_ALIAS_NB(sym) __asm __volatile__(".globl _" __STRING(sym) "; .thumb_func _" __STRING(sym) " ; .set _" __STRING(sym) ", _" __STRING(sym) __OSATOMIC_BARRIER) -# else -# define _OSATOMIC_ALIAS_NB(sym) __asm __volatile__(".globl _" __STRING(sym) "; .set _" __STRING(sym) ", _" __STRING(sym) __OSATOMIC_BARRIER) -# endif // __thumb__ -# endif // _OSATOMIC_NO_BARRIERS -#endif // !_ARM_ARCH_7 - -// Allow us to mark up functions as being uni/multiprocessor. -#define _OSATOMIC_VARIANT(sym) __asm("_" __STRING(sym) __OSATOMIC_SUFFIX) -#define _OSATOMIC_VARIANT_B(sym) __asm("_" __STRING(sym) __OSATOMIC_BARRIER) - -#if defined(__thumb__) - // For aliasing CompareAndSwap operations of the same size - #define _OSATOMIC_ALIAS_B(newsym, sym) \ - __asm __volatile__( \ - ".globl _" __STRING(newsym) __OSATOMIC_BARRIER ";" \ - ".thumb_func _" __STRING(newsym) __OSATOMIC_BARRIER ";" \ - ".set _" __STRING(newsym) __OSATOMIC_BARRIER ", _" __STRING(sym) __OSATOMIC_BARRIER \ - ) - - #define _OSATOMIC_ALIAS(newsym, sym) \ - __asm __volatile__( \ - ".globl _" __STRING(newsym) __OSATOMIC_SUFFIX ";" \ - ".thumb_func _" __STRING(newsym) __OSATOMIC_SUFFIX ";" \ - ".set _" __STRING(newsym) __OSATOMIC_SUFFIX ", _" __STRING(sym) __OSATOMIC_SUFFIX \ - ) -#else - // For aliasing CompareAndSwap operations of the same size - #define _OSATOMIC_ALIAS_B(newsym, sym) \ - __asm __volatile__( \ - ".globl _" __STRING(newsym) __OSATOMIC_BARRIER ";" \ - ".set _" __STRING(newsym) __OSATOMIC_BARRIER ", _" __STRING(sym) __OSATOMIC_BARRIER \ - ) - - #define _OSATOMIC_ALIAS(newsym, sym) \ - __asm __volatile__( \ - ".globl _" __STRING(newsym) __OSATOMIC_SUFFIX ";" \ - ".set _" __STRING(newsym) __OSATOMIC_SUFFIX ", _" __STRING(sym) __OSATOMIC_SUFFIX \ - ) -#endif // __thumb__ - -#endif // __arm__ - -#endif // __ARM_OSATOMIC_SHIMS__ diff --git a/src/libc/arm/sys/OSAtomicUP.c b/src/libc/arm/sys/OSAtomicUP.c deleted file mode 100644 index d9a24a154..000000000 --- a/src/libc/arm/sys/OSAtomicUP.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#define _OSATOMIC_NO_BARRIERS -#include "OSAtomic.c" diff --git a/src/libc/arm/sys/OSAtomic_resolvers.c b/src/libc/arm/sys/OSAtomic_resolvers.c deleted file mode 100644 index 28ad04fae..000000000 --- a/src/libc/arm/sys/OSAtomic_resolvers.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * This holds the C versions of OSAtomic.s resolver functions, used by - * everyone except dyld. - */ - -#include -#if defined(_ARM_ARCH_7) - -#include -#include -#include - -#if defined(VARIANT_DYLD) - -#define _STRDEF(x) __STRING(x) - -#define makeResolver_up_mp(name) \ - void* name ## $VARIANT$up(void); \ - void* name ## $VARIANT$mp(void); \ - void* name ## Resolver(void) __asm__( "_" #name ); \ - void* name ## Resolver(void) { \ - __asm__ __volatile__ ( \ - "ldr ip, L" #name "$commpage ;" \ - "ldr ip, [ip] ;" \ - "tst ip, $(" _STRDEF(kUP) ") ;" \ - "bne 1f ; " \ - "b _" __STRING(name) "$VARIANT$mp ;" \ - "1: b _" __STRING(name) "$VARIANT$up ;" \ - "L" #name "$commpage: .long " _STRDEF(_COMM_PAGE_CPU_CAPABILITIES) " ;" \ - : : : ); \ - } - -#define makeResolver_up_mp_wfe(name) makeResolver_up_mp(name) - -#else - -#define makeResolver_up_mp(name) \ - void name ## $VARIANT$up(void); \ - void name ## $VARIANT$mp(void); \ - void* name ## Resolver(void) __asm__( "_" #name ) ; \ - void* name ## Resolver(void) { \ - __asm__(".symbol_resolver _" #name); \ - /* return MP variant functions on kNumCPUs > 1 */ \ - if ((*(uint32_t*)(uintptr_t)_COMM_PAGE_CPU_CAPABILITIES & kUP) == 0) { \ - return name ## $VARIANT$mp; \ - } \ - return name ## $VARIANT$up; \ - } - -#define makeResolver_up_mp_wfe(name) \ - void name ## $VARIANT$up(void); \ - void name ## $VARIANT$mp(void); \ - void name ## $VARIANT$wfe(void); \ - void* name ## Resolver(void) __asm__( "_" #name ) ; \ - void* name ## Resolver(void) { \ - __asm__(".symbol_resolver _" #name); \ - uint32_t caps = *(uint32_t*)(uintptr_t)_COMM_PAGE_CPU_CAPABILITIES; \ - /* return WFE variant if we will get woken up */ \ - if ((caps & (kHasEvent | kUP)) == kHasEvent) { \ - return name ## $VARIANT$wfe; \ - } \ - /* return MP variant functions on kNumCPUs > 1 */ \ - else if ((caps & kUP) == 0) { \ - return name ## $VARIANT$mp; \ - } \ - return name ## $VARIANT$up; \ - } - -#endif // defined VARIANT_DYLD - -#include "OSAtomic_resolvers.h" - -#else // defined _ARM_ARCH_7 - -typedef int emptyFilesArentCFiles; - -#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD diff --git a/src/libc/arm/sys/OSAtomic_resolvers.h b/src/libc/arm/sys/OSAtomic_resolvers.h deleted file mode 100644 index ea82afe21..000000000 --- a/src/libc/arm/sys/OSAtomic_resolvers.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * This header file gets included by OSAtomic_resolvers.c and OSAtomic.s - * in order to create the appropriate resolvers for both libsystem_c.dylib - * and dyld's libc.a - */ - -makeResolver_up_mp(OSAtomicAdd32Barrier) -makeResolver_up_mp(OSAtomicOr32Barrier) -makeResolver_up_mp(OSAtomicOr32OrigBarrier) -makeResolver_up_mp(OSAtomicAnd32Barrier) -makeResolver_up_mp(OSAtomicAnd32OrigBarrier) -makeResolver_up_mp(OSAtomicXor32Barrier) -makeResolver_up_mp(OSAtomicXor32OrigBarrier) -makeResolver_up_mp(OSAtomicCompareAndSwap32Barrier) -makeResolver_up_mp(OSAtomicCompareAndSwapIntBarrier) -makeResolver_up_mp(OSAtomicCompareAndSwapLongBarrier) -makeResolver_up_mp(OSAtomicCompareAndSwapPtrBarrier) -makeResolver_up_mp(OSAtomicTestAndSetBarrier) -makeResolver_up_mp(OSAtomicTestAndClearBarrier) -makeResolver_up_mp(OSMemoryBarrier) -makeResolver_up_mp(OSAtomicEnqueue) -makeResolver_up_mp(OSAtomicDequeue) -makeResolver_up_mp(OSAtomicAdd64Barrier) -makeResolver_up_mp(OSAtomicCompareAndSwap64Barrier) - -makeResolver_up_mp_wfe(spin_lock) -makeResolver_up_mp_wfe(_spin_lock) -makeResolver_up_mp_wfe(OSSpinLockLock) - -makeResolver_up_mp(spin_lock_try) -makeResolver_up_mp(_spin_lock_try) -makeResolver_up_mp(OSSpinLockTry) - -makeResolver_up_mp(spin_unlock) -makeResolver_up_mp(_spin_unlock) -makeResolver_up_mp(OSSpinLockUnlock) diff --git a/src/libc/arm/sys/Spinlocks.c b/src/libc/arm/sys/Spinlocks.c deleted file mode 100644 index c428e1356..000000000 --- a/src/libc/arm/sys/Spinlocks.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "OSAtomic.h" -#include "../../darwin/SpinlocksLoadStoreEx.c" diff --git a/src/libc/arm/sys/SpinlocksUP.c b/src/libc/arm/sys/SpinlocksUP.c deleted file mode 100644 index aa09ea5c3..000000000 --- a/src/libc/arm/sys/SpinlocksUP.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -// On ARMv6, the default implementation already has no barriers, no need to do it again -#if defined(_ARM_ARCH_7) - -#define _OSATOMIC_NO_BARRIERS -#include "Spinlocks.c" - -#endif diff --git a/src/libc/arm/sys/SpinlocksWFE.c b/src/libc/arm/sys/SpinlocksWFE.c deleted file mode 100644 index 210767081..000000000 --- a/src/libc/arm/sys/SpinlocksWFE.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#if defined(_ARM_ARCH_7) - -#define _OSATOMIC_WFE -#include "Spinlocks.c" - -#endif diff --git a/src/libc/arm/sys/arm_commpage_gettimeofday.c b/src/libc/arm/sys/arm_commpage_gettimeofday.c deleted file mode 100644 index 4565bcdb5..000000000 --- a/src/libc/arm/sys/arm_commpage_gettimeofday.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int __commpage_gettimeofday(struct timeval *); - - -#define TIME_ADD(rsecs, secs, rfrac, frac, unit) \ -{ \ - (rfrac) += (frac); \ - while ((rfrac) >= (unit)) { \ - (rfrac) -= (unit); \ - (rsecs) += 1; \ - } \ - (rsecs) += (secs); \ -} - - -int __commpage_gettimeofday(struct timeval *tp) { - commpage_timeofday_data_t *commpage_timeofday_datap; - uint64_t tbr; - uint64_t t64; - uint64_t TimeBase; - uint32_t TimeStamp_usec; - uint32_t TimeStamp_sec; - uint32_t TimeBaseTicks_per_sec; - uint64_t TimeBase_magic; - uint32_t TimeBase_add; - uint32_t TimeBase_shift; - uint32_t x, q; - - - commpage_timeofday_datap = (commpage_timeofday_data_t *)_COMM_PAGE_TIMEOFDAY_DATA; - - do { - TimeBase = commpage_timeofday_datap->TimeBase; - TimeStamp_sec = commpage_timeofday_datap->TimeStamp_sec; - TimeStamp_usec = commpage_timeofday_datap->TimeStamp_usec; - TimeBaseTicks_per_sec = commpage_timeofday_datap->TimeBaseTicks_per_sec; - TimeBase_magic = commpage_timeofday_datap->TimeBase_magic; - TimeBase_add = commpage_timeofday_datap->TimeBase_add; - TimeBase_shift = commpage_timeofday_datap->TimeBase_shift; - } while (TimeBase != commpage_timeofday_datap->TimeBase); - - if (TimeBase == 0) - return(1); - - tbr = mach_absolute_time(); - - t64 = tbr - TimeBase; - - if (t64 >= (uint64_t)TimeBaseTicks_per_sec) - return(1); - - x = (uint32_t)t64; - q = ((uint64_t)x * (uint32_t)(TimeBase_magic)) >> 32; - tp->tv_usec = TimeBase_add ? (((x - q) >> 1) + q) >> (TimeBase_shift - 1) : q >> TimeBase_shift; - tp->tv_sec = 0; - - TIME_ADD(tp->tv_sec, TimeStamp_sec, tp->tv_usec, TimeStamp_usec, USEC_PER_SEC); - - return(0); -} diff --git a/src/libc/arm/sys/gcc_atomic.c b/src/libc/arm/sys/gcc_atomic.c deleted file mode 100644 index c96820a74..000000000 --- a/src/libc/arm/sys/gcc_atomic.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __clang__ - -#include -#include -#include -#include - -/* - * Implement gcc atomic "builtins" in terms of OSAtomic routines, - * since the ARM GCC target does not currently support them - */ - -int32_t __sync_fetch_and_add_4 (int32_t *ptr, int32_t value, ...) -{ - return OSAtomicAdd32Barrier(value, ptr) - value; -} - -int32_t __sync_fetch_and_sub_4 (int32_t *ptr, int32_t value, ...) -{ - return OSAtomicAdd32Barrier(-value, ptr) + value; -} - -uint32_t __sync_fetch_and_or_4(uint32_t *ptr, uint32_t value, ...) -{ - return OSAtomicOr32OrigBarrier(value, ptr); -} - -uint32_t __sync_fetch_and_and_4(uint32_t *ptr, uint32_t value, ...) -{ - return OSAtomicAnd32OrigBarrier(value, ptr); -} - -uint32_t __sync_fetch_and_xor_4(uint32_t *ptr, uint32_t value, ...) -{ - return OSAtomicXor32OrigBarrier(value, ptr); -} - -int32_t __sync_add_and_fetch_4 (int32_t *ptr, int32_t value, ...) -{ - return OSAtomicAdd32Barrier(value, ptr); -} - -int32_t __sync_sub_and_fetch_4 (int32_t *ptr, int32_t value, ...) -{ - return OSAtomicAdd32Barrier(-value, ptr); -} - -uint32_t __sync_or_and_fetch_4 (uint32_t *ptr, int32_t value, ...) -{ - return OSAtomicOr32Barrier(value, ptr); -} - -uint32_t __sync_and_and_fetch_4 (uint32_t *ptr, int32_t value, ...) -{ - return OSAtomicAnd32Barrier(value, ptr); -} - -uint32_t __sync_xor_and_fetch_4 (uint32_t *ptr, int32_t value, ...) -{ - return OSAtomicXor32Barrier(value, ptr); -} - -bool __sync_bool_compare_and_swap_4(int32_t *ptr, int32_t oldval, int32_t newval, ...) -{ - return OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr); -} - -int32_t __sync_val_compare_and_swap_4(int32_t *ptr, int32_t oldval, int32_t newval, ...) -{ - int32_t old = *ptr; - OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr); - return old; -} - -int32_t __sync_lock_test_and_set_4(int32_t *ptr, int32_t value, ...) -{ - int32_t old; - - do { - old = *ptr; - } while (!OSAtomicCompareAndSwap32Barrier(old, value, ptr)); - - return old; -} - -void __sync_lock_release_4(int32_t *ptr, ...) -{ - *ptr = 0; -} - -__private_extern__ -void __sync_synchronize(void) -{ - OSMemoryBarrier(); -} - -#endif diff --git a/src/libc/arm/sys/longjmp.s b/src/libc/arm/sys/longjmp.s deleted file mode 100644 index 8e8210351..000000000 --- a/src/libc/arm/sys/longjmp.s +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1998-2008 Apple Inc. All rights reserved. - * - * File: sys/arm/longjmp.s - * - * Implements siglongjmp(), longjmp(), _longjmp() - * - */ - -#include -#include "_setjmp.h" - -/* - * longjmp routines - */ - -/* void siglongjmp(sigjmp_buf env, int val); */ - -ENTRY_POINT(_siglongjmp) - ldr r2, [ r0, #JMP_SIGFLAG ] // load sigflag - tst r2, #0 // test if zero - beq L__exit // if zero do _longjmp() - // else *** fall through *** to longjmp() - -/* void longjmp(jmp_buf env, int val); */ - -ENTRY_POINT(_longjmp) - mov r6, r0 // preserve args across _sigsetmask - mov r8, r1 - ldr r0, [ r0, #JMP_sig ] // restore the signal mask - CALL_EXTERNAL(_sigsetmask) // make a (deprecated!) syscall to set the mask - mov r1, r8 - mov r0, r6 -L__exit: - BRANCH_EXTERNAL(__longjmp) diff --git a/src/libc/arm/sys/mach_absolute_time.s b/src/libc/arm/sys/mach_absolute_time.s deleted file mode 100644 index 716affce0..000000000 --- a/src/libc/arm/sys/mach_absolute_time.s +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#if __arm__ - .text - .align 2 - .globl _mach_absolute_time -_mach_absolute_time: - mov r12, #-3 - swi 0x80 - bx lr -#endif diff --git a/src/libc/arm/sys/setjmp.s b/src/libc/arm/sys/setjmp.s deleted file mode 100644 index 8fa9b993c..000000000 --- a/src/libc/arm/sys/setjmp.s +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1998-2008 Apple Inc. All rights reserved. - * - * File: sys/arm/setjmp.s - * - * Implements sigsetjmp(), setjmp(), _setjmp() - * - */ - -#include -#include "_setjmp.h" - -/* - * setjmp routines - */ - -/* int sigsetjmp(sigjmp_buf env, int savemask); */ - -ENTRY_POINT(_sigsetjmp) - str r1, [ r0, #JMP_SIGFLAG ] // save sigflag - tst r1, #0 // test if r1 is 0 - beq L__exit // if r1 == 0 do _setjmp() - // else *** fall through *** to setjmp() - -/* int setjmp(jmp_buf env); */ - -ENTRY_POINT(_setjmp) - str lr, [ r0, #JMP_lr ] - str r8, [ r0, #JMP_r8 ] - mov r8, r0 - mov r0, #1 // get the previous signal mask - mov r1, #0 // - add r2, r8, #JMP_sig // get address where previous mask needs to be - CALL_EXTERNAL(_sigprocmask) // make a syscall to get mask - mov r0, r8 // restore jmp_buf ptr - ldr r8, [ r0, #JMP_r8 ] - ldr lr, [ r0, #JMP_lr ] -L__exit: - BRANCH_EXTERNAL(__setjmp) diff --git a/src/libc/compat-43/CMakeLists.txt b/src/libc/compat-43/CMakeLists.txt index e4d933640..6ba0eb5ca 100644 --- a/src/libc/compat-43/CMakeLists.txt +++ b/src/libc/compat-43/CMakeLists.txt @@ -35,13 +35,15 @@ set(compat-cancelable_sources sigcompat.c FreeBSD/creat.c) add_library(libc-compat_cancelable OBJECT ${compat-cancelable_sources}) SET_TARGET_PROPERTIES(libc-compat_cancelable PROPERTIES COMPILE_DEFINITIONS "BUILDING_VARIANT;VARIANT_CANCELABLE" - COMPILE_FLAGS "-U__DARWIN_NON_CANCELABLE") + COMPILE_FLAGS "-U__DARWIN_NON_CANCELABLE -D__DARWIN_UNIX03=1") # *** # Legacy variants # *** -set(compat-legacy_sources FreeBSD/creat.c FreeBSD/killpg.c FreeBSD/setpgrp.c) +set(compat-legacy_sources FreeBSD/creat.c FreeBSD/killpg.c) add_library(libc-compat_legacy OBJECT ${compat-legacy_sources}) -SET_TARGET_PROPERTIES(libc-compat_legacy PROPERTIES COMPILE_DEFINITIONS "BUILDING_VARIANT;VARIANT_LEGACY") +SET_TARGET_PROPERTIES(libc-compat_legacy PROPERTIES + COMPILE_DEFINITIONS "BUILDING_VARIANT;VARIANT_LEGACY;_NONSTD_SOURCE" + COMPILE_FLAGS "-U__DARWIN_NON_CANCELABLE -U__DARWIN_UNIX03 -U_DARWIN_C_SOURCE -U_POSIX_C_SOURCE") diff --git a/src/libc/compat-43/sigcompat.c b/src/libc/compat-43/sigcompat.c index 8c4410db1..1e8ca3984 100644 --- a/src/libc/compat-43/sigcompat.c +++ b/src/libc/compat-43/sigcompat.c @@ -56,8 +56,6 @@ #if __DARWIN_UNIX03 #ifdef VARIANT_CANCELABLE #include - -extern void _pthread_testcancel(pthread_t thread, int isconforming); #endif /* VARIANT_CANCELABLE */ extern int __unix_conforming; #endif /* __DARWIN_UNIX03 */ @@ -69,13 +67,14 @@ extern int __unix_conforming; #ifndef BUILDING_VARIANT #if defined(__DYNAMIC__) extern int _sigaction_nobind (int sig, const struct sigaction *nsv, struct sigaction *osv); +extern int _sigvec_nobind (int, struct sigvec *, struct sigvec *); #endif static int -sigvec__(signo, sv, osv, bind) - int signo; - struct sigvec *sv, *osv; - int bind; +sigvec__(int signo, + struct sigvec *sv, + struct sigvec *osv, + int bind) { int ret; @@ -96,26 +95,25 @@ sigvec__(signo, sv, osv, bind) } int -sigvec(signo, sv, osv) - int signo; - struct sigvec *sv, *osv; +sigvec(int signo, + struct sigvec *sv, + struct sigvec *osv) { return sigvec__(signo, sv, osv, 1); } #if defined(__DYNAMIC__) int -_sigvec_nobind(signo, sv, osv) - int signo; - struct sigvec *sv, *osv; +_sigvec_nobind(int signo, + struct sigvec *sv, + struct sigvec *osv) { return sigvec__(signo, sv, osv, 0); } #endif int -sigsetmask(mask) - int mask; +sigsetmask(int mask) { int omask, n; @@ -126,8 +124,7 @@ sigsetmask(mask) } int -sigblock(mask) - int mask; +sigblock(int mask) { int omask, n; @@ -140,15 +137,14 @@ sigblock(mask) #if __DARWIN_UNIX03 int -sigpause(sig) - int sig; +sigpause(int sig) { sigset_t mask; if (__unix_conforming == 0) __unix_conforming = 1; #ifdef VARIANT_CANCELABLE - _pthread_testcancel(pthread_self(), 1); + pthread_testcancel(); #endif /* VARIANT_CANCELABLE */ if ((sig <= 0) || (sig >= NSIG)) { @@ -163,8 +159,7 @@ sigpause(sig) } #else int -sigpause(mask) - int mask; +sigpause(int mask) { return (sigsuspend((sigset_t *)&mask)); } @@ -172,8 +167,7 @@ sigpause(mask) #ifndef BUILDING_VARIANT int -sighold(sig) - int sig; +sighold(int sig) { sigset_t mask; @@ -187,8 +181,7 @@ sighold(sig) } int -sigrelse(sig) - int sig; +sigrelse(int sig) { sigset_t mask; @@ -203,8 +196,7 @@ sigrelse(sig) int -sigignore(sig) - int sig; +sigignore(int sig) { return (signal(sig, SIG_IGN) == SIG_ERR ? -1 : 0); } diff --git a/src/libc/darwin/CMakeLists.txt b/src/libc/darwin/CMakeLists.txt index f416da35b..61e420f5c 100644 --- a/src/libc/darwin/CMakeLists.txt +++ b/src/libc/darwin/CMakeLists.txt @@ -3,10 +3,10 @@ project(libc-darwin) cmake_minimum_required(VERSION 2.4.0) set(darwin_sources - #_dirhelper.c # Doesn't build, not needed now - kvm.c - libproc.c - MKGetTimeBaseInfo.c - proc_listpidspath.c) + atexit_receipt.c + compatibility_hacks.c + forceLibcToBuild.c + init_cpu_capabilities.c + kvm.c) add_library(libc-darwin OBJECT ${darwin_sources}) diff --git a/src/libc/darwin/OSAtomicLoadStoreEx.c b/src/libc/darwin/OSAtomicLoadStoreEx.c deleted file mode 100644 index 75d008bcd..000000000 --- a/src/libc/darwin/OSAtomicLoadStoreEx.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -// OSAtomic.h is included by files that include this C file. -/* #include "OSAtomic.h" */ - -int32_t OSAtomicAdd32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicAdd32); -int32_t OSAtomicAdd32(int32_t v, volatile int32_t *p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicAdd32); - int32_t r; - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(p, r); - r += v; - _osatomic_store_exclusive(p, r, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return r; -} - -int64_t OSAtomicAdd64(int64_t v, volatile int64_t *p) _OSATOMIC_VARIANT_B(OSAtomicAdd64); -int64_t OSAtomicAdd64(int64_t v, volatile int64_t *p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicAdd64); - - int64_t r; - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive64(p, r); - r += v; - _osatomic_store_exclusive64(p, r, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return r; -} - -int32_t OSAtomicOr32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicOr32); -int32_t OSAtomicOr32(int32_t v, volatile int32_t *p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicOr32); - int32_t r; - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(p, r); - r |= v; - _osatomic_store_exclusive(p, r, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return r; -} - -int32_t OSAtomicOr32Orig(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicOr32Orig); -int32_t OSAtomicOr32Orig(int32_t v, volatile int32_t *p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicOr32Orig); - int32_t r, n; - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(p, r); - n = r | v; - _osatomic_store_exclusive(p, n, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return r; -} - -int32_t OSAtomicAnd32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicAnd32); -int32_t OSAtomicAnd32(int32_t v, volatile int32_t *p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicAnd32); - int32_t r; - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(p, r); - r &= v; - _osatomic_store_exclusive(p, r, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return r; -} - -int32_t OSAtomicAnd32Orig(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicAnd32Orig); -int32_t OSAtomicAnd32Orig(int32_t v, volatile int32_t *p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicAnd32Orig); - int32_t r, n; - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(p, r); - n = r & v; - _osatomic_store_exclusive(p, n, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return r; -} - -int32_t OSAtomicXor32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicXor32); -int32_t OSAtomicXor32(int32_t v, volatile int32_t *p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicXor32); - int32_t r; - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(p, r); - r ^= v; - _osatomic_store_exclusive(p, r, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return r; -} - -int32_t OSAtomicXor32Orig(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicXor32Orig); -int32_t OSAtomicXor32Orig(int32_t v, volatile int32_t *p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicXor32Orig); - int32_t r, n; - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(p, r); - n = r ^ v; - _osatomic_store_exclusive(p, n, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return r; -} - -bool OSAtomicCompareAndSwap32(int32_t o, int32_t n, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicCompareAndSwap32); -bool OSAtomicCompareAndSwap32(int32_t o, int32_t n, volatile int32_t *p) -{ - _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapInt, OSAtomicCompareAndSwap32); - - _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwap32); - _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapInt); -#ifndef __LP64__ - _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapLong, OSAtomicCompareAndSwap32); - _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapPtr, OSAtomicCompareAndSwap32); - _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapLong); - _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapPtr); -#endif - - int32_t r; - uint32_t t; - - do { - _osatomic_load_exclusive(p, r); - if (r != o) return false; - _osatomic_store_barrier(); - _osatomic_store_exclusive(p, n, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return true; -} - -bool OSAtomicCompareAndSwap64(int64_t o, int64_t n, volatile int64_t *p) _OSATOMIC_VARIANT_B(OSAtomicCompareAndSwap64); -bool OSAtomicCompareAndSwap64(int64_t o, int64_t n, volatile int64_t *p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwap64); -#ifdef __LP64__ - _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapLong, OSAtomicCompareAndSwap64); - _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapPtr, OSAtomicCompareAndSwap64); - _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapLong); - _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapPtr); -#endif - - int64_t r; - uint32_t t; - - do { - _osatomic_load_exclusive64(p, r); - if (r != o) return false; - _osatomic_store_barrier(); - _osatomic_store_exclusive64(p, n, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return true; -} - -#if defined(_OSATOMIC_EXTRAS) - -void OSMemoryBarrier(void) _OSATOMIC_VARIANT(OSMemoryBarrier); -void OSMemoryBarrier(void) -{ - _osatomic_barrier(); -} - -typedef volatile struct { - void *item; - long unused; -} OSQueueHead; - -void OSAtomicEnqueue(OSQueueHead *l, void *n, size_t o) _OSATOMIC_VARIANT(OSAtomicEnqueue); -void OSAtomicEnqueue(OSQueueHead *l, void *n, size_t o) -{ - void ** r = (void **)((char *)n + o); - void * volatile * i = (void **)&(l->item); - void * q; - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(i, q); - *r = q; - _osatomic_store_exclusive(i, n, t); - } while (slowpath(t)); - _osatomic_barrier(); -} - -void* OSAtomicDequeue(OSQueueHead *l, size_t o) _OSATOMIC_VARIANT(OSAtomicDequeue); -void* OSAtomicDequeue(OSQueueHead *l, size_t o) -{ - void * h; - void ** r; - void * volatile * i = (void **)&(l->item); - uint32_t t; - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(i, r); - if (!r) return NULL; - h = *(void **)((char *)r + o); - _osatomic_store_exclusive(i, h, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return r; -} - -#endif - -bool OSAtomicTestAndSet(uint32_t n, volatile void * p) _OSATOMIC_VARIANT_B(OSAtomicTestAndSet); -bool OSAtomicTestAndSet(uint32_t n, volatile void * p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicTestAndSet); - uint32_t * ptr = (uint32_t *)((char *)p + (4 * (n / 32))); - uint32_t i, r, t; - - n = (0x80 >> (n & 7)) << (n & ~7 & 31); - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(ptr, r); - i = r | n; - if (i == r) break; - _osatomic_store_exclusive(ptr, i, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return ((r & n) != 0); -} - -bool OSAtomicTestAndClear(uint32_t n, volatile void * p) _OSATOMIC_VARIANT_B(OSAtomicTestAndClear); -bool OSAtomicTestAndClear(uint32_t n, volatile void * p) -{ - _OSATOMIC_ALIAS_NB(OSAtomicTestAndClear); - uint32_t * ptr = (uint32_t *)((char *)p + (4 * (n / 32))); - uint32_t i, r, t; - - n = (0x80 >> (n & 7)) << (n & ~7 & 31); - - _osatomic_store_barrier(); - do { - _osatomic_load_exclusive(ptr, r); - i = r & ~n; - if (i == r) break; - _osatomic_store_exclusive(ptr, i, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return ((r & n) != 0); -} - diff --git a/src/libc/darwin/SpinlocksLoadStoreEx.c b/src/libc/darwin/SpinlocksLoadStoreEx.c deleted file mode 100644 index a991ba0c4..000000000 --- a/src/libc/darwin/SpinlocksLoadStoreEx.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -// OSAtomic.h is included by files that include this C file. -/* #include "OSAtomic.h" */ - -typedef int32_t OSSpinLock; - -/* - * Bear with me, there's method to this madness. clang actually produces more optimal - * fastpath code if the lock code is split in half like this. - * - * Once we're spinning in userspace/kernel like this then we can be more lenient about - * how much effort is spent doing the spin. Where the lock is uncontended, this split - * arrangement produces a very good fastpath at the cost of some code duplication. - * - * Similarly, the gotos produce less wasteful code during spins then the equivalent code - * defined with loops. - */ - -#import - -static inline void _OSSpinLockSlow(volatile OSSpinLock * lock) _OSATOMIC_VARIANT(_OSSpinLockSlow); -static inline void _OSSpinLockSlow(volatile OSSpinLock * lock) -{ - int32_t r; - uint32_t t; - -_spin: ; -#if (defined(_ARM_ARCH_7) && !defined(_OSATOMIC_NO_BARRIERS)) - uint32_t tries = MP_SPIN_TRIES; - do { - if (*lock == 0) goto _try_store; - _osatomic_pause(); - } while (--tries); -#endif - - __asm__ ("mov r0, %[_a] ;" - "mov r1, %[_b] ;" - "mov r2, %[_c] ;" - "bl _syscall_thread_switch ;" - : : [_a] "i" (0), [_b] "i" (1), [_c] "i" (1) - : "r0", "r1", "r2", "r9", "r12", "lr" ); - -_try_store: - do { - _osatomic_load_exclusive(lock, r); - if (slowpath(r)) goto _spin; - _osatomic_store_exclusive(lock, 1, t); - } while (slowpath(t)); - - _osatomic_barrier(); -} - -void OSSpinLockLock(volatile OSSpinLock * lock) _OSATOMIC_VARIANT(OSSpinLockLock); -void OSSpinLockLock(volatile OSSpinLock * lock) -{ - _OSATOMIC_ALIAS(spin_lock, OSSpinLockLock); - _OSATOMIC_ALIAS(_spin_lock, OSSpinLockLock); - - int32_t r; - uint32_t t; - - do { - _osatomic_load_exclusive(lock, r); - if (slowpath(r)) return _OSSpinLockSlow(lock); - _osatomic_store_exclusive(lock, 1, t); - } while (slowpath(t)); - - _osatomic_barrier(); -} - -#ifndef _OSATOMIC_WFE - -bool OSSpinLockTry(OSSpinLock * lock) _OSATOMIC_VARIANT(OSSpinLockTry); -bool OSSpinLockTry(OSSpinLock * lock) -{ - _OSATOMIC_ALIAS(spin_lock_try, OSSpinLockTry); - _OSATOMIC_ALIAS(_spin_lock_try, OSSpinLockTry); - - int32_t r; - uint32_t t; - - do { - _osatomic_load_exclusive(lock, r); - if (slowpath(r)) return false; - _osatomic_store_exclusive(lock, 1, t); - } while (slowpath(t)); - - _osatomic_barrier(); - return (r == 0); -} - -void OSSpinLockUnlock(OSSpinLock * lock) _OSATOMIC_VARIANT(OSSpinLockUnlock); -void OSSpinLockUnlock(OSSpinLock * lock) -{ - _OSATOMIC_ALIAS(spin_unlock, OSSpinLockUnlock); - _OSATOMIC_ALIAS(_spin_unlock, OSSpinLockUnlock); - - _osatomic_barrier(); - *lock = 0; -} - -#endif // _OSATOMIC_WFE diff --git a/src/libc/darwin/_dirhelper.c b/src/libc/darwin/_dirhelper.c deleted file mode 100644 index 04749f660..000000000 --- a/src/libc/darwin/_dirhelper.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (c) 2006, 2007, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dirhelper.h" -#include "dirhelper_priv.h" - -#define BUCKETLEN 2 - -#define MUTEX_LOCK(x) if(__is_threaded) pthread_mutex_lock(x) -#define MUTEX_UNLOCK(x) if(__is_threaded) pthread_mutex_unlock(x) - -// Use 5 bits per character, to avoid uppercase and shell magic characters -#define ENCODEBITS 5 -#define ENCODEDSIZE ((8 * UUID_UID_SIZE + ENCODEBITS - 1) / ENCODEBITS) -#define MASK(x) ((1 << (x)) - 1) -#define UUID_UID_SIZE (sizeof(uuid_t) + sizeof(uid_t)) - -extern int __is_threaded; - -static const mode_t modes[] = { - 0755, /* user */ - 0700, /* temp */ - 0700, /* cache */ -}; - -static const char *subdirs[] = { - DIRHELPER_TOP_STR, - DIRHELPER_TEMP_STR, - DIRHELPER_CACHE_STR, -}; - -static pthread_once_t userdir_control = PTHREAD_ONCE_INIT; -static char *userdir = NULL; - -// lower case letter (minus vowels), plus numbers and _, making -// 32 characters. -static const char encode[] = "0123456789_bcdfghjklmnpqrstvwxyz"; - -static void -encode_uuid_uid(const uuid_t uuid, uid_t uid, char *str) -{ - unsigned char buf[UUID_UID_SIZE + 1]; - unsigned char *bp = buf; - int i; - unsigned int n; - - memcpy(bp, uuid, sizeof(uuid_t)); - uid = OSSwapHostToBigInt32(uid); - memcpy(bp + sizeof(uuid_t), &uid, sizeof(uid_t)); - bp[UUID_UID_SIZE] = 0; // this ensures the last encoded byte will have trailing zeros - for(i = 0; i < ENCODEDSIZE; i++) { - // 5 bits has 8 states - switch(i % 8) { - case 0: - n = *bp++; - *str++ = encode[n >> 3]; - break; - case 1: - n = ((n & MASK(3)) << 8) | *bp++; - *str++ = encode[n >> 6]; - break; - case 2: - n &= MASK(6); - *str++ = encode[n >> 1]; - break; - case 3: - n = ((n & MASK(1)) << 8) | *bp++; - *str++ = encode[n >> 4]; - break; - case 4: - n = ((n & MASK(4)) << 8) | *bp++; - *str++ = encode[n >> 7]; - break; - case 5: - n &= MASK(7); - *str++ = encode[n >> 2]; - break; - case 6: - n = ((n & MASK(2)) << 8) | *bp++; - *str++ = encode[n >> 5]; - break; - case 7: - *str++ = encode[n & MASK(5)]; - break; - } - } - *str = 0; -} - -char * -__user_local_dirname(uid_t uid, dirhelper_which_t which, char *path, size_t pathlen) -{ -#if TARGET_OS_IPHONE - char *tmpdir; -#else - uuid_t uuid; - char str[ENCODEDSIZE + 1]; -#endif - int res; - - if(which < 0 || which > DIRHELPER_USER_LOCAL_LAST) { - errno = EINVAL; - return NULL; - } - -#if TARGET_OS_IPHONE - /* We only support DIRHELPER_USER_LOCAL_TEMP on embedded. - * This interface really doesn't map from OSX to embedded, - * and clients of this interface will need to adapt when - * porting their applications to embedded. - * See: - */ - if(which == DIRHELPER_USER_LOCAL_TEMP) { - tmpdir = getenv("TMPDIR"); - if(!tmpdir) { - errno = EINVAL; - return NULL; - } - res = snprintf(path, pathlen, "%s", tmpdir); - } else { - errno = EINVAL; - return NULL; - } -#else - res = mbr_uid_to_uuid(uid, uuid); - if(res != 0) { - errno = res; - return NULL; - } - - // - // We partition the namespace so that we don't end up with too - // many users in a single directory. With 1024 buckets, we - // could scale to 1,000,000 users while keeping the average - // number of files in a single directory around 1000 - // - encode_uuid_uid(uuid, uid, str); - res = snprintf(path, pathlen, - "%s%.*s/%s/%s", - VAR_FOLDERS_PATH, BUCKETLEN, str, str + BUCKETLEN, subdirs[which]); -#endif - if(res >= pathlen) { - errno = EINVAL; - return NULL; /* buffer too small */ - } - return path; -} - -char * -__user_local_mkdir_p(char *path) -{ - char *next; - int res; - - next = path + strlen(VAR_FOLDERS_PATH); - while ((next = strchr(next, '/')) != NULL) { - *next = 0; // temporarily truncate - res = mkdir(path, 0755); - if (res != 0 && errno != EEXIST) - return NULL; - *next++ = '/'; // restore the slash and increment - } - return path; -} - -static void userdir_allocate(void) -{ - userdir = calloc(PATH_MAX, sizeof(char)); -} - -/* - * 9407258: Invalidate the dirhelper cache (userdir) of the child after fork. - * There is a rare case when launchd will have userdir set, and child process - * will sometimes inherit this cached value. - */ -__private_extern__ void -_dirhelper_fork_child(void) -{ - if(userdir) *userdir = 0; -} - -__private_extern__ char * -_dirhelper(dirhelper_which_t which, char *path, size_t pathlen) -{ - static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - struct stat sb; - - if(which < 0 || which > DIRHELPER_USER_LOCAL_LAST) { - errno = EINVAL; - return NULL; - } - - if (pthread_once(&userdir_control, userdir_allocate) - || !userdir) { - errno = ENOMEM; - return NULL; - } - - if(!*userdir) { - MUTEX_LOCK(&lock); - if (!*userdir) { - - if(__user_local_dirname(geteuid(), DIRHELPER_USER_LOCAL, userdir, PATH_MAX) == NULL) { - MUTEX_UNLOCK(&lock); - return NULL; - } - /* - * All dirhelper directories are now at the same level, so - * we need to remove the DIRHELPER_TOP_STR suffix to get the - * parent directory. - */ - userdir[strlen(userdir) - (sizeof(DIRHELPER_TOP_STR) - 1)] = 0; - /* - * check if userdir exists, and if not, either do the work - * ourself if we are root, or call - * __dirhelper_create_user_local to create it (we have to - * check again afterwards). - */ - if(stat(userdir, &sb) < 0) { - mach_port_t mp; - - if(errno != ENOENT) { /* some unknown error */ - *userdir = 0; - MUTEX_UNLOCK(&lock); - return NULL; - } - /* - * If we are root, lets do what dirhelper does for us. - */ - if (geteuid() == 0) { - if (__user_local_mkdir_p(userdir) == NULL) { - *userdir = 0; - MUTEX_UNLOCK(&lock); - return NULL; - } - } else { - if(bootstrap_look_up(bootstrap_port, DIRHELPER_BOOTSTRAP_NAME, &mp) != KERN_SUCCESS) { - errno = EPERM; - server_error: - mach_port_deallocate(mach_task_self(), mp); - MUTEX_UNLOCK(&lock); - return NULL; - } - if(__dirhelper_create_user_local(mp) != KERN_SUCCESS) { - errno = EPERM; - goto server_error; - } - /* double check that the directory really got created */ - if(stat(userdir, &sb) < 0) { - goto server_error; - } - mach_port_deallocate(mach_task_self(), mp); - } - } - } - MUTEX_UNLOCK(&lock); - } - - if(pathlen < strlen(userdir) + strlen(subdirs[which]) + 1) { - errno = EINVAL; - return NULL; /* buffer too small */ - } - strcpy(path, userdir); - strcat(path, subdirs[which]); - - /* - * create the subdir with the appropriate permissions if it doesn't already - * exist. On OS X, if we're under App Sandbox, we rely on the subdir having - * been already created for us. - */ -#if !TARGET_OS_IPHONE - if (!_xpc_runtime_is_app_sandboxed()) -#endif - if(mkdir(path, modes[which]) != 0 && errno != EEXIST) - return NULL; - -#if !TARGET_OS_IPHONE - char *userdir_suffix = NULL; - - if (_xpc_runtime_is_app_sandboxed()) { - /* - * if the subdir wasn't made for us, bail since we probably don't have - * permission to create it ourselves. - */ - if(stat(path, &sb) < 0) { - errno = EPERM; - return NULL; - } - - /* - * sandboxed applications get per-application directories named - * after the container - */ - userdir_suffix = getenv(XPC_ENV_SANDBOX_CONTAINER_ID); - if (!userdir_suffix) { - errno = EINVAL; - return NULL; - } - } else - userdir_suffix = getenv(DIRHELPER_ENV_USER_DIR_SUFFIX); - - if (userdir_suffix) { - /* - * suffix (usually container ID) doesn't end in a slash, so +2 is for slash and \0 - */ - if (pathlen < strlen(path) + strlen(userdir_suffix) + 2) { - errno = EINVAL; - return NULL; /* buffer too small */ - } - - strcat(path, userdir_suffix); - strcat(path, "/"); - - /* - * create suffix subdirectory with the appropriate permissions - * if it doesn't already exist. - */ - if (mkdir(path, modes[which]) != 0 && errno != EEXIST) - return NULL; - - /* - * update TMPDIR if necessary - */ - if (which == DIRHELPER_USER_LOCAL_TEMP) { - char *tmpdir = getenv("TMPDIR"); - if (!tmpdir || strncmp(tmpdir, path, strlen(path))) - setenv("TMPDIR", path, 1); - } - } -#endif - - return path; -} diff --git a/src/libc/darwin/atexit_receipt.c b/src/libc/darwin/atexit_receipt.c new file mode 100644 index 000000000..62bde8b86 --- /dev/null +++ b/src/libc/darwin/atexit_receipt.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + diff --git a/src/libc/darwin/compatibility_hacks.c b/src/libc/darwin/compatibility_hacks.c new file mode 100644 index 000000000..04a2dd853 --- /dev/null +++ b/src/libc/darwin/compatibility_hacks.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#if !TARGET_OS_IPHONE + +#define WEAK_SYMBOL_LD_CMD(sym, version) \ + __asm__(".section __TEXT,__const\n\t" \ + ".globl $ld$weak$os" #version "$_" #sym "\n\t" \ + "$ld$weak$os" #version "$_" #sym ":\n\t" \ + " .byte 0\n\t" \ + ".previous") + +#define ADDED_IN_10_12(sym) WEAK_SYMBOL_LD_CMD(sym, 10.11) + +ADDED_IN_10_12(getentropy); + +ADDED_IN_10_12(clock_getres); +ADDED_IN_10_12(clock_gettime); +ADDED_IN_10_12(clock_settime); + +ADDED_IN_10_12(basename_r); +ADDED_IN_10_12(dirname_r); + +ADDED_IN_10_12(mkostemp); +ADDED_IN_10_12(mkostemps); + +#endif /* TARGET_OS_IPHONE */ diff --git a/src/libc/darwin/dirhelper.defs b/src/libc/darwin/dirhelper.defs deleted file mode 100644 index ff428ed9c..000000000 --- a/src/libc/darwin/dirhelper.defs +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include - -subsystem dirhelper 47213; -serverprefix do_; - -routine __dirhelper_create_user_local( - server_port : mach_port_t; - ServerAuditToken remote_creds : audit_token_t); - -routine __dirhelper_idle_exit( - server_port : mach_port_t; - ServerAuditToken remote_creds : audit_token_t); diff --git a/src/libc/darwin/dirhelper_priv.h b/src/libc/darwin/dirhelper_priv.h deleted file mode 100644 index bbb7aec26..000000000 --- a/src/libc/darwin/dirhelper_priv.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2006, 2007, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _DIRHELPER_PRIV_H_ -#define _DIRHELPER_PRIV_H_ - -#include -#include - -#define VAR_FOLDERS_PATH "/var/folders/" - -#define DIRHELPER_BOOTSTRAP_NAME "com.apple.bsd.dirhelper" -#define DIRHELPER_CACHE_STR "C/" -#define DIRHELPER_TEMP_STR "T/" -#define DIRHELPER_TOP_STR "0/" -#define DIRHELPER_ENV_USER_DIR_SUFFIX "DIRHELPER_USER_DIR_SUFFIX" - -typedef enum { - DIRHELPER_USER_LOCAL = 0, - DIRHELPER_USER_LOCAL_TEMP, - DIRHELPER_USER_LOCAL_CACHE, - DIRHELPER_USER_LOCAL_LAST = DIRHELPER_USER_LOCAL_CACHE -} dirhelper_which_t; - -__BEGIN_DECLS -char *__user_local_dirname(uid_t uid, dirhelper_which_t which, char *path, - size_t pathlen); -char *__user_local_mkdir_p(char *path); -__END_DECLS - -#endif /* _DIRHELPER_PRIV_H_ */ diff --git a/src/libc/darwin/init_cpu_capabilities.c b/src/libc/darwin/init_cpu_capabilities.c new file mode 100644 index 000000000..62d1df2a8 --- /dev/null +++ b/src/libc/darwin/init_cpu_capabilities.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + +extern int _get_cpu_capabilities(void); + +int _cpu_capabilities = 0; +int _cpu_has_altivec = 0; // DEPRECATED: use _cpu_capabilities instead + +__private_extern__ void +_init_cpu_capabilities( void ) +{ +} diff --git a/src/libc/darwin/libc_private.h b/src/libc/darwin/libc_private.h new file mode 100644 index 000000000..3dc00ae26 --- /dev/null +++ b/src/libc/darwin/libc_private.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __LIBC_PRIVATE_H__ +#define __LIBC_PRIVATE_H__ + +#include +#include +#include + +__BEGIN_DECLS + +struct _libc_functions { + unsigned long version; + void (*atfork_prepare)(void); // version 1 + void (*atfork_parent)(void); // version 1 + void (*atfork_child)(void); // version 1 + char *(*dirhelper)(int, char *, size_t); // version 1 +}; + +struct ProgramVars; // forward reference + +__deprecated_msg("use _libc_initializer()") +extern void +__libc_init(const struct ProgramVars *vars, + void (*atfork_prepare)(void), + void (*atfork_parent)(void), + void (*atfork_child)(void), + const char *apple[]); + +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) +extern void +_libc_initializer(const struct _libc_functions *funcs, + const char *envp[], + const char *apple[], + const struct ProgramVars *vars); + +extern void +_libc_fork_child(void); + +extern int +_atexit_receipt(void); + +__IOS_AVAILABLE(9.0) __OSX_AVAILABLE(10.11) +extern void +abort_report_np(const char *, ...) __dead2 __printflike(1, 2); + +__END_DECLS + +#endif // __LIBC_PRIVATE_H__ diff --git a/src/libc/darwin/libproc.c b/src/libc/darwin/libproc.c deleted file mode 100644 index 9879aaafe..000000000 --- a/src/libc/darwin/libproc.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 2006, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#define CONFIG_EMBEDDED 1 -#include - -#include "libproc_internal.h" - -int __proc_info(int callnum, int pid, int flavor, uint64_t arg, void * buffer, int buffersize); -__private_extern__ int proc_setthreadname(void * buffer, int buffersize); -int __process_policy(int scope, int action, int policy, int policy_subtype, proc_policy_attribute_t * attrp, pid_t target_pid, uint64_t target_threadid); - - - -int -proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize) -{ - int retval; - - if ((type >= PROC_ALL_PIDS) || (type <= PROC_PPID_ONLY)) { - if ((retval = __proc_info(1, type, typeinfo,(uint64_t)0, buffer, buffersize)) == -1) - return(0); - } else { - errno = EINVAL; - retval = 0; - } - return(retval); -} - - -int -proc_listallpids(void * buffer, int buffersize) -{ - int numpids; - numpids = proc_listpids(PROC_ALL_PIDS, (uint32_t)0, buffer, buffersize); - - if (numpids == -1) - return(-1); - else - return(numpids/sizeof(int)); -} - -int -proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize) -{ - int numpids; - numpids = proc_listpids(PROC_PGRP_ONLY, (uint32_t)pgrpid, buffer, buffersize); - if (numpids == -1) - return(-1); - else - return(numpids/sizeof(int)); -} - -int -proc_listchildpids(pid_t ppid, void * buffer, int buffersize) -{ - int numpids; - numpids = proc_listpids(PROC_PPID_ONLY, (uint32_t)ppid, buffer, buffersize); - if (numpids == -1) - return(-1); - else - return(numpids/sizeof(int)); -} - - -int -proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize) -{ - int retval; - - if ((retval = __proc_info(2, pid, flavor, arg, buffer, buffersize)) == -1) - return(0); - - return(retval); -} - - -int -proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize) -{ - int retval; - - if ((retval = __proc_info(3, pid, flavor, (uint64_t)fd, buffer, buffersize)) == -1) - return(0); - - return (retval); -} - - -int -proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize) -{ - int retval; - - if ((retval = __proc_info(6, pid, flavor, (uint64_t)fileport, buffer, buffersize)) == -1) - return (0); - return (retval); -} - - -int -proc_name(int pid, void * buffer, uint32_t buffersize) -{ - int retval = 0, len; - struct proc_bsdinfo pbsd; - - - if (buffersize < sizeof(pbsd.pbi_name)) { - errno = ENOMEM; - return(0); - } - - retval = proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &pbsd, sizeof(struct proc_bsdinfo)); - if (retval != 0) { - if (pbsd.pbi_name[0]) { - bcopy(&pbsd.pbi_name, buffer, sizeof(pbsd.pbi_name)); - } else { - bcopy(&pbsd.pbi_comm, buffer, sizeof(pbsd.pbi_comm)); - } - len = strlen(buffer); - return(len); - } - return(0); -} - -int -proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize) -{ - int retval = 0, len; - struct proc_regionwithpathinfo reginfo; - - if (buffersize < MAXPATHLEN) { - errno = ENOMEM; - return(0); - } - - retval = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, (uint64_t)address, ®info, sizeof(struct proc_regionwithpathinfo)); - if (retval != -1) { - len = strlen(®info.prp_vip.vip_path[0]); - if (len != 0) { - if (len > MAXPATHLEN) - len = MAXPATHLEN; - bcopy(®info.prp_vip.vip_path[0], buffer, len); - return(len); - } - return(0); - } - return(0); - -} - -int -proc_kmsgbuf(void * buffer, uint32_t buffersize) -{ - int retval; - - if ((retval = __proc_info(4, 0, 0, (uint64_t)0, buffer, buffersize)) == -1) - return(0); - return (retval); -} - -int -proc_pidpath(int pid, void * buffer, uint32_t buffersize) -{ - int retval, len; - - if (buffersize < PROC_PIDPATHINFO_SIZE) { - errno = ENOMEM; - return(0); - } - if (buffersize > PROC_PIDPATHINFO_MAXSIZE) { - errno = EOVERFLOW; - return(0); - } - - retval = __proc_info(2, pid, PROC_PIDPATHINFO, (uint64_t)0, buffer, buffersize); - if (retval != -1) { - len = strlen(buffer); - return(len); - } - return (0); -} - - -int -proc_libversion(int *major, int * minor) -{ - - if (major != NULL) - *major = 1; - if (minor != NULL) - *minor = 1; - return(0); -} - -int -proc_setpcontrol(const int control) -{ - int retval ; - - if (control < PROC_SETPC_NONE || control > PROC_SETPC_TERMINATE) - return(EINVAL); - - if ((retval = __proc_info(5, getpid(), PROC_SELFSET_PCONTROL, (uint64_t)control, NULL, 0)) == -1) - return(errno); - - return(0); -} - - -__private_extern__ int -proc_setthreadname(void * buffer, int buffersize) -{ - int retval; - - retval = __proc_info(5, getpid(), PROC_SELFSET_THREADNAME, (uint64_t)0, buffer, buffersize); - - if (retval == -1) - return(errno); - else - return(0); -} - -int -proc_track_dirty(pid_t pid, uint32_t flags) -{ - if (__proc_info(8, pid, PROC_DIRTYCONTROL_TRACK, flags, NULL, 0) == -1) { - return errno; - } - - return 0; -} - -int -proc_set_dirty(pid_t pid, bool dirty) -{ - if (__proc_info(8, pid, PROC_DIRTYCONTROL_SET, dirty, NULL, 0) == -1) { - return errno; - } - - return 0; -} - -int -proc_get_dirty(pid_t pid, uint32_t *flags) -{ - int retval; - - if (!flags) { - return EINVAL; - } - - retval = __proc_info(8, pid, PROC_DIRTYCONTROL_GET, 0, NULL, 0); - if (retval == -1) { - return errno; - } - - *flags = retval; - - return 0; -} - -int -proc_terminate(pid_t pid, int *sig) -{ - int retval; - - if (!sig) { - return EINVAL; - } - - retval = __proc_info(7, pid, 0, 0, NULL, 0); - if (retval == -1) { - return errno; - } - - *sig = retval; - - return 0; -} - -#if TARGET_OS_EMBEDDED - -int -proc_setcpu_percentage(pid_t pid, int action, int percentage) -{ - proc_policy_cpuusage_attr_t attr; - - bzero(&attr, sizeof(proc_policy_cpuusage_attr_t)); - attr.ppattr_cpu_attr = action; - attr.ppattr_cpu_percentage = percentage; - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, &attr, pid, (uint64_t)0) != -1) - return(0); - else - return(errno); -} - -int -proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline) -{ - proc_policy_cpuusage_attr_t attr; - - bzero(&attr, sizeof(proc_policy_cpuusage_attr_t)); - attr.ppattr_cpu_attr = action; - attr.ppattr_cpu_attr_deadline = deadline; - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, &attr, pid, (uint64_t)0) != -1) - return(0); - else - return(errno); - -} - - -int -proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline) -{ - proc_policy_cpuusage_attr_t attr; - - bzero(&attr, sizeof(proc_policy_cpuusage_attr_t)); - attr.ppattr_cpu_attr = action; - attr.ppattr_cpu_percentage = percentage; - attr.ppattr_cpu_attr_deadline = deadline; - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, &attr, pid, (uint64_t)0) != -1) - return(0); - else - return(errno); -} - -int -proc_clear_cpulimits(pid_t pid) -{ - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_RESTORE, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, NULL, pid, (uint64_t)0) != -1) - return(0); - else - return(errno); - - -} - -int -proc_appstate(int pid, int * appstatep) -{ - int state; - - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_GET, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (int *)&state, pid, (uint64_t)0) != -1) { - if (appstatep != NULL) - *appstatep = state; - return(0); - } else - return(errno); - -} - - -int -proc_setappstate(int pid, int appstate) -{ - int state = appstate; - - switch (state) { - case PROC_APPSTATE_NONE: - case PROC_APPSTATE_ACTIVE: - case PROC_APPSTATE_INACTIVE: - case PROC_APPSTATE_BACKGROUND: - case PROC_APPSTATE_NONUI: - break; - default: - return(EINVAL); - } - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (int *)&state, pid, (uint64_t)0) != -1) - return(0); - else - return(errno); -} - -int -proc_devstatusnotify(int devicestatus) -{ - int state = devicestatus; - - switch (devicestatus) { - case PROC_DEVSTATUS_SHORTTERM: - case PROC_DEVSTATUS_LONGTERM: - break; - default: - return(EINVAL); - } - - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_DEVSTATUS, (int *)&state, getpid(), (uint64_t)0) != -1) { - return(0); - } else - return(errno); - -} - -int -proc_pidbind(int pid, uint64_t threadid, int bind) -{ - int state = bind; - pid_t passpid = pid; - - switch (bind) { - case PROC_PIDBIND_CLEAR: - passpid = getpid(); /* ignore pid on clear */ - break; - case PROC_PIDBIND_SET: - break; - default: - return(EINVAL); - } - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_PIDBIND, (int *)&state, passpid, threadid) != -1) - return(0); - else - return(errno); -} - -#else /* TARGET_OS_EMBEDDED */ - -int -proc_clear_vmpressure(pid_t pid) -{ - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_RESTORE, PROC_POLICY_RESOURCE_STARVATION, PROC_POLICY_RS_VIRTUALMEM, NULL, pid, (uint64_t)0) != -1) - return(0); - else - return(errno); -} - -/* set the current process as one who can resume suspended processes due to low virtual memory. Need to be root */ -int -proc_set_owner_vmpressure(void) -{ - int retval; - - if ((retval = __proc_info(5, getpid(), PROC_SELFSET_VMRSRCOWNER, (uint64_t)0, NULL, 0)) == -1) - return(errno); - - return(0); -} - -/* mark yourself to delay idle sleep on disk IO */ -int -proc_set_delayidlesleep(void) -{ - int retval; - - if ((retval = __proc_info(5, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)1, NULL, 0)) == -1) - return(errno); - - return(0); -} - -/* Reset yourself to delay idle sleep on disk IO, if already set */ -int -proc_clear_delayidlesleep(void) -{ - int retval; - - if ((retval = __proc_info(5, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)0, NULL, 0)) == -1) - return(errno); - - return(0); -} - -/* disable the launch time backgroudn policy and restore the process to default group */ -int -proc_disable_apptype(pid_t pid, int apptype) -{ - switch (apptype) { - case PROC_POLICY_OSX_APPTYPE_TAL: - case PROC_POLICY_OSX_APPTYPE_DASHCLIENT: - break; - default: - return(EINVAL); - - } - - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_DISABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1) - return(0); - else - return(errno); - -} - -/* re-enable the launch time background policy if it had been disabled. */ -int -proc_enable_apptype(pid_t pid, int apptype) -{ - switch (apptype) { - case PROC_POLICY_OSX_APPTYPE_TAL: - case PROC_POLICY_OSX_APPTYPE_DASHCLIENT: - break; - default: - return(EINVAL); - - } - - if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_ENABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1) - return(0); - else - return(errno); - -} - -#endif /* TARGET_OS_EMBEDDED */ - diff --git a/src/libc/darwin/libproc.h b/src/libc/darwin/libproc.h deleted file mode 100644 index cbc72d228..000000000 --- a/src/libc/darwin/libproc.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2006, 2007, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#ifndef _LIBPROC_H_ -#define _LIBPROC_H_ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -/* - * This header file contains private interfaces to obtain process information. - * These interfaces are subject to change in future releases. - */ - -/*! - @define PROC_LISTPIDSPATH_PATH_IS_VOLUME - @discussion This flag indicates that all processes that hold open - file references on the volume associated with the specified - path should be returned. - */ -#define PROC_LISTPIDSPATH_PATH_IS_VOLUME 1 - - -/*! - @define PROC_LISTPIDSPATH_EXCLUDE_EVTONLY - @discussion This flag indicates that file references that were opened - with the O_EVTONLY flag should be excluded from the matching - criteria. - */ -#define PROC_LISTPIDSPATH_EXCLUDE_EVTONLY 2 - -__BEGIN_DECLS - - -/*! - @function proc_listpidspath - @discussion A function which will search through the current - processes looking for open file references which match - a specified path or volume. - @param type types of processes to be searched (see proc_listpids) - @param typeinfo adjunct information for type - @param path file or volume path - @param pathflags flags to control which files should be considered - during the process search. - @param buffer a C array of int-sized values to be filled with - process identifiers that hold an open file reference - matching the specified path or volume. Pass NULL to - obtain the minimum buffer size needed to hold the - currently active processes. - @param buffersize the size (in bytes) of the provided buffer. - @result the number of bytes of data returned in the provided buffer; - -1 if an error was encountered; - */ -int proc_listpidspath(uint32_t type, - uint32_t typeinfo, - const char *path, - uint32_t pathflags, - void *buffer, - int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int proc_listallpids(void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); -int proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); -int proc_listchildpids(pid_t ppid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1); -int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -int proc_name(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int proc_kmsgbuf(void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int proc_pidpath(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int proc_libversion(int *major, int * minor) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -/* - * A process can use the following api to set its own process control - * state on resoure starvation. The argument can have one of the PROC_SETPC_XX values - */ -#define PROC_SETPC_NONE 0 -#define PROC_SETPC_THROTTLEMEM 1 -#define PROC_SETPC_SUSPEND 2 -#define PROC_SETPC_TERMINATE 3 - -int proc_setpcontrol(const int control) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); -int proc_setpcontrol(const int control); - -int proc_track_dirty(pid_t pid, uint32_t flags); -int proc_set_dirty(pid_t pid, bool dirty); -int proc_get_dirty(pid_t pid, uint32_t *flags); - -int proc_terminate(pid_t pid, int *sig); - -__END_DECLS - -#endif /*_LIBPROC_H_ */ diff --git a/src/libc/darwin/libproc_internal.h b/src/libc/darwin/libproc_internal.h deleted file mode 100644 index 6bf4accc4..000000000 --- a/src/libc/darwin/libproc_internal.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#ifndef _LIBPROC_INTERNALH_ -#define _LIBPROC_INTERNALH_ - -#include - -#include -#include - -__BEGIN_DECLS - -#if TARGET_OS_EMBEDDED - -#define PROC_SETCPU_ACTION_NONE 0 -#define PROC_SETCPU_ACTION_THROTTLE 1 -#define PROC_SETCPU_ACTION_SUSPEND 2 -#define PROC_SETCPU_ACTION_TERMINATE 3 -#define PROC_SETCPU_ACTION_NOTIFY 4 - -int proc_setcpu_percentage(pid_t pid, int action, int percentage) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0); -int proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0); -int proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0); -int proc_clear_cpulimits(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0); - -#define PROC_APPSTATE_NONE 0 -#define PROC_APPSTATE_ACTIVE 1 -#define PROC_APPSTATE_BACKGROUND 2 -#define PROC_APPSTATE_NONUI 3 -#define PROC_APPSTATE_INACTIVE 4 - -int proc_setappstate(int pid, int appstate); -int proc_appstate(int pid, int * appstatep); - -#define PROC_DEVSTATUS_SHORTTERM 1 -#define PROC_DEVSTATUS_LONGTERM 2 - -int proc_devstatusnotify(int devicestatus); - -#define PROC_PIDBIND_CLEAR 0 -#define PROC_PIDBIND_SET 1 -int proc_pidbind(int pid, uint64_t threadid, int bind); - - -#else /* TARGET_OS_EMBEDDED */ - -/* resume the process suspend due to low VM resource */ -int proc_clear_vmpressure(pid_t pid); -/* set self as the one who is going to resume suspended processes due to low VM. Need to be root */ -int proc_set_owner_vmpressure(void); - -/* mark yourself to delay idle sleep on disk IO */ -int proc_set_delayidlesleep(void); -/* Reset yourself to delay idle sleep on disk IO, if already set */ -int proc_clear_delayidlesleep(void); - - -/* sub policies for PROC_POLICY_APPTYPE */ -#define PROC_POLICY_OSX_APPTYPE_NONE 0 -#define PROC_POLICY_OSX_APPTYPE_TAL 1 /* TAL based launched */ -#define PROC_POLICY_OSX_APPTYPE_WIDGET 2 /* for dashboard client */ -#define PROC_POLICY_OSX_APPTYPE_DASHCLIENT 2 /* rename to move away from widget */ - -/* - * Resumes the backgrounded TAL or dashboard client. Only priv users can disable TAL apps. - * Valid apptype are PROC_POLICY_OSX_APPTYPE_DASHCLIENT and PROC_POLICY_OSX_APPTYPE_TAL. - * Returns 0 on success otherwise appropriate error code. - */ -int proc_disable_apptype(pid_t pid, int apptype); -int proc_enable_apptype(pid_t pid, int apptype); - -#endif /* TARGET_OS_EMBEDDED */ - -__END_DECLS - -#endif /* _LIBPROC_INTERNALH_ */ - diff --git a/src/libc/darwin/proc_listpidspath.c b/src/libc/darwin/proc_listpidspath.c deleted file mode 100644 index 2ee883fb0..000000000 --- a/src/libc/darwin/proc_listpidspath.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * Copyright (c) 2007, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -typedef struct { - // process IDs - int *pids; - int pids_count; - size_t pids_size; - - // threads - uint64_t *threads; - int thr_count; - size_t thr_size; - - // open file descriptors - struct proc_fdinfo *fds; - int fds_count; - size_t fds_size; - - // file/volume of interest - struct stat match_stat; - - // flags - uint32_t flags; - -} fdOpenInfo, *fdOpenInfoRef; - - -/* - * check_init - */ -static fdOpenInfoRef -check_init(const char *path, uint32_t flags) -{ - fdOpenInfoRef info; - int status; - - info = malloc(sizeof(*info)); - if (!info) - return NULL; - - info->pids = NULL; - info->pids_count = 0; - info->pids_size = 0; - - info->threads = NULL; - info->thr_count = 0; - info->thr_size = 0; - - info->fds = NULL; - info->fds_count = 0; - info->fds_size = 0; - - status = stat(path, &info->match_stat); - if (status == -1) { - goto fail; - } - - info->flags = flags; - - return info; - - fail : - - free(info); - return NULL; -} - - -/* - * check_free - */ -static void -check_free(fdOpenInfoRef info) -{ - if (info->pids != NULL) { - free(info->pids); - } - - if (info->threads != NULL) { - free(info->threads); - } - - if (info->fds != NULL) { - free(info->fds); - } - - free(info); - - return; -} - - -/* - * check_file - * check if a process vnode is of interest - * - * in : vnode stat(2) - * out : -1 if error - * 0 if no match - * 1 if match - */ -static int -check_file(fdOpenInfoRef info, struct vinfo_stat *sb) -{ - if (sb->vst_dev == 0) { - // if no info - return 0; - } - - if (sb->vst_dev != info->match_stat.st_dev) { - // if not the requested filesystem - return 0; - } - - if (!(info->flags & PROC_LISTPIDSPATH_PATH_IS_VOLUME) && - (sb->vst_ino != info->match_stat.st_ino)) { - // if not the requested file - return 0; - } - - return 1; -} - - -/* - * check_process_vnodes - * check [process] current working directory - * check [process] root directory - * - * in : pid - * out : -1 if error - * 0 if no match - * 1 if match - */ -static int -check_process_vnodes(fdOpenInfoRef info, int pid) -{ - int buf_used; - int status; - struct proc_vnodepathinfo vpi; - - buf_used = proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)); - if (buf_used <= 0) { - if (errno == ESRCH) { - // if the process is gone - return 0; - } - return -1; - } else if (buf_used < sizeof(vpi)) { - // if we didn't get enough information - return -1; - } - - // processing current working directory - status = check_file(info, &vpi.pvi_cdir.vip_vi.vi_stat); - if (status != 0) { - // if error or match - return status; - } - - // processing root directory - status = check_file(info, &vpi.pvi_rdir.vip_vi.vi_stat); - if (status != 0) { - // if error or match - return status; - } - - return 0; -} - - -/* - * check_process_text - * check [process] text (memory) - * - * in : pid - * out : -1 if error - * 0 if no match - * 1 if match - */ -static int -check_process_text(fdOpenInfoRef info, int pid) -{ - uint64_t a = 0; - int status; - - while (1) { // for all memory regions - int buf_used; - struct proc_regionwithpathinfo rwpi; - - // processing next address - buf_used = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, a, &rwpi, sizeof(rwpi)); - if (buf_used <= 0) { - if ((errno == ESRCH) || (errno == EINVAL)) { - // if no more text information is available for this process. - break; - } - return -1; - } else if (buf_used < sizeof(rwpi)) { - // if we didn't get enough information - return -1; - } - - status = check_file(info, &rwpi.prp_vip.vip_vi.vi_stat); - if (status != 0) { - // if error or match - return status; - } - - a = rwpi.prp_prinfo.pri_address + rwpi.prp_prinfo.pri_size; - } - - return 0; -} - - -/* - * check_process_fds - * check [process] open file descriptors - * - * in : pid - * out : -1 if error - * 0 if no match - * 1 if match - */ -static int -check_process_fds(fdOpenInfoRef info, int pid) -{ - int buf_used; - int i; - int status; - - // get list of open file descriptors - buf_used = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); - if (buf_used <= 0) { - return -1; - } - - while (1) { - if (buf_used > info->fds_size) { - // if we need to allocate [more] space - while (buf_used > info->fds_size) { - info->fds_size += (sizeof(struct proc_fdinfo) * 32); - } - - if (info->fds == NULL) { - info->fds = malloc(info->fds_size); - } else { - info->fds = reallocf(info->fds, info->fds_size); - } - if (info->fds == NULL) { - return -1; - } - } - - buf_used = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info->fds, info->fds_size); - if (buf_used <= 0) { - return -1; - } - - if ((buf_used + sizeof(struct proc_fdinfo)) >= info->fds_size) { - // if not enough room in the buffer for an extra fd - buf_used = info->fds_size + sizeof(struct proc_fdinfo); - continue; - } - - info->fds_count = buf_used / sizeof(struct proc_fdinfo); - break; - } - - // iterate through each file descriptor - for (i = 0; i < info->fds_count; i++) { - struct proc_fdinfo *fdp; - - fdp = &info->fds[i]; - switch (fdp->proc_fdtype) { - case PROX_FDTYPE_VNODE : { - int buf_used; - struct vnode_fdinfo vi; - - buf_used = proc_pidfdinfo(pid, fdp->proc_fd, PROC_PIDFDVNODEINFO, &vi, sizeof(vi)); - if (buf_used <= 0) { - if (errno == ENOENT) { - /* - * The file descriptor's vnode may have been revoked. This is a - * bit of a hack, since an ENOENT error might not always mean the - * descriptor's vnode has been revoked. As the libproc API - * matures, this code may need to be revisited. - */ - continue; - } - return -1; - } else if (buf_used < sizeof(vi)) { - // if we didn't get enough information - return -1; - } - - if ((info->flags & PROC_LISTPIDSPATH_EXCLUDE_EVTONLY) && - (vi.pfi.fi_openflags & O_EVTONLY)) { - // if this file should be excluded - continue; - } - - status = check_file(info, &vi.pvi.vi_stat); - if (status != 0) { - // if error or match - return status; - } - break; - } - default : - break; - } - } - - return 0; -} - - -/* - * check_process_threads - * check [process] thread working directories - * - * in : pid - * out : -1 if error - * 0 if no match - * 1 if match - */ -static int -check_process_threads(fdOpenInfoRef info, int pid) -{ - int buf_used; - int status; - struct proc_taskallinfo tai; - - buf_used = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, &tai, sizeof(tai)); - if (buf_used <= 0) { - if (errno == ESRCH) { - // if the process is gone - return 0; - } - return -1; - } else if (buf_used < sizeof(tai)) { - // if we didn't get enough information - return -1; - } - - // check thread info - if (tai.pbsd.pbi_flags & PROC_FLAG_THCWD) { - int i; - - // get list of threads - buf_used = tai.ptinfo.pti_threadnum * sizeof(uint64_t); - - while (1) { - if (buf_used > info->thr_size) { - // if we need to allocate [more] space - while (buf_used > info->thr_size) { - info->thr_size += (sizeof(uint64_t) * 32); - } - - if (info->threads == NULL) { - info->threads = malloc(info->thr_size); - } else { - info->threads = reallocf(info->threads, info->thr_size); - } - if (info->threads == NULL) { - return -1; - } - } - - buf_used = proc_pidinfo(pid, PROC_PIDLISTTHREADS, 0, info->threads, info->thr_size); - if (buf_used <= 0) { - return -1; - } - - if ((buf_used + sizeof(uint64_t)) >= info->thr_size) { - // if not enough room in the buffer for an extra thread - buf_used = info->thr_size + sizeof(uint64_t); - continue; - } - - info->thr_count = buf_used / sizeof(uint64_t); - break; - } - - // iterate through each thread - for (i = 0; i < info->thr_count; i++) { - uint64_t thr = info->threads[i]; - struct proc_threadwithpathinfo tpi; - - buf_used = proc_pidinfo(pid, PROC_PIDTHREADPATHINFO, thr, &tpi, sizeof(tpi)); - if (buf_used <= 0) { - if ((errno == ESRCH) || (errno == EINVAL)) { - // if the process or thread is gone - continue; - } - } else if (buf_used < sizeof(tai)) { - // if we didn't get enough information - return -1; - } - - status = check_file(info, &tpi.pvip.vip_vi.vi_stat); - if (status != 0) { - // if error or match - return status; - } - } - } - - return 0; -} - - -/* - * check_process - * check [process] current working and root directories - * check [process] text (memory) - * check [process] open file descriptors - * - * in : pid - * out : -1 if error - * 0 if no match - * 1 if match - */ -static int -check_process(fdOpenInfoRef info, int pid) -{ - int status; - - // check root and current working directory - status = check_process_vnodes(info, pid); - if (status != 0) { - // if error or match - return status; - } - - // check process text (memory) - status = check_process_text(info, pid); - if (status != 0) { - // if error or match - return status; - } - - // check open file descriptors - status = check_process_fds(info, pid); - if (status != 0) { - // if error or match - return status; - } - - // check per-thread working directories - status = check_process_threads(info, pid); - if (status != 0) { - // if error or match - return status; - } - - return 0; -} - - -/* - * proc_listpidspath - * - * in : type - * : typeinfo - * : path - * : pathflags - * : buffer - * : buffersize - * out : buffer filled with process IDs that have open file - * references that match the specified path or volume; - * return value is the bytes of the returned buffer - * that contains valid information. - */ -int -proc_listpidspath(uint32_t type, - uint32_t typeinfo, - const char *path, - uint32_t pathflags, - void *buffer, - int buffersize) -{ - int buf_used; - int *buf_next = (int *)buffer; - int i; - fdOpenInfoRef info; - int status = -1; - - if (buffer == NULL) { - // if this is a sizing request - return proc_listpids(type, typeinfo, NULL, 0); - } - - buffersize -= (buffersize % sizeof(int)); // make whole number of ints - if (buffersize < sizeof(int)) { - // if we can't even return a single PID - errno = ENOMEM; - return -1; - } - - // init - info = check_init(path, pathflags); - if (info == NULL) { - return -1; - } - - // get list of processes - buf_used = proc_listpids(type, typeinfo, NULL, 0); - if (buf_used <= 0) { - goto done; - } - - while (1) { - if (buf_used > info->pids_size) { - // if we need to allocate [more] space - while (buf_used > info->pids_size) { - info->pids_size += (sizeof(int) * 32); - } - - if (info->pids == NULL) { - info->pids = malloc(info->pids_size); - } else { - info->pids = reallocf(info->pids, info->pids_size); - } - if (info->pids == NULL) { - goto done; - } - } - - buf_used = proc_listpids(type, typeinfo, info->pids, info->pids_size); - if (buf_used <= 0) { - goto done; - } - - if ((buf_used + sizeof(int)) >= info->pids_size) { - // if not enough room in the buffer for an extra pid - buf_used = info->pids_size + sizeof(int); - continue; - } - - info->pids_count = buf_used / sizeof(int); - break; - } - - // iterate through each process - buf_used = 0; - for (i = info->pids_count - 1; i >= 0; i--) { - int pid; - int status; - - pid = info->pids[i]; - if (pid == 0) { - continue; - } - - status = check_process(info, pid); - if (status != 1) { - // if not a match - continue; - } - - *buf_next++ = pid; - buf_used += sizeof(int); - - if (buf_used >= buffersize) { - // if we have filled the buffer - break; - } - } - - status = buf_used; - - done : - - // cleanup - check_free(info); - - return status; -} diff --git a/src/libc/db/btree/FreeBSD/bt_seq.c b/src/libc/db/btree/FreeBSD/bt_seq.c index b0b8b04ed..1521ca21a 100644 --- a/src/libc/db/btree/FreeBSD/bt_seq.c +++ b/src/libc/db/btree/FreeBSD/bt_seq.c @@ -342,7 +342,7 @@ __bt_first(BTREE *t, const DBT *key, EPG *erval, int *exactp) * page) and return it. */ if ((ep = __bt_search(t, key, exactp)) == NULL) - return (0); + return (RET_SPECIAL); if (*exactp) { if (F_ISSET(t, B_NODUPS)) { *erval = *ep; diff --git a/src/libc/db/hash/FreeBSD/ndbm.c b/src/libc/db/hash/FreeBSD/ndbm.c index c589af811..e89d5d283 100644 --- a/src/libc/db/hash/FreeBSD/ndbm.c +++ b/src/libc/db/hash/FreeBSD/ndbm.c @@ -59,10 +59,7 @@ typedef DB DBM; * NULL on failure */ extern DBM * -dbm_open(file, flags, mode) - const char *file; - int flags; - mode_t mode; +dbm_open(const char *file, int flags, mode_t mode) { HASHINFO info; char path[MAXPATHLEN]; diff --git a/src/libc/db/mpool/FreeBSD/mpool.c b/src/libc/db/mpool/FreeBSD/mpool.c index 36fb30bb5..56e6a308f 100644 --- a/src/libc/db/mpool/FreeBSD/mpool.c +++ b/src/libc/db/mpool/FreeBSD/mpool.c @@ -281,7 +281,7 @@ mpool_sync(MPOOL *mp) /* Walk the lru chain, flushing any dirty pages to disk. */ TAILQ_FOREACH(bp, &mp->lqh, q) { - if (bp->flags & MPOOL_DIRTY) + if (bp->flags & MPOOL_DIRTY) { if (mpool_write(mp, bp) == RET_ERROR) { return (RET_ERROR); } else { @@ -289,6 +289,7 @@ mpool_sync(MPOOL *mp) if (mp->pgin != NULL) (mp->pgin)(mp->pgcookie, bp->pgno, bp->page); } + } } /* Sync the file descriptor. */ diff --git a/src/libc/derived/i386/libc-features.h b/src/libc/derived/i386/libc-features.h new file mode 100644 index 000000000..16da94569 --- /dev/null +++ b/src/libc/derived/i386/libc-features.h @@ -0,0 +1,29 @@ +#ifndef _LIBC_FEATURES_H_ +#define _LIBC_FEATURES_H_ + +#if !defined(__i386__) +#error Mismatched libc-features.h architecture +#endif + +#define UNIFDEF_LEGACY_RUNE_APIS 1 +#define LEGACY_CRT1_ENVIRON 1 +#define UNIFDEF_LEGACY_UTMP_APIS 1 +/* #undef UNIFDEF_MOVE_LOCALTIME */ +/* #undef UNIFDEF_TZDIR_SYMLINK */ +#if __DARWIN_ONLY_VERS_1050 +# error Feature mismatch: __DARWIN_ONLY_VERS_1050 == 1 +#endif /* __DARWIN_ONLY_VERS_1050 */ +#if __DARWIN_ONLY_UNIX_CONFORMANCE +# error Feature mismatch: __DARWIN_ONLY_UNIX_CONFORMANCE == 1 +#endif /* __DARWIN_ONLY_UNIX_CONFORMANCE */ +#if __DARWIN_ONLY_64_BIT_INO_T +# error Feature mismatch: __DARWIN_ONLY_64_BIT_INO_T == 1 +#endif /* __DARWIN_ONLY_64_BIT_INO_T */ +#define __APPLE_PR3417676_HACK__ 1 +#define PLOCKSTAT 1 +#define NOTIFY_TZ 1 +/* #undef LIBC_NO_LIBCRASHREPORTERCLIENT */ +/* #undef FEATURE_SMALL_STDIOBUF */ +#define XPRINTF_PERF 1 +/* #undef FEATURE_SIGNAL_RESTRICTION */ +#endif // _LIBC_FEATURES_H_ diff --git a/src/libc/derived/libc-features.h b/src/libc/derived/libc-features.h new file mode 100644 index 000000000..3ce7ee1a4 --- /dev/null +++ b/src/libc/derived/libc-features.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "i386/libc-features.h" +#elif defined (__x86_64__) +#include "x86_64/libc-features.h" +#endif diff --git a/src/libc/derived/x86_64/libc-features.h b/src/libc/derived/x86_64/libc-features.h new file mode 100644 index 000000000..5a4135c53 --- /dev/null +++ b/src/libc/derived/x86_64/libc-features.h @@ -0,0 +1,29 @@ +#ifndef _LIBC_FEATURES_H_ +#define _LIBC_FEATURES_H_ + +#if !defined(__x86_64__) +#error Mismatched libc-features.h architecture +#endif + +#define UNIFDEF_LEGACY_RUNE_APIS 1 +#define LEGACY_CRT1_ENVIRON 1 +#define UNIFDEF_LEGACY_UTMP_APIS 1 +/* #undef UNIFDEF_MOVE_LOCALTIME */ +/* #undef UNIFDEF_TZDIR_SYMLINK */ +#if __DARWIN_ONLY_VERS_1050 +# error Feature mismatch: __DARWIN_ONLY_VERS_1050 == 1 +#endif /* __DARWIN_ONLY_VERS_1050 */ +#if !__DARWIN_ONLY_UNIX_CONFORMANCE +# error Feature mismatch: __DARWIN_ONLY_UNIX_CONFORMANCE == 0 +#endif /* !__DARWIN_ONLY_UNIX_CONFORMANCE */ +#if __DARWIN_ONLY_64_BIT_INO_T +# error Feature mismatch: __DARWIN_ONLY_64_BIT_INO_T == 1 +#endif /* __DARWIN_ONLY_64_BIT_INO_T */ +#define __APPLE_PR3417676_HACK__ 1 +#define PLOCKSTAT 1 +#define NOTIFY_TZ 1 +/* #undef LIBC_NO_LIBCRASHREPORTERCLIENT */ +/* #undef FEATURE_SMALL_STDIOBUF */ +#define XPRINTF_PERF 1 +/* #undef FEATURE_SIGNAL_RESTRICTION */ +#endif // _LIBC_FEATURES_H_ diff --git a/src/libc/emulated/brk.c b/src/libc/emulated/brk.c index 3d2044602..3cf691819 100644 --- a/src/libc/emulated/brk.c +++ b/src/libc/emulated/brk.c @@ -41,6 +41,7 @@ #include /* for vm_allocate, vm_offset_t */ #include #include +#include static int sbrk_needs_init = TRUE; static vm_size_t sbrk_region_size = 4*1024*1024; /* Well, what should it be? */ @@ -74,7 +75,7 @@ void *sbrk(int size) return((void *)(sbrk_curbrk - size)); } -void *brk(void *x) +void *brk(const void *x) { errno = ENOMEM; return((void *)-1); diff --git a/src/libc/emulated/lchmod.c b/src/libc/emulated/lchmod.c index 50fda9981..836f65e17 100644 --- a/src/libc/emulated/lchmod.c +++ b/src/libc/emulated/lchmod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005, 2014 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,6 +21,8 @@ * @APPLE_LICENSE_HEADER_END@ */ +// NOTE: This system call emulation should move to libsystem_kernel.dylib + #include #include #include @@ -30,14 +32,9 @@ int lchmod(const char *path, mode_t mode) { - struct stat s; struct attrlist a; int m; - if(lstat(path, &s) < 0) - return -1; - if((s.st_mode & S_IFMT) != S_IFLNK) - return chmod(path, mode); bzero(&a, sizeof(a)); a.bitmapcount = ATTR_BIT_MAP_COUNT; a.commonattr = ATTR_CMN_ACCESSMASK; diff --git a/src/libc/fbsdcompat/_fbsd_compat_.h b/src/libc/fbsdcompat/_fbsd_compat_.h index cd2875ef5..f134d5cfd 100644 --- a/src/libc/fbsdcompat/_fbsd_compat_.h +++ b/src/libc/fbsdcompat/_fbsd_compat_.h @@ -35,6 +35,17 @@ #define __ct_rune_t ct_rune_t #define __va_list __darwin_va_list +#define __isthreaded 1 + +#ifdef _FLOCK_DEBUG +#define _FLOCKFILE(x) _flockfile_debug(x, __FILE__, __LINE__) +#else +#define _FLOCKFILE(x) _flockfile(x) +#endif + +#define FLOCKFILE(fp) _FLOCKFILE(fp) +#define FUNLOCKFILE(fp) _funlockfile(fp) + /* * Do the opposite of FreeBSD namespace.h; that is, map the "hidden" names * back to the real names. @@ -111,6 +122,7 @@ #define _recvfrom recvfrom #define _recvmsg recvmsg #define _select select +#define _pselect pselect #define _sendmsg sendmsg #define _sendto sendto #define _setsockopt setsockopt @@ -148,7 +160,6 @@ #define __makecontext makecontext #define __makecontext makecontext #define __pause pause -#define __pselect pselect #define __raise raise #define __signalcontext signalcontext #define __sleep sleep diff --git a/src/libc/fbsdcompat/libc_private.h b/src/libc/fbsdcompat/libc_private.h deleted file mode 100644 index cf4cf059f..000000000 --- a/src/libc/fbsdcompat/libc_private.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1998 John Birrell . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by John Birrell. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/lib/libc/include/libc_private.h,v 1.8 2002/11/13 21:55:22 deischen Exp $ - * - * Private definitions for libc, libc_r and libpthread. - * - */ - -#ifndef _LIBC_PRIVATE_H_ -#define _LIBC_PRIVATE_H_ - -#ifdef __APPLE__ -#define __isthreaded __is_threaded -#endif // __APPLE__ - -/* - * This global flag is non-zero when a process has created one - * or more threads. It is used to avoid calling locking functions - * when they are not required. - */ -extern int __isthreaded; - -/* - * File lock contention is difficult to diagnose without knowing - * where locks were set. Allow a debug library to be built which - * records the source file and line number of each lock call. - */ -#ifdef _FLOCK_DEBUG -#define _FLOCKFILE(x) _flockfile_debug(x, __FILE__, __LINE__) -#else -#define _FLOCKFILE(x) _flockfile(x) -#endif - -/* - * Macros for locking and unlocking FILEs. These test if the - * process is threaded to avoid locking when not required. - */ -#define FLOCKFILE(fp) if (__isthreaded) _FLOCKFILE(fp) -#define FUNLOCKFILE(fp) if (__isthreaded) _funlockfile(fp) - -/* - * Indexes into the pthread jump table. - * - * Warning! If you change this type, you must also change the threads - * libraries that reference it (libc_r, libpthread). - */ -typedef enum { - PJT_COND_BROADCAST, - PJT_COND_DESTROY, - PJT_COND_INIT, - PJT_COND_SIGNAL, - PJT_COND_WAIT, - PJT_GETSPECIFIC, - PJT_KEY_CREATE, - PJT_KEY_DELETE, - PJT_MAIN_NP, - PJT_MUTEX_DESTROY, - PJT_MUTEX_INIT, - PJT_MUTEX_LOCK, - PJT_MUTEX_TRYLOCK, - PJT_MUTEX_UNLOCK, - PJT_MUTEXATTR_DESTROY, - PJT_MUTEXATTR_INIT, - PJT_MUTEXATTR_SETTYPE, - PJT_ONCE, - PJT_RWLOCK_DESTROY, - PJT_RWLOCK_INIT, - PJT_RWLOCK_RDLOCK, - PJT_RWLOCK_TRYRDLOCK, - PJT_RWLOCK_TRYWRLOCK, - PJT_RWLOCK_UNLOCK, - PJT_RWLOCK_WRLOCK, - PJT_SELF, - PJT_SETSPECIFIC, - PJT_SIGMASK, - PJT_MAX -} pjt_index_t; - -typedef int (*pthread_func_t)(void); -typedef pthread_func_t pthread_func_entry_t[2]; - -extern pthread_func_entry_t __thr_jtable[]; - -#endif /* _LIBC_PRIVATE_H_ */ diff --git a/src/libc/fbsdcompat/sys/cdefs.h b/src/libc/fbsdcompat/sys/cdefs.h index a56be2c53..aea060617 100644 --- a/src/libc/fbsdcompat/sys/cdefs.h +++ b/src/libc/fbsdcompat/sys/cdefs.h @@ -66,8 +66,6 @@ * We define this here since , , and * require it. */ -#define __offsetof(type, field) ((size_t)(&((type *)0)->field)) - #define __strong_reference(sym,aliassym) \ extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym))); #define __weak_reference(sym,alias) diff --git a/src/libc/gdtoa/CMakeLists.txt b/src/libc/gdtoa/CMakeLists.txt index 3bce006dd..c0d4742b2 100644 --- a/src/libc/gdtoa/CMakeLists.txt +++ b/src/libc/gdtoa/CMakeLists.txt @@ -2,8 +2,9 @@ project(libc-gdtoa) cmake_minimum_required(VERSION 2.4.0) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h") include_directories("${CMAKE_CURRENT_SOURCE_DIR}") +include_directories("${CMAKE_SOURCE_DIR}/src/external/libpthread/pthread") # set(gdtoa_sources _ldbl_util.c) # doesn't build diff --git a/src/libc/gdtoa/FreeBSD/gdtoa-gethex.c b/src/libc/gdtoa/FreeBSD/gdtoa-gethex.c index 855726a53..fd0775c2a 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoa-gethex.c +++ b/src/libc/gdtoa/FreeBSD/gdtoa-gethex.c @@ -42,9 +42,9 @@ THIS SOFTWARE. int #ifdef KR_headers gethex(sp, fpi, exp, bp, sign, loc) - CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign; locale_t loc; + CONST char **sp; CONST FPI *fpi; Long *exp; Bigint **bp; int sign; locale_t loc; #else -gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t loc) +gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t loc) #endif { Bigint *b; diff --git a/src/libc/gdtoa/FreeBSD/gdtoa-hd_init.c b/src/libc/gdtoa/FreeBSD/gdtoa-hd_init.c index fa6e18dee..96ac73411 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoa-hd_init.c +++ b/src/libc/gdtoa/FreeBSD/gdtoa-hd_init.c @@ -31,8 +31,26 @@ THIS SOFTWARE. #include "gdtoaimp.h" - unsigned char hexdig[256]; +CONST unsigned char hexdig[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0, 0, 0, 0, 0, 0, + 0, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +#ifndef __APPLE__ static void #ifdef KR_headers htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; @@ -53,3 +71,6 @@ hexdig_init_D2A(Void) htinit(hexdig, USC "abcdef", 0x10 + 10); htinit(hexdig, USC "ABCDEF", 0x10 + 10); } +#else +void hexdig_init_D2A(void) {} +#endif diff --git a/src/libc/gdtoa/FreeBSD/gdtoa-hexnan.c b/src/libc/gdtoa/FreeBSD/gdtoa-hexnan.c index bc1b4bd9c..0c485b450 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoa-hexnan.c +++ b/src/libc/gdtoa/FreeBSD/gdtoa-hexnan.c @@ -55,9 +55,9 @@ L_shift(ULong *x, ULong *x1, int i) int #ifdef KR_headers hexnan(sp, fpi, x0) - CONST char **sp; FPI *fpi; ULong *x0; + CONST char **sp; CONST FPI *fpi; ULong *x0; #else -hexnan( CONST char **sp, FPI *fpi, ULong *x0) +hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0) #endif { #ifdef __APPLE__ diff --git a/src/libc/gdtoa/FreeBSD/gdtoa-strtod.c b/src/libc/gdtoa/FreeBSD/gdtoa-strtod.c index 3186f2541..265a56448 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoa-strtod.c +++ b/src/libc/gdtoa/FreeBSD/gdtoa-strtod.c @@ -145,7 +145,7 @@ strtod_l if (*s == '0') { #ifndef NO_HEX_FP /*{*/ { - static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; Long exp; ULong bits[2]; switch(s[1]) { @@ -272,7 +272,7 @@ strtod_l #ifdef INFNAN_CHECK /* Check for Nan and Infinity */ ULong bits[2]; - static FPI fpinan = /* only 52 explicit bits */ + static CONST FPI fpinan = /* only 52 explicit bits */ { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; if (!decpt) switch(c) { diff --git a/src/libc/gdtoa/FreeBSD/gdtoa-strtodg.c b/src/libc/gdtoa/FreeBSD/gdtoa-strtodg.c index e1acc54bc..c436ea9a8 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoa-strtodg.c +++ b/src/libc/gdtoa/FreeBSD/gdtoa-strtodg.c @@ -47,7 +47,7 @@ THIS SOFTWARE. extern CONST int fivesbits[]; int all_on(Bigint *b, int n); Bigint *set_ones(Bigint *b, int n); -int rvOK(U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv); +int rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv); int mantbits(U *d); #else /* !BUILDING_VARIANT */ @@ -188,9 +188,9 @@ set_ones(Bigint *b, int n) rvOK #ifdef KR_headers (d, fpi, exp, bits, exact, rd, irv) - U *d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; + U *d; CONST FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; #else - (U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) + (U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) #endif { Bigint *b; @@ -334,9 +334,9 @@ mantbits(U *d) strtodg #ifdef KR_headers (s00, se, fpi, exp, bits, loc) - CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; locale_t loc; + CONST char *s00; char **se; CONST FPI *fpi; Long *exp; ULong *bits; locale_t loc; #else - (CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits, locale_t loc) + (CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits, locale_t loc) #endif { int abe, abits, asub; diff --git a/src/libc/gdtoa/FreeBSD/gdtoa-strtof.c b/src/libc/gdtoa/FreeBSD/gdtoa-strtof.c index fc29f597b..1f84d7d91 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoa-strtof.c +++ b/src/libc/gdtoa/FreeBSD/gdtoa-strtof.c @@ -40,7 +40,7 @@ strtof_l(s, sp, loc) CONST char *s; char **sp; locale_t loc; strtof_l(CONST char *s, char **sp, locale_t loc) #endif { - static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + static CONST FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; ULong bits[1]; Long exp; int k; diff --git a/src/libc/gdtoa/FreeBSD/gdtoa-strtopdd.c b/src/libc/gdtoa/FreeBSD/gdtoa-strtopdd.c index 269574646..48f92042f 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoa-strtopdd.c +++ b/src/libc/gdtoa/FreeBSD/gdtoa-strtopdd.c @@ -51,9 +51,9 @@ strtopdd(CONST char *s, char **sp, double *dd, locale_t loc) #endif { #ifdef Sudden_Underflow - static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; + static CONST FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; #else - static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; + static CONST FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; #endif ULong bits[4]; Long exp; diff --git a/src/libc/gdtoa/FreeBSD/gdtoa.h b/src/libc/gdtoa/FreeBSD/gdtoa.h index 8bdcd4d47..317612d02 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoa.h +++ b/src/libc/gdtoa/FreeBSD/gdtoa.h @@ -110,7 +110,7 @@ extern char* gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, extern void freedtoa ANSI((char*)); extern float strtof ANSI((CONST char *, char **)); extern double strtod ANSI((CONST char *, char **)); -extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*, locale_t)) __DARWIN_ALIAS(strtodg); +extern int strtodg ANSI((CONST char*, char**, CONST FPI*, Long*, ULong*, locale_t)) __DARWIN_ALIAS(strtodg); extern char* g_ddfmt ANSI((char*, double*, int, size_t)); extern char* g_dfmt ANSI((char*, double*, int, size_t)); diff --git a/src/libc/gdtoa/FreeBSD/gdtoa_fltrnds.h b/src/libc/gdtoa/FreeBSD/gdtoa_fltrnds.h index 33e5f9e53..f170de5fd 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoa_fltrnds.h +++ b/src/libc/gdtoa/FreeBSD/gdtoa_fltrnds.h @@ -1,4 +1,5 @@ - FPI *fpi, fpi1; + CONST FPI *fpi; + FPI fpi1; int Rounding; #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ Rounding = Flt_Rounds; diff --git a/src/libc/gdtoa/FreeBSD/gdtoaimp.h b/src/libc/gdtoa/FreeBSD/gdtoaimp.h index 39012aa19..b967e8108 100644 --- a/src/libc/gdtoa/FreeBSD/gdtoaimp.h +++ b/src/libc/gdtoa/FreeBSD/gdtoaimp.h @@ -570,7 +570,7 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); extern char *dtoa_result; extern CONST double bigtens[], tens[], tinytens[]; - extern unsigned char hexdig[]; + extern CONST unsigned char hexdig[]; extern Bigint *Balloc ANSI((int)); extern void Bfree ANSI((Bigint*)); @@ -590,9 +590,9 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t)); extern char *dtoa ANSI((double d, int mode, int ndigits, int *decpt, int *sign, char **rve)); extern char *g__fmt ANSI((char*, char*, char*, int, ULong, size_t)); - extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int, locale_t)); + extern int gethex ANSI((CONST char**, CONST FPI*, Long*, Bigint**, int, locale_t)); extern void hexdig_init_D2A(Void); - extern int hexnan ANSI((CONST char**, FPI*, ULong*)); + extern int hexnan ANSI((CONST char**, CONST FPI*, ULong*)); extern int hi0bits_D2A ANSI((ULong)); extern Bigint *i2b ANSI((int)); extern Bigint *increment ANSI((Bigint*)); diff --git a/src/libc/gdtoa/FreeBSD/glue.c b/src/libc/gdtoa/FreeBSD/glue.c index e24f5ba4f..0db1914f4 100644 --- a/src/libc/gdtoa/FreeBSD/glue.c +++ b/src/libc/gdtoa/FreeBSD/glue.c @@ -7,10 +7,4 @@ #include "spinlock.h" -__attribute__ ((visibility ("visible"))) spinlock_t __gdtoa_locks[2]; - -static void bug_workaround() -{ - __gdtoa_locks[0] = 0; -} diff --git a/src/libc/gen/CMakeLists.txt b/src/libc/gen/CMakeLists.txt index 95fe373fc..736b5152a 100644 --- a/src/libc/gen/CMakeLists.txt +++ b/src/libc/gen/CMakeLists.txt @@ -2,23 +2,18 @@ project(libc-gen) cmake_minimum_required(VERSION 2.4.0) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -fblocks -DKERNEL_PRIVATE -DPRIVATE") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -fblocks -DPRIVATE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h") -# ASL and utmpx not built - -set(gen_sources #asl.c - #asl_core.c - #asl_fd.c - #asl_file.c - #asl_legacy1.c - #asl_msg.c - #asl_store.c - #asl_util.c - #assumes.c +include_directories(${CMAKE_SOURCE_DIR}/src/libmalloc/include) +include_directories(${CMAKE_SOURCE_DIR}/src/libmalloc/private) +include_directories(${CMAKE_SOURCE_DIR}/src/external/libpthread/pthread) +include_directories(${CMAKE_SOURCE_DIR}/src/external/syslog/libsystem_asl.tproj/include) + +set(gen_sources authentication.c backtrace.c - cache.c + clock_gettime.c confstr.c crypt.c devname.c @@ -32,58 +27,48 @@ set(gen_sources #asl.c getttyent.c getusershell.c getvfsbyname.c - isinf.c - isnan.c - #magazine_malloc.c # magazine or scalable - #malloc.c nanosleep.c nftw.c nlist.c - # NSSystemDirectories.c # moved into system_coreservices oldsyslog.c - platfunc.c - #scalable_malloc.c - setlogin.c + raise.c + setlogin.c sigsetops.c - _simple.c - stack_logging.c - stack_logging_disk.c strtofflags.c - sync_volume_np.c - #syslog.c - thread_stack_pcs.c + sync_volume_np.c + thread_stack_pcs.c uname.c - utmpx-darwin.c - wordexp.c) + utmpx-darwin.c +) set(gen_sources ${gen_sources} - FreeBSD/alarm.c - FreeBSD/arc4random.c + FreeBSD/alarm.c + FreeBSD/arc4random.c FreeBSD/assert.c - FreeBSD/basename.c + FreeBSD/basename.c FreeBSD/clock.c - FreeBSD/closedir.c - FreeBSD/ctermid.c - FreeBSD/daemon.c - FreeBSD/dirname.c - FreeBSD/drand48.c - FreeBSD/erand48.c - FreeBSD/err.c - FreeBSD/exec.c - FreeBSD/fmtcheck.c - FreeBSD/fmtmsg.c - FreeBSD/fnmatch.c - FreeBSD/ftok.c - FreeBSD/getbsize.c - FreeBSD/getcap.c - FreeBSD/getcwd.c - FreeBSD/gethostname.c - FreeBSD/getlogin.c - FreeBSD/getmntinfo64.c - FreeBSD/getmntinfo.c - FreeBSD/getpagesize.c - FreeBSD/getpeereid.c - FreeBSD/getprogname.c + FreeBSD/closedir.c + FreeBSD/ctermid.c + FreeBSD/daemon.c + FreeBSD/dirname.c + FreeBSD/drand48.c + FreeBSD/erand48.c + FreeBSD/err.c + FreeBSD/exec.c + FreeBSD/fmtcheck.c + FreeBSD/fmtmsg.c + FreeBSD/fnmatch.c + FreeBSD/ftok.c + FreeBSD/getbsize.c + FreeBSD/getcap.c + FreeBSD/getcwd.c + FreeBSD/gethostname.c + FreeBSD/getlogin.c + FreeBSD/getmntinfo.c + FreeBSD/getmntinfo64.c + FreeBSD/getpagesize.c + FreeBSD/getpeereid.c + FreeBSD/getprogname.c FreeBSD/glob.c FreeBSD/isatty.c FreeBSD/jrand48.c @@ -96,9 +81,7 @@ set(gen_sources ${gen_sources} FreeBSD/opendir.c FreeBSD/pause.c FreeBSD/popen.c - FreeBSD/pselect.c FreeBSD/psignal.c - FreeBSD/raise.c FreeBSD/_rand48.c FreeBSD/readdir.c FreeBSD/readpassphrase.c @@ -124,7 +107,7 @@ set(gen_sources ${gen_sources} FreeBSD/termios.c FreeBSD/time.c FreeBSD/times.c - # FreeBSD/timezone.c # incompatible with 'long timezone' + #FreeBSD/timezone.c # legacy only FreeBSD/ttyname.c FreeBSD/ttyslot.c FreeBSD/ualarm.c @@ -133,9 +116,13 @@ set(gen_sources ${gen_sources} FreeBSD/usleep.c FreeBSD/utime.c FreeBSD/vis.c - FreeBSD/wait3.c FreeBSD/wait.c - FreeBSD/waitpid.c) + FreeBSD/waitpid.c + FreeBSD/wait3.c + FreeBSD/wordexp.c + NetBSD/rb.c + NetBSD/utmpx.c + ) SET_SOURCE_FILES_PROPERTIES(FreeBSD/clock.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_CLOCK") SET_SOURCE_FILES_PROPERTIES(FreeBSD/daemon.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_DAEMON") @@ -146,7 +133,7 @@ SET_SOURCE_FILES_PROPERTIES(FreeBSD/nice.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_F SET_SOURCE_FILES_PROPERTIES(FreeBSD/opendir.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS___OPENDIR2 -DLIBC_ALIAS_OPENDIR -include __dirent.h") SET_SOURCE_FILES_PROPERTIES(FreeBSD/pause.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_PAUSE -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h") SET_SOURCE_FILES_PROPERTIES(FreeBSD/popen.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_POPEN -U_DARWIN_C_SOURCE -U_POSIX_C_SOURCE -D__DARWIN_C_LEVEL=200000L") -SET_SOURCE_FILES_PROPERTIES(FreeBSD/pselect.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_PSELECT -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h -U_DARWIN_C_SOURCE -U_POSIX_C_SOURCE -D__DARWIN_C_LEVEL=200000L") +#SET_SOURCE_FILES_PROPERTIES(FreeBSD/pselect.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_PSELECT -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h -U_DARWIN_C_SOURCE -U_POSIX_C_SOURCE -D__DARWIN_C_LEVEL=200000L") SET_SOURCE_FILES_PROPERTIES(FreeBSD/readdir.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -include __dirent.h") SET_SOURCE_FILES_PROPERTIES(FreeBSD/rewinddir.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_REWINDDIR -include __dirent.h") SET_SOURCE_FILES_PROPERTIES(FreeBSD/seekdir.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_SEEKDIR -include __dirent.h") @@ -154,7 +141,7 @@ SET_SOURCE_FILES_PROPERTIES(FreeBSD/setmode.c PROPERTIES COMPILE_FLAGS "${CMAKE_ SET_SOURCE_FILES_PROPERTIES(FreeBSD/sleep.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_SLEEP -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h") SET_SOURCE_FILES_PROPERTIES(FreeBSD/telldir.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS__SEEKDIR -DLIBC_ALIAS_TELLDIR -include __dirent.h") SET_SOURCE_FILES_PROPERTIES(FreeBSD/termios.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_TCDRAIN -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h") -SET_SOURCE_FILES_PROPERTIES(FreeBSD/timezone.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0") +#SET_SOURCE_FILES_PROPERTIES(FreeBSD/timezone.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_TIMEZONE") SET_SOURCE_FILES_PROPERTIES(FreeBSD/ttyname.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_TTYNAME_R") SET_SOURCE_FILES_PROPERTIES(FreeBSD/usleep.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_USLEEP") SET_SOURCE_FILES_PROPERTIES(FreeBSD/wait.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_WAIT") @@ -177,9 +164,10 @@ add_library(libc-gen OBJECT ${gen_sources}) # *** # Cancelable variants # *** -set(gen-cancelable_sources FreeBSD/lockf.c nanosleep.c FreeBSD/pause.c FreeBSD/pselect.c FreeBSD/sleep.c FreeBSD/termios.c FreeBSD/usleep.c FreeBSD/wait.c FreeBSD/waitpid.c) +set(gen-cancelable_sources FreeBSD/lockf.c nanosleep.c FreeBSD/pause.c FreeBSD/sleep.c FreeBSD/termios.c FreeBSD/usleep.c FreeBSD/wait.c FreeBSD/waitpid.c) add_library(libc-gen_cancelable OBJECT ${gen-cancelable_sources}) -SET_TARGET_PROPERTIES(libc-gen_cancelable PROPERTIES COMPILE_DEFINITIONS "BUILDING_VARIANT;VARIANT_CANCELABLE") +#SET_TARGET_PROPERTIES(libc-gen_cancelable PROPERTIES COMPILE_DEFINITIONS "BUILDING_VARIANT;VARIANT_CANCELABLE") +set_target_properties(libc-gen_cancelable PROPERTIES COMPILE_FLAGS "-D__DARWIN_NON_CANCELABLE=0 -DBUILDING_VARIANT -DVARIANT_CANCELABLE") # *** @@ -198,7 +186,7 @@ set(gen-legacy_sources FreeBSD/clock.c FreeBSD/closedir.c FreeBSD/fnmatch.c FreeBSD/lockf.c FreeBSD/pause.c FreeBSD/popen.c FreeBSD/rewinddir.c FreeBSD/seekdir.c FreeBSD/setmode.c FreeBSD/sleep.c FreeBSD/telldir.c FreeBSD/ttyname.c FreeBSD/usleep.c FreeBSD/wait.c FreeBSD/waitpid.c - FreeBSD/timezone.c FreeBSD/termios.c FreeBSD/nice.c FreeBSD/pselect.c + FreeBSD/timezone.c FreeBSD/termios.c FreeBSD/nice.c confstr.c crypt.c nftw.c FreeBSD/opendir.c) add_library(libc-gen_legacy OBJECT ${gen-legacy_sources}) @@ -208,16 +196,16 @@ SET_TARGET_PROPERTIES(libc-gen_legacy PROPERTIES COMPILE_FLAGS # *** # DARWIN_EXTSN variants # -set(gen-extsn_sources FreeBSD/popen.c FreeBSD/pselect.c) +set(gen-extsn_sources FreeBSD/popen.c) add_library(libc-gen_extsn OBJECT ${gen-extsn_sources}) SET_TARGET_PROPERTIES(libc-gen_extsn PROPERTIES COMPILE_DEFINITIONS "_DARWIN_UNLIMITED_STREAMS;_DARWIN_UNLIMITED_SELECT;BUILDING_VARIANT") # *** # DARWIN_EXTSN cancelable variants # -set(gen-extsn_canc_sources FreeBSD/pselect.c) -add_library(libc-gen_extsn_canc OBJECT ${gen-extsn_canc_sources}) -SET_TARGET_PROPERTIES(libc-gen_extsn_canc PROPERTIES COMPILE_DEFINITIONS "_DARWIN_UNLIMITED_STREAMS;_DARWIN_UNLIMITED_SELECT;BUILDING_VARIANT;VARIANT_CANCELABLE") +#set(gen-extsn_canc_sources FreeBSD/pselect.c) +#add_library(libc-gen_extsn_canc OBJECT ${gen-extsn_canc_sources}) +#SET_TARGET_PROPERTIES(libc-gen_extsn_canc PROPERTIES COMPILE_DEFINITIONS "_DARWIN_UNLIMITED_STREAMS;_DARWIN_UNLIMITED_SELECT;BUILDING_VARIANT;VARIANT_CANCELABLE") # *** # PRE1050 variants @@ -225,11 +213,6 @@ SET_TARGET_PROPERTIES(libc-gen_extsn_canc PROPERTIES COMPILE_DEFINITIONS "_DARWI set(gen-pre1050_sources FreeBSD/daemon.c) -# Because on i386 the default there is no "post-1050" version -if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64") - set(gen-pre1050_sources ${gen-pre1050_sources} FreeBSD/pselect.c) -endif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64") - add_library(libc-gen_pre1050 OBJECT ${gen-pre1050_sources}) SET_TARGET_PROPERTIES(libc-gen_pre1050 PROPERTIES COMPILE_FLAGS "-DBUILDING_VARIANT -DVARIANT_PRE1050 -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0") @@ -237,9 +220,9 @@ SET_TARGET_PROPERTIES(libc-gen_pre1050 PROPERTIES COMPILE_FLAGS "-DBUILDING_VARI # DYLD variants # *** -add_library(libc-gen_dyld OBJECT _simple.c FreeBSD/arc4random.c FreeBSD/closedir.c dirfd.c FreeBSD/getcwd.c FreeBSD/getpagesize.c nanosleep.c FreeBSD/opendir.c +add_library(libc-gen_dyld OBJECT FreeBSD/arc4random.c FreeBSD/closedir.c dirfd.c FreeBSD/getcwd.c FreeBSD/getpagesize.c nanosleep.c FreeBSD/opendir.c FreeBSD/readdir.c FreeBSD/scandir.c FreeBSD/sysctl.c FreeBSD/sysctlbyname.c FreeBSD/telldir.c FreeBSD/usleep.c FreeBSD/sysconf.c - FreeBSD/isatty.c FreeBSD/termios.c FreeBSD/getprogname.c errlst.c platfunc.c) + FreeBSD/isatty.c FreeBSD/termios.c FreeBSD/getprogname.c errlst.c) SET_TARGET_PROPERTIES(libc-gen_dyld PROPERTIES COMPILE_FLAGS "-UBUILDING_VARIANT -DVARIANT_DYLD -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN") diff --git a/src/libc/gen/FreeBSD/arc4random.3 b/src/libc/gen/FreeBSD/arc4random.3 index 44015afec..d8d55026a 100644 --- a/src/libc/gen/FreeBSD/arc4random.3 +++ b/src/libc/gen/FreeBSD/arc4random.3 @@ -1,4 +1,5 @@ -.\" $OpenBSD: arc4random.3,v 1.2 1997/04/27 22:40:25 angelos Exp $ +.\" $OpenBSD: arc4random.3,v 1.34 2014/07/19 16:11:16 naddy Exp $ +.\" .\" Copyright 1997 Niels Provos .\" All rights reserved. .\" @@ -28,100 +29,72 @@ .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" Manual page, using -mandoc macros -.\" $FreeBSD: src/lib/libc/gen/arc4random.3,v 1.18 2008/07/22 11:33:49 ache Exp $ .\" -.Dd April 15, 1997 +.Dd July 30, 2015 .Dt ARC4RANDOM 3 .Os .Sh NAME .Nm arc4random , .Nm arc4random_buf , -.Nm arc4random_uniform , -.Nm arc4random_stir , -.Nm arc4random_addrandom -.Nd arc4 random number generator -.Sh LIBRARY -.Lb libc +.Nm arc4random_uniform +.Nd random number generator .Sh SYNOPSIS .In stdlib.h -.Ft u_int32_t +.Ft uint32_t .Fn arc4random "void" .Ft void .Fn arc4random_buf "void *buf" "size_t nbytes" -.Ft u_int32_t -.Fn arc4random_uniform "u_int32_t upper_bound" -.Ft void -.Fn arc4random_stir "void" -.Ft void -.Fn arc4random_addrandom "unsigned char *dat" "int datlen" +.Ft uint32_t +.Fn arc4random_uniform "uint32_t upper_bound" .Sh DESCRIPTION -The -.Fn arc4random -function uses the key stream generator employed by the -arc4 cipher, which uses 8*8 8 bit S-Boxes. -The S-Boxes -can be in about -.if t 2\u\s71700\s10\d -.if n (2**1700) -states. -The -.Fn arc4random -function returns pseudo-random numbers in the range of 0 to -.if t 2\u\s731\s10\d\(mi1, -.if n (2**32)\(mi1, -and therefore has twice the range of -.Xr rand 3 +.Pp +These functions use a cryptographic pseudo-random number generator to generate +high quality random bytes very quickly. One data pool is used for all +consumers in a process, so that consumption under program flow can act as +additional stirring. The subsystem is re-seeded from the kernel random number +subsystem on a regular basis, and also upon +.Xr fork 2 . +.Pp +This family of functions provides higher quality random data than those +described in +.Xr rand 3 , +.Xr random 3 , and -.Xr random 3 . +.Xr rand48 3 . +They can be called in almost environments, including +.Xr chroot 2 +and their use is encouraged over all other standard library functions for +random numbers. +.Pp +.Fn arc4random +returns a single 32-bit value. .Pp .Fn arc4random_buf -function fills the region +fills the region .Fa buf of length .Fa nbytes -with ARC4-derived random data. +with random data. .Pp .Fn arc4random_uniform -will return a uniformly distributed random number less than +will return a single 32-bit value, uniformly distributed but less than .Fa upper_bound . -.Fn arc4random_uniform -is recommended over constructions like +This is recommended over constructions like .Dq Li arc4random() % upper_bound as it avoids "modulo bias" when the upper bound is not a power of two. -.Pp -The -.Fn arc4random_stir -function reads data from -.Pa /dev/urandom -and uses it to permute the S-Boxes via -.Fn arc4random_addrandom . -.Pp -There is no need to call -.Fn arc4random_stir -before using -.Fn arc4random -functions family, since -they automatically initialize themselves. -.Sh EXAMPLES -The following produces a drop-in replacement for the traditional -.Fn rand -and -.Fn random -functions using -.Fn arc4random : -.Pp -.Dl "#define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))" +In the worst case, this function may require multiple iterations +to ensure uniformity. +.Sh RETURN VALUES +These functions are always successful, and no return value is +reserved to indicate an error. .Sh SEE ALSO .Xr rand 3 , +.Xr rand48 3 , .Xr random 3 , -.Xr srandomdev 3 +.Xr random 4 .Sh HISTORY -.Pa RC4 -has been designed by RSA Data Security, Inc. -It was posted anonymously -to the USENET and was confirmed to be equivalent by several sources who -had access to the original cipher. -Since -.Pa RC4 -used to be a trade secret, the cipher is now referred to as -.Pa ARC4 . +The original version of this random number generator used the RC4 (also known +as ARC4) algorithm. In OS X 10.12 it was replaced with the NIST-approved AES +cipher, and it may be replaced again in the future as cryptographic techniques +advance. A good mnemonic is +.Dq A Replacement Call for Random . diff --git a/src/libc/gen/FreeBSD/arc4random.c.orig b/src/libc/gen/FreeBSD/arc4random.c.orig new file mode 100644 index 000000000..e49f56b40 --- /dev/null +++ b/src/libc/gen/FreeBSD/arc4random.c.orig @@ -0,0 +1,477 @@ +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Arc4 random number generator for OpenBSD. + * + * This code is derived from section 17.1 of Applied Cryptography, + * second edition, which describes a stream cipher allegedly + * compatible with RSA Labs "RC4" cipher (the actual description of + * which is a trade secret). The same algorithm is used as a stream + * cipher called "arcfour" in Tatu Ylonen's ssh package. + * + * Here the stream cipher has been modified always to include the time + * when initializing the state. That makes it impossible to + * regenerate the same random sequence twice, so this can't be used + * for encryption, but will generate good random numbers. + * + * RC4 is a registered trademark of RSA Laboratories. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/gen/arc4random.c,v 1.25 2008/09/09 09:46:36 ache Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "string.h" +#include "libc_private.h" + +#define CACHE_LENGTH 64 +#define BUFFERSIZE 32 + +#define INITIAL_COUNT 1600000 +#define MAX_BUF_COUNT 4096 + +static os_unfair_lock arc4_lock = OS_UNFAIR_LOCK_INIT; +static int arc4_count; + +uint64_t arc4random64(void); + +#define RANDOMDEV "/dev/random" + +static void +_my_getentropy(uint8_t *buf, size_t size){ + int fd; + ssize_t ret; + if (getentropy(buf, size) == 0) { + return; + } + + // The above should never fail, but we'll try /dev/random anyway + fd = open(RANDOMDEV, O_RDONLY, 0); + if (fd == -1) { +#if !defined(VARIANT_STATIC) + os_crash("arc4random: unable to open /dev/random"); +#else + abort(); +#endif + } +shortread: + ret = read(fd, buf, size); + if (ret == -1) { +#if !defined(VARIANT_STATIC) + os_crash("arc4random: unable to read from /dev/random"); +#else + abort(); +#endif + } else if ((size_t)ret < size) { + size -= (size_t)ret; + buf += ret; + goto shortread; + } + (void)close(fd); +} + +#if defined(__APPLE__) && !defined(VARIANT_STATIC) +#include +#include + +static struct ccdrbg_info rng_info; +static struct ccdrbg_nistctr_custom rng_custom; +static struct ccdrbg_state *rng_state; + +static int cache_pos = CACHE_LENGTH; +static uint32_t rand_buffer[CACHE_LENGTH]; + +static void +arc4_init(void) +{ + if (rng_state != NULL) return; + + uint8_t entropy[BUFFERSIZE]; + int ret; + rng_custom.ecb = ccaes_ecb_encrypt_mode(); + rng_custom.keylen = 16; + rng_custom.strictFIPS = 0; + rng_custom.use_df = 1; + ccdrbg_factory_nistctr(&rng_info, &rng_custom); + rng_state = malloc(rng_info.size); + os_assert(rng_state != NULL); + + _my_getentropy(entropy, BUFFERSIZE); + + ret = ccdrbg_init(&rng_info, rng_state, + sizeof(entropy), entropy, + 0, NULL, 0, NULL); + os_assert_zero(ret); + + memset_s(entropy, sizeof(entropy), 0, sizeof(entropy)); + + arc4_count = INITIAL_COUNT; +} + +static void +arc4_stir(void) +{ + uint8_t entropy[BUFFERSIZE]; + int ret; + + arc4_init(); + + _my_getentropy(entropy, BUFFERSIZE); + + ret = ccdrbg_reseed(&rng_info, rng_state, + sizeof(entropy), entropy, + 0, NULL); + os_assert_zero(ret); + + memset_s(entropy, sizeof(entropy), 0, sizeof(entropy)); + + arc4_count = INITIAL_COUNT; +} + +void +arc4random_addrandom(__unused u_char *dat, __unused int datlen) +{ + /* NOP - deprecated */ +} + +uint32_t +arc4random(void) +{ + int ret; + os_unfair_lock_lock(&arc4_lock); + arc4_init(); + if (arc4_count <= 0) { + arc4_stir(); + } + if (cache_pos >= CACHE_LENGTH) { + ret = ccdrbg_generate(&rng_info, rng_state, sizeof(rand_buffer), rand_buffer, 0, NULL); + os_assert_zero(ret); + cache_pos = 0; + } + uint32_t rand = rand_buffer[cache_pos]; + // Delete the current random number from buffer + memset_s(rand_buffer+cache_pos, sizeof(rand_buffer[cache_pos]), 0, sizeof(rand_buffer[cache_pos])); + arc4_count--; + cache_pos++; + os_unfair_lock_unlock(&arc4_lock); + return rand; +} + +void +arc4random_buf(void *_buf, size_t buf_size) +{ + uint8_t *buf = _buf; + os_unfair_lock_lock(&arc4_lock); + arc4_init(); + while (buf_size > 0) { + if (arc4_count <= 0 ) { + arc4_stir(); + } + size_t n = MIN(buf_size, (size_t)MIN(MAX_BUF_COUNT, arc4_count) * sizeof(uint32_t)); + int ret = ccdrbg_generate(&rng_info, rng_state, n, buf, 0, NULL); + os_assert_zero(ret); + buf_size -= n; + buf += n; + arc4_count -= n/sizeof(uint32_t); + + if (buf_size > 0) { + os_unfair_lock_unlock(&arc4_lock); + // Give others a chance to get the lock + os_unfair_lock_lock(&arc4_lock); + } + } + os_unfair_lock_unlock(&arc4_lock); +} + +__private_extern__ void +_arc4_fork_child(void) +{ + arc4_lock = OS_UNFAIR_LOCK_INIT; + cache_pos = CACHE_LENGTH; + if (rng_state != NULL) { + arc4_count = 0; + memset_s(rand_buffer, sizeof(rand_buffer), 0, sizeof(rand_buffer)); + memset_s(rng_state, rng_info.size, 0, rng_info.size); + free(rng_state); rng_state = NULL; + bzero(&rng_info, sizeof(rng_info)); + bzero(&rng_custom, sizeof(rng_custom)); + } +} + +#else /* __APPLE__ && !VARIANT_STATIC */ + +struct arc4_stream { + u_int8_t i; + u_int8_t j; + u_int8_t s[256]; +}; + +#define KEYSIZE 128 + +static struct arc4_stream rs = { + .i = 0, + .j = 0, + .s = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + } +}; +static int rs_stired; + +static inline u_int8_t arc4_getbyte(void); +static void arc4_stir(void); + +static struct { + struct timeval tv; + pid_t pid; + u_int8_t rnd[KEYSIZE]; +} rdat; +static volatile int rs_data_available = 0; + +static inline void +arc4_addrandom(u_char *dat, int datlen) +{ + int n; + u_int8_t si; + + rs.i--; + for (n = 0; n < 256; n++) { + rs.i = (rs.i + 1); + si = rs.s[rs.i]; + rs.j = (rs.j + si + dat[n % datlen]); + rs.s[rs.i] = rs.s[rs.j]; + rs.s[rs.j] = si; + } + rs.j = rs.i; +} + +static void +arc4_fetch(void) +{ + _my_getentropy((uint8_t*)&rdat, KEYSIZE); +} + +static void +arc4_stir(void) +{ + int n; + /* + * If we don't have data, we need some now before we can integrate + * it into the static buffers + */ + if (!rs_data_available) + { + arc4_fetch(); + } + rs_data_available = 0; + __sync_synchronize(); + + arc4_addrandom((u_char *)&rdat, KEYSIZE); + + /* + * Throw away the first N bytes of output, as suggested in the + * paper "Weaknesses in the Key Scheduling Algorithm of RC4" + * by Fluher, Mantin, and Shamir. N=1024 is based on + * suggestions in the paper "(Not So) Random Shuffles of RC4" + * by Ilya Mironov. + */ + for (n = 0; n < 1024; n++) + (void) arc4_getbyte(); + arc4_count = 1600000; + rs_stired = 1; +} + +static inline u_int8_t +arc4_getbyte(void) +{ + u_int8_t si, sj; + + rs.i = (rs.i + 1); + si = rs.s[rs.i]; + rs.j = (rs.j + si); + sj = rs.s[rs.j]; + rs.s[rs.i] = sj; + rs.s[rs.j] = si; + + return (rs.s[(si + sj) & 0xff]); +} + +static inline u_int32_t +arc4_getword(void) +{ + u_int32_t val; + + val = arc4_getbyte() << 24; + val |= arc4_getbyte() << 16; + val |= arc4_getbyte() << 8; + val |= arc4_getbyte(); + + return (val); +} + +/* 7944700: force restir in child */ +__private_extern__ void +_arc4_fork_child(void) +{ + arc4_lock = OS_UNFAIR_LOCK_INIT; + rs_stired = 0; + rs_data_available = 0; +} + +static inline int +arc4_check_stir(void) +{ + if (!rs_stired || arc4_count <= 0) { + arc4_stir(); + return 1; + } + return 0; +} + +void +arc4random_addrandom(u_char *dat, int datlen) +{ + os_unfair_lock_lock(&arc4_lock); + arc4_check_stir(); + arc4_addrandom(dat, datlen); + os_unfair_lock_unlock(&arc4_lock); +} + +u_int32_t +arc4random(void) +{ + u_int32_t rnd; + + os_unfair_lock_lock(&arc4_lock); + + int did_stir = arc4_check_stir(); + rnd = arc4_getword(); + arc4_count -= 4; + + os_unfair_lock_unlock(&arc4_lock); + if (did_stir) + { + /* stirring used up our data pool, we need to read in new data outside of the lock */ + arc4_fetch(); + rs_data_available = 1; + __sync_synchronize(); + } + + return (rnd); +} + +void +arc4random_buf(void *_buf, size_t n) +{ + u_char *buf = (u_char *)_buf; + int did_stir = 0; + + os_unfair_lock_lock(&arc4_lock); + + while (n--) { + if (arc4_check_stir()) + { + did_stir = 1; + } + buf[n] = arc4_getbyte(); + arc4_count--; + } + + os_unfair_lock_unlock(&arc4_lock); + if (did_stir) + { + /* stirring used up our data pool, we need to read in new data outside of the lock */ + arc4_fetch(); + rs_data_available = 1; + __sync_synchronize(); + } +} + +#endif /* __APPLE__ */ + +void +arc4random_stir(void) +{ + os_unfair_lock_lock(&arc4_lock); + arc4_stir(); + os_unfair_lock_unlock(&arc4_lock); +} + +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by trying successive ranges of bits from the random + * value, each large enough to hold the desired upper bound, until a range + * holding a value less than the bound is found. + */ +uint32_t +arc4random_uniform(uint32_t upper_bound) +{ + if (upper_bound < 2) + return 0; + + // find smallest 2**n -1 >= upper_bound + int zeros = __builtin_clz(upper_bound); + int bits = CHAR_BIT * sizeof(uint32_t) - zeros; + uint32_t mask = 0xFFFFFFFFU >> zeros; + + do { + uint32_t value = arc4random(); + + // If low 2**n-1 bits satisfy the requested condition, return result + uint32_t result = value & mask; + if (result < upper_bound) { + return result; + } + + // otherwise consume remaining bits of randomness looking for a satisfactory result. + int bits_left = zeros; + while (bits_left >= bits) { + value >>= bits; + result = value & mask; + if (result < upper_bound) { + return result; + } + bits_left -= bits; + } + } while (1); +} diff --git a/src/libc/gen/FreeBSD/assert.c b/src/libc/gen/FreeBSD/assert.c index 2e1c0b158..bf0de5384 100644 --- a/src/libc/gen/FreeBSD/assert.c +++ b/src/libc/gen/FreeBSD/assert.c @@ -36,7 +36,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/assert.c,v 1.8 2007/01/09 00:27:53 imp Exp #include #include #include -#include "CrashReporterClient.h" +#include #include "_simple.h" void diff --git a/src/libc/gen/FreeBSD/basename.3 b/src/libc/gen/FreeBSD/basename.3 index a9300b3e1..e37802c01 100644 --- a/src/libc/gen/FreeBSD/basename.3 +++ b/src/libc/gen/FreeBSD/basename.3 @@ -1,33 +1,22 @@ +.\" $OpenBSD: basename.3,v 1.20 2007/05/31 19:19:28 jmc Exp $ .\" .\" Copyright (c) 1997 Todd C. Miller -.\" All rights reserved. .\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. .\" -.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.\" $OpenBSD: basename.3,v 1.12 2000/04/18 03:01:25 aaron Exp $ -.\" $FreeBSD: src/lib/libc/gen/basename.3,v 1.7 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD$ .\" -.Dd August 17, 1997 +.Dd March 31, 2010 .Dt BASENAME 3 .Os .Sh NAME @@ -36,14 +25,13 @@ .Sh SYNOPSIS .In libgen.h .Ft char * -.Fo basename -.Fa "char *path" -.Fc +.Fn basename "char *path" +.Ft char * +.Fn basename_r "const char *path" "char *bname" .Sh DESCRIPTION The .Fn basename -function -returns the last component from the pathname pointed to by +function returns the last component from the pathname pointed to by .Fa path , deleting any trailing .Sq \&/ @@ -60,15 +48,30 @@ If is a null pointer or the empty string, a pointer to the string .Qq \&. is returned. +.Pp +The +.Fn basename_r +variation accepts a buffer of at least +.Dv MAXPATHLEN +bytes in which to store the resulting component. +.Sh IMPLEMENTATION NOTES +The +.Fn basename +function +returns a pointer to internal storage space allocated on the first call +that will be overwritten +by subsequent calls. +.Fn basename_r +is therefore preferred for threaded applications. .Sh RETURN VALUES On successful completion, .Fn basename -returns a pointer to the last component of +and +.Fn basename_r +return pointers to the last component of .Fa path . .Pp -If -.Fn basename -fails, a null pointer is returned and the global variable +If they fail, a null pointer is returned and the global variable .Va errno is set to indicate the error. .Sh ERRORS @@ -79,31 +82,10 @@ The following error codes may be set in The path component to be returned was larger than .Dv MAXPATHLEN . .El -.Sh WARNINGS -The -.Fn basename -function -returns a pointer to internal static storage space -that will be overwritten by subsequent calls. -The function may modify the string pointed to by -.Fa path . -.Sh LEGACY SYNOPSIS -.Fd #include -.Pp -.Ft char * -.br -.Fo basename -.Fa "const char *path" -.Fc ; -.Pp -In legacy mode, -.Fa path -will not be changed. .Sh SEE ALSO .Xr basename 1 , .Xr dirname 1 , -.Xr dirname 3 , -.Xr compat 5 +.Xr dirname 3 .Sh STANDARDS The .Fn basename @@ -116,5 +98,19 @@ function first appeared in .Ox 2.2 and .Fx 4.2 . +The +.Fn basename_r +function first appeared in OS X 10.12. .Sh AUTHORS -.An "Todd C. Miller" Aq Todd.Miller@courtesan.com +.An Todd C. Miller +.Sh CAVEATS +.Fn basename +returns a pointer to internal static storage space that will be overwritten +by subsequent calls. +.Pp +Other vendor implementations of +.Fn basename +may modify the contents of the string passed to +.Fn basename ; +this should be taken into account when writing code which calls this function +if portability is desired. diff --git a/src/libc/gen/FreeBSD/basename.c b/src/libc/gen/FreeBSD/basename.c index 3de44fb29..140ccbb6a 100644 --- a/src/libc/gen/FreeBSD/basename.c +++ b/src/libc/gen/FreeBSD/basename.c @@ -39,38 +39,29 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/basename.c,v 1.7 2002/12/30 01:41:14 marcel #include #include -#if __DARWIN_UNIX03 -#define const /**/ -#endif - char * -basename(path) - const char *path; +basename_r(const char *path, char *bname) { - static char *bname = NULL; const char *endp, *startp; - - if (bname == NULL) { - bname = (char *)malloc(MAXPATHLEN); - if (bname == NULL) - return(NULL); - } + size_t len; /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { - (void)strcpy(bname, "."); - return(bname); + bname[0] = '.'; + bname[1] = '\0'; + return (bname); } - /* Strip trailing slashes */ + /* Strip any trailing slashes */ endp = path + strlen(path) - 1; while (endp > path && *endp == '/') endp--; /* All slashes becomes "/" */ if (endp == path && *endp == '/') { - (void)strcpy(bname, "/"); - return(bname); + bname[0] = '/'; + bname[1] = '\0'; + return (bname); } /* Find the start of the base */ @@ -78,11 +69,29 @@ basename(path) while (startp > path && *(startp - 1) != '/') startp--; - if (endp - startp + 2 > MAXPATHLEN) { + len = endp - startp + 1; + if (len >= MAXPATHLEN) { errno = ENAMETOOLONG; - return(NULL); + return (NULL); + } + memcpy(bname, startp, len); + bname[len] = '\0'; + return (bname); +} + +#if __DARWIN_UNIX03 +#define const /**/ +#endif + +char * +basename(const char *path) +{ + static char *bname = NULL; + + if (bname == NULL) { + bname = (char *)malloc(MAXPATHLEN); + if (bname == NULL) + return (NULL); } - (void)strncpy(bname, startp, endp - startp + 1); - bname[endp - startp + 1] = '\0'; - return(bname); + return (basename_r(path, bname)); } diff --git a/src/libc/gen/FreeBSD/clock.3 b/src/libc/gen/FreeBSD/clock.3 index 1869d0992..2b7977178 100644 --- a/src/libc/gen/FreeBSD/clock.3 +++ b/src/libc/gen/FreeBSD/clock.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)clock.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/clock.3,v 1.12 2007/01/09 00:27:53 imp Exp $ +.\" $FreeBSD$ .\" .Dd June 4, 1993 .Dt CLOCK 3 @@ -58,8 +58,7 @@ The function returns the amount of time used unless an error occurs, in which case the return value is \-1. .Sh SEE ALSO -.Xr getrusage 2 , -.Xr clocks 7 +.Xr getrusage 2 .Sh STANDARDS The .Fn clock diff --git a/src/libc/gen/FreeBSD/ctermid.3 b/src/libc/gen/FreeBSD/ctermid.3 index 2085245e5..c1ba29737 100644 --- a/src/libc/gen/FreeBSD/ctermid.3 +++ b/src/libc/gen/FreeBSD/ctermid.3 @@ -26,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)ctermid.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/ctermid.3,v 1.12 2007/01/09 00:27:53 imp Exp $ +.\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd October 1, 2011 .Dt CTERMID 3 .Os .Sh NAME @@ -40,24 +40,24 @@ .Sh SYNOPSIS .In stdio.h .Ft char * -.Fn ctermid "char *s" +.Fn ctermid "char *buf" .Ft char * -.Fn ctermid_r "char *s" +.Fn ctermid_r "char *buf" .Sh DESCRIPTION The .Fn ctermid -function generates a string that, when used as a pathname, refers to +function generates a string, that, when used as a pathname, refers to the current controlling terminal of the calling process. .Pp If -.Fa s +.Fa buf is the .Dv NULL pointer, a pointer to a static area is returned. Otherwise, the pathname is copied into the memory referenced by -.Fa s . +.Fa buf . The argument -.Fa s +.Fa buf is assumed to be at least .Dv L_ctermid (as defined in the include @@ -69,9 +69,9 @@ The .Fn ctermid_r function provides the same functionality as -.Fn ctermid , +.Fn ctermid except that if -.Fa s +.Fa buf is a .Dv NULL pointer, @@ -81,14 +81,18 @@ is returned. The current implementation simply returns .Ql /dev/tty . .Sh RETURN VALUES -Upon successful completion, a -.Pf non- Dv NULL -pointer is returned. -Otherwise, a -.Dv NULL -pointer is returned and the global variable -.Va errno -is set to indicate the error. +The +.Fn ctermid +function returns +.Fa buf +if it is +.Pf non- Dv NULL , +otherwise it returns the address of a static buffer. +The +.Fn ctermid_r +function always returns +.Fa buf , +even if it is the NULL pointer. .Sh ERRORS The current implementation detects no error conditions. .Sh SEE ALSO diff --git a/src/libc/gen/FreeBSD/daemon.3 b/src/libc/gen/FreeBSD/daemon.3 index a2d9f2b2b..0df7cd1a4 100644 --- a/src/libc/gen/FreeBSD/daemon.3 +++ b/src/libc/gen/FreeBSD/daemon.3 @@ -45,6 +45,11 @@ The .Fn daemon function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons. +The +.Xr fork 2 +system call is used; see CAVEATS below about the environment after a +.Fn fork +(without a corresponding call to one of the exec routines). On Mac OS X, the use of this API is discouraged in favor of using .Xr launchd 8 . .Pp @@ -74,6 +79,7 @@ and .Xr setsid 2 . .Sh SEE ALSO .Xr fork 2 , +.Xr launchd 8 , .Xr setsid 2 , .Xr sigaction 2 .Sh HISTORY @@ -82,6 +88,20 @@ The function first appeared in .Bx 4.4 . .Sh CAVEATS +There are limits to what you can do in the child process. +To be totally safe you should restrict yourself to only +executing async-signal safe operations (see +.Xr sigaction 2 ) +until such time +as one of the exec functions is called. +All APIs, including global data symbols, in any framework or library +should be assumed to be unsafe after a +.Fn fork +unless explicitly documented to be safe or async-signal safe. +If you need to use these frameworks in the child +process, you must exec. +In this situation it is reasonable to exec yourself. +.Pp Unless the .Fa noclose argument is non-zero, diff --git a/src/libc/gen/FreeBSD/dirname.3 b/src/libc/gen/FreeBSD/dirname.3 index 330b42640..9c9d7f10f 100644 --- a/src/libc/gen/FreeBSD/dirname.3 +++ b/src/libc/gen/FreeBSD/dirname.3 @@ -28,6 +28,10 @@ .Fo dirname .Fa "char *path" .Fc +.Ft char * +.Fo dirname_r +.Fa "const char *path" "char *dname" +.Fc .Sh DESCRIPTION The .Fn dirname @@ -55,6 +59,8 @@ function returns a pointer to internal storage space allocated on the first call that will be overwritten by subsequent calls. +.Fn dirname_r +is therefore preferred for threaded applications. .Pp Other vendor implementations of .Fn dirname @@ -92,6 +98,10 @@ The following error codes may be set in .It Bq Er ENAMETOOLONG The path component to be returned was larger than .Dv MAXPATHLEN . +.It Bq Er ENOMEM +The static buffer used for storing the path in +.Fn dirname +could not be allocated. .El .Sh SEE ALSO .Xr basename 1 , @@ -110,5 +120,8 @@ function first appeared in .Ox 2.2 and .Fx 4.2 . +The +.Fn dirname_r +function first appeared in OS X 10.12. .Sh AUTHORS .An "Todd C. Miller" diff --git a/src/libc/gen/FreeBSD/dirname.c b/src/libc/gen/FreeBSD/dirname.c index 5164e185d..c291a0636 100644 --- a/src/libc/gen/FreeBSD/dirname.c +++ b/src/libc/gen/FreeBSD/dirname.c @@ -25,22 +25,11 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/dirname.c,v 1.8 2008/11/03 05:19:45 delphij #include #include -#if __DARWIN_UNIX03 -#define const /**/ -#endif - char * -dirname(const char *path) +dirname_r(const char *path, char *dname) { - static char *dname = NULL; - size_t len; const char *endp; - - if (dname == NULL) { - dname = (char *)malloc(MAXPATHLEN); - if (dname == NULL) - return(NULL); - } + size_t len; /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { @@ -79,3 +68,20 @@ dirname(const char *path) dname[len] = '\0'; return (dname); } + +#if __DARWIN_UNIX03 +#define const /**/ +#endif + +char * +dirname(const char *path) +{ + static char *dname = NULL; + + if (dname == NULL) { + dname = (char *)malloc(MAXPATHLEN); + if (dname == NULL) + return (NULL); + } + return (dirname_r(path, dname)); +} diff --git a/src/libc/gen/FreeBSD/err.c b/src/libc/gen/FreeBSD/err.c index e6e03f628..aec34223d 100644 --- a/src/libc/gen/FreeBSD/err.c +++ b/src/libc/gen/FreeBSD/err.c @@ -82,7 +82,7 @@ __private_extern__ struct _e_err_exit _e_err_exit = {ERR_EXIT_UNDEF}; * otherwise use \x (x is value) * (NUL isn't used) */ -static unsigned char escape[256] = { +static const unsigned char escape[256] = { /* NUL */ 0, /* Unused: strings can't contain nulls */ /* SOH STX ETX EOT ENQ ACK BEL */ @@ -159,7 +159,7 @@ err_set_file(void *fp) void err_set_exit(void (*ef)(int)) { - _e_err_exit.type = ERR_EXIT_FUNC; + _e_err_exit.type = ef ? ERR_EXIT_FUNC : ERR_EXIT_UNDEF; _e_err_exit.func = ef; } @@ -167,7 +167,7 @@ err_set_exit(void (*ef)(int)) void err_set_exit_b(void (^ef)(int)) { - _e_err_exit.type = ERR_EXIT_BLOCK; + _e_err_exit.type = ef ? ERR_EXIT_BLOCK : ERR_EXIT_UNDEF; _e_err_exit.block = Block_copy(ef); } #endif /* __BLOCKS__ */ @@ -213,13 +213,17 @@ verrc(int eval, int code, const char *fmt, va_list ap) fprintf(_e_err_file, ": "); } fprintf(_e_err_file, "%s\n", strerror(code)); - if (_e_err_exit.type) + if (_e_err_exit.type) { #ifdef __BLOCKS__ - if (_e_err_exit.type == ERR_EXIT_BLOCK) + if (_e_err_exit.type == ERR_EXIT_BLOCK) { _e_err_exit.block(eval); - else -#endif /* __BLOCKS__ */ + } else { _e_err_exit.func(eval); + } +#else + _e_err_exit.func(eval); +#endif /* __BLOCKS__ */ + } exit(eval); } @@ -241,13 +245,17 @@ verrx(int eval, const char *fmt, va_list ap) if (fmt != NULL) _e_visprintf(_e_err_file, fmt, ap); fprintf(_e_err_file, "\n"); - if (_e_err_exit.type) + if (_e_err_exit.type) { #ifdef __BLOCKS__ - if (_e_err_exit.type == ERR_EXIT_BLOCK) + if (_e_err_exit.type == ERR_EXIT_BLOCK) { _e_err_exit.block(eval); - else -#endif /* __BLOCKS__ */ + } else { _e_err_exit.func(eval); + } +#else + _e_err_exit.func(eval); +#endif /* __BLOCKS__ */ + } exit(eval); } diff --git a/src/libc/gen/FreeBSD/fmtmsg.c b/src/libc/gen/FreeBSD/fmtmsg.c index e912693d0..ada1c9dda 100644 --- a/src/libc/gen/FreeBSD/fmtmsg.c +++ b/src/libc/gen/FreeBSD/fmtmsg.c @@ -47,7 +47,7 @@ static const char *sevinfo(int); static int validmsgverb(const char *); -static const char *validlist[] = { +static const char * const validlist[] = { "label", "severity", "text", "action", "tag", NULL }; diff --git a/src/libc/gen/FreeBSD/fnmatch.c b/src/libc/gen/FreeBSD/fnmatch.c index 51a1f9755..f016eef8e 100644 --- a/src/libc/gen/FreeBSD/fnmatch.c +++ b/src/libc/gen/FreeBSD/fnmatch.c @@ -286,7 +286,7 @@ rangematch(pattern, test, string, flags, newp, news, patmbs, strmbs, loc) pattern++; else if (*pattern == '[' && ((special = *(pattern + 1)) == '.' || special == '=' || special == ':')) { cp = (pattern += 2); - while(cp = strchr(cp, special)) { + while((cp = strchr(cp, special))) { if (*(cp + 1) == ']') break; cp++; @@ -351,8 +351,9 @@ treat_like_collating_symbol: *(cp + 3) != ']') return (RANGE_ERROR); len = __collate_equiv_match(ec, NULL, 0, test, string, strlen(string), strmbs, &sclen, loc); - if (len < 0) + if (len == (size_t)-1) { return (RANGE_ERROR); + } if (len > 0) { ok = 1; string += sclen; @@ -402,12 +403,12 @@ treat_like_collating_symbol: if (c2 == EOS) return (RANGE_ERROR); - if (c2 == '[' && (special = *pattern) == '.' || special == '=' || special == ':') { + if ((c2 == '[' && (special = *pattern) == '.') || special == '=' || special == ':') { /* no equivalence classes or character classes as end of range */ if (special == '=' || special == ':') return (RANGE_ERROR); cp = ++pattern; - while(cp = strchr(cp, special)) { + while((cp = strchr(cp, special))) { if (*(cp + 1) == ']') break; cp++; diff --git a/src/libc/gen/FreeBSD/getbsize.3 b/src/libc/gen/FreeBSD/getbsize.3 index 55d334856..2caf5fe1c 100644 --- a/src/libc/gen/FreeBSD/getbsize.3 +++ b/src/libc/gen/FreeBSD/getbsize.3 @@ -26,14 +26,14 @@ .\" SUCH DAMAGE. .\" .\" @(#)getbsize.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/getbsize.3,v 1.11 2007/01/09 00:27:53 imp Exp $ +.\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd November 16, 2012 .Dt GETBSIZE 3 .Os .Sh NAME .Nm getbsize -.Nd get user block size +.Nd get preferred block size .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -43,11 +43,31 @@ .Sh DESCRIPTION The .Fn getbsize -function determines the user's preferred block size based on the value of the -.Dq BLOCKSIZE -environment variable; see -.Xr environ 7 -for details on its use and format. +function returns a preferred block size for reporting by system utilities +.Xr df 1 , +.Xr du 1 , +.Xr ls 1 +and +.Xr systat 1 , +based on the value of the +.Ev BLOCKSIZE +environment variable. +.Ev BLOCKSIZE +may be specified directly in bytes, or in multiples of a kilobyte by +specifying a number followed by ``K'' or ``k'', in multiples of a +megabyte by specifying a number followed by ``M'' or ``m'' or in +multiples of a gigabyte by specifying a number followed by ``G'' or +``g''. +Multiples must be integers. +.Pp +Valid values of +.Ev BLOCKSIZE +are 512 bytes to 1 gigabyte. +Sizes less than 512 bytes are rounded up to 512 bytes, and sizes +greater than 1 GB are rounded down to 1 GB. +In each case +.Fn getbsize +produces a warning message. .Pp The .Fn getbsize @@ -61,10 +81,6 @@ terminating null). The memory referenced by .Fa blocksizep is filled in with block size, in bytes. -.Pp -If the user's block size is unreasonable, a warning message is -written to standard error and the returned information reflects -a block size of 512 bytes. .Sh SEE ALSO .Xr df 1 , .Xr du 1 , diff --git a/src/libc/gen/FreeBSD/getbsize.c b/src/libc/gen/FreeBSD/getbsize.c index b213c37fb..bbf5b1e89 100644 --- a/src/libc/gen/FreeBSD/getbsize.c +++ b/src/libc/gen/FreeBSD/getbsize.c @@ -31,7 +31,7 @@ static char sccsid[] = "@(#)getbsize.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/getbsize.c,v 1.9 2008/08/04 06:53:13 cperciva Exp $"); +__FBSDID("$FreeBSD$"); #include #include @@ -39,9 +39,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/getbsize.c,v 1.9 2008/08/04 06:53:13 cperci #include char * -getbsize(headerlenp, blocksizep) - int *headerlenp; - long *blocksizep; +getbsize(int *headerlenp, long *blocksizep) { static char header[20]; long n, max, mul, blocksize; diff --git a/src/libc/gen/FreeBSD/getcwd.c b/src/libc/gen/FreeBSD/getcwd.c index 512b88cd6..c41854896 100644 --- a/src/libc/gen/FreeBSD/getcwd.c +++ b/src/libc/gen/FreeBSD/getcwd.c @@ -143,7 +143,7 @@ __private_getcwd(pt, size, usegetpath) ino_t root_ino; size_t ptsize, upsize; int save_errno; - char *ept, *eup, *up, c; + char *ept, *eup, *up; /* * If no buffer specified by the user, allocate one as necessary. diff --git a/src/libc/gen/FreeBSD/getlogin.c b/src/libc/gen/FreeBSD/getlogin.c index f60de8de4..ce4efc2fb 100644 --- a/src/libc/gen/FreeBSD/getlogin.c +++ b/src/libc/gen/FreeBSD/getlogin.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/getlogin.c,v 1.11 2009/12/05 19:04:21 ed Ex #include #include #include +#include #include #include #include "namespace.h" @@ -45,28 +46,30 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/getlogin.c,v 1.11 2009/12/05 19:04:21 ed Ex #include "libc_private.h" -#define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&logname_mutex) -#define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&logname_mutex) +extern int __getlogin(char *, int); -extern int __getlogin(char *, int); - -int _logname_valid; /* known to setlogin() */ -static pthread_mutex_t logname_mutex = PTHREAD_MUTEX_INITIALIZER; +__private_extern__ pthread_mutex_t __logname_mutex = PTHREAD_MUTEX_INITIALIZER; +__private_extern__ char *__logname = NULL; static char * getlogin_basic(int *status) { - static char logname[MAXLOGNAME]; + if (__logname == NULL) { + __logname = calloc(1, MAXLOGNAME); + if (__logname == NULL) { + *status = ENOMEM; + return (NULL); + } + } - if (_logname_valid == 0) { - if (__getlogin(logname, sizeof(logname)) < 0) { + if (__logname[0] == 0) { + if (__getlogin(__logname, MAXLOGNAME) < 0) { *status = errno; return (NULL); } - _logname_valid = 1; } *status = 0; - return (*logname ? logname : NULL); + return (*__logname ? __logname : NULL); } char * @@ -75,9 +78,9 @@ getlogin(void) char *result; int status; - THREAD_LOCK(); + pthread_mutex_lock(&__logname_mutex); result = getlogin_basic(&status); - THREAD_UNLOCK(); + pthread_mutex_unlock(&__logname_mutex); return (result); } @@ -87,15 +90,15 @@ getlogin_r(char *logname, size_t namelen) char *result; int len; int status; - - THREAD_LOCK(); + + pthread_mutex_lock(&__logname_mutex); result = getlogin_basic(&status); if (status == 0) { - if ((len = strlen(result) + 1) > namelen) + if (strlcpy(logname, __logname, namelen) > namelen) { status = ERANGE; - else - strncpy(logname, result, len); + } } - THREAD_UNLOCK(); + pthread_mutex_unlock(&__logname_mutex); + return (status); } diff --git a/src/libc/gen/FreeBSD/pause.c b/src/libc/gen/FreeBSD/pause.c index 99576fdc4..2cb962cb1 100644 --- a/src/libc/gen/FreeBSD/pause.c +++ b/src/libc/gen/FreeBSD/pause.c @@ -27,16 +27,14 @@ * SUCH DAMAGE. */ +#if defined(VARIANT_CANCELABLE) && __DARWIN_NON_CANCELABLE != 0 +#error cancellable call vs. __DARWIN_NON_CANCELABLE mismatch +#endif + #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ -/* For the cancelable variant, we call the cancelable sigsuspend */ -#ifdef VARIANT_CANCELABLE -#undef __DARWIN_NON_CANCELABLE -#define __DARWIN_NON_CANCELABLE 0 -#endif /* VARIANT_CANCELABLE */ - #include __FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.8 2009/12/05 19:31:38 ed Exp $"); diff --git a/src/libc/gen/FreeBSD/pselect.3 b/src/libc/gen/FreeBSD/pselect.3 deleted file mode 100644 index 615a399b0..000000000 --- a/src/libc/gen/FreeBSD/pselect.3 +++ /dev/null @@ -1,127 +0,0 @@ -.\" -.\" Copyright 2002 Massachusetts Institute of Technology -.\" -.\" Permission to use, copy, modify, and distribute this software and -.\" its documentation for any purpose and without fee is hereby -.\" granted, provided that both the above copyright notice and this -.\" permission notice appear in all copies, that both the above -.\" copyright notice and this permission notice appear in all -.\" supporting documentation, and that the name of M.I.T. not be used -.\" in advertising or publicity pertaining to distribution of the -.\" software without specific, written prior permission. M.I.T. makes -.\" no representations about the suitability of this software for any -.\" purpose. It is provided "as is" without express or implied -.\" warranty. -.\" -.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS -.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, -.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT -.\" SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc/gen/pselect.3,v 1.4 2002/12/18 10:13:54 ru Exp $ -.\" -.Dd June 16, 2002 -.Dt PSELECT 3 -.Os -.Sh NAME -.Nm pselect -.Nd synchronous I/O multiplexing a la POSIX.1g -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In unistd.h -.Ft int -.Fo pselect -.Fa "int nfds" -.Fa "fd_set *restrict readfds" -.Fa "fd_set *restrict writefds" -.Fa "fd_set *restrict errorfds" -.Fa "const struct timespec *restrict timeout" -.Fa "const sigset_t *restrict sigmask" -.Fc -.Sh DESCRIPTION -The -.Fn pselect -function was introduced by -.St -p1003.1g-2000 -as a slightly stronger version of -.Xr select 2 . -The -.Fa nfds , readfds , writefds , -and -.Fa errorfds -arguments are all identical to the analogous arguments of -.Fn select . -The -.Fa timeout -argument in -.Fn pselect -points to a -.Vt "const struct timespec" , -rather than the (modifiable) -.Vt "struct timeval" -used by -.Fn select ; -as in -.Fn select , -a null pointer may be passed to indicate that -.Fn pselect -should wait indefinitely. -Finally, -.Fa sigmask -specifies a signal mask which is set while waiting for input. -When -.Fn pselect -returns, the original signal mask is restored. -.Pp -See -.Xr select 2 -for a more detailed discussion of the semantics of this interface, and -for macros used to manipulate the -.Vt "fd_set" -data type. -.Sh IMPLEMENTATION NOTES -The -.Fn pselect -function is implemented in the C library as a wrapper around -.Fn select . -.Sh RETURN VALUES -The -.Fn pselect -function returns the same values and under the same conditions as -.Fn select . -.Sh ERRORS -The -.Fn pselect -function may fail for any of the reasons documented for -.Xr select 2 -and (if a signal mask is provided) -.Xr sigprocmask 2 . -.Sh SEE ALSO -.Xr kqueue 2 , -.Xr poll 2 , -.Xr select 2 , -.Xr sigprocmask 2 -.Sh STANDARDS -The -.Fn pselect -function conforms to -.St -p1003.1-2001 . -.Sh HISTORY -The -.Fn pselect -function first appeared in -.Fx 5.0 . -.Sh AUTHORS -The -.Fn pselect -function and this manual page were written by -.An Garrett Wollman Aq wollman@FreeBSD.org . diff --git a/src/libc/gen/FreeBSD/pselect.c b/src/libc/gen/FreeBSD/pselect.c deleted file mode 100644 index 4bc62fc2f..000000000 --- a/src/libc/gen/FreeBSD/pselect.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2000 Massachusetts Institute of Technology - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby - * granted, provided that both the above copyright notice and this - * permission notice appear in all copies, that both the above - * copyright notice and this permission notice appear in all - * supporting documentation, and that the name of M.I.T. not be used - * in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. M.I.T. makes - * no representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS - * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT - * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050) -#undef __DARWIN_NON_CANCELABLE -#endif /* VARIANT_CANCELABLE */ - -#ifdef VARIANT_DARWINEXTSN -#define _DARWIN_UNLIMITED_SELECT -#endif /* VARIANT_DARWINEXTSN */ - -#include -__FBSDID("$FreeBSD: src/lib/libc/gen/pselect.c,v 1.6 2002/10/12 16:13:37 mike Exp $"); - -#include "namespace.h" -#include -#include -#include -#include - -#include -#include -#include "un-namespace.h" - -__weak_reference(__pselect, pselect); - -/* - * Emulate the POSIX 1003.1g-2000 `pselect' interface. This is the - * same as the traditional BSD `select' function, except that it uses - * a timespec rather than a timeval, doesn't modify the timeout argument, - * and allows the user to specify a signal mask to apply during the select. - */ -int -__pselect(int count, fd_set * __restrict rfds, fd_set * __restrict wfds, - fd_set * __restrict efds, const struct timespec * __restrict timo, - const sigset_t * __restrict mask) -{ - sigset_t omask; - struct timeval tvtimo, *tvp; - int rv, sverrno; - - if (timo) { - TIMESPEC_TO_TIMEVAL(&tvtimo, timo); - tvp = &tvtimo; - } else - tvp = 0; - - if (mask != 0) { - rv = _sigprocmask(SIG_SETMASK, mask, &omask); - if (rv != 0) - return rv; - } - - rv = _select(count, rfds, wfds, efds, tvp); - if (mask != 0) { - sverrno = errno; - _sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0); - errno = sverrno; - } - - return rv; -} diff --git a/src/libc/gen/FreeBSD/raise.3 b/src/libc/gen/FreeBSD/raise.3 index dbdff2682..59649b2a3 100644 --- a/src/libc/gen/FreeBSD/raise.3 +++ b/src/libc/gen/FreeBSD/raise.3 @@ -30,14 +30,14 @@ .\" SUCH DAMAGE. .\" .\" @(#)raise.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/raise.3,v 1.8 2007/01/09 00:27:55 imp Exp $ +.\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd September 21, 2016 .Dt RAISE 3 .Os .Sh NAME .Nm raise -.Nd send a signal to the current process +.Nd send a signal to the current thread .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -49,7 +49,7 @@ The .Fn raise function sends the signal .Fa sig -to the current process. +to the current thread. .Sh RETURN VALUES .Rv -std raise .Sh ERRORS @@ -62,9 +62,10 @@ for any of the errors specified for the library functions .Xr getpid 2 and -.Xr kill 2 . +.Xr pthread_kill 2 . .Sh SEE ALSO -.Xr kill 2 +.Xr kill 2 , +.Xr pthread_kill 2 .Sh STANDARDS The .Fn raise diff --git a/src/libc/gen/FreeBSD/raise.c b/src/libc/gen/FreeBSD/raise.c deleted file mode 100644 index e9665e8f5..000000000 --- a/src/libc/gen/FreeBSD/raise.c +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)raise.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/gen/raise.c,v 1.5 2007/01/09 00:27:55 imp Exp $"); - -#include -#include - -__weak_reference(__raise, raise); -__weak_reference(__raise, _raise); - -int -__raise(s) - int s; -{ - return(kill(getpid(), s)); -} diff --git a/src/libc/gen/FreeBSD/readpassphrase.3 b/src/libc/gen/FreeBSD/readpassphrase.3 index 3bd361742..9f74b2f43 100644 --- a/src/libc/gen/FreeBSD/readpassphrase.3 +++ b/src/libc/gen/FreeBSD/readpassphrase.3 @@ -1,33 +1,26 @@ -.\" $OpenBSD: readpassphrase.3,v 1.7 2001/12/15 15:37:51 millert Exp $ +.\" $OpenBSD: readpassphrase.3,v 1.17 2007/05/31 19:19:28 jmc Exp $ .\" -.\" Copyright (c) 2000 Todd C. Miller -.\" All rights reserved. +.\" Copyright (c) 2000, 2002 Todd C. Miller .\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. .\" -.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.\" $FreeBSD: src/lib/libc/gen/readpassphrase.3,v 1.7 2005/01/20 09:17:02 ru Exp $ +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. .\" -.Dd December 7, 2001 +.\" $FreeBSD$ +.\" +.Dd May 31, 2007 .Dt READPASSPHRASE 3 .Os .Sh NAME @@ -79,6 +72,8 @@ force input to lower case force input to upper case .It Dv RPP_SEVENBIT strip the high bit from input +.It Dv RPP_STDIN +force read of passphrase from stdin .El .Pp The calling process should zero the passphrase as soon as possible to @@ -87,7 +82,7 @@ space. .Sh RETURN VALUES Upon successful completion, .Fn readpassphrase -returns a pointer to the null-terminated passphrase. +returns a pointer to the NUL-terminated passphrase. If an error is encountered, the terminal state is restored and a .Dv NULL @@ -117,40 +112,6 @@ if (compare(transform(passbuf), epass) != 0) memset(passbuf, 0, sizeof(passbuf)); .Ed -.Sh SIGNALS -The -.Fn readpassphrase -function -will catch the following signals: -.Pp -.Bl -tag -compact -.It Dv SIGINT -.It Dv SIGHUP -.It Dv SIGQUIT -.It Dv SIGTERM -.It Dv SIGTSTP -.It Dv SIGTTIN -.It Dv SIGTTOU -.El -.Pp -When one of the above signals is intercepted, terminal echo will -be restored if it had previously been turned off. -If a signal handler was installed for the signal when -.Fn readpassphrase -was called that handler is then executed. -If no handler was previously installed for the signal then the -default action is taken as per -.Xr sigaction 2 . -.Pp -The -.Dv SIGTSTP , SIGTTIN , -and -.Dv SIGTTOU -signals (stop signal generated from keyboard or due to terminal I/O -from a background process) are treated specially. -When the process is resumed after it has been stopped, -.Fn readpassphrase -will reprint the prompt and the user may then enter a passphrase. .Sh ERRORS .Bl -tag -width Er .It Bq Er EINTR @@ -159,14 +120,14 @@ The function was interrupted by a signal. .It Bq Er EINVAL The -.Fa bufsiz +.Ar bufsiz argument was zero. .It Bq Er EIO The process is a member of a background process attempting to read from its controlling terminal, the process is ignoring or blocking the .Dv SIGTTIN -signal or the process group is orphaned. +signal, or the process group is orphaned. .It Bq Er EMFILE The process has already reached its limit for open file descriptors. .It Bq Er ENFILE @@ -176,6 +137,35 @@ There is no controlling terminal and the .Dv RPP_REQUIRE_TTY flag was specified. .El +.Sh SIGNALS +The +.Fn readpassphrase +function +will catch the following signals: +.Bd -literal -offset indent +SIGALRM SIGHUP SIGINT +SIGPIPE SIGQUIT SIGTERM +SIGTSTP SIGTTIN SIGTTOU +.Ed +.Pp +When one of the above signals is intercepted, terminal echo will +be restored if it had previously been turned off. +If a signal handler was installed for the signal when +.Fn readpassphrase +was called, that handler is then executed. +If no handler was previously installed for the signal then the +default action is taken as per +.Xr sigaction 2 . +.Pp +The +.Dv SIGTSTP , SIGTTIN +and +.Dv SIGTTOU +signals (stop signals generated from keyboard or due to terminal I/O +from a background process) are treated specially. +When the process is resumed after it has been stopped, +.Fn readpassphrase +will reprint the prompt and the user may then enter a passphrase. .Sh SEE ALSO .Xr sigaction 2 , .Xr getpass 3 @@ -189,3 +179,5 @@ The .Fn readpassphrase function first appeared in .Ox 2.9 . +.Dv RPP_STDIN +was introduced in OS X 10.12. diff --git a/src/libc/gen/FreeBSD/readpassphrase.c b/src/libc/gen/FreeBSD/readpassphrase.c index 45ac15f29..646a8c6d8 100644 --- a/src/libc/gen/FreeBSD/readpassphrase.c +++ b/src/libc/gen/FreeBSD/readpassphrase.c @@ -1,37 +1,27 @@ -/* $OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $ */ +/* $OpenBSD: readpassphrase.c,v 1.24 2013/11/24 23:51:29 deraadt Exp $ */ /* - * Copyright (c) 2000 Todd C. Miller - * All rights reserved. + * Copyright (c) 2000-2002, 2007, 2010 + * Todd C. Miller * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/readpassphrase.c,v 1.6 2002/03/09 03:16:41 green Exp $"); #include "xlocale_private.h" @@ -47,8 +37,9 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/readpassphrase.c,v 1.6 2002/03/09 03:16:41 #include #include #include "un-namespace.h" +#include "libc_private.h" -static volatile sig_atomic_t signo; +static volatile int signo[NSIG]; static void handler(int); @@ -56,11 +47,11 @@ char * readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) { ssize_t nr; - int input, output, save_errno; + int input, output, save_errno, i, need_restart, input_is_tty; char ch, *p, *end; struct termios term, oterm; - struct sigaction sa, saveint, savehup, savequit, saveterm; - struct sigaction savetstp, savettin, savettou; + struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; + struct sigaction savetstp, savettin, savettou, savepipe; locale_t loc = __current_locale(); /* I suppose we could alloc on demand in this case (XXX). */ @@ -70,59 +61,83 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) } restart: + for (i = 0; i < NSIG; i++) + signo[i] = 0; + nr = -1; + save_errno = 0; + need_restart = 0; /* * Read and write to /dev/tty if available. If not, read from * stdin and write to stderr unless a tty is required. */ - if ((input = output = _open(_PATH_TTY, O_RDWR)) == -1) { - if (flags & RPP_REQUIRE_TTY) { - errno = ENOTTY; - return(NULL); + input_is_tty = 0; + if (!(flags & RPP_STDIN)) { + input = output = _open(_PATH_TTY, O_RDWR | O_CLOEXEC); + if (input == -1) { + if (flags & RPP_REQUIRE_TTY) { + errno = ENOTTY; + return(NULL); + } + input = STDIN_FILENO; + output = STDERR_FILENO; + } else { + input_is_tty = 1; } + } else { input = STDIN_FILENO; output = STDERR_FILENO; } + /* + * Turn off echo if possible. + * If we are using a tty but are not the foreground pgrp this will + * generate SIGTTOU, so do it *before* installing the signal handlers. + */ + if (input_is_tty && tcgetattr(input, &oterm) == 0) { + memcpy(&term, &oterm, sizeof(term)); + if (!(flags & RPP_ECHO_ON)) + term.c_lflag &= ~(ECHO | ECHONL); + if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) + term.c_cc[VSTATUS] = _POSIX_VDISABLE; + (void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); + } else { + memset(&term, 0, sizeof(term)); + term.c_lflag |= ECHO; + memset(&oterm, 0, sizeof(oterm)); + oterm.c_lflag |= ECHO; + } + /* * Catch signals that would otherwise cause the user to end * up with echo turned off in the shell. Don't worry about - * things like SIGALRM and SIGPIPE for now. + * things like SIGXCPU and SIGVTALRM for now. */ sigemptyset(&sa.sa_mask); sa.sa_flags = 0; /* don't restart system calls */ sa.sa_handler = handler; - (void)_sigaction(SIGINT, &sa, &saveint); + (void)_sigaction(SIGALRM, &sa, &savealrm); (void)_sigaction(SIGHUP, &sa, &savehup); + (void)_sigaction(SIGINT, &sa, &saveint); + (void)_sigaction(SIGPIPE, &sa, &savepipe); (void)_sigaction(SIGQUIT, &sa, &savequit); (void)_sigaction(SIGTERM, &sa, &saveterm); (void)_sigaction(SIGTSTP, &sa, &savetstp); (void)_sigaction(SIGTTIN, &sa, &savettin); (void)_sigaction(SIGTTOU, &sa, &savettou); - /* Turn off echo if possible. */ - if (tcgetattr(input, &oterm) == 0) { - memcpy(&term, &oterm, sizeof(term)); - if (!(flags & RPP_ECHO_ON)) - term.c_lflag &= ~(ECHO | ECHONL); - if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) - term.c_cc[VSTATUS] = _POSIX_VDISABLE; - (void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term); - } else { - memset(&term, 0, sizeof(term)); - memset(&oterm, 0, sizeof(oterm)); - } - - (void)_write(output, prompt, strlen(prompt)); + if (!(flags & RPP_STDIN)) + (void)_write(output, prompt, strlen(prompt)); end = buf + bufsiz - 1; - for (p = buf; (nr = _read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { + p = buf; + while ((nr = _read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { if (p < end) { if ((flags & RPP_SEVENBIT)) ch &= 0x7f; if (isalpha_l(ch, loc)) { if ((flags & RPP_FORCELOWER)) - ch = tolower_l(ch, loc); + ch = (char)tolower_l(ch, loc); if ((flags & RPP_FORCEUPPER)) - ch = toupper_l(ch, loc); + ch = (char)toupper_l(ch, loc); } *p++ = ch; } @@ -133,49 +148,66 @@ restart: (void)_write(output, "\n", 1); /* Restore old terminal settings and signals. */ - if (memcmp(&term, &oterm, sizeof(term)) != 0) - (void)tcsetattr(input, TCSANOW|TCSASOFT, &oterm); - (void)_sigaction(SIGINT, &saveint, NULL); + if (memcmp(&term, &oterm, sizeof(term)) != 0) { + while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 && + errno == EINTR && !signo[SIGTTOU]) + continue; + } + (void)_sigaction(SIGALRM, &savealrm, NULL); (void)_sigaction(SIGHUP, &savehup, NULL); + (void)_sigaction(SIGINT, &saveint, NULL); (void)_sigaction(SIGQUIT, &savequit, NULL); + (void)_sigaction(SIGPIPE, &savepipe, NULL); (void)_sigaction(SIGTERM, &saveterm, NULL); (void)_sigaction(SIGTSTP, &savetstp, NULL); (void)_sigaction(SIGTTIN, &savettin, NULL); (void)_sigaction(SIGTTOU, &savettou, NULL); - if (input != STDIN_FILENO) + if (input_is_tty) (void)_close(input); /* * If we were interrupted by a signal, resend it to ourselves * now that we have restored the signal handlers. */ - if (signo) { - kill(getpid(), signo); - switch (signo) { - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - signo = 0; - goto restart; + for (i = 0; i < NSIG; i++) { + if (signo[i]) { + kill(getpid(), i); + switch (i) { + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + need_restart = 1; + } } } + if (need_restart) + goto restart; - errno = save_errno; + if (save_errno) + errno = save_errno; return(nr == -1 ? NULL : buf); } char * getpass(const char *prompt) { - static char buf[_PASSWORD_LEN + 1]; + const size_t bufsiz = _PASSWORD_LEN + 1; + static char *buf = NULL; - if (readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF) == NULL) + if (buf == NULL) { + buf = malloc(bufsiz); + if (buf == NULL) { + return NULL; + } + } + + if (readpassphrase(prompt, buf, bufsiz, RPP_ECHO_OFF) == NULL) { buf[0] = '\0'; - return(buf); + } + return buf; } static void handler(int s) { - - signo = s; + signo[s] = 1; } diff --git a/src/libc/gen/FreeBSD/scandir.3 b/src/libc/gen/FreeBSD/scandir.3 index d8b81f391..f09b0942b 100644 --- a/src/libc/gen/FreeBSD/scandir.3 +++ b/src/libc/gen/FreeBSD/scandir.3 @@ -61,7 +61,8 @@ entries using It returns the number of entries in the array. A pointer to the array of directory entries is stored in the location referenced by -.Fa namelist . +.Fa namelist +(even if the number of entries is 0). .Pp The .Fa select diff --git a/src/libc/gen/FreeBSD/sleep.c b/src/libc/gen/FreeBSD/sleep.c index 9d2095e35..a04789da6 100644 --- a/src/libc/gen/FreeBSD/sleep.c +++ b/src/libc/gen/FreeBSD/sleep.c @@ -27,10 +27,9 @@ * SUCH DAMAGE. */ -#ifdef VARIANT_CANCELABLE -#undef __DARWIN_NON_CANCELABLE -#define __DARWIN_NON_CANCELABLE 0 -#endif /* VARIANT_CANCELABLE */ +#if defined(VARIANT_CANCELABLE) && __DARWIN_NON_CANCELABLE != 0 +#error cancellable call vs. __DARWIN_NON_CANCELABLE mismatch +#endif #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; diff --git a/src/libc/gen/FreeBSD/sysconf.c b/src/libc/gen/FreeBSD/sysconf.c index 2b9dc6cf9..ca90c7a38 100644 --- a/src/libc/gen/FreeBSD/sysconf.c +++ b/src/libc/gen/FreeBSD/sysconf.c @@ -13,10 +13,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -38,7 +34,7 @@ static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/gen/sysconf.c,v 1.20 2002/11/17 08:54:29 dougb Exp $"); +__FBSDID("$FreeBSD: lib/libc/gen/sysconf.c r168718 $"); #include #include @@ -80,10 +76,9 @@ sysconf(name) quad_t qdvalue; /* for kern.sysv.shmmin */ size_t len; int mib[3], sverrno, value; - long defaultresult; + long lvalue, defaultresult; const char *path; - len = sizeof(value); defaultresult = -1; switch (name) { @@ -173,11 +168,11 @@ sysconf(name) do_NAME_MAX: sverrno = errno; errno = 0; - value = pathconf(path, _PC_NAME_MAX); - if (value == -1 && errno != 0) + lvalue = pathconf(path, _PC_NAME_MAX); + if (lvalue == -1 && errno != 0) return (-1); errno = sverrno; - return (value); + return (lvalue); case _SC_ASYNCHRONOUS_IO: #if _POSIX_ASYNCHRONOUS_IO == 0 @@ -257,11 +252,23 @@ do_NAME_MAX: return (_POSIX_TIMERS); #endif case _SC_AIO_LISTIO_MAX: +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_AIO_LISTIO_MAX) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_AIO_LISTIO_MAX; +#else + mib[0] = CTL_KERN;; + mib[1] = KERN_AIOMAX; +#endif + break; case _SC_AIO_MAX: +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_AIO_MAX) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_AIO_MAX; +#else mib[0] = CTL_KERN;; mib[1] = KERN_AIOMAX; +#endif break; - case _SC_AIO_PRIO_DELTA_MAX: #if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_AIO_PRIO_DELTA_MAX) mib[0] = CTL_P1003_1B; @@ -304,7 +311,14 @@ do_NAME_MAX: return (-1); #endif case _SC_SEM_NSEMS_MAX: +#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_RTSIG_MAX) + mib[0] = CTL_P1003_1B; + mib[1] = CTL_P1003_1B_SEM_NSEMS_MAX; + goto yesno; +#else + len = sizeof(value); return (sysctlbyname("kern.sysv.semmns", &value, &len, NULL, 0) == -1 ? -1 : value); +#endif case _SC_SEM_VALUE_MAX: #if SEM_VALUE_MAX == 0 @@ -330,18 +344,34 @@ do_NAME_MAX: return (-1); #endif -yesno: if (sysctl(mib, 2, &value, &len, NULL, 0) == -1) +yesno: + len = sizeof(value); + if (sysctl(mib, 2, &value, &len, NULL, 0) == -1) return (-1); if (value == 0) return (defaultresult); - return (value); + return ((long)value); + case _SC_2_PBS: case _SC_2_PBS_ACCOUNTING: case _SC_2_PBS_CHECKPOINT: case _SC_2_PBS_LOCATE: case _SC_2_PBS_MESSAGE: case _SC_2_PBS_TRACK: - return -1; +#if _POSIX2_PBS == 0 +#error "don't know how to determine _SC_2_PBS" + /* + * This probably requires digging through the filesystem + * to see if the appropriate package has been installed. + * Since we don't currently support this option at all, + * it's not worth the effort to write the code now. + * Figuring out which of the sub-options are supported + * would be even more difficult, so it's probably easier + * to always say ``no''. + */ +#else + return (_POSIX2_PBS); +#endif case _SC_ADVISORY_INFO: #if _POSIX_ADVISORY_INFO == 0 #error "_POSIX_ADVISORY_INFO" @@ -619,9 +649,37 @@ yesno: if (sysctl(mib, 2, &value, &len, NULL, 0) == -1) case _SC_PASS_MAX: return (PASS_MAX); +#ifdef _SC_PHYS_PAGES + case _SC_PHYS_PAGES: +#ifdef __APPLE__ + { + long memsize; + long pagesize; + + len = sizeof(memsize); + if (sysctlbyname("hw.memsize", &memsize, &len, NULL, 0) == -1) + return (-1); + + len = sizeof(pagesize); + if (sysctlbyname("hw.pagesize", &pagesize, &len, NULL, 0) == -1) + return (-1); + + return (memsize / pagesize); + } +#else + len = sizeof(lvalue); + if (sysctlbyname("hw.availpages", &lvalue, &len, NULL, 0) == -1) + return (-1); + return (lvalue); +#endif +#endif + default: errno = EINVAL; return (-1); } - return (sysctl(mib, 2, &value, &len, NULL, 0) == -1 ? -1 : value); + len = sizeof(value); + if (sysctl(mib, 2, &value, &len, NULL, 0) == -1) + value = -1; + return ((long)value); } diff --git a/src/libc/gen/FreeBSD/sysctl.3 b/src/libc/gen/FreeBSD/sysctl.3 index 8c8e4bc75..90c199085 100644 --- a/src/libc/gen/FreeBSD/sysctl.3 +++ b/src/libc/gen/FreeBSD/sysctl.3 @@ -9,10 +9,6 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)sysctl.3 8.4 (Berkeley) 5/9/95 -.\" $FreeBSD: src/lib/libc/gen/sysctl.3,v 1.63 2004/07/02 23:52:10 ru Exp $ +.\" $FreeBSD$ .\" -.Dd October 21, 2008 +.Dd May 17, 2013 .Dt SYSCTL 3 .Os .Sh NAME @@ -155,48 +151,13 @@ repeatedly request the same variable (the function runs in about a third the time as the same request made via the .Fn sysctlbyname function). -The -.Fn sysctlnametomib -function is also useful for fetching mib prefixes and then adding -a final component. -For example, to fetch process information -for processes with pid's less than 100: -.Pp -.Bd -literal -offset indent -compact -int i, mib[4]; -size_t len; -struct kinfo_proc kp; - -/* Fill out the first three components of the mib */ -len = 4; -sysctlnametomib("kern.proc.pid", mib, &len); - -/* Fetch and print entries for pid's < 100 */ -for (i = 0; i < 100; i++) { - mib[3] = i; - len = sizeof(kp); - if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1) - perror("sysctl"); - else if (len > 0) - printkproc(&kp); -} -.Ed -.Pp -Note: Implementation of -.Fn printkproc --- to print whatever data deemed necessary from the large -.Vt kinfo_proc -structure ( -.In sys/sysctl.h -) -- is left as an exercise for the reader. .Pp The top level names are defined with a CTL_ prefix in .In sys/sysctl.h , and are as follows. The next and subsequent levels down are found in the include files listed here, and described in separate sections below. -.Pp -.Bl -column CTLXMACHDEP "Next level names" -offset indent +.Bl -column CTLXMACHDEPXXX "Next level namesXXXXXX" -offset indent .It Sy "Name Next level names Description" .It "CTL_DEBUG sys/sysctl.h Debugging" .It "CTL_VFS sys/mount.h File system" @@ -206,61 +167,25 @@ listed here, and described in separate sections below. .It "CTL_NET sys/socket.h Networking" .It "CTL_USER sys/sysctl.h User-level" .It "CTL_VM sys/resources.h Virtual memory (struct loadavg)" -.It "CTL_VM sys/vmmeter.h Virtual memory (struct vmtotal)" .El .Pp For example, the following retrieves the maximum number of processes allowed in the system: .Pp .Bd -literal -offset indent -compact -int mib[2], maxproc; -size_t len; - -mib[0] = CTL_KERN; -mib[1] = KERN_MAXPROC; -len = sizeof(maxproc); -sysctl(mib, 2, &maxproc, &len, NULL, 0); +int maxproc; +size_t len = sizeof(maxproc); +sysctlbyname("kern.maxproc", &maxproc, &len, NULL, 0); .Ed .Pp To retrieve the standard search path for the system utilities: .Pp .Bd -literal -offset indent -compact -int mib[2]; -size_t len; char *p; - -mib[0] = CTL_USER; -mib[1] = USER_CS_PATH; -sysctl(mib, 2, NULL, &len, NULL, 0); +size_t len; +sysctlbyname("user.cs_path", NULL, &len, NULL, 0); p = malloc(len); -sysctl(mib, 2, p, &len, NULL, 0); -.Ed -.Ss CTL_DEBUG -The debugging variables vary from system to system. -A debugging variable may be added or deleted without need to recompile -.Fn sysctl -to know about it. -Each time it runs, -.Fn sysctl -gets the list of debugging variables from the kernel and -displays their current values. -The system defines twenty -.Pq Vt "struct ctldebug" -variables named -.Va debug0 -through -.Va debug19 . -They are declared as separate variables so that they can be -individually initialized at the location of their associated variable. -The loader prevents multiple use of the same variable by issuing errors -if a variable is initialized in more than one place. -For example, to export the variable -.Va dospecialcheck -as a debugging variable, the following declaration would be used: -.Pp -.Bd -literal -offset indent -compact -int dospecialcheck = 1; -struct ctldebug debug5 = { "dospecialcheck", &dospecialcheck }; +sysctlbyname("user.cs_path", p, &len, NULL, 0); .Ed .Ss CTL_VFS A distinguished second level name, VFS_GENERIC, @@ -284,53 +209,60 @@ The string and integer information available for the CTL_HW level is detailed below. The changeable column shows whether a process with appropriate privilege may change the value. -.Bl -column "Second level nameXXXXXX" integerXXX -offset indent -.It Sy "Second level name Type Changeable" -.It "HW_MACHINE string no" -.It "HW_MODEL string no" -.It "HW_NCPU integer no (DEPRECATED)" -.It "HW_BYTEORDER integer no" -.It "HW_PHYSMEM integer no" -.It "HW_MEMSIZE integer no" -.It "HW_USERMEM integer no" -.It "HW_PAGESIZE integer no" -.It "HW_FLOATINGPOINT integer no" -.It "HW_MACHINE_ARCH string no" -.\".It "HW_DISKNAMES integer no" -.\".It "HW_DISKSTATS integer no" +.Bl -column "xxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxx" -offset indent +.It Sy "Name Type Changeable" +.It "hw.activecpu int32_t no" +.It "hw.byteorder int32_t no" +.It "hw.cacheconfig uint64_t[] no" +.It "hw.cachelinesize int64_t no" +.It "hw.cachesize uint64_t[] no" +.It "hw.cpu64bit_capable int32_t no" +.It "hw.cpufamily int32_t no" +.It "hw.cpufrequency int64_t no" +.It "hw.cpufrequency_max int64_t no" +.It "hw.cpufrequency_min int64_t no" +.It "hw.cpusubtype int32_t no" +.It "hw.cputhreadtype int32_t no" +.It "hw.cputype int32_t no" +.It "hw.l1dcachesize int64_t no" +.It "hw.l1icachesize int64_t no" +.It "hw.l2cachesize int64_t no" +.It "hw.l3cachesize int64_t no" +.It "hw.logicalcpu int32_t no" +.It "hw.logicalcpu_max int32_t no" +.It "hw.machine char[] no" +.It "hw.memsize int64_t no" +.It "hw.model char[] no" +.It "hw.ncpu int32_t no" +.It "hw.packages int32_t no" +.It "hw.pagesize int64_t no" +.It "hw.physicalcpu int32_t no" +.It "hw.physicalcpu_max int32_t no" +.It "hw.tbfrequency int64_t no" .El -.Pp .Bl -tag -width 6n -.It Li HW_MACHINE -The machine class. -.It Li HW_MODEL -The machine model -.It Li HW_NCPU (DEPRECATED) -The number of cpus. It is recommended that you use "hw.physicalcpu" "hw.physicalcpu_max" "hw.logicalcpu" or "hw.logicalcpu_max" instead. -.It Li "hw.physicalcpu" -The number of physical processors available in the current power management mode. -.It Li "hw.physicalcpu_max" -The maximum number of physical processors that could be available this boot. +.It Li "hw.byteorder" +The byte order (4321 or 1234). +.It Li "hw.model" +The machine model. +.It Li "hw.ncpu" +The number of cpus. This attribute is deprecated and it is recommended that +.Va "hw.logicalcpu" , +.Va "hw.logicalcpu_max" , +.Va "hw.physicalcpu" , +or +.Va "hw.physicalcpu_max" +be used instead. .It Li "hw.logicalcpu" The number of logical processors available in the current power management mode. .It Li "hw.logicalcpu_max" The maximum number of logical processors that could be available this boot. -.It Li HW_BYTEORDER -The byteorder (4,321, or 1,234). -.It Li HW_PHYSMEM -The bytes of physical memory represented by a 32-bit integer (for backward compatibility). Use HW_MEMSIZE instead. -.It Li HW_MEMSIZE -The bytes of physical memory represented by a 64-bit integer. -.It Li HW_USERMEM -The bytes of non-kernel memory. -.It Li HW_PAGESIZE -The software page size. -.It Li HW_FLOATINGPOINT -Nonzero if the floating point support is in hardware. -.It Li HW_MACHINE_ARCH -The machine dependent architecture type. -.\".It Fa HW_DISKNAMES -.\".It Fa HW_DISKSTATS +.It Li "hw.physicalcpu" +The number of physical processors available in the current power management mode. +.It Li "hw.physicalcpu_max" +The maximum number of physical processors that could be available this boot. +.It Li "hw.pagesize" +The software page size in bytes. .El .Ss CTL_KERN The string and integer information available for the CTL_KERN level @@ -341,203 +273,170 @@ The types of data currently available are process information, system vnodes, the open file entries, routing table entries, virtual memory statistics, load average history, and clock rate information. -.Bl -column "KERNXMAXFILESPERPROCXXX" "struct clockrateXXX" -offset indent -.It Sy "Second level name Type Changeable" -.It "KERN_ARGMAX integer no" -.It "KERN_BOOTFILE string yes" -.It "KERN_BOOTTIME struct timeval no" -.It "KERN_CLOCKRATE struct clockinfo no" -.It "KERN_FILE struct file no" -.It "KERN_HOSTID integer yes" -.It "KERN_HOSTNAME string yes" -.It "KERN_JOB_CONTROL integer no" -.It "KERN_MAXFILES integer yes" -.It "KERN_MAXFILESPERPROC integer yes" -.It "KERN_MAXPROC integer no" -.It "KERN_MAXPROCPERUID integer yes" -.It "KERN_MAXVNODES integer yes" -.It "KERN_NGROUPS integer no" -.It "KERN_NISDOMAINNAME string yes" -.It "KERN_OSRELDATE integer no" -.It "KERN_OSRELEASE string no" -.It "KERN_OSREV integer no" -.It "KERN_OSTYPE string no" -.It "KERN_POSIX1 integer no" -.It "KERN_PROC struct kinfo_proc no" -.It "KERN_PROF node not applicable" -.It "KERN_QUANTUM integer yes" -.It "KERN_SAVED_IDS integer no" -.It "KERN_SECURELVL integer raise only" -.It "KERN_UPDATEINTERVAL integer no" -.It "KERN_VERSION string no" -.It "KERN_VNODE struct vnode no" +.Bl -column "xxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxx" -offset indent +.It Sy "Name Type Changeable" +.It "kern.argmax int32_t no" +.It "kern.bootargs char[] no" +.It "kern.boottime struct timeval no" +.It "kern.check_openevt int32_t yes" +.It "kern.clockrate struct clockinfo no" +.It "kern.coredump int32_t yes" +.It "kern.corefile char[] yes" +.It "kern.flush_cache_on_write int32_t yes" +.It "kern.hostid int32_t yes" +.It "kern.hostname char[] yes" +.It "kern.job_control int32_t no" +.It "kern.maxfiles int32_t yes" +.It "kern.maxfilesperproc int32_t yes" +.It "kern.maxnbuf int32_t yes" +.It "kern.maxproc int32_t yes" +.It "kern.maxprocperuid int32_t yes" +.It "kern.maxvnodes int32_t yes" +.It "kern.msgbuf int32_t yes" +.It "kern.nbuf int32_t no" +.It "kern.netboot int32_t no" +.It "kern.ngroups int32_t no" +.It "kern.nisdomainname char[] yes" +.It "kern.num_files int32_t no" +.It "kern.num_tasks int32_t no" +.It "kern.num_taskthreads int32_t no" +.It "kern.num_threads int32_t no" +.It "kern.num_vnodes int32_t no" +.It "kern.nx int32_t yes" +.It "kern.osrelease char[] no" +.It "kern.osrevision int32_t no" +.It "kern.ostype char[] no" +.It "kern.osversion char[] yes" +.It "kern.posix1version int32_t no" +.It "kern.procname char[] yes" +.It "kern.safeboot int32_t no" +.It "kern.saved_ids int32_t no" +.It "kern.secure_kernel int32_t no" +.It "kern.securelevel int32_t yes" +.It "kern.singleuser int32_t no" +.It "kern.sleeptime struct timeval no" +.It "kern.slide int32_t no" +.It "kern.stack_depth_max int32_t no" +.It "kern.stack_size int32_t no" +.It "kern.sugid_coredump int32_t yes" +.It "kern.sugid_scripts int32_t yes" +.It "kern.symfile char[] no" +.It "kern.usrstack int32_t no" +.It "kern.usrstack64 int64_t no" +.It "kern.uuid char[] no" +.It "kern.version char[] no" +.It "kern.waketime struct timeval no" .El -.Pp .Bl -tag -width 6n -.It Li KERN_ARGMAX +.It Li "kern.argmax" The maximum bytes of argument to .Xr execve 2 . -.It Li KERN_BOOTFILE -The full pathname of the file from which the kernel was loaded. -.It Li KERN_BOOTTIME +.It Li "kern.boottime" A .Va struct timeval structure is returned. This structure contains the time that the system was booted. -.It Li KERN_CLOCKRATE +.It Li "kern.clockrate" A .Va struct clockinfo structure is returned. This structure contains the clock, statistics clock and profiling clock frequencies, the number of micro-seconds per hz tick and the skew rate. -.It Li KERN_FILE -Return the entire file table. -The returned data consists of a single -.Va struct filehead -followed by an array of -.Va struct file , -whose size depends on the current number of such objects in the system. -.It Li KERN_HOSTID +.It Li "kern.hostid" Get or set the host id. -.It Li KERN_HOSTNAME +.It Li "kern.hostname" Get or set the hostname. -.It Li KERN_JOB_CONTROL +.It Li "kern.job_control" Return 1 if job control is available on this system, otherwise 0. -.It Li KERN_MAXFILES +.It Li "kern.maxfiles" The maximum number of files that may be open in the system. -.It Li KERN_MAXFILESPERPROC +.It Li "kern.maxfilesperproc" The maximum number of files that may be open for a single process. This limit only applies to processes with an effective uid of nonzero at the time of the open request. Files that have already been opened are not affected if the limit or the effective uid is changed. -.It Li KERN_MAXPROC +.It Li "kern.maxproc" The maximum number of concurrent processes the system will allow. -.It Li KERN_MAXPROCPERUID +.It Li "kern.maxprocperuid" The maximum number of concurrent processes the system will allow for a single effective uid. This limit only applies to processes with an effective uid of nonzero at the time of a fork request. Processes that have already been started are not affected if the limit is changed. -.It Li KERN_MAXVNODES +.It Li "kern.maxvnodes" The maximum number of vnodes available on the system. -.It Li KERN_NGROUPS +.It Li "kern.ngroups" The maximum number of supplemental groups. -.It Li KERN_NISDOMAINNAME +.It Li "kern.nisdomainname" The name of the current YP/NIS domain. -.It Li KERN_OSRELDATE -The kernel release version in the format -.Ar M Ns Ar mm Ns Ar R Ns Ar xx , -where -.Ar M -is the major version, -.Ar mm -is the two digit minor version, -.Ar R -is 0 if release branch, otherwise 1, -and -.Ar xx -is updated when the available APIs change. -.Pp -The userland release version is available from -.In osreldate.h ; -parse this file if you need to get the release version of -the currently installed userland. -.It Li KERN_OSRELEASE +.It Li "kern.osrelease" The system release string. -.It Li KERN_OSREV -The system revision string. -.It Li KERN_OSTYPE +.It Li "kern.osrevision" +The system revision number. +.It Li "kern.ostype" The system type string. -.It Li KERN_POSIX1 +.It Li "kern.posix1version" The version of .St -p1003.1 with which the system attempts to comply. -.It Li KERN_PROC -Return the entire process table, or a subset of it. -An array of -.Va struct kinfo_proc -structures is returned, -whose size depends on the current number of such objects in the system. -The third and fourth level names are as follows: -.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent -.It "Third level name Fourth level is:" -.It "KERN_PROC_ALL None" -.It "KERN_PROC_PID A process ID" -.It "KERN_PROC_PGRP A process group" -.It "KERN_PROC_TTY A tty device" -.It "KERN_PROC_UID A user ID" -.It "KERN_PROC_RUID A real user ID" -.El -.It Li KERN_PROF -Return profiling information about the kernel. -If the kernel is not compiled for profiling, -attempts to retrieve any of the KERN_PROF values will -fail with -.Er ENOENT . -The third level names for the string and integer profiling information -is detailed below. -The changeable column shows whether a process with appropriate -privilege may change the value. -.Bl -column "GPROFXGMONPARAMXXX" "struct gmonparamXXX" -offset indent -.It Sy "Third level name Type Changeable" -.It "GPROF_STATE integer yes" -.It "GPROF_COUNT u_short[\|] yes" -.It "GPROF_FROMS u_short[\|] yes" -.It "GPROF_TOS struct tostruct yes" -.It "GPROF_GMONPARAM struct gmonparam no" -.El -.Pp -The variables are as follows: -.Bl -tag -width 6n -.It Li GPROF_STATE -Returns GMON_PROF_ON or GMON_PROF_OFF to show that profiling -is running or stopped. -.It Li GPROF_COUNT -Array of statistical program counter counts. -.It Li GPROF_FROMS -Array indexed by program counter of call-from points. -.It Li GPROF_TOS -Array of -.Va struct tostruct -describing destination of calls and their counts. -.It Li GPROF_GMONPARAM -Structure giving the sizes of the above arrays. -.El -.It Li KERN_QUANTUM -The maximum period of time, in microseconds, for which a process is allowed -to run without being preempted if other processes are in the run queue. -.It Li KERN_SAVED_IDS +.It Li "kern.saved_ids" Returns 1 if saved set-group and saved set-user ID is available. -.It Li KERN_SECURELVL +.It Li "kern.securelevel" The system security level. This level may be raised by processes with appropriate privilege. It may not be lowered. -.It Li KERN_VERSION +.It Li "kern.version" The system version string. -.It Li KERN_VNODE -Return the entire vnode table. -Note, the vnode table is not necessarily a consistent snapshot of -the system. -The returned data consists of an array whose size depends on the -current number of such objects in the system. -Each element of the array contains the kernel address of a vnode -.Va struct vnode * -followed by the vnode itself -.Va struct vnode . .El .Ss CTL_MACHDEP The set of variables defined is architecture dependent. The following variables are defined for the i386 architecture. -.Bl -column "CONSOLE_DEVICEXXX" "struct bootinfoXXX" -offset indent -.It Sy "Second level name Type Changeable" -.It Li "CPU_CONSDEV dev_t no" -.It Li "CPU_ADJKERNTZ int yes" -.It Li "CPU_DISRTCSET int yes" -.It Li "CPU_BOOTINFO struct bootinfo no" -.It Li "CPU_WALLCLOCK int yes" +.Bl -column "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxx" -offset indent +.It Sy "Name Type Changeable" +.It "machdep.cpu.address_bits.physical int32_t no" +.It "machdep.cpu.address_bits.virtual int32_t no" +.It "machdep.cpu.brand int32_t no" +.It "machdep.cpu.brand_string char[] no" +.It "machdep.cpu.cache.L2_associativity int32_t no" +.It "machdep.cpu.cache.linesize int32_t no" +.It "machdep.cpu.cache.size int32_t no" +.It "machdep.cpu.core_count int32_t no" +.It "machdep.cpu.cores_per_package int32_t no" +.It "machdep.cpu.extfamily int32_t no" +.It "machdep.cpu.extfeature_bits int64_t no" +.It "machdep.cpu.extfeatures char[] no" +.It "machdep.cpu.extmodel int32_t no" +.It "machdep.cpu.family int32_t no" +.It "machdep.cpu.feature_bits int64_t no" +.It "machdep.cpu.features char[] no" +.It "machdep.cpu.leaf7_feature_bits uint32_t no" +.It "machdep.cpu.leaf7_features char[] no" +.It "machdep.cpu.logical_per_package int32_t no" +.It "machdep.cpu.max_basic uint32_t no" +.It "machdep.cpu.max_ext uint32_t no" +.It "machdep.cpu.microcode_version int32_t no" +.It "machdep.cpu.model int32_t no" +.It "machdep.cpu.processor_flag int32_t no" +.It "machdep.cpu.signature int32_t no" +.It "machdep.cpu.stepping int32_t no" +.It "machdep.cpu.thread_count int32_t no" +.It "machdep.cpu.tlb.data.large int32_t no" +.It "machdep.cpu.tlb.data.large_level1 int32_t no" +.It "machdep.cpu.tlb.data.small int32_t no" +.It "machdep.cpu.tlb.data.small_level1 int32_t no" +.It "machdep.cpu.tlb.inst.large int32_t no" +.It "machdep.cpu.tlb.inst.small int32_t no" +.It "machdep.cpu.tlb.shared int32_t no" +.It "machdep.cpu.ucupdate int32_t yes" +.It "machdep.cpu.vendor char[] no" +.It "machdep.cpu.xsave.extended_state uint32_t no" +.It "machdep.tsc.deep_idle_rebase uint32_t yes" +.It "machdep.tsc.frequency int64_t no" +.It "machdep.tsc.nanotime.generation uint32_t no" +.It "machdep.tsc.nanotime.shift uint32_t no" .El .Ss CTL_NET The string and integer information available for the CTL_NET level @@ -550,7 +449,6 @@ privilege may change the value. .It "PF_INET IPv4 values yes" .It "PF_INET6 IPv6 values yes" .El -.Pp .Bl -tag -width 6n .It Li PF_ROUTE Return the entire routing table or a subset of it. @@ -562,13 +460,14 @@ The length of each message is contained in the message header. The third level name is a protocol number, which is currently always 0. The fourth level name is an address family, which may be set to 0 to select all address families. -The fifth and sixth level names are as follows: -.Bl -column "Fifth level nameXXXXXX" "Sixth level is:XXX" -offset indent -.It Sy "Fifth level name Sixth level is:" -.It "NET_RT_FLAGS rtflags" -.It "NET_RT_DUMP None" -.It "NET_RT_IFLIST 0 or if_index" -.It "NET_RT_IFMALIST 0 or if_index" +The fifth, sixth, and seventh level names are as follows: +.Bl -column -offset indent "Fifth level Sixth level" "Seventh level" +.It Sy "Fifth level Sixth level" Ta Sy "Seventh level" +.It "NET_RT_FLAGS rtflags" Ta "None" +.It "NET_RT_DUMP None" Ta "None or fib number" +.It "NET_RT_IFLIST 0 or if_index" Ta None +.It "NET_RT_IFMALIST 0 or if_index" Ta None +.It "NET_RT_IFLISTL 0 or if_index" Ta None .El .Pp The @@ -633,98 +532,98 @@ The string and integer information available for the CTL_USER level is detailed below. The changeable column shows whether a process with appropriate privilege may change the value. -.Bl -column "USER_COLL_WEIGHTS_MAXXXX" "integerXXX" -offset indent -.It Sy "Second level name Type Changeable" -.It "USER_BC_BASE_MAX integer no" -.It "USER_BC_DIM_MAX integer no" -.It "USER_BC_SCALE_MAX integer no" -.It "USER_BC_STRING_MAX integer no" -.It "USER_COLL_WEIGHTS_MAX integer no" -.It "USER_CS_PATH string no" -.It "USER_EXPR_NEST_MAX integer no" -.It "USER_LINE_MAX integer no" -.It "USER_POSIX2_CHAR_TERM integer no" -.It "USER_POSIX2_C_BIND integer no" -.It "USER_POSIX2_C_DEV integer no" -.It "USER_POSIX2_FORT_DEV integer no" -.It "USER_POSIX2_FORT_RUN integer no" -.It "USER_POSIX2_LOCALEDEF integer no" -.It "USER_POSIX2_SW_DEV integer no" -.It "USER_POSIX2_UPE integer no" -.It "USER_POSIX2_VERSION integer no" -.It "USER_RE_DUP_MAX integer no" -.It "USER_STREAM_MAX integer no" -.It "USER_TZNAME_MAX integer no" +.Bl -column "xxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxx" -offset indent +.It Sy "Name Type Changeable" +.It "user.bc_base_max int32_t no" +.It "user.bc_dim_max int32_t no" +.It "user.bc_scale_max int32_t no" +.It "user.bc_string_max int32_t no" +.It "user.coll_weights_max int32_t no" +.It "user.cs_path char[] no" +.It "user.expr_nest_max int32_t no" +.It "user.line_max int32_t no" +.It "user.posix2_c_bind int32_t no" +.It "user.posix2_c_dev int32_t no" +.It "user.posix2_char_term int32_t no" +.It "user.posix2_fort_dev int32_t no" +.It "user.posix2_fort_run int32_t no" +.It "user.posix2_localedef int32_t no" +.It "user.posix2_sw_dev int32_t no" +.It "user.posix2_upe int32_t no" +.It "user.posix2_version int32_t no" +.It "user.re_dup_max int32_t no" +.It "user.stream_max int32_t no" +.It "user.tzname_max int32_t no" .El .Bl -tag -width 6n .Pp -.It Li USER_BC_BASE_MAX +.It Li "user.bc_base_max" The maximum ibase/obase values in the .Xr bc 1 utility. -.It Li USER_BC_DIM_MAX +.It Li "user.bc_dim_max" The maximum array size in the .Xr bc 1 utility. -.It Li USER_BC_SCALE_MAX +.It Li "user.bc_scale_max" The maximum scale value in the .Xr bc 1 utility. -.It Li USER_BC_STRING_MAX +.It Li "user.bc_string_max" The maximum string length in the .Xr bc 1 utility. -.It Li USER_COLL_WEIGHTS_MAX +.It Li "user.coll_weights_max" The maximum number of weights that can be assigned to any entry of the LC_COLLATE order keyword in the locale definition file. -.It Li USER_CS_PATH +.It Li "user.cs_path" Return a value for the .Ev PATH environment variable that finds all the standard utilities. -.It Li USER_EXPR_NEST_MAX +.It Li "user.expr_nest_max" The maximum number of expressions that can be nested within parenthesis by the .Xr expr 1 utility. -.It Li USER_LINE_MAX +.It Li "user.line_max" The maximum length in bytes of a text-processing utility's input line. -.It Li USER_POSIX2_CHAR_TERM -Return 1 if the system supports at least one terminal type capable of -all operations described in -.St -p1003.2 , -otherwise 0. -.It Li USER_POSIX2_C_BIND +.It Li "user.posix2_c_bind" Return 1 if the system's C-language development facilities support the C-Language Bindings Option, otherwise 0. -.It Li USER_POSIX2_C_DEV +.It Li "user.posix2_c_dev" Return 1 if the system supports the C-Language Development Utilities Option, otherwise 0. -.It Li USER_POSIX2_FORT_DEV +.It Li "user.posix2_char_term" +Return 1 if the system supports at least one terminal type capable of +all operations described in +.St -p1003.2 , +otherwise 0. +.It Li "user.posix2_fort_dev" Return 1 if the system supports the FORTRAN Development Utilities Option, otherwise 0. -.It Li USER_POSIX2_FORT_RUN +.It Li "user.posix2_fort_run" Return 1 if the system supports the FORTRAN Runtime Utilities Option, otherwise 0. -.It Li USER_POSIX2_LOCALEDEF +.It Li "user.posix2_localedef" Return 1 if the system supports the creation of locales, otherwise 0. -.It Li USER_POSIX2_SW_DEV +.It Li "user.posix2_sw_dev" Return 1 if the system supports the Software Development Utilities Option, otherwise 0. -.It Li USER_POSIX2_UPE +.It Li "user.posix2_upe" Return 1 if the system supports the User Portability Utilities Option, otherwise 0. -.It Li USER_POSIX2_VERSION +.It Li "user.posix2_version" The version of .St -p1003.2 with which the system attempts to comply. -.It Li USER_RE_DUP_MAX +.It Li "user.re_dup_max" The maximum number of repeated occurrences of a regular expression permitted when using interval notation. -.It Li USER_STREAM_MAX +.It Li "user.stream_max" The minimum maximum number of streams that a process may have open at any one time. -.It Li USER_TZNAME_MAX +.It Li "user.tzname_max" The minimum maximum number of types supported for the name of a timezone. .El @@ -733,59 +632,37 @@ The string and integer information available for the CTL_VM level is detailed below. The changeable column shows whether a process with appropriate privilege may change the value. -.Bl -column "Second level nameXXXXXX" "struct loadavgXXX" -offset indent -.It Sy "Second level name Type Changeable" -.It "VM_LOADAVG struct loadavg no" -.It "VM_PAGEOUT_ALGORITHM integer yes" -.It "VM_SWAPPING_ENABLED integer maybe" -.It "VM_V_CACHE_MAX integer yes" -.It "VM_V_CACHE_MIN integer yes" -.It "VM_V_FREE_MIN integer yes" -.It "VM_V_FREE_RESERVED integer yes" -.It "VM_V_FREE_TARGET integer yes" -.It "VM_V_INACTIVE_TARGET integer yes" -.It "VM_V_PAGEOUT_FREE_MIN integer yes" +.Bl -column "xxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxx" -offset indent +.It Sy "Name Type Changeable" +.It "vm.loadavg struct loadavg no" +.It "vm.swapusage struct xsw_usage no" .El .Pp .Bl -tag -width 6n -.It Li VM_LOADAVG +.It Li "vm.loadavg" Return the load average history. The returned data consists of a .Va struct loadavg . -.It Li VM_PAGEOUT_ALGORITHM -0 if the statistics-based page management algorithm is in use -or 1 if the near-LRU algorithm is in use. -.It Li VM_SWAPPING_ENABLED -1 if process swapping is enabled or 0 if disabled. -This variable is -permanently set to 0 if the kernel was built with swapping disabled. -.It Li VM_V_CACHE_MAX -Maximum desired size of the cache queue. -.It Li VM_V_CACHE_MIN -Minimum desired size of the cache queue. -If the cache queue size -falls very far below this value, the pageout daemon is awakened. -.It Li VM_V_FREE_MIN -Minimum amount of memory (cache memory plus free memory) -required to be available before a process waiting on memory will be -awakened. -.It Li VM_V_FREE_RESERVED -Processes will awaken the pageout daemon and wait for memory if the -number of free and cached pages drops below this value. -.It Li VM_V_FREE_TARGET -The total amount of free memory (including cache memory) that the -pageout daemon tries to maintain. -.It Li VM_V_INACTIVE_TARGET -The desired number of inactive pages that the pageout daemon should -achieve when it runs. -Inactive pages can be quickly inserted into -process address space when needed. -.It Li VM_V_PAGEOUT_FREE_MIN -If the amount of free and cache memory falls below this value, the -pageout daemon will enter "memory conserving mode" to avoid deadlock. .El .Sh RETURN VALUES .Rv -std +.Sh FILES +.Bl -tag -width -compact +.It In sys/sysctl.h +definitions for top level identifiers, second level kernel and hardware +identifiers, and user level identifiers +.It In sys/socket.h +definitions for second level network identifiers +.It In netinet/in.h +definitions for third level IPv4/IPv6 identifiers and +fourth level IPv4/v6 identifiers +.It In netinet/icmp_var.h +definitions for fourth level ICMP identifiers +.It In netinet/icmp6.h +definitions for fourth level ICMPv6 identifiers +.It In netinet/udp_var.h +definitions for fourth level UDP identifiers +.El .Sh ERRORS The following errors may be reported: .Bl -tag -width Er @@ -839,28 +716,8 @@ An attempt is made to set a read-only value. .It Bq Er EPERM A process without appropriate privilege attempts to set a value. .El -.Sh FILES -.Bl -tag -width -compact -.It In sys/sysctl.h -definitions for top level identifiers, second level kernel and hardware -identifiers, and user level identifiers -.It In sys/socket.h -definitions for second level network identifiers -.It In sys/gmon.h -definitions for third level profiling identifiers -.It In mach/vm_param.h -definitions for second level virtual memory identifiers -.It In netinet/in.h -definitions for third level IPv4/IPv6 identifiers and -fourth level IPv4/v6 identifiers -.It In netinet/icmp_var.h -definitions for fourth level ICMP identifiers -.It In netinet/icmp6.h -definitions for fourth level ICMPv6 identifiers -.It In netinet/udp_var.h -definitions for fourth level UDP identifiers -.El .Sh SEE ALSO +.Xr confstr 3 , .Xr sysconf 3 , .Xr sysctl 8 .Sh HISTORY diff --git a/src/libc/gen/FreeBSD/sysctl.c b/src/libc/gen/FreeBSD/sysctl.c index 7205820f6..c890aae01 100644 --- a/src/libc/gen/FreeBSD/sysctl.c +++ b/src/libc/gen/FreeBSD/sysctl.c @@ -47,11 +47,8 @@ extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); int -sysctl(name, namelen, oldp, oldlenp, newp, newlen) - int *name; - u_int namelen; - void *oldp, *newp; - size_t *oldlenp, newlen; +sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) +__attribute__((disable_tail_calls)) { if (name[0] != CTL_USER) { if (namelen == 2 && name[0] == CTL_KERN && name[1] == KERN_EXEC) { diff --git a/src/libc/gen/FreeBSD/sysctlbyname.c b/src/libc/gen/FreeBSD/sysctlbyname.c index e949a5cde..c79d132b0 100644 --- a/src/libc/gen/FreeBSD/sysctlbyname.c +++ b/src/libc/gen/FreeBSD/sysctlbyname.c @@ -14,6 +14,14 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/sysctlbyname.c,v 1.5 2002/02/01 00:57:29 ob #include #include #include +#include +#include + +extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen); +extern int +__sysctlbyname(const char *name, size_t namelen, void *oldp, size_t *oldlenp, void *newp, + size_t newlen); int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp, @@ -24,16 +32,23 @@ sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp, int error; size_t oidlen; +#if !TARGET_IPHONE_SIMULATOR + /* Try primary system call first, fall back if not supported */ + error = __sysctlbyname(name, strlen(name), oldp, oldlenp, newp, newlen); + if ((error == 0) || (errno != ENOSYS)) + return error; +#endif /* !TARGET_IPHONE_SIMULATOR */ + name2oid_oid[0] = 0; /* This is magic & undocumented! */ name2oid_oid[1] = 3; oidlen = sizeof(real_oid); - error = sysctl(name2oid_oid, 2, real_oid, &oidlen, (void *)name, + error = __sysctl(name2oid_oid, 2, real_oid, &oidlen, (void *)name, strlen(name)); if (error < 0) return error; oidlen /= sizeof (int); - error = sysctl(real_oid, oidlen, oldp, oldlenp, newp, newlen); + error = __sysctl(real_oid, oidlen, oldp, oldlenp, newp, newlen); return (error); } diff --git a/src/libc/gen/FreeBSD/sysctlnametomib.c b/src/libc/gen/FreeBSD/sysctlnametomib.c index 1a932ec46..3b19413ae 100644 --- a/src/libc/gen/FreeBSD/sysctlnametomib.c +++ b/src/libc/gen/FreeBSD/sysctlnametomib.c @@ -31,6 +31,9 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/sysctlnametomib.c,v 1.4 2003/01/04 00:11:11 #include #include +extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen); + /* * This function uses a presently undocumented interface to the kernel * to walk the tree and get the type so it can print the value. @@ -49,7 +52,7 @@ sysctlnametomib(const char *name, int *mibp, size_t *sizep) oid[1] = 3; *sizep *= sizeof (int); - error = sysctl(oid, 2, mibp, sizep, (void *)name, strlen(name)); + error = __sysctl(oid, 2, mibp, sizep, (void *)name, strlen(name)); *sizep /= sizeof (int); return (error); } diff --git a/src/libc/gen/FreeBSD/termios.c b/src/libc/gen/FreeBSD/termios.c index ab540d679..9b0bb2c84 100644 --- a/src/libc/gen/FreeBSD/termios.c +++ b/src/libc/gen/FreeBSD/termios.c @@ -36,8 +36,6 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/termios.c,v 1.16 2009/05/07 13:49:48 ed Exp #if __DARWIN_UNIX03 #ifdef VARIANT_CANCELABLE #include - -extern void _pthread_testcancel(pthread_t thread, int isconforming); #endif /* VARIANT_CANCELABLE */ #endif /* __DARWIN_UNIX03 */ @@ -227,7 +225,7 @@ __tcdrain(fd) { #if __DARWIN_UNIX03 #ifdef VARIANT_CANCELABLE - _pthread_testcancel(pthread_self(), 1); + pthread_testcancel(); #endif /* VARIANT_CANCELABLE */ #endif /* __DARWIN_UNIX03 */ return (_ioctl(fd, TIOCDRAIN, 0)); @@ -264,9 +262,6 @@ int tcflow(fd, action) int fd, action; { - struct termios term; - u_char c; - switch (action) { case TCOOFF: return (_ioctl(fd, TIOCSTOP, 0)); diff --git a/src/libc/gen/FreeBSD/times.3 b/src/libc/gen/FreeBSD/times.3 index f8e5f01d0..261c1aebc 100644 --- a/src/libc/gen/FreeBSD/times.3 +++ b/src/libc/gen/FreeBSD/times.3 @@ -9,10 +9,6 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)times.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/times.3,v 1.10 2001/10/01 16:08:51 ru Exp $ +.\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd December 1, 2008 .Dt TIMES 3 .Os .Sh NAME @@ -43,9 +39,7 @@ .Sh SYNOPSIS .In sys/times.h .Ft clock_t -.Fo times -.Fa "struct tms *buffer" -.Fc +.Fn times "struct tms *tp" .Sh DESCRIPTION .Bf -symbolic This interface is obsoleted by @@ -63,7 +57,7 @@ of a second since Time. .Pp It also fills in the structure pointed to by -.Fa buffer +.Fa tp with time-accounting information. .Pp The @@ -136,8 +130,7 @@ and .Xr time 1 , .Xr getrusage 2 , .Xr gettimeofday 2 , -.Xr wait 2 , -.Xr clocks 7 +.Xr wait 2 .Sh STANDARDS The .Fn times diff --git a/src/libc/gen/FreeBSD/unvis.3 b/src/libc/gen/FreeBSD/unvis.3 index cee1e61b8..73b91da60 100644 --- a/src/libc/gen/FreeBSD/unvis.3 +++ b/src/libc/gen/FreeBSD/unvis.3 @@ -1,3 +1,6 @@ +.\" $NetBSD: unvis.3,v 1.27 2012/12/15 07:34:36 wiz Exp $ +.\" $FreeBSD$ +.\" .\" Copyright (c) 1989, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -9,7 +12,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -26,9 +29,8 @@ .\" SUCH DAMAGE. .\" .\" @(#)unvis.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/gen/unvis.3,v 1.18 2007/01/09 00:27:56 imp Exp $ .\" -.Dd December 11, 1993 +.Dd March 12, 2011 .Dt UNVIS 3 .Os .Sh NAME @@ -44,7 +46,11 @@ .Ft int .Fn strunvis "char *dst" "const char *src" .Ft int +.Fn strnunvis "char *dst" "size_t dlen" "const char *src" +.Ft int .Fn strunvisx "char *dst" "const char *src" "int flag" +.Ft int +.Fn strnunvisx "char *dst" "size_t dlen" "const char *src" "int flag" .Sh DESCRIPTION The .Fn unvis , @@ -57,37 +63,37 @@ by the .Xr vis 3 function, back into the original form. -Unvis is called with successive characters in -.Fa c -until a valid -sequence is recognized, at which time the decoded character is -available at the character pointed to by -.Fa cp . -Strunvis decodes the -characters pointed to by -.Fa src -into the buffer pointed to by -.Fa dst . +.Pp +The +.Fn unvis +function is called with successive characters in +.Ar c +until a valid sequence is recognized, at which time the decoded +character is available at the character pointed to by +.Ar cp . .Pp The .Fn strunvis -function -simply copies -.Fa src +function decodes the characters pointed to by +.Ar src +into the buffer pointed to by +.Ar dst . +The +.Fn strunvis +function simply copies +.Ar src to -.Fa dst , +.Ar dst , decoding any escape sequences along the way, and returns the number of characters placed into -.Fa dst , +.Ar dst , or \-1 if an invalid escape sequence was detected. The size of -.Fa dst -should be -equal to the size of -.Fa src -(that is, no expansion takes place during -decoding). +.Ar dst +should be equal to the size of +.Ar src +(that is, no expansion takes place during decoding). .Pp The .Fn strunvisx @@ -95,58 +101,53 @@ function does the same as the .Fn strunvis function, but it allows you to add a flag that specifies the style the string -.Fa src +.Ar src is encoded with. -Currently, the only supported flag is -.Dv VIS_HTTPSTYLE . +Currently, the supported flags are: +.Dv VIS_HTTPSTYLE +and +.Dv VIS_MIMESTYLE . .Pp The .Fn unvis -function -implements a state machine that can be used to decode an arbitrary -stream of bytes. -All state associated with the bytes being decoded -is stored outside the +function implements a state machine that can be used to decode an +arbitrary stream of bytes. +All state associated with the bytes being decoded is stored outside the .Fn unvis function (that is, a pointer to the state is passed in), so calls decoding different streams can be freely intermixed. -To -start decoding a stream of bytes, first initialize an integer -to zero. +To start decoding a stream of bytes, first initialize an integer to zero. Call .Fn unvis with each successive byte, along with a pointer to this integer, and a pointer to a destination character. The .Fn unvis -function -has several return codes that must be handled properly. +function has several return codes that must be handled properly. They are: .Bl -tag -width UNVIS_VALIDPUSH -.It Li \&0 (zero) +.It Li \&0 No (zero) Another character is necessary; nothing has been recognized yet. .It Dv UNVIS_VALID A valid character has been recognized and is available at the location -pointed to by cp. +pointed to by +.Fa cp . .It Dv UNVIS_VALIDPUSH A valid character has been recognized and is available at the location -pointed to by cp; however, the character currently passed in should -be passed in again. +pointed to by +.Fa cp ; +however, the character currently passed in should be passed in again. .It Dv UNVIS_NOCHAR A valid sequence was detected, but no character was produced. -This -return code is necessary to indicate a logical break between characters. +This return code is necessary to indicate a logical break between characters. .It Dv UNVIS_SYNBAD -An invalid escape sequence was detected, or the decoder is in an -unknown state. +An invalid escape sequence was detected, or the decoder is in an unknown state. The decoder is placed into the starting state. .El .Pp When all bytes in the stream have been processed, call .Fn unvis -one more time with -.Fa flag -set to +one more time with flag set to .Dv UNVIS_END to extract any remaining character (the character passed in is ignored). .Pp @@ -154,9 +155,26 @@ The .Fa flag argument is also used to specify the encoding style of the source. If set to -.Dv VIS_HTTPSTYLE , +.Dv VIS_HTTPSTYLE +or +.Dv VIS_HTTP1808 , .Fn unvis will decode URI strings as specified in RFC 1808. +If set to +.Dv VIS_HTTP1866 , +.Fn unvis +will decode entity references and numeric character references +as specified in RFC 1866. +If set to +.Dv VIS_MIMESTYLE , +.Fn unvis +will decode MIME Quoted-Printable strings as specified in RFC 2045. +If set to +.Dv VIS_NOESCAPE , +.Fn unvis +will not decode +.Ql \e +quoted characters. .Pp The following code fragment illustrates a proper use of .Fn unvis . @@ -166,25 +184,51 @@ char out; while ((ch = getchar()) != EOF) { again: - switch(unvis(&out, ch, &state, 0)) { + switch(unvis(\*[Am]out, ch, \*[Am]state, 0)) { case 0: case UNVIS_NOCHAR: break; case UNVIS_VALID: - (void) putchar(out); + (void)putchar(out); break; case UNVIS_VALIDPUSH: - (void) putchar(out); + (void)putchar(out); goto again; case UNVIS_SYNBAD: - (void)fprintf(stderr, "bad sequence!\en"); - exit(1); + errx(EXIT_FAILURE, "Bad character sequence!"); } } -if (unvis(&out, (char)0, &state, UNVIS_END) == UNVIS_VALID) - (void) putchar(out); +if (unvis(\*[Am]out, '\e0', \*[Am]state, UNVIS_END) == UNVIS_VALID) + (void)putchar(out); .Ed +.Sh ERRORS +The functions +.Fn strunvis , +.Fn strnunvis , +.Fn strunvisx , +and +.Fn strnunvisx +will return \-1 on error and set +.Va errno +to: +.Bl -tag -width Er +.It Bq Er EINVAL +An invalid escape sequence was detected, or the decoder is in an unknown state. +.El +.Pp +In addition the functions +.Fn strnunvis +and +.Fn strnunvisx +will can also set +.Va errno +on error to: +.Bl -tag -width Er +.It Bq Er ENOSPC +Not enough space to perform the conversion. +.El .Sh SEE ALSO +.Xr unvis 1 , .Xr vis 1 , .Xr vis 3 .Rs @@ -198,3 +242,18 @@ The function first appeared in .Bx 4.4 . +The +.Fn strnunvis +and +.Fn strnunvisx +functions appeared in OS X 10.12. +.Sh BUGS +The names +.Dv VIS_HTTP1808 +and +.Dv VIS_HTTP1866 +are wrong. +Percent-encoding was defined in RFC 1738, the original RFC for URL. +RFC 1866 defines HTML 2.0, an application of SGML, from which it +inherits concepts of numeric character references and entity +references. diff --git a/src/libc/gen/FreeBSD/unvis.c b/src/libc/gen/FreeBSD/unvis.c index da2efbf30..f8ff22b69 100644 --- a/src/libc/gen/FreeBSD/unvis.c +++ b/src/libc/gen/FreeBSD/unvis.c @@ -1,3 +1,5 @@ +/* $NetBSD: unvis.c,v 1.41 2012/12/15 04:29:53 matt Exp $ */ + /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -27,18 +29,34 @@ * SUCH DAMAGE. */ +#include #if defined(LIBC_SCCS) && !defined(lint) +#if 0 static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: unvis.c,v 1.41 2012/12/15 04:29:53 matt Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/gen/unvis.c,v 1.10 2007/01/09 00:27:56 imp Exp $"); - #include "xlocale_private.h" #include + +#include #include +#include +#include +#include #include +#define _DIAGASSERT(x) assert(x) + +/* + * Return the number of elements in a statically-allocated array, + * __x. + */ +#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0])) + +#if !HAVE_VIS /* * decode driven by state machine */ @@ -49,12 +67,128 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/unvis.c,v 1.10 2007/01/09 00:27:56 imp Exp #define S_CTRL 4 /* control char started (^) */ #define S_OCTAL2 5 /* octal digit 2 */ #define S_OCTAL3 6 /* octal digit 3 */ -#define S_HEX2 7 /* hex digit 2 */ - -#define S_HTTP 0x080 /* %HEXHEX escape */ +#define S_HEX 7 /* mandatory hex digit */ +#define S_HEX1 8 /* http hex digit */ +#define S_HEX2 9 /* http hex digit 2 */ +#define S_MIME1 10 /* mime hex digit 1 */ +#define S_MIME2 11 /* mime hex digit 2 */ +#define S_EATCRNL 12 /* mime eating CRNL */ +#define S_AMP 13 /* seen & */ +#define S_NUMBER 14 /* collecting number */ +#define S_STRING 15 /* collecting string */ #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -#define ishex(c) ((((u_char)(c)) >= '0' && ((u_char)(c)) <= '9') || (((u_char)(c)) >= 'a' && ((u_char)(c)) <= 'f')) +#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) +#define XTOD(c) (isdigit(c) ? (c - '0') : ((c - 'A') + 10)) + +/* + * RFC 1866 + */ +static const struct nv { + char name[7]; + uint8_t value; +} nv[] = { + { "AElig", 198 }, /* capital AE diphthong (ligature) */ + { "Aacute", 193 }, /* capital A, acute accent */ + { "Acirc", 194 }, /* capital A, circumflex accent */ + { "Agrave", 192 }, /* capital A, grave accent */ + { "Aring", 197 }, /* capital A, ring */ + { "Atilde", 195 }, /* capital A, tilde */ + { "Auml", 196 }, /* capital A, dieresis or umlaut mark */ + { "Ccedil", 199 }, /* capital C, cedilla */ + { "ETH", 208 }, /* capital Eth, Icelandic */ + { "Eacute", 201 }, /* capital E, acute accent */ + { "Ecirc", 202 }, /* capital E, circumflex accent */ + { "Egrave", 200 }, /* capital E, grave accent */ + { "Euml", 203 }, /* capital E, dieresis or umlaut mark */ + { "Iacute", 205 }, /* capital I, acute accent */ + { "Icirc", 206 }, /* capital I, circumflex accent */ + { "Igrave", 204 }, /* capital I, grave accent */ + { "Iuml", 207 }, /* capital I, dieresis or umlaut mark */ + { "Ntilde", 209 }, /* capital N, tilde */ + { "Oacute", 211 }, /* capital O, acute accent */ + { "Ocirc", 212 }, /* capital O, circumflex accent */ + { "Ograve", 210 }, /* capital O, grave accent */ + { "Oslash", 216 }, /* capital O, slash */ + { "Otilde", 213 }, /* capital O, tilde */ + { "Ouml", 214 }, /* capital O, dieresis or umlaut mark */ + { "THORN", 222 }, /* capital THORN, Icelandic */ + { "Uacute", 218 }, /* capital U, acute accent */ + { "Ucirc", 219 }, /* capital U, circumflex accent */ + { "Ugrave", 217 }, /* capital U, grave accent */ + { "Uuml", 220 }, /* capital U, dieresis or umlaut mark */ + { "Yacute", 221 }, /* capital Y, acute accent */ + { "aacute", 225 }, /* small a, acute accent */ + { "acirc", 226 }, /* small a, circumflex accent */ + { "acute", 180 }, /* acute accent */ + { "aelig", 230 }, /* small ae diphthong (ligature) */ + { "agrave", 224 }, /* small a, grave accent */ + { "amp", 38 }, /* ampersand */ + { "aring", 229 }, /* small a, ring */ + { "atilde", 227 }, /* small a, tilde */ + { "auml", 228 }, /* small a, dieresis or umlaut mark */ + { "brvbar", 166 }, /* broken (vertical) bar */ + { "ccedil", 231 }, /* small c, cedilla */ + { "cedil", 184 }, /* cedilla */ + { "cent", 162 }, /* cent sign */ + { "copy", 169 }, /* copyright sign */ + { "curren", 164 }, /* general currency sign */ + { "deg", 176 }, /* degree sign */ + { "divide", 247 }, /* divide sign */ + { "eacute", 233 }, /* small e, acute accent */ + { "ecirc", 234 }, /* small e, circumflex accent */ + { "egrave", 232 }, /* small e, grave accent */ + { "eth", 240 }, /* small eth, Icelandic */ + { "euml", 235 }, /* small e, dieresis or umlaut mark */ + { "frac12", 189 }, /* fraction one-half */ + { "frac14", 188 }, /* fraction one-quarter */ + { "frac34", 190 }, /* fraction three-quarters */ + { "gt", 62 }, /* greater than */ + { "iacute", 237 }, /* small i, acute accent */ + { "icirc", 238 }, /* small i, circumflex accent */ + { "iexcl", 161 }, /* inverted exclamation mark */ + { "igrave", 236 }, /* small i, grave accent */ + { "iquest", 191 }, /* inverted question mark */ + { "iuml", 239 }, /* small i, dieresis or umlaut mark */ + { "laquo", 171 }, /* angle quotation mark, left */ + { "lt", 60 }, /* less than */ + { "macr", 175 }, /* macron */ + { "micro", 181 }, /* micro sign */ + { "middot", 183 }, /* middle dot */ + { "nbsp", 160 }, /* no-break space */ + { "not", 172 }, /* not sign */ + { "ntilde", 241 }, /* small n, tilde */ + { "oacute", 243 }, /* small o, acute accent */ + { "ocirc", 244 }, /* small o, circumflex accent */ + { "ograve", 242 }, /* small o, grave accent */ + { "ordf", 170 }, /* ordinal indicator, feminine */ + { "ordm", 186 }, /* ordinal indicator, masculine */ + { "oslash", 248 }, /* small o, slash */ + { "otilde", 245 }, /* small o, tilde */ + { "ouml", 246 }, /* small o, dieresis or umlaut mark */ + { "para", 182 }, /* pilcrow (paragraph sign) */ + { "plusmn", 177 }, /* plus-or-minus sign */ + { "pound", 163 }, /* pound sterling sign */ + { "quot", 34 }, /* double quote */ + { "raquo", 187 }, /* angle quotation mark, right */ + { "reg", 174 }, /* registered sign */ + { "sect", 167 }, /* section sign */ + { "shy", 173 }, /* soft hyphen */ + { "sup1", 185 }, /* superscript one */ + { "sup2", 178 }, /* superscript two */ + { "sup3", 179 }, /* superscript three */ + { "szlig", 223 }, /* small sharp s, German (sz ligature) */ + { "thorn", 254 }, /* small thorn, Icelandic */ + { "times", 215 }, /* multiply sign */ + { "uacute", 250 }, /* small u, acute accent */ + { "ucirc", 251 }, /* small u, circumflex accent */ + { "ugrave", 249 }, /* small u, grave accent */ + { "uml", 168 }, /* umlaut (dieresis) */ + { "uuml", 252 }, /* small u, dieresis or umlaut mark */ + { "yacute", 253 }, /* small y, acute accent */ + { "yen", 165 }, /* yen sign */ + { "yuml", 255 }, /* small y, dieresis or umlaut mark */ +}; /* * unvis - decode characters previously encoded by vis @@ -62,235 +196,362 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/unvis.c,v 1.10 2007/01/09 00:27:56 imp Exp int unvis(char *cp, int c, int *astate, int flag) { - locale_t loc = __current_locale(); + unsigned char uc = (unsigned char)c; + unsigned char st, ia, is, lc; + +/* + * Bottom 8 bits of astate hold the state machine state. + * Top 8 bits hold the current character in the http 1866 nv string decoding + */ +#define GS(a) ((a) & 0xff) +#define SS(a, b) (((uint32_t)(a) << 24) | (b)) +#define GI(a) ((uint32_t)(a) >> 24) + + _DIAGASSERT(cp != NULL); + _DIAGASSERT(astate != NULL); + st = GS(*astate); if (flag & UNVIS_END) { - if (*astate == S_OCTAL2 || *astate == S_OCTAL3) { - *astate = S_GROUND; - return (UNVIS_VALID); + switch (st) { + case S_OCTAL2: + case S_OCTAL3: + case S_HEX2: + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case S_GROUND: + return UNVIS_NOCHAR; + default: + return UNVIS_SYNBAD; } - return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); } - switch (*astate & ~S_HTTP) { + switch (st) { case S_GROUND: *cp = 0; - if (c == '\\') { - *astate = S_START; - return (0); + if ((flag & VIS_NOESCAPE) == 0 && c == '\\') { + *astate = SS(0, S_START); + return UNVIS_NOCHAR; + } + if ((flag & VIS_HTTP1808) && c == '%') { + *astate = SS(0, S_HEX1); + return UNVIS_NOCHAR; + } + if ((flag & VIS_HTTP1866) && c == '&') { + *astate = SS(0, S_AMP); + return UNVIS_NOCHAR; } - if (flag & VIS_HTTPSTYLE && c == '%') { - *astate = S_START | S_HTTP; - return (0); + if ((flag & VIS_MIMESTYLE) && c == '=') { + *astate = SS(0, S_MIME1); + return UNVIS_NOCHAR; } *cp = c; - return (UNVIS_VALID); + return UNVIS_VALID; case S_START: - if (*astate & S_HTTP) { - if (ishex(tolower_l(c, loc))) { - *cp = isdigit_l(c, loc) ? (c - '0') : (tolower_l(c, loc) - 'a'); - *astate = S_HEX2; - return (0); - } - } switch(c) { case '\\': *cp = c; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': *cp = (c - '0'); - *astate = S_OCTAL2; - return (0); + *astate = SS(0, S_OCTAL2); + return UNVIS_NOCHAR; case 'M': - *cp = 0200; - *astate = S_META; - return (0); + *cp = (char)0200; + *astate = SS(0, S_META); + return UNVIS_NOCHAR; case '^': - *astate = S_CTRL; - return (0); + *astate = SS(0, S_CTRL); + return UNVIS_NOCHAR; case 'n': *cp = '\n'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'r': *cp = '\r'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'b': *cp = '\b'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'a': *cp = '\007'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'v': *cp = '\v'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 't': *cp = '\t'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'f': *cp = '\f'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 's': *cp = ' '; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'E': *cp = '\033'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 'x': + *astate = SS(0, S_HEX); + return UNVIS_NOCHAR; case '\n': /* * hidden newline */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); + *astate = SS(0, S_GROUND); + return UNVIS_NOCHAR; case '$': /* * hidden marker */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); + *astate = SS(0, S_GROUND); + return UNVIS_NOCHAR; } - *astate = S_GROUND; - return (UNVIS_SYNBAD); + goto bad; case S_META: if (c == '-') - *astate = S_META1; + *astate = SS(0, S_META1); else if (c == '^') - *astate = S_CTRL; - else { - *astate = S_GROUND; - return (UNVIS_SYNBAD); - } - return (0); + *astate = SS(0, S_CTRL); + else + goto bad; + return UNVIS_NOCHAR; case S_META1: - *astate = S_GROUND; + *astate = SS(0, S_GROUND); *cp |= c; - return (UNVIS_VALID); + return UNVIS_VALID; case S_CTRL: if (c == '?') *cp |= 0177; else *cp |= c & 037; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case S_OCTAL2: /* second possible octal digit */ - if (isoctal(c)) { + if (isoctal(uc)) { /* * yes - and maybe a third */ *cp = (*cp << 3) + (c - '0'); - *astate = S_OCTAL3; - return (0); + *astate = SS(0, S_OCTAL3); + return UNVIS_NOCHAR; } /* * no - done with current sequence, push back passed char */ - *astate = S_GROUND; - return (UNVIS_VALIDPUSH); + *astate = SS(0, S_GROUND); + return UNVIS_VALIDPUSH; case S_OCTAL3: /* third possible octal digit */ - *astate = S_GROUND; - if (isoctal(c)) { + *astate = SS(0, S_GROUND); + if (isoctal(uc)) { *cp = (*cp << 3) + (c - '0'); - return (UNVIS_VALID); + return UNVIS_VALID; } /* * we were done, push back passed char */ - return (UNVIS_VALIDPUSH); + return UNVIS_VALIDPUSH; - case S_HEX2: /* second mandatory hex digit */ - if (ishex(tolower_l(c, loc))) { - *cp = (isdigit_l(c, loc) ? (*cp << 4) + (c - '0') : (*cp << 4) + (tolower_l(c, loc) - 'a' + 10)); + case S_HEX: + if (!isxdigit(uc)) + goto bad; + /*FALLTHROUGH*/ + case S_HEX1: + if (isxdigit(uc)) { + *cp = xtod(uc); + *astate = SS(0, S_HEX2); + return UNVIS_NOCHAR; } + /* + * no - done with current sequence, push back passed char + */ + *astate = SS(0, S_GROUND); + return UNVIS_VALIDPUSH; + + case S_HEX2: *astate = S_GROUND; - return (UNVIS_VALID); + if (isxdigit(uc)) { + *cp = xtod(uc) | (*cp << 4); + return UNVIS_VALID; + } + return UNVIS_VALIDPUSH; + + case S_MIME1: + if (uc == '\n' || uc == '\r') { + *astate = SS(0, S_EATCRNL); + return UNVIS_NOCHAR; + } + if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { + *cp = XTOD(uc); + *astate = SS(0, S_MIME2); + return UNVIS_NOCHAR; + } + goto bad; + + case S_MIME2: + if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { + *astate = SS(0, S_GROUND); + *cp = XTOD(uc) | (*cp << 4); + return UNVIS_VALID; + } + goto bad; + + case S_EATCRNL: + switch (uc) { + case '\r': + case '\n': + return UNVIS_NOCHAR; + case '=': + *astate = SS(0, S_MIME1); + return UNVIS_NOCHAR; + default: + *cp = uc; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + } + + case S_AMP: + *cp = 0; + if (uc == '#') { + *astate = SS(0, S_NUMBER); + return UNVIS_NOCHAR; + } + *astate = SS(0, S_STRING); + /*FALLTHROUGH*/ + + case S_STRING: + ia = *cp; /* index in the array */ + is = GI(*astate); /* index in the string */ + lc = is == 0 ? 0 : nv[ia].name[is - 1]; /* last character */ + + if (uc == ';') + uc = '\0'; + + for (; ia < __arraycount(nv); ia++) { + if (is != 0 && nv[ia].name[is - 1] != lc) + goto bad; + if (nv[ia].name[is] == uc) + break; + } + + if (ia == __arraycount(nv)) + goto bad; + + if (uc != 0) { + *cp = ia; + *astate = SS(is + 1, S_STRING); + return UNVIS_NOCHAR; + } + + *cp = nv[ia].value; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + + case S_NUMBER: + if (uc == ';') + return UNVIS_VALID; + if (!isdigit(uc)) + goto bad; + *cp += (*cp * 10) + uc - '0'; + return UNVIS_NOCHAR; default: + bad: /* * decoder in unknown state - (probably uninitialized) */ - *astate = S_GROUND; - return (UNVIS_SYNBAD); + *astate = SS(0, S_GROUND); + return UNVIS_SYNBAD; } } /* - * strunvis - decode src into dst + * strnunvisx - decode src into dst * * Number of chars decoded into dst is returned, -1 on error. * Dst is null terminated. */ int -strunvis(char *dst, const char *src) +strnunvisx(char *dst, size_t dlen, const char *src, int flag) { char c; - char *start = dst; + char t = '\0', *start = dst; int state = 0; - while ( (c = *src++) ) { - again: - switch (unvis(dst, c, &state, 0)) { + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); +#define CHECKSPACE() \ + do { \ + if (dlen-- == 0) { \ + errno = ENOSPC; \ + return -1; \ + } \ + } while (/*CONSTCOND*/0) + + while ((c = *src++) != '\0') { + again: + switch (unvis(&t, c, &state, flag)) { case UNVIS_VALID: - dst++; + CHECKSPACE(); + *dst++ = t; break; case UNVIS_VALIDPUSH: - dst++; + CHECKSPACE(); + *dst++ = t; goto again; case 0: case UNVIS_NOCHAR: break; + case UNVIS_SYNBAD: + errno = EINVAL; + return -1; default: - return (-1); + _DIAGASSERT(/*CONSTCOND*/0); + errno = EINVAL; + return -1; } } - if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) - dst++; + if (unvis(&t, c, &state, UNVIS_END) == UNVIS_VALID) { + CHECKSPACE(); + *dst++ = t; + } + CHECKSPACE(); *dst = '\0'; - return (dst - start); + return (int)(dst - start); } int strunvisx(char *dst, const char *src, int flag) { - char c; - char *start = dst; - int state = 0; - - while ( (c = *src++) ) { - again: - switch (unvis(dst, c, &state, flag)) { - case UNVIS_VALID: - dst++; - break; - case UNVIS_VALIDPUSH: - dst++; - goto again; - case 0: - case UNVIS_NOCHAR: - break; - default: - return (-1); - } - } - if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) - dst++; - *dst = '\0'; - return (dst - start); + return strnunvisx(dst, (size_t)~0, src, flag); +} + +int +strunvis(char *dst, const char *src) +{ + return strnunvisx(dst, (size_t)~0, src, 0); +} + +int +strnunvis(char *dst, size_t dlen, const char *src) +{ + return strnunvisx(dst, dlen, src, 0); } +#endif diff --git a/src/libc/gen/FreeBSD/usleep.3 b/src/libc/gen/FreeBSD/usleep.3 index e99b773da..12b927467 100644 --- a/src/libc/gen/FreeBSD/usleep.3 +++ b/src/libc/gen/FreeBSD/usleep.3 @@ -26,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)usleep.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/usleep.3,v 1.19 2007/01/09 00:27:56 imp Exp $ +.\" $FreeBSD$ .\" .Dd February 13, 1998 .Dt USLEEP 3 @@ -39,29 +39,37 @@ .Sh SYNOPSIS .In unistd.h .Ft int -.Fo usleep -.Fa "useconds_t useconds" -.Fc +.Fn usleep "useconds_t microseconds" .Sh DESCRIPTION The .Fn usleep function suspends execution of the calling thread until either -.Fa useconds -microseconds have elapsed -or a signal is delivered to the thread whose action -is to invoke a signal-catching function -or to terminate the thread or process. -The actual time slept may be longer, due to system latencies -and possible limitations in the timer resolution of the hardware. +.Fa microseconds +microseconds have elapsed or a signal is delivered to the thread and its +action is to invoke a signal-catching function or to terminate the +process. +System activity or limitations may lengthen the sleep by an indeterminate amount. .Pp -This function is implemented, using -.Xr nanosleep 2 , +This function is implemented using +.Xr nanosleep 2 by pausing for -.Fa useconds +.Fa microseconds microseconds or until a signal occurs. Consequently, in this implementation, -sleeping has no effect on the state of process timers +sleeping has no effect on the state of process timers, and there is no special handling for SIGALRM. +Also, this implementation does not put a limit on the value of +.Fa microseconds +(other than that limited by the size of the +.Ft useconds_t +type); some other platforms require it to be less than one million. +.Sh NOTE +The +.Fn usleep +function is obsolescent. +Use +.Xr nanosleep 2 +instead. .Sh RETURN VALUES .Rv -std usleep .Sh ERRORS diff --git a/src/libc/gen/FreeBSD/usleep.c b/src/libc/gen/FreeBSD/usleep.c index fc8054b10..47525d33e 100644 --- a/src/libc/gen/FreeBSD/usleep.c +++ b/src/libc/gen/FreeBSD/usleep.c @@ -27,10 +27,9 @@ * SUCH DAMAGE. */ -#ifdef VARIANT_CANCELABLE -#undef __DARWIN_NON_CANCELABLE -#define __DARWIN_NON_CANCELABLE 0 -#endif /* VARIANT_CANCELABLE */ +#if defined(VARIANT_CANCELABLE) && __DARWIN_NON_CANCELABLE != 0 +#error cancellable call vs. __DARWIN_NON_CANCELABLE mismatch +#endif #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; diff --git a/src/libc/gen/FreeBSD/vis.3 b/src/libc/gen/FreeBSD/vis.3 index 2fa771c33..7ad956271 100644 --- a/src/libc/gen/FreeBSD/vis.3 +++ b/src/libc/gen/FreeBSD/vis.3 @@ -1,3 +1,6 @@ +.\" $NetBSD: vis.3,v 1.39 2013/02/20 20:05:26 christos Exp $ +.\" $FreeBSD$ +.\" .\" Copyright (c) 1989, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -9,7 +12,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -25,14 +28,26 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" From: @(#)vis.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/gen/vis.3,v 1.30 2007/01/09 00:27:56 imp Exp $ +.\" @(#)vis.3 8.1 (Berkeley) 6/9/93 .\" -.Dd April 9, 2006 +.Dd February 19, 2013 .Dt VIS 3 .Os .Sh NAME -.Nm vis +.Nm vis , +.Nm nvis , +.Nm strvis , +.Nm strnvis , +.Nm strvisx , +.Nm strnvisx , +.Nm strenvisx , +.Nm svis , +.Nm snvis , +.Nm strsvis , +.Nm strsnvis , +.Nm strsvisx , +.Nm strsnvisx , +.Nm strsenvisx .Nd visually encode characters .Sh LIBRARY .Lb libc @@ -40,10 +55,32 @@ .In vis.h .Ft char * .Fn vis "char *dst" "int c" "int flag" "int nextc" +.Ft char * +.Fn nvis "char *dst" "size_t dlen" "int c" "int flag" "int nextc" .Ft int .Fn strvis "char *dst" "const char *src" "int flag" .Ft int +.Fn strnvis "char *dst" "size_t dlen" "const char *src" "int flag" +.Ft int .Fn strvisx "char *dst" "const char *src" "size_t len" "int flag" +.Ft int +.Fn strnvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" +.Ft int +.Fn strenvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" "int *cerr_ptr" +.Ft char * +.Fn svis "char *dst" "int c" "int flag" "int nextc" "const char *extra" +.Ft char * +.Fn snvis "char *dst" "size_t dlen" "int c" "int flag" "int nextc" "const char *extra" +.Ft int +.Fn strsvis "char *dst" "const char *src" "int flag" "const char *extra" +.Ft int +.Fn strsnvis "char *dst" "size_t dlen" "const char *src" "int flag" "const char *extra" +.Ft int +.Fn strsvisx "char *dst" "const char *src" "size_t len" "int flag" "const char *extra" +.Ft int +.Fn strsnvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" "const char *extra" +.Ft int +.Fn strsenvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" "const char *extra" "int *cerr_ptr" .Sh DESCRIPTION The .Fn vis @@ -55,19 +92,16 @@ a string which represents the character If .Fa c needs no encoding, it is copied in unaltered. -The string is -null terminated, and a pointer to the end of the string is +The string is null terminated, and a pointer to the end of the string is returned. The maximum length of any encoding is four -characters (not including the trailing +bytes (not including the trailing .Dv NUL ) ; thus, when encoding a set of characters into a buffer, the size of the buffer should -be four times the number of characters encoded, plus one for the trailing +be four times the number of bytes encoded, plus one for the trailing .Dv NUL . -The -.Fa flag -argument is used for altering the default range of +The flag parameter is used for altering the default range of characters considered for encoding and for altering the visual representation. The additional character, @@ -77,9 +111,11 @@ is only used when selecting the encoding format (explained below). .Pp The -.Fn strvis +.Fn strvis , +.Fn strnvis , +.Fn strvisx , and -.Fn strvisx +.Fn strnvisx functions copy into .Fa dst a visual representation of @@ -87,14 +123,18 @@ the string .Fa src . The .Fn strvis -function encodes characters from +and +.Fn strnvis +functions encode characters from .Fa src up to the first .Dv NUL . The .Fn strvisx -function encodes exactly +and +.Fn strnvisx +functions encode exactly .Fa len characters from .Fa src @@ -108,35 +148,96 @@ terminate The size of .Fa dst must be four times the number -of characters encoded from +of bytes encoded from .Fa src (plus one for the .Dv NUL ) . Both -forms return the number of characters in dst (not including -the trailing +forms return the number of characters in +.Fa dst +(not including the trailing .Dv NUL ) . +The +.Dq Nm n +versions of the functions also take an additional argument +.Fa dlen +that indicates the length of the +.Fa dst +buffer. +If +.Fa dlen +is not large enough to fit the converted string then the +.Fn strnvis +and +.Fn strnvisx +functions return \-1 and set +.Va errno +to +.Dv ENOSPC . +The +.Fn strenvisx +function takes an additional argument, +.Fa cerr_ptr , +that is used to pass in and out a multibyte conversion error flag. +This is useful when processing single characters at a time when +it is possible that the locale may be set to something other +than the locale of the characters in the input data. +.Pp +The functions +.Fn svis , +.Fn snvis , +.Fn strsvis , +.Fn strsnvis , +.Fn strsvisx , +.Fn strsnvisx , +and +.Fn strsenvisx +correspond to +.Fn vis , +.Fn nvis , +.Fn strvis , +.Fn strnvis , +.Fn strvisx , +.Fn strnvisx , +and +.Fn strenvisx +but have an additional argument +.Fa extra , +pointing to a +.Dv NUL +terminated list of characters. +These characters will be copied encoded or backslash-escaped into +.Fa dst . +These functions are useful e.g. to remove the special meaning +of certain characters to shells. .Pp The encoding is a unique, invertible representation composed entirely of graphic characters; it can be decoded back into the original form using the -.Xr unvis 3 -or +.Xr unvis 3 , .Xr strunvis 3 +or +.Xr strnunvis 3 functions. .Pp There are two parameters that can be controlled: the range of -characters that are encoded, and the type -of representation used. -By default, all non-graphic characters -except space, tab, and newline are encoded. -(See -.Xr isgraph 3 . ) +characters that are encoded (applies only to +.Fn vis , +.Fn nvis , +.Fn strvis , +.Fn strnvis , +.Fn strvisx , +and +.Fn strnvisx ) , +and the type of representation used. +By default, all non-graphic characters, +except space, tab, and newline are encoded (see +.Xr isgraph 3 ) . The following flags alter this: .Bl -tag -width VIS_WHITEX .It Dv VIS_GLOB -Also encode magic characters +Also encode the magic characters .Ql ( * , .Ql \&? , .Ql \&[ @@ -158,30 +259,54 @@ Synonym for \&| .Dv VIS_NL . .It Dv VIS_SAFE -Only encode "unsafe" characters. -Unsafe means control -characters which may cause common terminals to perform +Only encode +.Dq unsafe +characters. +Unsafe means control characters which may cause common terminals to perform unexpected functions. -Currently this form allows space, -tab, newline, backspace, bell, and return - in addition -to all graphic characters - unencoded. +Currently this form allows space, tab, newline, backspace, bell, and +return \(em in addition to all graphic characters \(em unencoded. .El .Pp +(The above flags have no effect for +.Fn svis , +.Fn snvis , +.Fn strsvis , +.Fn strsnvis , +.Fn strsvisx , +and +.Fn strsnvisx . +When using these functions, place all graphic characters to be +encoded in an array pointed to by +.Fa extra . +In general, the backslash character should be included in this array, see the +warning on the use of the +.Dv VIS_NOSLASH +flag below). +.Pp There are four forms of encoding. -Most forms use the backslash character +All forms use the backslash character .Ql \e to introduce a special -sequence; two backslashes are used to represent a real backslash. +sequence; two backslashes are used to represent a real backslash, +except +.Dv VIS_HTTPSTYLE +that uses +.Ql % , +or +.Dv VIS_MIMESTYLE +that uses +.Ql = . These are the visual formats: -.Bl -tag -width VIS_HTTPSTYLE +.Bl -tag -width VIS_CSTYLE .It (default) Use an .Ql M to represent meta characters (characters with the 8th bit set), and use caret .Ql ^ -to represent control characters see -.Pf ( Xr iscntrl 3 ) . +to represent control characters (see +.Xr iscntrl 3 ) . The following formats are used: .Bl -tag -width xxxxx .It Dv \e^C @@ -227,32 +352,21 @@ Represents Meta-space. Use C-style backslash sequences to represent standard non-printable characters. The following sequences are used to represent the indicated characters: -.Pp -.Bl -tag -width ".Li \e0" -offset indent -compact -.It Li \ea -.Dv BEL No (007) -.It Li \eb -.Dv BS No (010) -.It Li \ef -.Dv NP No (014) -.It Li \en -.Dv NL No (012) -.It Li \er -.Dv CR No (015) -.It Li \es -.Dv SP No (040) -.It Li \et -.Dv HT No (011) -.It Li \ev -.Dv VT No (013) -.It Li \e0 -.Dv NUL No (000) -.El +.Bd -unfilled -offset indent +.Li \ea Tn \(em BEL No (007) +.Li \eb Tn \(em BS No (010) +.Li \ef Tn \(em NP No (014) +.Li \en Tn \(em NL No (012) +.Li \er Tn \(em CR No (015) +.Li \es Tn \(em SP No (040) +.Li \et Tn \(em HT No (011) +.Li \ev Tn \(em VT No (013) +.Li \e0 Tn \(em NUL No (000) +.Ed .Pp When using this format, the .Fa nextc -argument is looked at to determine -if a +parameter is looked at to determine if a .Dv NUL character can be encoded as .Ql \e0 @@ -262,20 +376,28 @@ If .Fa nextc is an octal digit, the latter representation is used to avoid ambiguity. -.It Dv VIS_HTTPSTYLE -Use URI encoding as described in RFC 1808. -The form is -.Ql %dd -where -.Ar d -represents a hexadecimal digit. .It Dv VIS_OCTAL Use a three digit octal sequence. The form is .Ql \eddd where -.Ar d +.Em d represents an octal digit. +.It Dv VIS_HTTPSTYLE +Use URI encoding as described in RFC 1738. +The form is +.Ql %xx +where +.Em x +represents a lower case hexadecimal digit. +.It Dv VIS_MIMESTYLE +Use MIME Quoted-Printable encoding as described in RFC 2045, only don't +break lines and don't handle CRLF. +The form is +.Ql =XX +where +.Em X +represents an upper case hexadecimal digit. .El .Pp There is one additional flag, @@ -289,20 +411,96 @@ meta characters as .Ql M-C ) . With this flag set, the encoding is ambiguous and non-invertible. +.Sh MULTIBYTE CHARACTER SUPPORT +These functions support multibyte character input. +The encoding conversion is influenced by the setting of the +.Ev LC_CTYPE +environment variable which defines the set of characters +that can be copied without encoding. +.Pp +When 8-bit data is present in the input, +.Ev LC_CTYPE +must be set to the correct locale or to the C locale. +If the locales of the data and the conversion are mismatched, +multibyte character recognition may fail and encoding will be performed +byte-by-byte instead. +.Pp +As noted above, +.Fa dst +must be four times the number of bytes processed from +.Fa src . +But note that each multibyte character can be up to +.Dv MB_LEN_MAX +bytes +.\" (see +.\" .Xr multibyte 3 ) +so in terms of multibyte characters, +.Fa dst +must be four times +.Dv MB_LEN_MAX +times the number of characters processed from +.Fa src . +.Sh ENVIRONMENT +.Bl -tag -width ".Ev LC_CTYPE" +.It Ev LC_CTYPE +Specify the locale of the input data. +Set to C if the input data locale is unknown. +.El +.Sh ERRORS +The functions +.Fn nvis +and +.Fn snvis +will return +.Dv NULL +and the functions +.Fn strnvis , +.Fn strnvisx , +.Fn strsnvis , +and +.Fn strsnvisx , +will return \-1 when the +.Fa dlen +destination buffer size is not enough to perform the conversion while +setting +.Va errno +to: +.Bl -tag -width ".Bq Er ENOSPC" +.It Bq Er ENOSPC +The destination buffer size is not large enough to perform the conversion. +.El .Sh SEE ALSO .Xr unvis 1 , +.Xr vis 1 , +.Xr glob 3 , +.\" .Xr multibyte 3 , .Xr unvis 3 .Rs -.%A R. Fielding -.%T Relative Uniform Resource Locators -.%O RFC1808 +.%A T. Berners-Lee +.%T Uniform Resource Locators (URL) +.%O "RFC 1738" +.Re +.Rs +.%T "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies" +.%O "RFC 2045" .Re .Sh HISTORY -These functions first appeared in +The +.Fn vis , +.Fn strvis , +and +.Fn strvisx +functions first appeared in .Bx 4.4 . -.Sh BUGS The -.Nm -family of functions do not recognize multibyte characters, and thus -may consider them to be non-printable when they are in fact printable -(and vice versa.) +.Fn svis , +.Fn strsvis , +.Fn strsvisx +.Fn nvis , +.Fn strnvis , +.Fn strnvisx , +.Fn snvis , +.Fn strsnvis +and +.Fn strsnvisx +functions as well as multibyte character support were added in OS X 10.12. diff --git a/src/libc/gen/FreeBSD/vis.c b/src/libc/gen/FreeBSD/vis.c index 3a4b67c4c..f48f17303 100644 --- a/src/libc/gen/FreeBSD/vis.c +++ b/src/libc/gen/FreeBSD/vis.c @@ -1,3 +1,5 @@ +/* $NetBSD: vis.c,v 1.62 2014/09/08 17:35:01 christos Exp $ */ + /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -10,7 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -27,179 +29,639 @@ * SUCH DAMAGE. */ +/*- + * Copyright (c) 1999, 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)vis.c 8.1 (Berkeley) 7/19/93"; +__RCSID("$NetBSD: vis.c,v 1.62 2014/09/08 17:35:01 christos Exp $"); #endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/gen/vis.c,v 1.14 2007/01/09 00:27:56 imp Exp $"); - -#include "xlocale_private.h" +#ifdef __FBSDID +__FBSDID("$FreeBSD$"); +#define _DIAGASSERT(x) assert(x) +#endif #include -#include +#include + +#include +#include +#include +#include +#include +#include + +#if !HAVE_VIS || !HAVE_SVIS #include +#include #include -#include +#include -#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +/* + * The reason for going through the trouble to deal with character encodings + * in vis(3), is that we use this to safe encode output of commands. This + * safe encoding varies depending on the character set. For example if we + * display ps output in French, we don't want to display French characters + * as M-foo. + */ + +static wchar_t *do_svis(wchar_t *, wint_t, int, wint_t, const wchar_t *); + +#undef BELL +#define BELL L'\a' + +#define iswoctal(c) (((u_char)(c)) >= L'0' && ((u_char)(c)) <= L'7') +#define iswwhite(c) (c == L' ' || c == L'\t' || c == L'\n') +#define iswsafe(c) (c == L'\b' || c == BELL || c == L'\r') +#define xtoa(c) L"0123456789abcdef"[c] +#define XTOA(c) L"0123456789ABCDEF"[c] + +#define MAXEXTRAS 10 + +_Static_assert(MB_LEN_MAX <= sizeof(uint64_t)); /* - * vis - visually encode characters + * This is do_hvis, for HTTP style (RFC 1808) */ -char * -vis(dst, c, flag, nextc) - char *dst; - int c, nextc; - int flag; -{ - locale_t loc = __current_locale(); - - c = (unsigned char)c; - - if (flag & VIS_HTTPSTYLE) { - /* Described in RFC 1808 */ - if (!(isalnum_l(c, loc) /* alpha-numeric */ - /* safe */ - || c == '$' || c == '-' || c == '_' || c == '.' || c == '+' - /* extra */ - || c == '!' || c == '*' || c == '\'' || c == '(' - || c == ')' || c == ',')) { - *dst++ = '%'; - snprintf_l(dst, 4, loc, (c < 16 ? "0%X" : "%X"), c); - dst += 2; - goto done; +static wchar_t * +do_hvis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra) +{ + if (iswalnum(c) + /* safe */ + || c == L'$' || c == L'-' || c == L'_' || c == L'.' || c == L'+' + /* extra */ + || c == L'!' || c == L'*' || c == L'\'' || c == L'(' || c == L')' + || c == L',') + dst = do_svis(dst, c, flags, nextc, extra); + else { + *dst++ = L'%'; + *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); + *dst++ = xtoa((unsigned int)c & 0xf); + } + + return dst; +} + +/* + * This is do_mvis, for Quoted-Printable MIME (RFC 2045) + * NB: No handling of long lines or CRLF. + */ +static wchar_t * +do_mvis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra) +{ + if ((c != L'\n') && + /* Space at the end of the line */ + ((iswspace(c) && (nextc == L'\r' || nextc == L'\n')) || + /* Out of range */ + (!iswspace(c) && (c < 33 || (c > 60 && c < 62) || c > 126)) || + /* Specific char to be escaped */ + wcschr(L"#$@[\\]^`{|}~", c) != NULL)) { + *dst++ = L'='; + *dst++ = XTOA(((unsigned int)c >> 4) & 0xf); + *dst++ = XTOA((unsigned int)c & 0xf); + } else + dst = do_svis(dst, c, flags, nextc, extra); + return dst; +} + +/* + * Output single byte of multibyte character. + */ +static wchar_t * +do_mbyte(wchar_t *dst, wint_t c, int flags, wint_t nextc, int iswextra) +{ + if (flags & VIS_CSTYLE) { + switch (c) { + case L'\n': + *dst++ = L'\\'; *dst++ = L'n'; + return dst; + case L'\r': + *dst++ = L'\\'; *dst++ = L'r'; + return dst; + case L'\b': + *dst++ = L'\\'; *dst++ = L'b'; + return dst; + case BELL: + *dst++ = L'\\'; *dst++ = L'a'; + return dst; + case L'\v': + *dst++ = L'\\'; *dst++ = L'v'; + return dst; + case L'\t': + *dst++ = L'\\'; *dst++ = L't'; + return dst; + case L'\f': + *dst++ = L'\\'; *dst++ = L'f'; + return dst; + case L' ': + *dst++ = L'\\'; *dst++ = L's'; + return dst; + case L'\0': + *dst++ = L'\\'; *dst++ = L'0'; + if (iswoctal(nextc)) { + *dst++ = L'0'; + *dst++ = L'0'; + } + return dst; + default: + if (iswgraph(c)) { + *dst++ = L'\\'; + *dst++ = c; + return dst; + } + } + } + if (iswextra || ((c & 0177) == L' ') || (flags & VIS_OCTAL)) { + *dst++ = L'\\'; + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + L'0'; + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + L'0'; + *dst++ = (c & 07) + L'0'; + } else { + if ((flags & VIS_NOSLASH) == 0) + *dst++ = L'\\'; + + if (c & 0200) { + c &= 0177; + *dst++ = L'M'; + } + + if (iswcntrl(c)) { + *dst++ = L'^'; + if (c == 0177) + *dst++ = L'?'; + else + *dst++ = c + L'@'; + } else { + *dst++ = L'-'; + *dst++ = c; } } - if ((flag & VIS_GLOB) && - (c == '*' || c == '?' || c == '[' || c == '#')) - ; - else if (isgraph_l(c, loc) || - ((flag & VIS_SP) == 0 && c == ' ') || - ((flag & VIS_TAB) == 0 && c == '\t') || - ((flag & VIS_NL) == 0 && c == '\n') || - ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) { + return dst; +} + +/* + * This is do_vis, the central code of vis. + * dst: Pointer to the destination buffer + * c: Character to encode + * flags: Flags word + * nextc: The character following 'c' + * extra: Pointer to the list of extra characters to be + * backslash-protected. + */ +static wchar_t * +do_svis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra) +{ + int iswextra, i, shft; + uint64_t bmsk, wmsk; + + iswextra = wcschr(extra, c) != NULL; + if (!iswextra && (iswgraph(c) || iswwhite(c) || + ((flags & VIS_SAFE) && iswsafe(c)))) { *dst++ = c; - if (c == '\\' && (flag & VIS_NOSLASH) == 0) - *dst++ = '\\'; - *dst = '\0'; - return (dst); + return dst; } - if (flag & VIS_CSTYLE) { - switch(c) { - case '\n': - *dst++ = '\\'; - *dst++ = 'n'; - goto done; - case '\r': - *dst++ = '\\'; - *dst++ = 'r'; - goto done; - case '\b': - *dst++ = '\\'; - *dst++ = 'b'; - goto done; - case '\a': - *dst++ = '\\'; - *dst++ = 'a'; - goto done; - case '\v': - *dst++ = '\\'; - *dst++ = 'v'; - goto done; - case '\t': - *dst++ = '\\'; - *dst++ = 't'; - goto done; - case '\f': - *dst++ = '\\'; - *dst++ = 'f'; - goto done; - case ' ': - *dst++ = '\\'; - *dst++ = 's'; - goto done; - case '\0': - *dst++ = '\\'; - *dst++ = '0'; - if (isoctal(nextc)) { - *dst++ = '0'; - *dst++ = '0'; - } - goto done; + /* See comment in istrsenvisx() output loop, below. */ + wmsk = 0; + for (i = sizeof(wmsk) - 1; i >= 0; i--) { + shft = i * NBBY; + bmsk = (uint64_t)0xffLL << shft; + wmsk |= bmsk; + if ((c & wmsk) || i == 0) + dst = do_mbyte(dst, (wint_t)( + (uint64_t)(c & bmsk) >> shft), + flags, nextc, iswextra); + } + + return dst; +} + +typedef wchar_t *(*visfun_t)(wchar_t *, wint_t, int, wint_t, const wchar_t *); + +/* + * Return the appropriate encoding function depending on the flags given. + */ +static visfun_t +getvisfun(int flags) +{ + if (flags & VIS_HTTPSTYLE) + return do_hvis; + if (flags & VIS_MIMESTYLE) + return do_mvis; + return do_svis; +} + +/* + * Expand list of extra characters to not visually encode. + */ +static wchar_t * +makeextralist(int flags, const char *src) +{ + wchar_t *dst, *d; + size_t len; + + len = strlen(src); + if ((dst = calloc(len + MAXEXTRAS, sizeof(*dst))) == NULL) + return NULL; + + if (mbstowcs(dst, src, len) == (size_t)-1) { + size_t i; + for (i = 0; i < len; i++) + dst[i] = (wint_t)(u_char)src[i]; + d = dst + len; + } else + d = dst + wcslen(dst); + + if (flags & VIS_GLOB) { + *d++ = L'*'; + *d++ = L'?'; + *d++ = L'['; + *d++ = L'#'; + } + + if (flags & VIS_SP) *d++ = L' '; + if (flags & VIS_TAB) *d++ = L'\t'; + if (flags & VIS_NL) *d++ = L'\n'; + if ((flags & VIS_NOSLASH) == 0) *d++ = L'\\'; + *d = L'\0'; + + return dst; +} + +/* + * istrsenvisx() + * The main internal function. + * All user-visible functions call this one. + */ +static int +istrsenvisx(char *mbdst, size_t *dlen, const char *mbsrc, size_t mblength, + int flags, const char *mbextra, int *cerr_ptr) +{ + wchar_t *dst, *src, *pdst, *psrc, *start, *extra; + size_t len, olen; + uint64_t bmsk, wmsk; + wint_t c; + visfun_t f; + int clen = 0, cerr = 0, error = -1, i, shft; + ssize_t mbslength, maxolen; + + _DIAGASSERT(mbdst != NULL); + _DIAGASSERT(mbsrc != NULL || mblength == 0); + _DIAGASSERT(mbextra != NULL); + + /* + * Input (mbsrc) is a char string considered to be multibyte + * characters. The input loop will read this string pulling + * one character, possibly multiple bytes, from mbsrc and + * converting each to wchar_t in src. + * + * The vis conversion will be done using the wide char + * wchar_t string. + * + * This will then be converted back to a multibyte string to + * return to the caller. + */ + + /* Allocate space for the wide char strings */ + psrc = pdst = extra = NULL; + if ((psrc = calloc(mblength + 1, sizeof(*psrc))) == NULL) + return -1; + if ((pdst = calloc((4 * mblength) + 1, sizeof(*pdst))) == NULL) + goto out; + dst = pdst; + src = psrc; + + /* Use caller's multibyte conversion error flag. */ + if (cerr_ptr) + cerr = *cerr_ptr; + + /* + * Input loop. + * Handle up to mblength characters (not bytes). We do not + * stop at NULs because we may be processing a block of data + * that includes NULs. + */ + mbslength = (ssize_t)mblength; + /* + * When inputing a single character, must also read in the + * next character for nextc, the look-ahead character. + */ + if (mbslength == 1) + mbslength++; + while (mbslength > 0) { + /* Convert one multibyte character to wchar_t. */ + if (!cerr) + clen = mbtowc(src, mbsrc, MB_LEN_MAX); + if (cerr || clen < 0) { + /* Conversion error, process as a byte instead. */ + *src = (wint_t)(u_char)*mbsrc; + clen = 1; + cerr = 1; } + if (clen == 0) + /* + * NUL in input gives 0 return value. process + * as single NUL byte and keep going. + */ + clen = 1; + /* Advance buffer character pointer. */ + src++; + /* Advance input pointer by number of bytes read. */ + mbsrc += clen; + /* Decrement input byte count. */ + mbslength -= clen; } - if (((c & 0177) == ' ') || isgraph_l(c, loc) || (flag & VIS_OCTAL)) { - *dst++ = '\\'; - *dst++ = ((u_char)c >> 6 & 07) + '0'; - *dst++ = ((u_char)c >> 3 & 07) + '0'; - *dst++ = ((u_char)c & 07) + '0'; - goto done; + len = src - psrc; + src = psrc; + /* + * In the single character input case, we will have actually + * processed two characters, c and nextc. Reset len back to + * just a single character. + */ + if (mblength < len) + len = mblength; + + /* Convert extra argument to list of characters for this mode. */ + extra = makeextralist(flags, mbextra); + if (!extra) { + if (dlen && *dlen == 0) { + errno = ENOSPC; + goto out; + } + *mbdst = '\0'; /* can't create extra, return "" */ + error = 0; + goto out; } - if ((flag & VIS_NOSLASH) == 0) - *dst++ = '\\'; - if (c & 0200) { - c &= 0177; - *dst++ = 'M'; + + /* Look up which processing function to call. */ + f = getvisfun(flags); + + /* + * Main processing loop. + * Call do_Xvis processing function one character at a time + * with next character available for look-ahead. + */ + for (start = dst; len > 0; len--) { + c = *src++; + dst = (*f)(dst, c, flags, len >= 1 ? *src : L'\0', extra); + if (dst == NULL) { + errno = ENOSPC; + goto out; + } } - if (iscntrl_l(c, loc)) { - *dst++ = '^'; - if (c == 0177) - *dst++ = '?'; - else - *dst++ = c + '@'; - } else { - *dst++ = '-'; - *dst++ = c; + + /* Terminate the string in the buffer. */ + *dst = L'\0'; + + /* + * Output loop. + * Convert wchar_t string back to multibyte output string. + * If we have hit a multi-byte conversion error on input, + * output byte-by-byte here. Else use wctomb(). + */ + len = wcslen(start); + maxolen = dlen ? *dlen : (wcslen(start) * MB_LEN_MAX + 1); + olen = 0; + for (dst = start; len > 0; len--) { + if (!cerr) + clen = wctomb(mbdst, *dst); + if (cerr || clen < 0) { + /* + * Conversion error, process as a byte(s) instead. + * Examine each byte and higher-order bytes for + * data. E.g., + * 0x000000000000a264 -> a2 64 + * 0x000000001f00a264 -> 1f 00 a2 64 + */ + clen = 0; + wmsk = 0; + for (i = sizeof(wmsk) - 1; i >= 0; i--) { + shft = i * NBBY; + bmsk = (uint64_t)0xffLL << shft; + wmsk |= bmsk; + if ((*dst & wmsk) || i == 0) + mbdst[clen++] = (char)( + (uint64_t)(*dst & bmsk) >> + shft); + } + cerr = 1; + } + /* If this character would exceed our output limit, stop. */ + if (olen + clen > (size_t)maxolen) + break; + /* Advance output pointer by number of bytes written. */ + mbdst += clen; + /* Advance buffer character pointer. */ + dst++; + /* Incrment output character count. */ + olen += clen; } -done: - *dst = '\0'; - return (dst); + + /* Terminate the output string. */ + *mbdst = '\0'; + + /* Pass conversion error flag out. */ + if (cerr_ptr) + *cerr_ptr = cerr; + + free(extra); + free(pdst); + free(psrc); + + return (int)olen; +out: + free(extra); + free(pdst); + free(psrc); + return error; +} + +static int +istrsenvisxl(char *mbdst, size_t *dlen, const char *mbsrc, + int flags, const char *mbextra, int *cerr_ptr) +{ + return istrsenvisx(mbdst, dlen, mbsrc, + mbsrc != NULL ? strlen(mbsrc) : 0, flags, mbextra, cerr_ptr); +} + +#endif + +#if !HAVE_SVIS +/* + * The "svis" variants all take an "extra" arg that is a pointer + * to a NUL-terminated list of characters to be encoded, too. + * These functions are useful e. g. to encode strings in such a + * way so that they are not interpreted by a shell. + */ + +char * +svis(char *mbdst, int c, int flags, int nextc, const char *mbextra) +{ + char cc[2]; + int ret; + + cc[0] = c; + cc[1] = nextc; + + ret = istrsenvisx(mbdst, NULL, cc, 1, flags, mbextra, NULL); + if (ret < 0) + return NULL; + return mbdst + ret; +} + +char * +snvis(char *mbdst, size_t dlen, int c, int flags, int nextc, const char *mbextra) +{ + char cc[2]; + int ret; + + cc[0] = c; + cc[1] = nextc; + + ret = istrsenvisx(mbdst, &dlen, cc, 1, flags, mbextra, NULL); + if (ret < 0) + return NULL; + return mbdst + ret; +} + +int +strsvis(char *mbdst, const char *mbsrc, int flags, const char *mbextra) +{ + return istrsenvisxl(mbdst, NULL, mbsrc, flags, mbextra, NULL); +} + +int +strsnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags, const char *mbextra) +{ + return istrsenvisxl(mbdst, &dlen, mbsrc, flags, mbextra, NULL); +} + +int +strsvisx(char *mbdst, const char *mbsrc, size_t len, int flags, const char *mbextra) +{ + return istrsenvisx(mbdst, NULL, mbsrc, len, flags, mbextra, NULL); +} + +int +strsnvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags, + const char *mbextra) +{ + return istrsenvisx(mbdst, &dlen, mbsrc, len, flags, mbextra, NULL); +} + +int +strsenvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags, + const char *mbextra, int *cerr_ptr) +{ + return istrsenvisx(mbdst, &dlen, mbsrc, len, flags, mbextra, cerr_ptr); +} +#endif + +#if !HAVE_VIS +/* + * vis - visually encode characters + */ +char * +vis(char *mbdst, int c, int flags, int nextc) +{ + char cc[2]; + int ret; + + cc[0] = c; + cc[1] = nextc; + + ret = istrsenvisx(mbdst, NULL, cc, 1, flags, "", NULL); + if (ret < 0) + return NULL; + return mbdst + ret; +} + +char * +nvis(char *mbdst, size_t dlen, int c, int flags, int nextc) +{ + char cc[2]; + int ret; + + cc[0] = c; + cc[1] = nextc; + + ret = istrsenvisx(mbdst, &dlen, cc, 1, flags, "", NULL); + if (ret < 0) + return NULL; + return mbdst + ret; } /* - * strvis, strvisx - visually encode characters from src into dst + * strvis - visually encode characters from src into dst * * Dst must be 4 times the size of src to account for possible - * expansion. The length of dst, not including the trailing NUL, + * expansion. The length of dst, not including the trailing NULL, * is returned. - * - * Strvisx encodes exactly len bytes from src into dst. - * This is useful for encoding a block of data. */ + int -strvis(dst, src, flag) - char *dst; - const char *src; - int flag; +strvis(char *mbdst, const char *mbsrc, int flags) { - char c; - char *start; + return istrsenvisxl(mbdst, NULL, mbsrc, flags, "", NULL); +} - for (start = dst; (c = *src); ) - dst = vis(dst, c, flag, *++src); - *dst = '\0'; - return (dst - start); +int +strnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags) +{ + return istrsenvisxl(mbdst, &dlen, mbsrc, flags, "", NULL); } +/* + * strvisx - visually encode characters from src into dst + * + * Dst must be 4 times the size of src to account for possible + * expansion. The length of dst, not including the trailing NULL, + * is returned. + * + * Strvisx encodes exactly len characters from src into dst. + * This is useful for encoding a block of data. + */ + int -strvisx(dst, src, len, flag) - char *dst; - const char *src; - size_t len; - int flag; +strvisx(char *mbdst, const char *mbsrc, size_t len, int flags) { - int c; - char *start; + return istrsenvisx(mbdst, NULL, mbsrc, len, flags, "", NULL); +} - for (start = dst; len > 1; len--) { - c = *src; - dst = vis(dst, c, flag, *++src); - } - if (len) - dst = vis(dst, *src, flag, '\0'); - *dst = '\0'; +int +strnvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags) +{ + return istrsenvisx(mbdst, &dlen, mbsrc, len, flags, "", NULL); +} - return (dst - start); +int +strenvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags, + int *cerr_ptr) +{ + return istrsenvisx(mbdst, &dlen, mbsrc, len, flags, "", cerr_ptr); } +#endif diff --git a/src/libc/gen/FreeBSD/wordexp.3 b/src/libc/gen/FreeBSD/wordexp.3 new file mode 100644 index 000000000..498ef1b94 --- /dev/null +++ b/src/libc/gen/FreeBSD/wordexp.3 @@ -0,0 +1,206 @@ +.\" +.\" Copyright (c) 2002 Tim J. Robbins +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd July 29, 2004 +.Dt WORDEXP 3 +.Os +.Sh NAME +.Nm wordexp +.Nd "perform shell-style word expansions" +.\" .Sh LIBRARY +.\" .Lb libc +.Sh SYNOPSIS +.In wordexp.h +.Ft int +.Fn wordexp "const char * restrict words" "wordexp_t * restrict we" "int flags" +.Ft void +.Fn wordfree "wordexp_t *we" +.Sh DESCRIPTION +The +.Fn wordexp +function performs shell-style word expansion on +.Fa words +and places the list of words into the +.Va we_wordv +member of +.Fa we , +and the number of words into +.Va we_wordc . +.Pp +The +.Fa flags +argument is the bitwise inclusive OR of any of the following constants: +.Bl -tag -width ".Dv WRDE_SHOWERR" +.It Dv WRDE_APPEND +Append the words to those generated by a previous call to +.Fn wordexp . +.It Dv WRDE_DOOFFS +As many +.Dv NULL +pointers as are specified by the +.Va we_offs +member of +.Fa we +are added to the front of +.Va we_wordv . +.It Dv WRDE_NOCMD +Disallow command substitution in +.Fa words . +See the note in +.Sx BUGS +before using this. +.It Dv WRDE_REUSE +The +.Fa we +argument was passed to a previous successful call to +.Fn wordexp +but has not been passed to +.Fn wordfree . +The implementation may reuse the space allocated to it. +.It Dv WRDE_SHOWERR +Do not redirect shell error messages to +.Pa /dev/null . +.It Dv WRDE_UNDEF +Report error on an attempt to expand an undefined shell variable. +.El +.Pp +The +.Vt wordexp_t +structure is defined in +.In wordexp.h +as: +.Bd -literal -offset indent +typedef struct { + size_t we_wordc; /* count of words matched */ + char **we_wordv; /* pointer to list of words */ + size_t we_offs; /* slots to reserve in we_wordv */ +} wordexp_t; +.Ed +.Pp +The +.Fn wordfree +function frees the memory allocated by +.Fn wordexp . +.Sh IMPLEMENTATION NOTES +The +.Fn wordexp +function is implemented as a wrapper around the undocumented +.Ic wordexp +shell built-in command. +.Sh RETURN VALUES +The +.Fn wordexp +function returns zero if successful, otherwise it returns one of the following +error codes: +.Bl -tag -width ".Dv WRDE_NOSPACE" +.It Dv WRDE_BADCHAR +The +.Fa words +argument contains one of the following unquoted characters: +.Aq newline , +.Ql | , +.Ql & , +.Ql \&; , +.Ql < , +.Ql > , +.Ql \&( , +.Ql \&) , +.Ql { , +.Ql } . +.It Dv WRDE_BADVAL +An attempt was made to expand an undefined shell variable and +.Dv WRDE_UNDEF +is set in +.Fa flags . +.It Dv WRDE_CMDSUB +An attempt was made to use command substitution and +.Dv WRDE_NOCMD +is set in +.Fa flags . +.It Dv WRDE_NOSPACE +Not enough memory to store the result. +.It Dv WRDE_SYNTAX +Shell syntax error in +.Fa words . +.El +.Pp +The +.Fn wordfree +function returns no value. +.Sh ENVIRONMENT +.Bl -tag -width ".Ev IFS" +.It Ev IFS +Field separator. +.El +.Sh EXAMPLES +Invoke the editor on all +.Pa .c +files in the current directory +and +.Pa /etc/motd +(error checking omitted): +.Bd -literal -offset indent +wordexp_t we; + +wordexp("${EDITOR:-vi} *.c /etc/motd", &we, 0); +execvp(we.we_wordv[0], we.we_wordv); +.Ed +.Sh DIAGNOSTICS +Diagnostic messages from the shell are written to the standard error output +if +.Dv WRDE_SHOWERR +is set in +.Fa flags . +.Sh SEE ALSO +.Xr sh 1 , +.Xr fnmatch 3 , +.Xr glob 3 , +.Xr popen 3 , +.Xr system 3 +.Sh STANDARDS +The +.Fn wordexp +and +.Fn wordfree +functions conform to +.St -p1003.1-2001 . +.Sh BUGS +Do not pass untrusted user data to +.Fn wordexp , +regardless of whether the +.Dv WRDE_NOCMD +flag is set. +The +.Fn wordexp +function attempts to detect input that would cause commands to be +executed before passing it to the shell +but it does not use the same parser so it may be fooled. +.Pp +The current +.Fn wordexp +implementation does not recognize multibyte characters, since the +shell (which it invokes to perform expansions) does not. diff --git a/src/libc/gen/FreeBSD/wordexp.c b/src/libc/gen/FreeBSD/wordexp.c new file mode 100644 index 000000000..4a6316b3f --- /dev/null +++ b/src/libc/gen/FreeBSD/wordexp.c @@ -0,0 +1,600 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#if TARGET_OS_IPHONE +/* */ + +#include +int wordexp(const char *restrict words __unused, wordexp_t *restrict pwordexp __unused, int flags __unused) { + return WRDE_NOSPACE; +} + +void wordfree(wordexp_t *pwordexp __unused) { +} + +#else + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#ifdef __APPLE__ +// For _NSGetEnviron() -- which gives us a pointer to environ +#include +#include +#endif /* __APPLE__ */ + +__FBSDID("$FreeBSD$"); + +#ifdef __APPLE__ +/* + * To maintain backwards compatibility with wordexp_t, we can't put + * we_strings and we_nbytes in wordexp_t. So we create a new structure, + * we_int_t, that has wi_strings and wi_nbytes, as well as the we_wordv + * storage. + */ +typedef struct { + char *wi_strings; + size_t wi_nbytes; + char *wi_wordv[0]; +} we_int_t; +/* + * Normally, we_wordv will point to wi_wordv, so we need macros to convert + * back and forth between wi_wordv and the we_int_t structure. + */ +#define WE_INT_T(x) ((we_int_t *)((char *)(x) - sizeof(we_int_t))) +#define WE_STRINGS(we) (WE_INT_T((we)->we_wordv)->wi_strings) +#define WE_WORDV(x) ((x)->wi_wordv) + +/* + * bash will return success, yet print a command substitution/syntax error + * to stderr. So we need to capture stderr, and see if it contains this error. + */ +static const char command_substitution_str[] = "command substitution"; +static const char syntax_error_str[] = "syntax error"; +static const char unbound_variable_str[] = " unbound variable"; +#endif /* __APPLE__ */ + +static int we_askshell(const char *, wordexp_t *, int); +static int we_check(const char *, int); + +/* + * wordexp -- + * Perform shell word expansion on `words' and place the resulting list + * of words in `we'. See wordexp(3). + * + * Specified by IEEE Std. 1003.1-2001. + */ +int +#ifdef __APPLE__ +wordexp(const char * __restrict words, wordexp_t * __restrict we0, int flags) +#else /* !__APPLE__ */ +wordexp(const char * __restrict words, wordexp_t * __restrict we, int flags) +#endif /* !__APPLE__ */ +{ + int error; +#ifdef __APPLE__ + wordexp_t temp; + wordexp_t *we = &temp; + + if ((error = we_check(words, flags)) != 0) return (error); + we->we_offs = we0->we_offs; + if (flags & WRDE_APPEND) { + size_t i; + size_t vofs = we0->we_wordc + (flags & WRDE_DOOFFS ? we0->we_offs : 0); + we_int_t *wi0 = WE_INT_T(we0->we_wordv); + we_int_t *wi = malloc((vofs + 1) * sizeof(char *) + sizeof(we_int_t)); + + if (!wi) return (WRDE_NOSPACE); + memcpy(wi, wi0, (vofs + 1) * sizeof(char *) + sizeof(we_int_t)); + wi->wi_strings = malloc(wi->wi_nbytes); + if (!wi->wi_strings) { + free(wi); + return (WRDE_NOSPACE); + } + memcpy(wi->wi_strings, wi0->wi_strings, wi->wi_nbytes); + for (i = 0; i < vofs; i++) + if (wi->wi_wordv[i] != NULL) + wi->wi_wordv[i] += wi->wi_strings - wi0->wi_strings; + we->we_wordc = we0->we_wordc; + we->we_wordv = WE_WORDV(wi); + } else { + we->we_wordc = 0; + we->we_wordv = NULL; + } +#else /* !__APPLE__ */ + if (flags & WRDE_REUSE) + wordfree(we); + if ((flags & WRDE_APPEND) == 0) { + we->we_wordc = 0; + we->we_wordv = NULL; + we->we_strings = NULL; + we->we_nbytes = 0; + } + if ((error = we_check(words, flags)) != 0) { + wordfree(we); + return (error); + } +#endif /* !__APPLE__ */ + if ((error = we_askshell(words, we, flags)) != 0) { +#ifdef __APPLE__ + if (error == WRDE_NOSPACE) { + if (flags & WRDE_REUSE) + wordfree(we0); + *we0 = *we; + } else { + wordfree(we); + } +#else /* !__APPLE__ */ + wordfree(we); +#endif /* !__APPLE__ */ + return (error); + } +#ifdef __APPLE__ + if (flags & WRDE_REUSE) + wordfree(we0); + *we0 = *we; +#endif /* __APPLE__ */ + return (0); +} + +static size_t +we_read_fully(int fd, char *buffer, size_t len) +{ + size_t done; + ssize_t nread; + + done = 0; + do { + nread = _read(fd, buffer + done, len - done); + if (nread == -1 && errno == EINTR) + continue; + if (nread <= 0) + break; + done += nread; + } while (done != len); + return done; +} + +/* + * we_askshell -- + * Use the `wordexp' /bin/sh builtin function to do most of the work + * in expanding the word string. This function is complicated by + * memory management. + */ +static int +we_askshell(const char *words, wordexp_t *we, int flags) +{ + int pdes[2]; /* Pipe to child */ + char bbuf[9]; /* Buffer for byte count */ + char wbuf[9]; /* Buffer for word count */ + long nwords, nbytes; /* Number of words, bytes from child */ + long i; /* Handy integer */ + size_t sofs; /* Offset into we->we_strings */ + size_t vofs; /* Offset into we->we_wordv */ + pid_t pid; /* Process ID of child */ + pid_t wpid; /* waitpid return value */ + int status; /* Child exit status */ + int error; /* Our return value */ + int serrno; /* errno to return */ + char *np, *p; /* Handy pointers */ + char *nstrings; /* Temporary for realloc() */ +#ifdef __APPLE__ + int perr[2]; /* Pipe to child error */ + we_int_t *nwv; /* Temporary for realloc() */ + int spawnerr = 0; + posix_spawn_file_actions_t file_actions; + posix_spawnattr_t attr; +#else /* !__APPLE__ */ + char **nwv; /* Temporary for realloc() */ +#endif /* !__APPLE__ */ + sigset_t newsigblock, oldsigblock; + + serrno = errno; + +#ifdef __APPLE__ + if (pipe(pdes) < 0) +#else /* !__APPLE__ */ + if (pipe2(pdes, O_CLOEXEC) < 0) +#endif /* !__APPLE__ */ + return (WRDE_NOSPACE); /* XXX */ +#ifdef __APPLE__ + if (pipe(perr) < 0) { + close(pdes[0]); + close(pdes[1]); + return (WRDE_NOSPACE); /* XXX */ + } +#endif /* __APPLE__ */ + (void)sigemptyset(&newsigblock); + (void)sigaddset(&newsigblock, SIGCHLD); + (void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); +#ifdef __APPLE__ + if ((spawnerr = posix_spawnattr_init(&attr)) != 0) goto spawnerrexit; + do { + sigset_t spawnsig; + if ((spawnerr = posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT)) != 0) break; + (void)sigfillset(&spawnsig); + if ((spawnerr = posix_spawnattr_setsigdefault(&attr, &spawnsig)) != 0) break; + (void)sigemptyset(&spawnsig); + if ((spawnerr = posix_spawnattr_setsigmask(&attr, &spawnsig)) != 0) break; + if ((spawnerr = posix_spawn_file_actions_init(&file_actions)) != 0) break; + do { + char *argv[7] = {"sh"}; + const char cmd[] = "[ $# -gt 0 ] && export IFS=\"$1\";/usr/lib/system/wordexp-helper "; + int a = 1; + char *buf; + int buflen; + char *IFS; + if (pdes[1] == STDOUT_FILENO) { + if ((spawnerr = posix_spawn_file_actions_addinherit_np(&file_actions, STDOUT_FILENO)) != 0) break; + } else { + if ((spawnerr = posix_spawn_file_actions_adddup2(&file_actions, pdes[1], STDOUT_FILENO)) != 0) break; + } + if (perr[1] == STDERR_FILENO) { + if ((spawnerr = posix_spawn_file_actions_addinherit_np(&file_actions, STDERR_FILENO)) != 0) break; + } else { + if ((spawnerr = posix_spawn_file_actions_adddup2(&file_actions, perr[1], STDERR_FILENO)) != 0) break; + } + if (flags & WRDE_UNDEF) argv[a++] = "-u"; + argv[a++] = "-c"; + buflen = (sizeof(cmd) - 1) + strlen(words) + 1; + if ((buf = malloc(buflen)) == NULL) { + spawnerr = errno; + break; + } + strcpy(buf, cmd); + strcat(buf, words); + argv[a++] = buf; + if ((IFS = getenv("IFS")) != NULL) { + argv[a++] = "--"; + argv[a++] = IFS; + } + argv[a] = NULL; + spawnerr = posix_spawn(&pid, _PATH_BSHELL, &file_actions, &attr, argv, *_NSGetEnviron()); + free(buf); + } while(0); + posix_spawn_file_actions_destroy(&file_actions); + } while(0); + posix_spawnattr_destroy(&attr); + if (spawnerr) { +spawnerrexit: + close(pdes[0]); + close(pdes[1]); + close(perr[0]); + close(perr[1]); + errno = spawnerr; + return (WRDE_NOSPACE); /* XXX */ + } +#else /* !__APPLE__ */ + if ((pid = fork()) < 0) { + serrno = errno; + _close(pdes[0]); + _close(pdes[1]); + (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + errno = serrno; + return (WRDE_NOSPACE); /* XXX */ + } + else if (pid == 0) { + /* + * We are the child; just get /bin/sh to run the wordexp + * builtin on `words'. + */ + (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + if ((pdes[1] != STDOUT_FILENO ? + _dup2(pdes[1], STDOUT_FILENO) : + _fcntl(pdes[1], F_SETFD, 0)) < 0) + _exit(1); + execl(_PATH_BSHELL, "sh", flags & WRDE_UNDEF ? "-u" : "+u", + "-c", "eval \"$1\";eval \"wordexp $2\"", "", + flags & WRDE_SHOWERR ? "" : "exec 2>/dev/null", words, + (char *)NULL); + _exit(1); + } +#endif /* !__APPLE__ */ + + /* + * We are the parent; read the output of the shell wordexp function, + * which is a 32-bit hexadecimal word count, a 32-bit hexadecimal + * byte count (not including terminating null bytes), followed by + * the expanded words separated by nulls. + */ + _close(pdes[1]); +#ifdef __APPLE__ + close(perr[1]); +#endif /* __APPLE__ */ + if (we_read_fully(pdes[0], wbuf, 8) != 8 || + we_read_fully(pdes[0], bbuf, 8) != 8) { + error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX; + serrno = errno; + goto cleanup; + } + wbuf[8] = bbuf[8] = '\0'; + nwords = strtol(wbuf, NULL, 16); + nbytes = strtol(bbuf, NULL, 16) + nwords; + + /* + * Allocate or reallocate (when flags & WRDE_APPEND) the word vector + * and string storage buffers for the expanded words we're about to + * read from the child. + */ +#ifndef __APPLE__ + sofs = we->we_nbytes; +#endif /* !__APPLE__ */ + vofs = we->we_wordc; + if ((flags & (WRDE_DOOFFS|WRDE_APPEND)) == (WRDE_DOOFFS|WRDE_APPEND)) + vofs += we->we_offs; + we->we_wordc += nwords; +#ifndef __APPLE__ + we->we_nbytes += nbytes; +#endif /* !__APPLE__ */ +#ifdef __APPLE__ + if ((nwv = realloc(we->we_wordv ? WE_INT_T(we->we_wordv) : NULL, (we->we_wordc + 1 + + (flags & WRDE_DOOFFS ? we->we_offs : 0)) * + sizeof(char *) + sizeof(we_int_t))) == NULL) +#else /* !__APPLE__ */ + if ((nwv = realloc(we->we_wordv, (we->we_wordc + 1 + + (flags & WRDE_DOOFFS ? we->we_offs : 0)) * + sizeof(char *))) == NULL) +#endif /* !__APPLE__ */ + { + error = WRDE_NOSPACE; + goto cleanup; + } +#ifdef __APPLE__ + if (!we->we_wordv) { + nwv->wi_strings = NULL; + nwv->wi_nbytes = 0; + } + sofs = nwv->wi_nbytes; + nwv->wi_nbytes += nbytes; + we->we_wordv = WE_WORDV(nwv); +#else /* !__APPLE__ */ + we->we_wordv = nwv; +#endif /* !__APPLE__ */ +#ifdef __APPLE__ + if ((nstrings = realloc(nwv->wi_strings, nwv->wi_nbytes)) == NULL) +#else /* !__APPLE__ */ + if ((nstrings = realloc(we->we_strings, we->we_nbytes)) == NULL) +#endif /* !__APPLE__ */ + { + error = WRDE_NOSPACE; + goto cleanup; + } + for (i = 0; i < vofs; i++) + if (we->we_wordv[i] != NULL) +#ifdef __APPLE__ + we->we_wordv[i] += nstrings - nwv->wi_strings; +#else /* !__APPLE__ */ + we->we_wordv[i] += nstrings - we->we_strings; +#endif /* !__APPLE__ */ +#ifdef __APPLE__ + nwv->wi_strings = nstrings; +#else /* !__APPLE__ */ + we->we_strings = nstrings; +#endif /* !__APPLE__ */ + +#ifdef __APPLE__ + if (we_read_fully(pdes[0], nwv->wi_strings + sofs, nbytes) != nbytes) +#else /* !__APPLE__ */ + if (we_read_fully(pdes[0], we->we_strings + sofs, nbytes) != nbytes) +#endif /* !__APPLE__ */ + { + error = flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX; + serrno = errno; + goto cleanup; + } +#ifdef __APPLE__ + char err_buf[1024]; + ssize_t err_sz = read(perr[0], err_buf, sizeof(err_buf) - 1); + if (err_sz > 0) { + err_buf[err_sz] = '\0'; + if (flags & WRDE_SHOWERR) { + fputs(err_buf, stderr); + } + } else if (err_sz < 0) { + serrno = errno; + error = WRDE_NOSPACE; + goto cleanup; + } +#endif /* __APPLE__ */ + + error = 0; +cleanup: + _close(pdes[0]); +#ifdef __APPLE__ + close(perr[0]); +#endif /* __APPLE__ */ + do + wpid = _waitpid(pid, &status, 0); + while (wpid < 0 && errno == EINTR); + (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); + if (error != 0) { + errno = serrno; + return (error); + } + if (wpid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) + return (flags & WRDE_UNDEF ? WRDE_BADVAL : WRDE_SYNTAX); +#ifdef __APPLE__ + const char *cs = strstr(err_buf, command_substitution_str); + if (cs && strstr(cs + (sizeof(command_substitution_str) - 1), syntax_error_str)) { + return (strstr(err_buf, unbound_variable_str) ? WRDE_BADVAL : WRDE_SYNTAX); + } +#endif /* __APPLE__ */ + + /* + * Break the null-terminated expanded word strings out into + * the vector. + */ + if (vofs == 0 && flags & WRDE_DOOFFS) + while (vofs < we->we_offs) + we->we_wordv[vofs++] = NULL; +#ifdef __APPLE__ + p = nwv->wi_strings + sofs; +#else /* !__APPLE__ */ + p = we->we_strings + sofs; +#endif /* !__APPLE__ */ + while (nwords-- != 0) { + we->we_wordv[vofs++] = p; + if ((np = memchr(p, '\0', nbytes)) == NULL) + return (WRDE_NOSPACE); /* XXX */ + nbytes -= np - p + 1; + p = np + 1; + } + we->we_wordv[vofs] = NULL; + + return (0); +} + +/* + * we_check -- + * Check that the string contains none of the following unquoted + * special characters: |&;<>(){} + * or command substitutions when WRDE_NOCMD is set in flags. + */ +static int +we_check(const char *words, int flags) +{ + char c; + int dquote, level, quote, squote; + + quote = squote = dquote = 0; + while ((c = *words++) != '\0') { + switch (c) { + case '\\': + if (squote == 0) + quote ^= 1; + continue; + case '\'': + if (quote + dquote == 0) + squote ^= 1; + break; + case '"': + if (quote + squote == 0) + dquote ^= 1; + break; + case '`': + if (quote + squote == 0 && flags & WRDE_NOCMD) + return (WRDE_CMDSUB); + while ((c = *words++) != '\0' && c != '`') + if (c == '\\' && (c = *words++) == '\0') + break; + if (c == '\0') + return (WRDE_SYNTAX); + break; + case '|': case '&': case ';': case '<': case '>': + case '{': case '}': case '(': case ')': case '\n': + if (quote + squote + dquote == 0) + return (WRDE_BADCHAR); + break; + case '$': + if ((c = *words++) == '\0') + break; + else if (quote + squote == 0 && c == '(') { + if (flags & WRDE_NOCMD && *words != '(') + return (WRDE_CMDSUB); + level = 1; + while ((c = *words++) != '\0') { + if (c == '\\') { + if ((c = *words++) == '\0') + break; + } else if (c == '(') + level++; + else if (c == ')' && --level == 0) + break; + } + if (c == '\0' || level != 0) + return (WRDE_SYNTAX); + } else if (quote + squote == 0 && c == '{') { + level = 1; + while ((c = *words++) != '\0') { + if (c == '\\') { + if ((c = *words++) == '\0') + break; + } else if (c == '{') + level++; + else if (c == '}' && --level == 0) + break; + } + if (c == '\0' || level != 0) + return (WRDE_SYNTAX); + } else + --words; + break; + default: + break; + } + quote = 0; + } + if (quote + squote + dquote != 0) + return (WRDE_SYNTAX); + + return (0); +} + +/* + * wordfree -- + * Free the result of wordexp(). See wordexp(3). + * + * Specified by IEEE Std. 1003.1-2001. + */ +void +wordfree(wordexp_t *we) +{ + + if (we == NULL) + return; +#ifdef __APPLE__ + if (we->we_wordv) { + free(WE_STRINGS(we)); + free(WE_INT_T(we->we_wordv)); + } +#else /* !__APPLE__ */ + free(we->we_wordv); +#endif /* !__APPLE__ */ +#ifndef __APPLE__ + free(we->we_strings); +#endif /* !__APPLE__ */ + we->we_wordv = NULL; +#ifndef __APPLE__ + we->we_strings = NULL; + we->we_nbytes = 0; +#endif /* !__APPLE__ */ + we->we_wordc = 0; +} + +#endif /* TARGET_OS_IPHONE */ diff --git a/src/libc/gen/NetBSD/rb.c b/src/libc/gen/NetBSD/rb.c new file mode 100644 index 000000000..2efdf3599 --- /dev/null +++ b/src/libc/gen/NetBSD/rb.c @@ -0,0 +1,1440 @@ +/* $NetBSD: rb.c,v 1.11 2011/06/20 09:11:16 mrg Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Portions Copyright (c) 2012 Apple Inc. All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#undef RBSMALL +#undef RBDEBUG +#undef RBSTATS +#undef RBTEST + +#define _RBTREE_NO_OPAQUE_STRUCTS_ + +#ifdef RBTEST +#include "rbtree.h" +#else +#include +#endif + +#ifndef __predict_false +#ifdef __GNUC__ +#define __predict_false(x) (__builtin_expect((long)(x), 0l)) +#else +#define __predict_false(x) (x) +#endif +#endif + +#define RB_DIR_OTHER RB_DIR_RIGHT + +#define rb_left rb_nodes[RB_DIR_LEFT] +#define rb_right rb_nodes[RB_DIR_RIGHT] + +#define RB_FLAG_POSITION 0x2 +#define RB_FLAG_RED 0x1 +#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED) +#define RB_FATHER(rb) \ + ((struct rb_node *)((rb)->rb_info & ~RB_FLAG_MASK)) +#define RB_SET_FATHER(rb, father) \ + ((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK))) + +#define RB_SENTINEL_P(rb) ((rb) == NULL) +#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left) +#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right) +#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb))) +#define RB_CHILDLESS_P(rb) \ + (RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb))) +#define RB_TWOCHILDREN_P(rb) \ + (!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb)) + +#define RB_POSITION(rb) \ + (((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT) +#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT) +#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT) +#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0) +#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0) +#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED)) +#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED)) +#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED)) +#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb)) +#define RB_SET_POSITION(rb, position) \ + ((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \ + ((rb)->rb_info &= ~RB_FLAG_POSITION))) +#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK)) +#define RB_COPY_PROPERTIES(dst, src) \ + ((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK)) +#define RB_SWAP_PROPERTIES(a, b) do { \ + uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \ + (a)->rb_info ^= xorinfo; \ + (b)->rb_info ^= xorinfo; \ + } while (/*CONSTCOND*/ 0) + +#ifndef static_assert +#define _static_assert_concat_(a,b) a##b +#define _static_assert_concat(a,b) _static_assert_concat_(a,b) +#define static_assert(c, m) struct _static_assert_concat(static_assert_failure_, __LINE__) { int _static_assert_concat(static_assert_failure_, __LINE__)[(c)? 1 : -1]; } +#endif + +/* The size of struct_rbnode must match: + * sizeof(struct rb_node { void * opaque[3] }) + */ +typedef struct rb_node { + struct rb_node *rb_nodes[2]; + + /* + * rb_info contains the two flags and the parent back pointer. + * We put the two flags in the low two bits since we know that + * rb_node will have an alignment of 4 or 8 bytes. + */ + uintptr_t rb_info; +} rb_node_t; + +static_assert(sizeof(struct { void * opaque[3]; }) == sizeof(rb_node_t), + "Mismatch in size between opaque and internal rb_node_t"); + +typedef struct rb_tree { + struct rb_node *rbt_root; + const rb_tree_ops_t *rbt_ops; + struct rb_node *rbt_minmax[2]; + uintptr_t rbt_count; + void *unused[3]; // Unused padding for possible future use +} rb_tree_t; + +static_assert(sizeof(struct { void * opaque[8]; }) == sizeof(rb_tree_t), + "Mismatch in size between opaque and internal rb_tree_t"); + +static void rb_tree_insert_rebalance(struct rb_tree *, struct rb_node *); +static void rb_tree_removal_rebalance(struct rb_tree *, struct rb_node *, + unsigned int); +#ifdef RBDEBUG +static const struct rb_node *rb_tree_iterate_const(const struct rb_tree *, + const struct rb_node *, const unsigned int); +static bool rb_tree_check_node(const struct rb_tree *, const struct rb_node *, + const struct rb_node *, bool); + +TAILQ_HEAD(rb_node_qh, rb_node); + +#define RB_TAILQ_REMOVE(a, b, c) TAILQ_REMOVE(a, b, c) +#define RB_TAILQ_INIT(a) TAILQ_INIT(a) +#define RB_TAILQ_INSERT_HEAD(a, b, c) TAILQ_INSERT_HEAD(a, b, c) +#define RB_TAILQ_INSERT_BEFORE(a, b, c) TAILQ_INSERT_BEFORE(a, b, c) +#define RB_TAILQ_INSERT_AFTER(a, b, c, d) TAILQ_INSERT_AFTER(a, b, c, d) + +#define KASSERT(s) assert(s) +#else + +#define rb_tree_check_node(a, b, c, d) true + +#define RB_TAILQ_REMOVE(a, b, c) do { } while (/*CONSTCOND*/0) +#define RB_TAILQ_INIT(a) do { } while (/*CONSTCOND*/0) +#define RB_TAILQ_INSERT_HEAD(a, b, c) do { } while (/*CONSTCOND*/0) +#define RB_TAILQ_INSERT_BEFORE(a, b, c) do { } while (/*CONSTCOND*/0) +#define RB_TAILQ_INSERT_AFTER(a, b, c, d) do { } while (/*CONSTCOND*/0) + +#define KASSERT(s) do { } while (/*CONSTCOND*/ 0) +#endif + +#ifdef RBSTATS +#define RBSTAT_INC(v) ((void)((v)++)) +#define RBSTAT_DEC(v) ((void)((v)--)) +#else +#define RBSTAT_INC(v) do { } while (/*CONSTCOND*/0) +#define RBSTAT_DEC(v) do { } while (/*CONSTCOND*/0) +#endif + +#define RB_NODETOITEM(rbto, rbn) \ + ((void *)((uintptr_t)(rbn) - (rbto)->rbto_node_offset)) +#define RB_ITEMTONODE(rbto, rbn) \ + ((rb_node_t *)((uintptr_t)(rbn) + (rbto)->rbto_node_offset)) + +#define RB_SENTINEL_NODE NULL + +void +rb_tree_init(struct rb_tree *rbt, const rb_tree_ops_t *ops) +{ + + rbt->rbt_ops = ops; + rbt->rbt_root = RB_SENTINEL_NODE; + RB_TAILQ_INIT(&rbt->rbt_nodes); +#ifndef RBSMALL + rbt->rbt_minmax[RB_DIR_LEFT] = rbt->rbt_root; /* minimum node */ + rbt->rbt_minmax[RB_DIR_RIGHT] = rbt->rbt_root; /* maximum node */ +#endif + rbt->rbt_count = 0; +#ifdef RBSTATS + rbt->rbt_insertions = 0; + rbt->rbt_removals = 0; + rbt->rbt_insertion_rebalance_calls = 0; + rbt->rbt_insertion_rebalance_passes = 0; + rbt->rbt_removal_rebalance_calls = 0; + rbt->rbt_removal_rebalance_passes = 0; +#endif +} + +void * +rb_tree_find_node(struct rb_tree *rbt, const void *key) +{ + const rb_tree_ops_t *rbto = rbt->rbt_ops; + rbto_compare_key_fn compare_key = rbto->rbto_compare_key; + struct rb_node *parent = rbt->rbt_root; + + while (!RB_SENTINEL_P(parent)) { + void *pobj = RB_NODETOITEM(rbto, parent); + const signed int diff = (*compare_key)(rbto->rbto_context, + pobj, key); + if (diff == 0) + return pobj; + parent = parent->rb_nodes[diff < 0]; + } + + return NULL; +} + +void * +rb_tree_find_node_geq(struct rb_tree *rbt, const void *key) +{ + const rb_tree_ops_t *rbto = rbt->rbt_ops; + rbto_compare_key_fn compare_key = rbto->rbto_compare_key; + struct rb_node *parent = rbt->rbt_root, *last = NULL; + + while (!RB_SENTINEL_P(parent)) { + void *pobj = RB_NODETOITEM(rbto, parent); + const signed int diff = (*compare_key)(rbto->rbto_context, + pobj, key); + if (diff == 0) + return pobj; + if (diff > 0) + last = parent; + parent = parent->rb_nodes[diff < 0]; + } + + return last == NULL ? NULL : RB_NODETOITEM(rbto, last); +} + +void * +rb_tree_find_node_leq(struct rb_tree *rbt, const void *key) +{ + const rb_tree_ops_t *rbto = rbt->rbt_ops; + rbto_compare_key_fn compare_key = rbto->rbto_compare_key; + struct rb_node *parent = rbt->rbt_root, *last = NULL; + + while (!RB_SENTINEL_P(parent)) { + void *pobj = RB_NODETOITEM(rbto, parent); + const signed int diff = (*compare_key)(rbto->rbto_context, + pobj, key); + if (diff == 0) + return pobj; + if (diff < 0) + last = parent; + parent = parent->rb_nodes[diff < 0]; + } + + return last == NULL ? NULL : RB_NODETOITEM(rbto, last); +} + +void * +rb_tree_insert_node(struct rb_tree *rbt, void *object) +{ + const rb_tree_ops_t *rbto = rbt->rbt_ops; + rbto_compare_nodes_fn compare_nodes = rbto->rbto_compare_nodes; + struct rb_node *parent, *tmp, *self = RB_ITEMTONODE(rbto, object); + unsigned int position; + bool rebalance; + + RBSTAT_INC(rbt->rbt_insertions); + + tmp = rbt->rbt_root; + /* + * This is a hack. Because rbt->rbt_root is just a struct rb_node *, + * just like rb_node->rb_nodes[RB_DIR_LEFT], we can use this fact to + * avoid a lot of tests for root and know that even at root, + * updating RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will + * update rbt->rbt_root. + */ + parent = (struct rb_node *)(void *)&rbt->rbt_root; + position = RB_DIR_LEFT; + + /* + * Find out where to place this new leaf. + */ + while (!RB_SENTINEL_P(tmp)) { + void *tobj = RB_NODETOITEM(rbto, tmp); + const signed int diff = (*compare_nodes)(rbto->rbto_context, + tobj, object); + if (__predict_false(diff == 0)) { + /* + * Node already exists; return it. + */ + return tobj; + } + parent = tmp; + position = (diff < 0); + tmp = parent->rb_nodes[position]; + } + +#ifdef RBDEBUG + { + struct rb_node *prev = NULL, *next = NULL; + + if (position == RB_DIR_RIGHT) + prev = parent; + else if (tmp != rbt->rbt_root) + next = parent; + + /* + * Verify our sequential position + */ + KASSERT(prev == NULL || !RB_SENTINEL_P(prev)); + KASSERT(next == NULL || !RB_SENTINEL_P(next)); + if (prev != NULL && next == NULL) + next = TAILQ_NEXT(prev, rb_link); + if (prev == NULL && next != NULL) + prev = TAILQ_PREV(next, rb_node_qh, rb_link); + KASSERT(prev == NULL || !RB_SENTINEL_P(prev)); + KASSERT(next == NULL || !RB_SENTINEL_P(next)); + KASSERT(prev == NULL || (*compare_nodes)(rbto->rbto_context, + RB_NODETOITEM(rbto, prev), RB_NODETOITEM(rbto, self)) < 0); + KASSERT(next == NULL || (*compare_nodes)(rbto->rbto_context, + RB_NODETOITEM(rbto, self), RB_NODETOITEM(rbto, next)) < 0); + } +#endif + + /* + * Initialize the node and insert as a leaf into the tree. + */ + RB_SET_FATHER(self, parent); + RB_SET_POSITION(self, position); + if (__predict_false(parent == (struct rb_node *)(void *)&rbt->rbt_root)) { + RB_MARK_BLACK(self); /* root is always black */ +#ifndef RBSMALL + rbt->rbt_minmax[RB_DIR_LEFT] = self; + rbt->rbt_minmax[RB_DIR_RIGHT] = self; +#endif + rebalance = false; + } else { + KASSERT(position == RB_DIR_LEFT || position == RB_DIR_RIGHT); +#ifndef RBSMALL + /* + * Keep track of the minimum and maximum nodes. If our + * parent is a minmax node and we on their min/max side, + * we must be the new min/max node. + */ + if (parent == rbt->rbt_minmax[position]) + rbt->rbt_minmax[position] = self; +#endif /* !RBSMALL */ + /* + * All new nodes are colored red. We only need to rebalance + * if our parent is also red. + */ + RB_MARK_RED(self); + rebalance = RB_RED_P(parent); + } + KASSERT(RB_SENTINEL_P(parent->rb_nodes[position])); + self->rb_left = parent->rb_nodes[position]; + self->rb_right = parent->rb_nodes[position]; + parent->rb_nodes[position] = self; + KASSERT(RB_CHILDLESS_P(self)); + + /* + * Insert the new node into a sorted list for easy sequential access + */ + rbt->rbt_count++; +#ifdef RBDEBUG + if (RB_ROOT_P(rbt, self)) { + RB_TAILQ_INSERT_HEAD(&rbt->rbt_nodes, self, rb_link); + } else if (position == RB_DIR_LEFT) { + KASSERT((*compare_nodes)(rbto->rbto_context, + RB_NODETOITEM(rbto, self), + RB_NODETOITEM(rbto, RB_FATHER(self))) < 0); + RB_TAILQ_INSERT_BEFORE(RB_FATHER(self), self, rb_link); + } else { + KASSERT((*compare_nodes)(rbto->rbto_context, + RB_NODETOITEM(rbto, RB_FATHER(self)), + RB_NODETOITEM(rbto, self)) < 0); + RB_TAILQ_INSERT_AFTER(&rbt->rbt_nodes, RB_FATHER(self), + self, rb_link); + } +#endif + KASSERT(rb_tree_check_node(rbt, self, NULL, !rebalance)); + + /* + * Rebalance tree after insertion + */ + if (rebalance) { + rb_tree_insert_rebalance(rbt, self); + KASSERT(rb_tree_check_node(rbt, self, NULL, true)); + } + + /* Succesfully inserted, return our node pointer. */ + return object; +} + +/* + * Swap the location and colors of 'self' and its child @ which. The child + * can not be a sentinel node. This is our rotation function. However, + * since it preserves coloring, it great simplifies both insertion and + * removal since rotation almost always involves the exchanging of colors + * as a separate step. + */ +/*ARGSUSED*/ +static void +rb_tree_reparent_nodes(struct rb_tree *rbt, struct rb_node *old_father, + const unsigned int which) +{ + const unsigned int other = which ^ RB_DIR_OTHER; + struct rb_node * const grandpa = RB_FATHER(old_father); + struct rb_node * const old_child = old_father->rb_nodes[which]; + struct rb_node * const new_father = old_child; + struct rb_node * const new_child = old_father; + + KASSERT(which == RB_DIR_LEFT || which == RB_DIR_RIGHT); + + KASSERT(!RB_SENTINEL_P(old_child)); + KASSERT(RB_FATHER(old_child) == old_father); + + KASSERT(rb_tree_check_node(rbt, old_father, NULL, false)); + KASSERT(rb_tree_check_node(rbt, old_child, NULL, false)); + KASSERT(RB_ROOT_P(rbt, old_father) || + rb_tree_check_node(rbt, grandpa, NULL, false)); + + /* + * Exchange descendant linkages. + */ + grandpa->rb_nodes[RB_POSITION(old_father)] = new_father; + new_child->rb_nodes[which] = old_child->rb_nodes[other]; + new_father->rb_nodes[other] = new_child; + + /* + * Update ancestor linkages + */ + RB_SET_FATHER(new_father, grandpa); + RB_SET_FATHER(new_child, new_father); + + /* + * Exchange properties between new_father and new_child. The only + * change is that new_child's position is now on the other side. + */ +#if 0 + { + struct rb_node tmp; + tmp.rb_info = 0; + RB_COPY_PROPERTIES(&tmp, old_child); + RB_COPY_PROPERTIES(new_father, old_father); + RB_COPY_PROPERTIES(new_child, &tmp); + } +#else + RB_SWAP_PROPERTIES(new_father, new_child); +#endif + RB_SET_POSITION(new_child, other); + + /* + * Make sure to reparent the new child to ourself. + */ + if (!RB_SENTINEL_P(new_child->rb_nodes[which])) { + RB_SET_FATHER(new_child->rb_nodes[which], new_child); + RB_SET_POSITION(new_child->rb_nodes[which], which); + } + + KASSERT(rb_tree_check_node(rbt, new_father, NULL, false)); + KASSERT(rb_tree_check_node(rbt, new_child, NULL, false)); + KASSERT(RB_ROOT_P(rbt, new_father) || + rb_tree_check_node(rbt, grandpa, NULL, false)); +} + +static void +rb_tree_insert_rebalance(struct rb_tree *rbt, struct rb_node *self) +{ + struct rb_node * father = RB_FATHER(self); + struct rb_node * grandpa = RB_FATHER(father); + struct rb_node * uncle; + unsigned int which; + unsigned int other; + + KASSERT(!RB_ROOT_P(rbt, self)); + KASSERT(RB_RED_P(self)); + KASSERT(RB_RED_P(father)); + RBSTAT_INC(rbt->rbt_insertion_rebalance_calls); + + for (;;) { + KASSERT(!RB_SENTINEL_P(self)); + + KASSERT(RB_RED_P(self)); + KASSERT(RB_RED_P(father)); + /* + * We are red and our parent is red, therefore we must have a + * grandfather and he must be black. + */ + grandpa = RB_FATHER(father); + KASSERT(RB_BLACK_P(grandpa)); + KASSERT(RB_DIR_RIGHT == 1 && RB_DIR_LEFT == 0); + which = (father == grandpa->rb_right); + other = which ^ RB_DIR_OTHER; + uncle = grandpa->rb_nodes[other]; + + if (RB_BLACK_P(uncle)) + break; + + RBSTAT_INC(rbt->rbt_insertion_rebalance_passes); + /* + * Case 1: our uncle is red + * Simply invert the colors of our parent and + * uncle and make our grandparent red. And + * then solve the problem up at his level. + */ + RB_MARK_BLACK(uncle); + RB_MARK_BLACK(father); + if (__predict_false(RB_ROOT_P(rbt, grandpa))) { + /* + * If our grandpa is root, don't bother + * setting him to red, just return. + */ + KASSERT(RB_BLACK_P(grandpa)); + return; + } + RB_MARK_RED(grandpa); + self = grandpa; + father = RB_FATHER(self); + KASSERT(RB_RED_P(self)); + if (RB_BLACK_P(father)) { + /* + * If our greatgrandpa is black, we're done. + */ + KASSERT(RB_BLACK_P(rbt->rbt_root)); + return; + } + } + + KASSERT(!RB_ROOT_P(rbt, self)); + KASSERT(RB_RED_P(self)); + KASSERT(RB_RED_P(father)); + KASSERT(RB_BLACK_P(uncle)); + KASSERT(RB_BLACK_P(grandpa)); + /* + * Case 2&3: our uncle is black. + */ + if (self == father->rb_nodes[other]) { + /* + * Case 2: we are on the same side as our uncle + * Swap ourselves with our parent so this case + * becomes case 3. Basically our parent becomes our + * child. + */ + rb_tree_reparent_nodes(rbt, father, other); + KASSERT(RB_FATHER(father) == self); + KASSERT(self->rb_nodes[which] == father); + KASSERT(RB_FATHER(self) == grandpa); + self = father; + father = RB_FATHER(self); + } + KASSERT(RB_RED_P(self) && RB_RED_P(father)); + KASSERT(grandpa->rb_nodes[which] == father); + /* + * Case 3: we are opposite a child of a black uncle. + * Swap our parent and grandparent. Since our grandfather + * is black, our father will become black and our new sibling + * (former grandparent) will become red. + */ + rb_tree_reparent_nodes(rbt, grandpa, which); + KASSERT(RB_FATHER(self) == father); + KASSERT(RB_FATHER(self)->rb_nodes[RB_POSITION(self) ^ RB_DIR_OTHER] == grandpa); + KASSERT(RB_RED_P(self)); + KASSERT(RB_BLACK_P(father)); + KASSERT(RB_RED_P(grandpa)); + + /* + * Final step: Set the root to black. + */ + RB_MARK_BLACK(rbt->rbt_root); +} + +static void +rb_tree_prune_node(struct rb_tree *rbt, struct rb_node *self, bool rebalance) +{ + const unsigned int which = RB_POSITION(self); + struct rb_node *father = RB_FATHER(self); +#ifndef RBSMALL + const bool was_root = RB_ROOT_P(rbt, self); +#endif + + KASSERT(rebalance || (RB_ROOT_P(rbt, self) || RB_RED_P(self))); + KASSERT(!rebalance || RB_BLACK_P(self)); + KASSERT(RB_CHILDLESS_P(self)); + KASSERT(rb_tree_check_node(rbt, self, NULL, false)); + + /* + * Since we are childless, we know that self->rb_left is pointing + * to the sentinel node. + */ + father->rb_nodes[which] = self->rb_left; + + /* + * Remove ourselves from the node list, decrement the count, + * and update min/max. + */ + RB_TAILQ_REMOVE(&rbt->rbt_nodes, self, rb_link); + rbt->rbt_count--; +#ifndef RBSMALL + if (__predict_false(rbt->rbt_minmax[RB_POSITION(self)] == self)) { + rbt->rbt_minmax[RB_POSITION(self)] = father; + /* + * When removing the root, rbt->rbt_minmax[RB_DIR_LEFT] is + * updated automatically, but we also need to update + * rbt->rbt_minmax[RB_DIR_RIGHT]; + */ + if (__predict_false(was_root)) { + rbt->rbt_minmax[RB_DIR_RIGHT] = father; + } + } + RB_SET_FATHER(self, NULL); +#endif + + /* + * Rebalance if requested. + */ + if (rebalance) + rb_tree_removal_rebalance(rbt, father, which); + KASSERT(was_root || rb_tree_check_node(rbt, father, NULL, true)); +} + +/* + * When deleting an interior node + */ +static void +rb_tree_swap_prune_and_rebalance(struct rb_tree *rbt, struct rb_node *self, + struct rb_node *standin) +{ + const unsigned int standin_which = RB_POSITION(standin); + unsigned int standin_other = standin_which ^ RB_DIR_OTHER; + struct rb_node *standin_son; + struct rb_node *standin_father = RB_FATHER(standin); + bool rebalance = RB_BLACK_P(standin); + + if (standin_father == self) { + /* + * As a child of self, any childen would be opposite of + * our parent. + */ + KASSERT(RB_SENTINEL_P(standin->rb_nodes[standin_other])); + standin_son = standin->rb_nodes[standin_which]; + } else { + /* + * Since we aren't a child of self, any childen would be + * on the same side as our parent. + */ + KASSERT(RB_SENTINEL_P(standin->rb_nodes[standin_which])); + standin_son = standin->rb_nodes[standin_other]; + } + + /* + * the node we are removing must have two children. + */ + KASSERT(RB_TWOCHILDREN_P(self)); + /* + * If standin has a child, it must be red. + */ + KASSERT(RB_SENTINEL_P(standin_son) || RB_RED_P(standin_son)); + + /* + * Verify things are sane. + */ + KASSERT(rb_tree_check_node(rbt, self, NULL, false)); + KASSERT(rb_tree_check_node(rbt, standin, NULL, false)); + + if (__predict_false(RB_RED_P(standin_son))) { + /* + * We know we have a red child so if we flip it to black + * we don't have to rebalance. + */ + KASSERT(rb_tree_check_node(rbt, standin_son, NULL, true)); + RB_MARK_BLACK(standin_son); + rebalance = false; + + if (standin_father == self) { + KASSERT(RB_POSITION(standin_son) == standin_which); + } else { + KASSERT(RB_POSITION(standin_son) == standin_other); + /* + * Change the son's parentage to point to his grandpa. + */ + RB_SET_FATHER(standin_son, standin_father); + RB_SET_POSITION(standin_son, standin_which); + } + } + + if (standin_father == self) { + /* + * If we are about to delete the standin's father, then when + * we call rebalance, we need to use ourselves as our father. + * Otherwise remember our original father. Also, sincef we are + * our standin's father we only need to reparent the standin's + * brother. + * + * | R --> S | + * | Q S --> Q T | + * | t --> | + */ + KASSERT(RB_SENTINEL_P(standin->rb_nodes[standin_other])); + KASSERT(!RB_SENTINEL_P(self->rb_nodes[standin_other])); + KASSERT(self->rb_nodes[standin_which] == standin); + /* + * Have our son/standin adopt his brother as his new son. + */ + standin_father = standin; + } else { + /* + * | R --> S . | + * | / \ | T --> / \ | / | + * | ..... | S --> ..... | T | + * + * Sever standin's connection to his father. + */ + standin_father->rb_nodes[standin_which] = standin_son; + /* + * Adopt the far son. + */ + standin->rb_nodes[standin_other] = self->rb_nodes[standin_other]; + RB_SET_FATHER(standin->rb_nodes[standin_other], standin); + KASSERT(RB_POSITION(self->rb_nodes[standin_other]) == standin_other); + /* + * Use standin_other because we need to preserve standin_which + * for the removal_rebalance. + */ + standin_other = standin_which; + } + + /* + * Move the only remaining son to our standin. If our standin is our + * son, this will be the only son needed to be moved. + */ + KASSERT(standin->rb_nodes[standin_other] != self->rb_nodes[standin_other]); + standin->rb_nodes[standin_other] = self->rb_nodes[standin_other]; + RB_SET_FATHER(standin->rb_nodes[standin_other], standin); + + /* + * Now copy the result of self to standin and then replace + * self with standin in the tree. + */ + RB_COPY_PROPERTIES(standin, self); + RB_SET_FATHER(standin, RB_FATHER(self)); + RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin; + + /* + * Remove ourselves from the node list, decrement the count, + * and update min/max. + */ + RB_TAILQ_REMOVE(&rbt->rbt_nodes, self, rb_link); + rbt->rbt_count--; +#ifndef RBSMALL + if (__predict_false(rbt->rbt_minmax[RB_POSITION(self)] == self)) + rbt->rbt_minmax[RB_POSITION(self)] = RB_FATHER(self); + RB_SET_FATHER(self, NULL); +#endif + + KASSERT(rb_tree_check_node(rbt, standin, NULL, false)); + KASSERT(RB_FATHER_SENTINEL_P(standin) + || rb_tree_check_node(rbt, standin_father, NULL, false)); + KASSERT(RB_LEFT_SENTINEL_P(standin) + || rb_tree_check_node(rbt, standin->rb_left, NULL, false)); + KASSERT(RB_RIGHT_SENTINEL_P(standin) + || rb_tree_check_node(rbt, standin->rb_right, NULL, false)); + + if (!rebalance) + return; + + rb_tree_removal_rebalance(rbt, standin_father, standin_which); + KASSERT(rb_tree_check_node(rbt, standin, NULL, true)); +} + +/* + * We could do this by doing + * rb_tree_node_swap(rbt, self, which); + * rb_tree_prune_node(rbt, self, false); + * + * But it's more efficient to just evalate and recolor the child. + */ +static void +rb_tree_prune_blackred_branch(struct rb_tree *rbt, struct rb_node *self, + unsigned int which) +{ + struct rb_node *father = RB_FATHER(self); + struct rb_node *son = self->rb_nodes[which]; +#ifndef RBSMALL + const bool was_root = RB_ROOT_P(rbt, self); +#endif + + KASSERT(which == RB_DIR_LEFT || which == RB_DIR_RIGHT); + KASSERT(RB_BLACK_P(self) && RB_RED_P(son)); + KASSERT(!RB_TWOCHILDREN_P(son)); + KASSERT(RB_CHILDLESS_P(son)); + KASSERT(rb_tree_check_node(rbt, self, NULL, false)); + KASSERT(rb_tree_check_node(rbt, son, NULL, false)); + + /* + * Remove ourselves from the tree and give our former child our + * properties (position, color, root). + */ + RB_COPY_PROPERTIES(son, self); + father->rb_nodes[RB_POSITION(son)] = son; + RB_SET_FATHER(son, father); + + /* + * Remove ourselves from the node list, decrement the count, + * and update minmax. + */ + RB_TAILQ_REMOVE(&rbt->rbt_nodes, self, rb_link); + rbt->rbt_count--; +#ifndef RBSMALL + if (__predict_false(was_root)) { + KASSERT(rbt->rbt_minmax[which] == son); + rbt->rbt_minmax[which ^ RB_DIR_OTHER] = son; + } else if (rbt->rbt_minmax[RB_POSITION(self)] == self) { + rbt->rbt_minmax[RB_POSITION(self)] = son; + } + RB_SET_FATHER(self, NULL); +#endif + + KASSERT(was_root || rb_tree_check_node(rbt, father, NULL, true)); + KASSERT(rb_tree_check_node(rbt, son, NULL, true)); +} + +void +rb_tree_remove_node(struct rb_tree *rbt, void *object) +{ + const rb_tree_ops_t *rbto = rbt->rbt_ops; + struct rb_node *standin, *self = RB_ITEMTONODE(rbto, object); + unsigned int which; + + KASSERT(!RB_SENTINEL_P(self)); + RBSTAT_INC(rbt->rbt_removals); + + /* + * In the following diagrams, we (the node to be removed) are S. Red + * nodes are lowercase. T could be either red or black. + * + * Remember the major axiom of the red-black tree: the number of + * black nodes from the root to each leaf is constant across all + * leaves, only the number of red nodes varies. + * + * Thus removing a red leaf doesn't require any other changes to a + * red-black tree. So if we must remove a node, attempt to rearrange + * the tree so we can remove a red node. + * + * The simpliest case is a childless red node or a childless root node: + * + * | T --> T | or | R --> * | + * | s --> * | + */ + if (RB_CHILDLESS_P(self)) { + const bool rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self); + rb_tree_prune_node(rbt, self, rebalance); + return; + } + KASSERT(!RB_CHILDLESS_P(self)); + if (!RB_TWOCHILDREN_P(self)) { + /* + * The next simpliest case is the node we are deleting is + * black and has one red child. + * + * | T --> T --> T | + * | S --> R --> R | + * | r --> s --> * | + */ + which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT; + KASSERT(RB_BLACK_P(self)); + KASSERT(RB_RED_P(self->rb_nodes[which])); + KASSERT(RB_CHILDLESS_P(self->rb_nodes[which])); + rb_tree_prune_blackred_branch(rbt, self, which); + return; + } + KASSERT(RB_TWOCHILDREN_P(self)); + + /* + * We invert these because we prefer to remove from the inside of + * the tree. + */ + which = RB_POSITION(self) ^ RB_DIR_OTHER; + + /* + * Let's find the node closes to us opposite of our parent + * Now swap it with ourself, "prune" it, and rebalance, if needed. + */ + standin = RB_ITEMTONODE(rbto, rb_tree_iterate(rbt, object, which)); + rb_tree_swap_prune_and_rebalance(rbt, self, standin); +} + +static void +rb_tree_removal_rebalance(struct rb_tree *rbt, struct rb_node *parent, + unsigned int which) +{ + KASSERT(!RB_SENTINEL_P(parent)); + KASSERT(RB_SENTINEL_P(parent->rb_nodes[which])); + KASSERT(which == RB_DIR_LEFT || which == RB_DIR_RIGHT); + RBSTAT_INC(rbt->rbt_removal_rebalance_calls); + + while (RB_BLACK_P(parent->rb_nodes[which])) { + unsigned int other = which ^ RB_DIR_OTHER; + struct rb_node *brother = parent->rb_nodes[other]; + + RBSTAT_INC(rbt->rbt_removal_rebalance_passes); + + KASSERT(!RB_SENTINEL_P(brother)); + /* + * For cases 1, 2a, and 2b, our brother's children must + * be black and our father must be black + */ + if (RB_BLACK_P(parent) + && RB_BLACK_P(brother->rb_left) + && RB_BLACK_P(brother->rb_right)) { + if (RB_RED_P(brother)) { + /* + * Case 1: Our brother is red, swap its + * position (and colors) with our parent. + * This should now be case 2b (unless C or E + * has a red child which is case 3; thus no + * explicit branch to case 2b). + * + * B -> D + * A d -> b E + * C E -> A C + */ + KASSERT(RB_BLACK_P(parent)); + rb_tree_reparent_nodes(rbt, parent, other); + brother = parent->rb_nodes[other]; + KASSERT(!RB_SENTINEL_P(brother)); + KASSERT(RB_RED_P(parent)); + KASSERT(RB_BLACK_P(brother)); + KASSERT(rb_tree_check_node(rbt, brother, NULL, false)); + KASSERT(rb_tree_check_node(rbt, parent, NULL, false)); + } else { + /* + * Both our parent and brother are black. + * Change our brother to red, advance up rank + * and go through the loop again. + * + * B -> *B + * *A D -> A d + * C E -> C E + */ + RB_MARK_RED(brother); + KASSERT(RB_BLACK_P(brother->rb_left)); + KASSERT(RB_BLACK_P(brother->rb_right)); + if (RB_ROOT_P(rbt, parent)) + return; /* root == parent == black */ + KASSERT(rb_tree_check_node(rbt, brother, NULL, false)); + KASSERT(rb_tree_check_node(rbt, parent, NULL, false)); + which = RB_POSITION(parent); + parent = RB_FATHER(parent); + continue; + } + } + /* + * Avoid an else here so that case 2a above can hit either + * case 2b, 3, or 4. + */ + if (RB_RED_P(parent) + && RB_BLACK_P(brother) + && RB_BLACK_P(brother->rb_left) + && RB_BLACK_P(brother->rb_right)) { + KASSERT(RB_RED_P(parent)); + KASSERT(RB_BLACK_P(brother)); + KASSERT(RB_BLACK_P(brother->rb_left)); + KASSERT(RB_BLACK_P(brother->rb_right)); + /* + * We are black, our father is red, our brother and + * both nephews are black. Simply invert/exchange the + * colors of our father and brother (to black and red + * respectively). + * + * | f --> F | + * | * B --> * b | + * | N N --> N N | + */ + RB_MARK_BLACK(parent); + RB_MARK_RED(brother); + KASSERT(rb_tree_check_node(rbt, brother, NULL, true)); + break; /* We're done! */ + } else { + /* + * Our brother must be black and have at least one + * red child (it may have two). + */ + KASSERT(RB_BLACK_P(brother)); + KASSERT(RB_RED_P(brother->rb_nodes[which]) || + RB_RED_P(brother->rb_nodes[other])); + if (RB_BLACK_P(brother->rb_nodes[other])) { + /* + * Case 3: our brother is black, our near + * nephew is red, and our far nephew is black. + * Swap our brother with our near nephew. + * This result in a tree that matches case 4. + * (Our father could be red or black). + * + * | F --> F | + * | x B --> x B | + * | n --> n | + */ + KASSERT(RB_RED_P(brother->rb_nodes[which])); + rb_tree_reparent_nodes(rbt, brother, which); + KASSERT(RB_FATHER(brother) == parent->rb_nodes[other]); + brother = parent->rb_nodes[other]; + KASSERT(RB_RED_P(brother->rb_nodes[other])); + } + /* + * Case 4: our brother is black and our far nephew + * is red. Swap our father and brother locations and + * change our far nephew to black. (these can be + * done in either order so we change the color first). + * The result is a valid red-black tree and is a + * terminal case. (again we don't care about the + * father's color) + * + * If the father is red, we will get a red-black-black + * tree: + * | f -> f --> b | + * | B -> B --> F N | + * | n -> N --> | + * + * If the father is black, we will get an all black + * tree: + * | F -> F --> B | + * | B -> B --> F N | + * | n -> N --> | + * + * If we had two red nephews, then after the swap, + * our former father would have a red grandson. + */ + KASSERT(RB_BLACK_P(brother)); + KASSERT(RB_RED_P(brother->rb_nodes[other])); + RB_MARK_BLACK(brother->rb_nodes[other]); + rb_tree_reparent_nodes(rbt, parent, other); + break; /* We're done! */ + } + } + KASSERT(rb_tree_check_node(rbt, parent, NULL, true)); +} + +void * +rb_tree_iterate(struct rb_tree *rbt, void *object, const unsigned int direction) +{ + const rb_tree_ops_t *rbto = rbt->rbt_ops; + const unsigned int other = direction ^ RB_DIR_OTHER; + struct rb_node *self; + + KASSERT(direction == RB_DIR_LEFT || direction == RB_DIR_RIGHT); + + if (object == NULL) { +#ifndef RBSMALL + if (RB_SENTINEL_P(rbt->rbt_root)) + return NULL; + return RB_NODETOITEM(rbto, rbt->rbt_minmax[direction == RB_DIR_LEFT ? RB_DIR_RIGHT : RB_DIR_LEFT]); +#else + self = rbt->rbt_root; + if (RB_SENTINEL_P(self)) + return NULL; + while (!RB_SENTINEL_P(self->rb_nodes[direction == RB_DIR_LEFT ? RB_DIR_RIGHT : RB_DIR_LEFT])) + self = self->rb_nodes[direction == RB_DIR_LEFT ? RB_DIR_RIGHT : RB_DIR_LEFT]; + return RB_NODETOITEM(rbto, self); +#endif /* !RBSMALL */ + } + self = RB_ITEMTONODE(rbto, object); + KASSERT(!RB_SENTINEL_P(self)); + /* + * We can't go any further in this direction. We proceed up in the + * opposite direction until our parent is in direction we want to go. + */ + if (RB_SENTINEL_P(self->rb_nodes[direction])) { + while (!RB_ROOT_P(rbt, self)) { + if (other == RB_POSITION(self)) + return RB_NODETOITEM(rbto, RB_FATHER(self)); + self = RB_FATHER(self); + } + return NULL; + } + + /* + * Advance down one in current direction and go down as far as possible + * in the opposite direction. + */ + self = self->rb_nodes[direction]; + KASSERT(!RB_SENTINEL_P(self)); + while (!RB_SENTINEL_P(self->rb_nodes[other])) + self = self->rb_nodes[other]; + return RB_NODETOITEM(rbto, self); +} + +#ifdef RBDEBUG +static const struct rb_node * +rb_tree_iterate_const(const struct rb_tree *rbt, const struct rb_node *self, + const unsigned int direction) +{ + const unsigned int other = direction ^ RB_DIR_OTHER; + KASSERT(direction == RB_DIR_LEFT || direction == RB_DIR_RIGHT); + + if (self == NULL) { +#ifndef RBSMALL + if (RB_SENTINEL_P(rbt->rbt_root)) + return NULL; + return rbt->rbt_minmax[direction]; +#else + self = rbt->rbt_root; + if (RB_SENTINEL_P(self)) + return NULL; + while (!RB_SENTINEL_P(self->rb_nodes[direction])) + self = self->rb_nodes[direction]; + return self; +#endif /* !RBSMALL */ + } + KASSERT(!RB_SENTINEL_P(self)); + /* + * We can't go any further in this direction. We proceed up in the + * opposite direction until our parent is in direction we want to go. + */ + if (RB_SENTINEL_P(self->rb_nodes[direction])) { + while (!RB_ROOT_P(rbt, self)) { + if (other == RB_POSITION(self)) + return RB_FATHER(self); + self = RB_FATHER(self); + } + return NULL; + } + + /* + * Advance down one in current direction and go down as far as possible + * in the opposite direction. + */ + self = self->rb_nodes[direction]; + KASSERT(!RB_SENTINEL_P(self)); + while (!RB_SENTINEL_P(self->rb_nodes[other])) + self = self->rb_nodes[other]; + return self; +} + +static unsigned int +rb_tree_count_black(const struct rb_node *self) +{ + unsigned int left, right; + + if (RB_SENTINEL_P(self)) + return 0; + + left = rb_tree_count_black(self->rb_left); + right = rb_tree_count_black(self->rb_right); + + KASSERT(left == right); + + return left + RB_BLACK_P(self); +} + +static bool +rb_tree_check_node(const struct rb_tree *rbt, const struct rb_node *self, + const struct rb_node *prev, bool red_check) +{ + const rb_tree_ops_t *rbto = rbt->rbt_ops; + rbto_compare_nodes_fn compare_nodes = rbto->rbto_compare_nodes; + + KASSERT(!RB_SENTINEL_P(self)); + KASSERT(prev == NULL || (*compare_nodes)(rbto->rbto_context, + RB_NODETOITEM(rbto, prev), RB_NODETOITEM(rbto, self)) < 0); + + /* + * Verify our relationship to our parent. + */ + if (RB_ROOT_P(rbt, self)) { + KASSERT(self == rbt->rbt_root); + KASSERT(RB_POSITION(self) == RB_DIR_LEFT); + KASSERT(RB_FATHER(self)->rb_nodes[RB_DIR_LEFT] == self); + KASSERT(RB_FATHER(self) == (const struct rb_node *) &rbt->rbt_root); + } else { + int diff = (*compare_nodes)(rbto->rbto_context, + RB_NODETOITEM(rbto, self), + RB_NODETOITEM(rbto, RB_FATHER(self))); + + KASSERT(self != rbt->rbt_root); + KASSERT(!RB_FATHER_SENTINEL_P(self)); + if (RB_POSITION(self) == RB_DIR_LEFT) { + KASSERT(diff < 0); + KASSERT(RB_FATHER(self)->rb_nodes[RB_DIR_LEFT] == self); + } else { + KASSERT(diff > 0); + KASSERT(RB_FATHER(self)->rb_nodes[RB_DIR_RIGHT] == self); + } + } + + /* + * Verify our position in the linked list against the tree itself. + */ + { + const struct rb_node *prev0 = rb_tree_iterate_const(rbt, self, RB_DIR_LEFT); + const struct rb_node *next0 = rb_tree_iterate_const(rbt, self, RB_DIR_RIGHT); + KASSERT(prev0 == TAILQ_PREV(self, rb_node_qh, rb_link)); + KASSERT(next0 == TAILQ_NEXT(self, rb_link)); +#ifndef RBSMALL + KASSERT(prev0 != NULL || self == rbt->rbt_minmax[RB_DIR_LEFT]); + KASSERT(next0 != NULL || self == rbt->rbt_minmax[RB_DIR_RIGHT]); +#endif + } + + /* + * The root must be black. + * There can never be two adjacent red nodes. + */ + if (red_check) { + KASSERT(!RB_ROOT_P(rbt, self) || RB_BLACK_P(self)); + (void) rb_tree_count_black(self); + if (RB_RED_P(self)) { + const struct rb_node *brother; + KASSERT(!RB_ROOT_P(rbt, self)); + brother = RB_FATHER(self)->rb_nodes[RB_POSITION(self) ^ RB_DIR_OTHER]; + KASSERT(RB_BLACK_P(RB_FATHER(self))); + /* + * I'm red and have no children, then I must either + * have no brother or my brother also be red and + * also have no children. (black count == 0) + */ + KASSERT(!RB_CHILDLESS_P(self) + || RB_SENTINEL_P(brother) + || RB_RED_P(brother) + || RB_CHILDLESS_P(brother)); + /* + * If I'm not childless, I must have two children + * and they must be both be black. + */ + KASSERT(RB_CHILDLESS_P(self) + || (RB_TWOCHILDREN_P(self) + && RB_BLACK_P(self->rb_left) + && RB_BLACK_P(self->rb_right))); + /* + * If I'm not childless, thus I have black children, + * then my brother must either be black or have two + * black children. + */ + KASSERT(RB_CHILDLESS_P(self) + || RB_BLACK_P(brother) + || (RB_TWOCHILDREN_P(brother) + && RB_BLACK_P(brother->rb_left) + && RB_BLACK_P(brother->rb_right))); + } else { + /* + * If I'm black and have one child, that child must + * be red and childless. + */ + KASSERT(RB_CHILDLESS_P(self) + || RB_TWOCHILDREN_P(self) + || (!RB_LEFT_SENTINEL_P(self) + && RB_RIGHT_SENTINEL_P(self) + && RB_RED_P(self->rb_left) + && RB_CHILDLESS_P(self->rb_left)) + || (!RB_RIGHT_SENTINEL_P(self) + && RB_LEFT_SENTINEL_P(self) + && RB_RED_P(self->rb_right) + && RB_CHILDLESS_P(self->rb_right))); + + /* + * If I'm a childless black node and my parent is + * black, my 2nd closet relative away from my parent + * is either red or has a red parent or red children. + */ + if (!RB_ROOT_P(rbt, self) + && RB_CHILDLESS_P(self) + && RB_BLACK_P(RB_FATHER(self))) { + const unsigned int which = RB_POSITION(self); + const unsigned int other = which ^ RB_DIR_OTHER; + const struct rb_node *relative0, *relative; + + relative0 = rb_tree_iterate_const(rbt, + self, other); + KASSERT(relative0 != NULL); + relative = rb_tree_iterate_const(rbt, + relative0, other); + KASSERT(relative != NULL); + KASSERT(RB_SENTINEL_P(relative->rb_nodes[which])); +#if 0 + KASSERT(RB_RED_P(relative) + || RB_RED_P(relative->rb_left) + || RB_RED_P(relative->rb_right) + || RB_RED_P(RB_FATHER(relative))); +#endif + } + } + /* + * A grandparent's children must be real nodes and not + * sentinels. First check out grandparent. + */ + KASSERT(RB_ROOT_P(rbt, self) + || RB_ROOT_P(rbt, RB_FATHER(self)) + || RB_TWOCHILDREN_P(RB_FATHER(RB_FATHER(self)))); + /* + * If we are have grandchildren on our left, then + * we must have a child on our right. + */ + KASSERT(RB_LEFT_SENTINEL_P(self) + || RB_CHILDLESS_P(self->rb_left) + || !RB_RIGHT_SENTINEL_P(self)); + /* + * If we are have grandchildren on our right, then + * we must have a child on our left. + */ + KASSERT(RB_RIGHT_SENTINEL_P(self) + || RB_CHILDLESS_P(self->rb_right) + || !RB_LEFT_SENTINEL_P(self)); + + /* + * If we have a child on the left and it doesn't have two + * children make sure we don't have great-great-grandchildren on + * the right. + */ + KASSERT(RB_TWOCHILDREN_P(self->rb_left) + || RB_CHILDLESS_P(self->rb_right) + || RB_CHILDLESS_P(self->rb_right->rb_left) + || RB_CHILDLESS_P(self->rb_right->rb_left->rb_left) + || RB_CHILDLESS_P(self->rb_right->rb_left->rb_right) + || RB_CHILDLESS_P(self->rb_right->rb_right) + || RB_CHILDLESS_P(self->rb_right->rb_right->rb_left) + || RB_CHILDLESS_P(self->rb_right->rb_right->rb_right)); + + /* + * If we have a child on the right and it doesn't have two + * children make sure we don't have great-great-grandchildren on + * the left. + */ + KASSERT(RB_TWOCHILDREN_P(self->rb_right) + || RB_CHILDLESS_P(self->rb_left) + || RB_CHILDLESS_P(self->rb_left->rb_left) + || RB_CHILDLESS_P(self->rb_left->rb_left->rb_left) + || RB_CHILDLESS_P(self->rb_left->rb_left->rb_right) + || RB_CHILDLESS_P(self->rb_left->rb_right) + || RB_CHILDLESS_P(self->rb_left->rb_right->rb_left) + || RB_CHILDLESS_P(self->rb_left->rb_right->rb_right)); + + /* + * If we are fully interior node, then our predecessors and + * successors must have no children in our direction. + */ + if (RB_TWOCHILDREN_P(self)) { + const struct rb_node *prev0; + const struct rb_node *next0; + + prev0 = rb_tree_iterate_const(rbt, self, RB_DIR_LEFT); + KASSERT(prev0 != NULL); + KASSERT(RB_RIGHT_SENTINEL_P(prev0)); + + next0 = rb_tree_iterate_const(rbt, self, RB_DIR_RIGHT); + KASSERT(next0 != NULL); + KASSERT(RB_LEFT_SENTINEL_P(next0)); + } + } + + return true; +} + +void +rb_tree_check(const struct rb_tree *rbt, bool red_check) +{ + const struct rb_node *self; + const struct rb_node *prev; +#ifdef RBSTATS + unsigned int count = 0; +#endif + + KASSERT(rbt->rbt_root != NULL); + KASSERT(RB_LEFT_P(rbt->rbt_root)); + +#if defined(RBSTATS) && !defined(RBSMALL) + KASSERT(rbt->rbt_count > 1 + || rbt->rbt_minmax[RB_DIR_LEFT] == rbt->rbt_minmax[RB_DIR_RIGHT]); +#endif + + prev = NULL; + TAILQ_FOREACH(self, &rbt->rbt_nodes, rb_link) { + rb_tree_check_node(rbt, self, prev, false); +#ifdef RBSTATS + count++; +#endif + } +#ifdef RBSTATS + KASSERT(rbt->rbt_count == count); +#endif + if (red_check) { + KASSERT(RB_BLACK_P(rbt->rbt_root)); + KASSERT(RB_SENTINEL_P(rbt->rbt_root) + || rb_tree_count_black(rbt->rbt_root)); + + /* + * The root must be black. + * There can never be two adjacent red nodes. + */ + TAILQ_FOREACH(self, &rbt->rbt_nodes, rb_link) { + rb_tree_check_node(rbt, self, NULL, true); + } + } +} +#endif /* RBDEBUG */ + +#ifdef RBSTATS +static void +rb_tree_mark_depth(const struct rb_tree *rbt, const struct rb_node *self, + size_t *depths, size_t depth) +{ + if (RB_SENTINEL_P(self)) + return; + + if (RB_TWOCHILDREN_P(self)) { + rb_tree_mark_depth(rbt, self->rb_left, depths, depth + 1); + rb_tree_mark_depth(rbt, self->rb_right, depths, depth + 1); + return; + } + depths[depth]++; + if (!RB_LEFT_SENTINEL_P(self)) { + rb_tree_mark_depth(rbt, self->rb_left, depths, depth + 1); + } + if (!RB_RIGHT_SENTINEL_P(self)) { + rb_tree_mark_depth(rbt, self->rb_right, depths, depth + 1); + } +} + +void +rb_tree_depths(const struct rb_tree *rbt, size_t *depths) +{ + rb_tree_mark_depth(rbt, rbt->rbt_root, depths, 1); +} +#endif /* RBSTATS */ + +size_t rb_tree_count(rb_tree_t *rbt) { + if (__predict_false(rbt == NULL)) + return 0; + + return rbt->rbt_count; +} diff --git a/src/libc/gen/NetBSD/rbtree.3 b/src/libc/gen/NetBSD/rbtree.3 new file mode 100644 index 000000000..cc7deedcf --- /dev/null +++ b/src/libc/gen/NetBSD/rbtree.3 @@ -0,0 +1,261 @@ +.\" $NetBSD: rbtree.3,v 1.7 2012/08/19 19:31:13 wiz Exp $ +.\" +.\" Copyright (c) 2010 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" Portions Copyright (c) 2012 Apple Inc. All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Matt Thomas, Niels Provos, and David Young. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd August 19, 2012 +.Dt RBTREE 3 +.Os +.Sh NAME +.Nm rbtree +.Nd red-black tree +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/rbtree.h +.Ft void +.Fn rb_tree_init "rb_tree_t *rbt" "const rb_tree_ops_t *ops" +.Ft void * +.Fn rb_tree_insert_node "rb_tree_t *rbt" "void *rb" +.Ft void +.Fn rb_tree_remove_node "rb_tree_t *rbt" "void *rb" +.Ft void * +.Fn rb_tree_find_node "rb_tree_t *rbt" "const void *key" +.Ft void * +.Fn rb_tree_find_node_geq "rb_tree_t *rbt" "const void *key" +.Ft void * +.Fn rb_tree_find_node_leq "rb_tree_t *rbt" "const void *key" +.Ft void * +.Fn rb_tree_iterate "rb_tree_t *rbt" "void *rb" "const unsigned int direction" +.Ft size_t +.Fn rb_tree_count "rb_tree_t *rbt" +.Sh DESCRIPTION +.Nm +provides red-black trees. +A red-black tree is a binary search tree with the node color as an +extra attribute. +It fulfills a set of conditions: +.Bl -enum -offset indent +.It +Every search path from the root to a leaf consists of the same number of +black nodes. +.It +Each red node (except for the root) has a black parent. +.It +Each leaf node is black. +.El +.Pp +Every operation on a red-black tree is bounded as O(lg n). +The maximum height of a red-black tree is 2lg (n+1). +.Sh TYPES +.Bl -tag -width compact +.It Vt rb_tree_t +A red-black tree. +.It Vt typedef signed int \ +(* rbto_compare_nodes_fn)(void *context, const void *node1, const void *node2); +The node-comparison operator. +Defines an ordering on nodes. +Returns a negative value if the first node +.Ar node1 +precedes the second node +.Ar node2 . +Returns a positive value if the first node +.Ar node1 +follows the second node +.Ar node2 . +Returns 0 if the first node +.Ar node1 +and the second node +.Ar node2 +are identical according to the ordering. +.It Vt typedef signed int \ +(* rbto_compare_key_fn)(void *context, const void *node, const void *key); +The node-key comparison operator. +Defines the order of nodes and keys. +Returns a negative value if the node +.Ar node +precedes the key +.Ar key . +Returns a positive value if the node +.Ar node +follows the key +.Ar key . +Returns 0 if the node +.Ar node +is identical to the key +.Ar key +according to the ordering. +.It Vt rb_tree_ops_t +Defines the operator for comparing two nodes in the same tree, +the operator for comparing a node in the tree with a key, +the offset of member +.Vt rb_node_t +within a node, +and the opaque context passed to the operators. +Members of +.Vt rb_tree_ops_t +are +.Bd -literal + rbto_compare_nodes_fn rbto_compare_nodes; + rbto_compare_key_fn rbto_compare_key; + size_t rbto_node_offset; + void *rbto_context; +.Ed +.It Vt rb_node_t +A node in a red-black tree has this structure as a member. +.El +.Sh FUNCTIONS +.Bl -tag -width compact +.It Fn rb_tree_init "rbt" "ops" +Initialize the red-black tree +.Fa rbt . +Let the comparison operators given by +.Fa ops +define the order of nodes in the tree for +the purposes of insertion, search, and iteration. +.Fn rb_tree_init +always succeeds. +.It Fn rb_tree_insert_node "rbt" "rb" +Insert the node +.Fa rb +into the tree +.Fa rbt . +Return inserted node on success, +already existing node on failure. +.It Fn rb_tree_remove_node "rbt" "rb" +Remove the node +.Fa rb +from the tree +.Fa rbt . +.It Fn rb_tree_find_node "rbt" "key" +Search the tree +.Fa rbt +for a node exactly matching +.Fa key . +If no such node is in the tree, return +.Dv NULL . +Otherwise, return the matching node. +.It Fn rb_tree_find_node_geq "rbt" "key" +Search the tree +.Fa rbt +for a node that exactly matches +.Fa key +and return it. +If no such node is present, return the first node following +.Fa key +or, if no such node is in the tree, return +.Dv NULL . +.It Fn rb_tree_find_node_leq "rbt" "key" +Search the tree +.Fa rbt +for a node that exactly matches +.Fa key +and return it. +If no such node is present, return the first node preceding +.Fa key +or, if no such node is in the tree, return +.Dv NULL . +.It Fn rb_tree_iterate "rbt" "rb" "direction" +If +.Fa direction +is +.Dv RB_DIR_LEFT , +return the node in the tree +.Fa rbt +immediately preceding the node +.Fa rb +or, if +.Fa rb +is +.Dv NULL , +return the last node in +.Fa rbt +or, if the tree is empty, return +.Dv NULL . +.Pp +If +.Fa direction +is +.Dv RB_DIR_RIGHT , +return the node in the tree +.Fa rbt +immediately following the node +.Fa rb +or, if +.Fa rb +is +.Dv NULL , +return the first node in +.Fa rbt +or, if the tree is empty, return +.Dv NULL . +.It Fn rb_tree_count "rbt" +Return the number of nodes in the tree +.Fa rbt . +If +.Fa rbt +is +.Dv NULL , +0 is returned. +.El +.Sh IMPLEMENTATION DETAILS +.Nx 6.0 +included a version of this API that returned the wrong result when using +.Fn rb_tree_iterate +to find the first or last node. +This implementation does not have this bug. +If you wish to maintain portability with +.Nx 6.0 , +it is recomended that you use the +.Fn RB_TREE_MIN +and +.Fn RB_TREE_MAX +macros rather than using +.Fn rb_tree_iterate +directly. +.Sh SEE ALSO +.Xr queue 3 +.Sh HISTORY +The +.Nm +interface first appeared in +.Nx 6.0 . +.Sh AUTHORS +.An Matt Thomas Aq matt@NetBSD.org +wrote +.Nm . +.Pp +.An Niels Provos Aq provos@citi.umich.edu +wrote the +.Xr tree 3 +manual page. +Portions of this page derive from that page. +.\" .Sh CAVEATS +.\" .Sh BUGS +.\" .Sh SECURITY CONSIDERATIONS diff --git a/src/libc/gen/NetBSD/utmpx.c b/src/libc/gen/NetBSD/utmpx.c index 0eda3d465..d68553eeb 100644 --- a/src/libc/gen/NetBSD/utmpx.c +++ b/src/libc/gen/NetBSD/utmpx.c @@ -56,17 +56,26 @@ __RCSID("$NetBSD: utmpx.c,v 1.25 2008/04/28 20:22:59 martin Exp $"); #include #include -/* This is the default struct _utmpx shared by the POSIX APIs */ -__private_extern__ -struct _utmpx __utx__ = { - __UTX_MAGIC__, /* magic */ - {}, /* ut */ - PTHREAD_MUTEX_INITIALIZER, /* utmpx_mutex */ - _PATH_UTMPX, /* utfile */ - NULL, /* fp */ - 1, /* utfile_system */ - 0, /* readonly */ -}; +static struct _utmpx *__utx__ = NULL; + +static void +__default_utx_init(void) +{ + __utx__ = calloc(1, sizeof(struct _utmpx)); + const char magic[] = __UTX_MAGIC__; + memcpy(&__utx__->magic, magic, UTMPX_MAGIC); + pthread_mutex_init(&__utx__->utmpx_mutex, NULL); + __utx__->utfile = _PATH_UTMPX; + __utx__->utfile_system = 1; +} + +struct _utmpx * +__default_utx(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, &__default_utx_init); + return __utx__; +} static struct utmpx *__getutxid(struct _utmpx *, const struct utmpx *); @@ -98,9 +107,9 @@ _setutxent(struct _utmpx *U) void -setutxent() +setutxent(void) { - _setutxent(&__utx__); + _setutxent(__default_utx()); } @@ -129,9 +138,9 @@ _endutxent(struct _utmpx *U) void -endutxent() +endutxent(void) { - _endutxent(&__utx__); + _endutxent(__default_utx()); } @@ -232,9 +241,9 @@ _getutxent(struct _utmpx *U) struct utmpx * -getutxent() +getutxent(void) { - return _getutxent(&__utx__); + return _getutxent(__default_utx()); } @@ -266,7 +275,7 @@ _getutxid(struct _utmpx *U, const struct utmpx *utx) struct utmpx * getutxid(const struct utmpx *utx) { - return _getutxid(&__utx__, utx); + return _getutxid(__default_utx(), utx); } @@ -349,7 +358,7 @@ _getutxline(struct _utmpx *U, const struct utmpx *utx) struct utmpx * getutxline(const struct utmpx *utx) { - return _getutxline(&__utx__, utx); + return _getutxline(__default_utx(), utx); } @@ -365,7 +374,7 @@ _pututxline(struct _utmpx *U, const struct utmpx *utx) TEST_UTMPX_T("_pututxline", U); UTMPX_LOCK(U); - if ((ux = __pututxline(&__utx__, utx)) != NULL && __utx__.utfile_system) { + if ((ux = __pututxline(__default_utx(), utx)) != NULL && __default_utx()->utfile_system) { _utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */ #ifdef UTMP_COMPAT _write_utmp_compat(ux); @@ -379,7 +388,7 @@ _pututxline(struct _utmpx *U, const struct utmpx *utx) struct utmpx * pututxline(const struct utmpx *utx) { - return _pututxline(&__utx__, utx); + return _pututxline(__default_utx(), utx); } __private_extern__ struct utmpx * @@ -544,7 +553,7 @@ _utmpxname(struct _utmpx *U, const char *fname) int utmpxname(const char *fname) { - return _utmpxname(&__utx__, fname); + return _utmpxname(__default_utx(), fname); } #ifdef UNIFDEF_LEGACY_UTMP_APIS diff --git a/src/libc/gen/_simple.c b/src/libc/gen/_simple.c deleted file mode 100644 index a1ad96465..000000000 --- a/src/libc/gen/_simple.c +++ /dev/null @@ -1,722 +0,0 @@ -// Modified by Lubos Dolezel for Darling (dummyfied ASL stuff until implemented) -/* - * Copyright (c) 2005, 2006, 2009 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include -#include -#ifndef VARIANT_DYLD -#include -#endif /* !VARIANT_DYLD */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef DARLING -#include -#endif - -#include "_simple.h" - -#ifndef VM_PAGE_SIZE -#define VM_PAGE_SIZE 4096 -#endif - -#define SBUF_SIZE(s) (((SBUF *)(s))->b.end - ((SBUF *)(s))->b.buf + 1) -/* we use a small buffer to minimize stack usage constraints */ -#define MYBUFSIZE 32 - -typedef struct _BUF { - char *buf; - char *ptr; - char *end; - int fd; - void (*full)(struct _BUF *); -} BUF; - -typedef struct _SBUF { - BUF b; -#ifndef VARIANT_DYLD - jmp_buf j; -#endif /* !VARIANT_DYLD */ -} SBUF; - -#define ASL_SERVICE_NAME "com.apple.system.logger" - -static mach_port_t asl_port; -static pthread_once_t asl_init_once = PTHREAD_ONCE_INIT; - -/* private extern exports from asl.c */ -const char *_asl_escape(unsigned char); - -/* flush the buffer */ -static void -_flush(BUF *b) -{ - char *buf = b->buf; - int n = b->ptr - buf; - int w; - - while(n > 0) { - w = write(b->fd, buf, n); - if(w < 0) { - if(errno == EINTR || errno == EAGAIN) - continue; - break; - } - n -= w; - buf += n; - } -} - -/* flush the buffer and reset the pointer */ -static void -_flush_reset(BUF *b) -{ - _flush(b); - b->ptr = b->buf; -} - -/* enlarge the buffer */ -static void -_enlarge(BUF *b) -{ - vm_address_t new; - vm_size_t sold, snew; - intptr_t diff; - - new = (vm_address_t)(b->end + 1); - if(vm_allocate(mach_task_self(), &new, VM_PAGE_SIZE, 0) == 0) { - /* page is adjacent */ - b->end += VM_PAGE_SIZE; - return; - } - sold = SBUF_SIZE(b); - snew = (sold + VM_PAGE_SIZE) & ~(VM_PAGE_SIZE - 1); - if(vm_allocate(mach_task_self(), &new, snew, 1) != 0) -#ifndef VARIANT_DYLD - longjmp(((SBUF *)b)->j, 1); /* out of memory */ -#else /* VARIANT_DYLD */ - abort(); /* out of memory */ -#endif /* !VARIANT_DYLD */ - diff = new - (vm_address_t)b->buf; - memcpy((void *)new, b->buf, sold); - if((intptr_t)(b->buf) & (VM_PAGE_SIZE - 1)) { - sold &= ~(VM_PAGE_SIZE - 1); - b->buf = (char *)((intptr_t)(b->buf + VM_PAGE_SIZE) & ~(VM_PAGE_SIZE - 1)); - b->end = (char *)(new + snew - 1); - } else - b->end += diff + VM_PAGE_SIZE; - if(sold > 0) { - vm_deallocate(mach_task_self(), (vm_address_t)b->buf, sold); - } - b->buf = (char *)new; - b->ptr += diff; -} - -static inline void put_s(BUF *, _esc_func, const char *); -/* output a single character */ -static inline void -put_c(BUF *b, _esc_func esc, unsigned char c) -{ - const char *cp; - - if(esc && (cp = esc(c)) != NULL) - put_s(b, NULL, cp); - else { - if(b->ptr >= b->end) - b->full(b); - *b->ptr++ = c; - } -} - -/* output a null-terminated string */ -static inline void -put_s(BUF *b, _esc_func esc, const char *str) -{ - while(*str) - put_c(b, esc, *str++); -} - -/* output a string of the specified size */ -static inline void -put_n(BUF *b, _esc_func esc, const char *str, int n) -{ - while(n-- > 0) - put_c(b, esc, *str++); -} - -/* - * Output the signed decimal string representing the number in "in". "width" is - * the minimum field width, and "zero" is a boolean value, true for zero padding - * (otherwise blank padding). - */ -static void -dec(BUF *b, _esc_func esc, long long in, int width, int zero) -{ - char buf[32]; - char *cp = buf + sizeof(buf); - int pad; - int neg = 0; - unsigned long long n = (unsigned long long)in; - - if(in < 0) { - neg++; - width--; - n = ~n + 1; - } - *--cp = 0; - if(n) { - while(n) { - *--cp = (n % 10) + '0'; - n /= 10; - } - } else - *--cp = '0'; - if(neg && zero) { - put_c(b, esc, '-'); - neg = 0; - } - pad = width - strlen(cp); - zero = zero ? '0' : ' '; - while(pad-- > 0) - put_c(b, esc, zero); - if(neg) - put_c(b, esc, '-'); - put_s(b, esc, cp); -} - -/* - * Output the hex string representing the number in "n". "width" is the - * minimum field width, and "zero" is a boolean value, true for zero padding - * (otherwise blank padding). "upper" is a boolean value, true for upper - * case hex characters, lower case otherwise. "p" is a boolean value, true - * if 0x should be prepended (for %p), otherwise nothing. - */ -static char _h[] = "0123456789abcdef"; -static char _H[] = "0123456789ABCDEF"; -static char _0x[] = "0x"; - -static void -hex(BUF *b, _esc_func esc, unsigned long long n, int width, int zero, int upper, int p) -{ - char buf[32]; - char *cp = buf + sizeof(buf); - char *h = upper ? _H : _h; - - *--cp = 0; - if(n) { - while(n) { - *--cp = h[n & 0xf]; - n >>= 4; - } - } else - *--cp = '0'; - if(p) { - width -= 2; - if(zero) { - put_s(b, esc, _0x); - p = 0; - } - } - width -= strlen(cp); - zero = zero ? '0' : ' '; - while(width-- > 0) - put_c(b, esc, zero); - if(p) - put_s(b, esc, _0x); - put_s(b, esc, cp); -} - -/* - * Output the unsigned decimal string representing the number in "n". "width" - * is the minimum field width, and "zero" is a boolean value, true for zero - * padding (otherwise blank padding). - */ -static void -udec(BUF *b, _esc_func esc, unsigned long long n, int width, int zero) -{ - char buf[32]; - char *cp = buf + sizeof(buf); - int pad; - - *--cp = 0; - if(n) { - while(n) { - *--cp = (n % 10) + '0'; - n /= 10; - } - } else - *--cp = '0'; - pad = width - strlen(cp); - zero = zero ? '0' : ' '; - while(pad-- > 0) - put_c(b, esc, zero); - put_s(b, esc, cp); -} - -/* - * Output the unsigned decimal string representing the number in "n", rounded - * to the nearest MB, KB or b. "width" is the minimum field width, and "zero" - * is a boolean value, true for zero padding (otherwise blank padding). - */ -static void -ydec(BUF *b, _esc_func esc, unsigned long long n, int width, int zero) -{ - if(n >= 10 * (1 << 20)) { - n += (1 << 19); - udec(b, esc, n >> 20, width, zero); - put_s(b, esc, "MB"); - } else if (n >= 10 * (1 << 10)) { - n += (1 << 9); - udec(b, esc, n >> 10, width, zero); - put_s(b, esc, "KB"); - } else { - udec(b, esc, n, width, zero); - put_s(b, esc, "b"); - } -} - -/* - * The actual engine for all the _simple_*printf routines. - */ -static void -__simple_bprintf(BUF *b, _esc_func esc, const char *fmt, va_list ap) -{ - while(*fmt) { - int lflag, zero, width; - char *cp; - if(!(cp = strchr(fmt, '%'))) { - put_s(b, esc, fmt); - break; - } - put_n(b, esc, fmt, cp - fmt); - fmt = cp + 1; - if(*fmt == '%') { - put_c(b, esc, '%'); - fmt++; - continue; - } - lflag = zero = width = 0; - for(;;) { - switch(*fmt) { - case '0': - zero++; - fmt++; - /* drop through */ - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - while(*fmt >= '0' && *fmt <= '9') - width = 10 * width + (*fmt++ - '0'); - continue; - case 'c': - zero = zero ? '0' : ' '; - width--; - while(width-- > 0) - put_c(b, esc, zero); - put_c(b, esc, va_arg(ap, int)); - break; - case 'd': case 'i': - switch(lflag) { - case 0: - dec(b, esc, va_arg(ap, int), width, zero); - break; - case 1: - dec(b, esc, va_arg(ap, long), width, zero); - break; - default: - dec(b, esc, va_arg(ap, long long), width, zero); - break; - } - break; - case 'l': - lflag++; - fmt++; - continue; - case 'p': - hex(b, esc, (unsigned long)va_arg(ap, void *), width, zero, 0, 1); - break; - case 's': - cp = va_arg(ap, char *); - width -= strlen(cp); - zero = zero ? '0' : ' '; - while(width-- > 0) - put_c(b, esc, zero); - put_s(b, esc, cp); - break; - case 'u': - switch(lflag) { - case 0: - udec(b, esc, va_arg(ap, unsigned int), width, zero); - break; - case 1: - udec(b, esc, va_arg(ap, unsigned long), width, zero); - break; - default: - udec(b, esc, va_arg(ap, unsigned long long), width, zero); - break; - } - break; - case 'X': case 'x': - switch(lflag) { - case 0: - hex(b, esc, va_arg(ap, unsigned int), width, zero, - *fmt == 'X', 0); - break; - case 1: - hex(b, esc, va_arg(ap, unsigned long), width, zero, - *fmt == 'X', 0); - break; - default: - hex(b, esc, va_arg(ap, unsigned long long), width, zero, - *fmt == 'X', 0); - break; - } - break; - case 'y': - switch(lflag) { - case 0: - ydec(b, esc, va_arg(ap, unsigned int), width, zero); - break; - case 1: - ydec(b, esc, va_arg(ap, unsigned long), width, zero); - break; - default: - ydec(b, esc, va_arg(ap, unsigned long long), width, zero); - break; - } - break; - default: - put_c(b, esc, *fmt); - break; - } - break; - } - fmt++; - } -} - -/* - * A simplified vfprintf variant. The format string is interpreted with - * arguments from the va_list, and the results are written to the given - * file descriptor. - */ -void -_simple_vdprintf(int fd, const char *fmt, va_list ap) -{ - BUF b; - char buf[MYBUFSIZE]; - - b.buf = buf; - b.fd = fd; - b.ptr = b.buf; - b.end = b.buf + MYBUFSIZE; - b.full = _flush_reset; - __simple_bprintf(&b, NULL, fmt, ap); - _flush(&b); -} - -/* - * A simplified fprintf variant. The format string is interpreted with - * arguments from the variable argument list, and the results are written - * to the given file descriptor. - */ -void -_simple_dprintf(int fd, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - _simple_vdprintf(fd, fmt, ap); - va_end(ap); -} - -/* - * A simplified string allocate routine. Pass the opaque pointer to structure - * to _simple_*sprintf() routines. Use _simple_string() to retrieve the - * current string (the string is guaranteed to be null terminated only on - * the call to _simple_string()). Use _simple_sfree() to free the structure - * and string memory. - */ -_SIMPLE_STRING -_simple_salloc(void) -{ - SBUF *b; - - if(vm_allocate(mach_task_self(), (vm_address_t *)&b, VM_PAGE_SIZE, 1)) - return NULL; - b->b.ptr = b->b.buf = (char *)b + sizeof(SBUF); - b->b.end = (char *)b + VM_PAGE_SIZE - 1; - b->b.full = _enlarge; - return (_SIMPLE_STRING)b; -} - -/* - * The format string is interpreted with arguments from the va_list, and the - * results are appended to the string maintained by the opaque structure, as - * returned by a previous call to _simple_salloc(). Non-zero is returned on - * out-of-memory error. - */ -int -_simple_vsprintf(_SIMPLE_STRING b, const char *fmt, va_list ap) -{ - return _simple_vesprintf(b, NULL, fmt, ap); -} - -/* - * The format string is interpreted with arguments from the variable argument - * list, and the results are appended to the string maintained by the opaque - * structure, as returned by a previous call to _simple_salloc(). Non-zero is - * returned on out-of-memory error. - */ -int -_simple_sprintf(_SIMPLE_STRING b, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = _simple_vesprintf(b, NULL, fmt, ap); - va_end(ap); - return ret; -} - -/* - * Like _simple_vsprintf(), except __esc is a function to call on each - * character; the function returns NULL if the character should be passed - * as is, otherwise, the returned character string is used instead. - */ -int -_simple_vesprintf(_SIMPLE_STRING b, _esc_func esc, const char *fmt, va_list ap) -{ -#ifndef VARIANT_DYLD - if(setjmp(((SBUF *)b)->j)) - return -1; -#endif /* !VARIANT_DYLD */ - __simple_bprintf((BUF *)b, esc, fmt, ap); - return 0; -} - -/* - * Like _simple_sprintf(), except __esc is a function to call on each - * character; the function returns NULL if the character should be passed - * as is, otherwise, the returned character string is used instead. - */ -int _simple_esprintf(_SIMPLE_STRING b, _esc_func esc, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = _simple_vesprintf(b, esc, fmt, ap); - va_end(ap); - return ret; -} - -/* - * Return the null terminated string from the opaque structure, as returned - * by a previous call to _simple_salloc(). - */ -char * -_simple_string(_SIMPLE_STRING b) -{ - *((BUF *)b)->ptr = 0; - return ((BUF *)b)->buf; -} - -/* - * Reposition the pointer to the first null in the buffer. After a call to - * _simple_string, the buffer can be modified, and shrunk. - */ -void -_simple_sresize(_SIMPLE_STRING b) -{ - ((BUF *)b)->ptr = ((BUF *)b)->buf + strlen(((BUF *)b)->buf); -} - -/* - * Append the null-terminated string to the string associated with the opaque - * structure. Non-zero is returned on out-of-memory error. - */ -int -_simple_sappend(_SIMPLE_STRING b, const char *str) -{ - return _simple_esappend(b, NULL, str); -} - -/* - * Like _simple_sappend(), except __esc is a function to call on each - * character; the function returns NULL if the character should be passed - * as is, otherwise, the returned character string is used instead. - */ -int _simple_esappend(_SIMPLE_STRING b, _esc_func esc, const char *str) -{ -#ifndef VARIANT_DYLD - if(setjmp(((SBUF *)b)->j)) - return -1; -#endif /* !VARIANT_DYLD */ - put_s((BUF *)b, esc, str); - return 0; -} - -/* - * Write the string associated with the opaque structure to the file descriptor. - */ -void -_simple_put(_SIMPLE_STRING b, int fd) -{ - ((BUF *)b)->fd = fd; - _flush((BUF *)b); -} - -/* - * Write the string associated with the opaque structure and a trailing newline, - * to the file descriptor. - */ -void -_simple_putline(_SIMPLE_STRING b, int fd) -{ - ((BUF *)b)->fd = fd; - *((BUF *)b)->ptr++ = '\n'; - _flush((BUF *)b); - ((BUF *)b)->ptr--; -} - -/* - * Free the opaque structure, and the associated string. - */ -void -_simple_sfree(_SIMPLE_STRING b) -{ - vm_size_t s; - - if(b == NULL) return; - if(((intptr_t)(((SBUF *)b)->b.buf) & (VM_PAGE_SIZE - 1)) == 0) { - vm_deallocate(mach_task_self(), (vm_address_t)((SBUF *)b)->b.buf, SBUF_SIZE(b)); - s = VM_PAGE_SIZE; - } else - s = ((SBUF *)b)->b.end - (char *)b + 1; - vm_deallocate(mach_task_self(), (vm_address_t)b, s); -} - -/* - * Simplified ASL log interface; does not use malloc. Unfortunately, this - * requires knowledge of the format used by ASL. - */ - -static void -_simple_asl_init(void) -{ -#ifndef DARLING - kern_return_t status; - char *str; - - if (asl_port == MACH_PORT_NULL) - { - str = getenv("ASL_DISABLE"); - if ((str != NULL) && (!strcmp(str, "1"))) return; - - status = bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &asl_port); - if (status != KERN_SUCCESS) asl_port = MACH_PORT_NULL; - } -#endif -} - -void -_simple_asl_log_prog(int level, const char *facility, const char *message, const char *prog) -{ -#ifndef DARLING - - _SIMPLE_STRING b; - - if (pthread_once(&asl_init_once, _simple_asl_init) != 0) return; - if (asl_port == MACH_PORT_NULL) return; - - if ((b = _simple_salloc()) == NULL) return; - - do - { - kern_return_t kstatus; - vm_address_t out; - int outlen; - char *cp; - struct timeval tv; - - gettimeofday(&tv, NULL); - - if (_simple_sprintf(b, " 0 [Time ", 0)) break; - if (_simple_esprintf(b, _asl_escape, "%lu", tv.tv_sec)) break; - if (_simple_sappend(b, "] [Sender ")) break; - if (_simple_esappend(b, _asl_escape, prog)) break; - if (_simple_sappend(b, "] [Level ")) break; - if (_simple_esprintf(b, _asl_escape, "%d", level)) break; - if (_simple_sappend(b, "] [Facility ")) break; - if (_simple_esappend(b, _asl_escape, facility)) break; - if (_simple_sappend(b, "] [Message ")) break; - if (_simple_esappend(b, _asl_escape, message)) break; - - /* remove trailing (escaped) newlines */ - cp = _simple_string(b); - cp += strlen(cp); - for (;;) - { - cp -= 2; - if (strcmp(cp, "\\n") != 0) break; - *cp = 0; - } - - _simple_sresize(b); - - if (_simple_sappend(b, "]\n")) break; - - cp = _simple_string(b); - - /* - * The MIG defs for _asl_server_message specifies "dealloc", - * so we copy the string into a new vm buffer and send that. - */ - outlen = strlen(cp); - kstatus = vm_allocate(mach_task_self(), &out, outlen, TRUE); - if (kstatus != KERN_SUCCESS) break; - - memcpy((void *)out, cp, outlen); - _asl_server_message(asl_port, (caddr_t)out, outlen); - } while (0); - - _simple_sfree(b); -#endif -} - -void -_simple_asl_log(int level, const char *facility, const char *message) -{ - _simple_asl_log_prog(level, facility, message, getprogname()); -} diff --git a/src/libc/gen/asl.3 b/src/libc/gen/asl.3 deleted file mode 100644 index 2f7f87668..000000000 --- a/src/libc/gen/asl.3 +++ /dev/null @@ -1,1111 +0,0 @@ -.\" Copyright (c) 2005-2011 Apple Inc. -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of Apple Computer nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" -.Dd October 1, 2011 -.Dt asl 3 -.Os "Mac OS X" -.Sh NAME -.Nm asl_add_log_file , -.Nm asl_close , -.Nm asl_close_auxiliary_file , -.Nm asl_create_auxiliary_file , -.Nm asl_free , -.Nm asl_get , -.Nm asl_key , -.Nm asl_log , -.Nm asl_log_auxiliary_location , -.Nm asl_log_descriptor , -.Nm asl_new , -.Nm asl_open , -.Nm asl_open_from_file , -.Nm asl_remove_log_file , -.Nm asl_search , -.Nm asl_send , -.Nm asl_set , -.Nm asl_set_filter , -.Nm asl_set_query , -.Nm asl_unset , -.Nm asl_vlog , -.Nm aslresponse_free , -.Nm aslresponse_next -.Nd system log message sending and searching functions -.Sh SYNOPSIS -.Fd #include -.\" -.Ft int -.Fo asl_add_log_file -.Fa "aslclient asl" -.Fa "int descriptor" -.Fc -.Ft void -.Fo asl_close -.Fa "aslclient asl" -.Fc -.Ft void -.Fo asl_close_auxiliary_file -.Fa "int descriptor" -.Fc -.Ft void -.Fo asl_create_auxiliary_file -.Fa "aslmsg msg" -.Fa "const char *title" -.Fa "const char *uti" -.Fa "int *out_descriptor" -.Fc -.Ft void -.Fo asl_free -.Fa "aslmsg msg" -.Fc -.Ft const char * -.Fo asl_get -.Fa "aslmsg msg" -.Fa "const char *key" -.Fc -.Ft const char * -.Fo asl_key -.Fa "aslmsg msg" -.Fa "uint32_t n" -.Fc -.Ft int -.Fo asl_log -.Fa "aslclient asl" -.Fa "aslmsg msg" -.Fa "int level" -.Fa "const char *format" -.Fa "..." -.Fc -.Ft void -.Fo asl_log_auxiliary_location -.Fa "aslmsg msg" -.Fa "const char *title" -.Fa "const char *uti" -.Fa "const char *url" -.Fc -.Ft int -.Fo asl_log_descriptor -.Fa "aslclient asl" -.Fa "aslmsg msg" -.Fa "int level" -.Fa "int descriptor" -.Fa "uint32_t fd_type" -.Fc -.Ft aslmsg -.Fo asl_new -.Fa "uint32_t type" -.Fc -.Ft aslclient -.Fo asl_open -.Fa "const char *ident" -.Fa "const char *facility" -.Fa "uint32_t opts" -.Fc -.Ft aslclient -.Fo asl_open_from_file -.Fa "int descriptor" -.Fa "const char *ident" -.Fa "const char *facility" -.Fc -.Ft int -.Fo asl_remove_log_file -.Fa "aslclient asl" -.Fa "int descriptor" -.Fc -.Ft aslresponse -.Fo asl_search -.Fa "aslclient asl" -.Fa "aslmsg msg" -.Fc -.Ft int -.Fo asl_send -.Fa "aslclient asl" -.Fa "aslmsg msg" -.Fc -.Ft int -.Fo asl_set -.Fa "aslmsg msg" -.Fa "const char *key" -.Fa "const char *value" -.Fc -.Ft int -.Fo asl_set_filter -.Fa "aslclient asl" -.Fa "int f" -.Fc -.Ft int -.Fo asl_set_query -.Fa "aslmsg msg" -.Fa "const char *key" -.Fa "const char *value" -.Fa "uint32_t op" -.Fc -.Ft int -.Fo asl_unset -.Fa "aslmsg msg" -.Fa "const char *key" -.Fc -.Ft int -.Fo asl_vlog -.Fa "aslclient asl" -.Fa "aslmsg msg" -.Fa "int level" -.Fa "const char *format" -.Fa "va_list ap" -.Fc -.Ft void -.Fo aslresponse_free -.Fa "aslresponse r" -.Fc -.Ft aslmsg -.Fo aslresponse_next -.Fa "aslresponse r" -.Fc -.Sh DESCRIPTION -These routines provide an interface to the Apple System Log facility. -They are intended to be a replacement for the -.Xr syslog 3 -API, which will continue to be supported for backwards compatibility. -The new API allows client applications -to create flexible, structured messages and send them to the -.Nm syslogd -server, where they may undergo additional processing. -Messages received by the server are saved in a data store -(subject to input filtering constraints). -This API permits clients to create queries -and search the message data store for matching messages. -.Pp -An introduction to the concepts underlying this interface follows the interface summary below. -.Ss INTERFACE SUMMARY -.Fo asl_open -.Fa ident -.Fa facility -.Fa opts -.Fc -creates and returns a client handle, or NULL if an error occurs in the library. -Messages sent using this handle will default to having the string -.Ar ident -as the value associated with the ASL_KEY_SENDER key, and the value -.Ar facility -associated with the ASL_KEY_FACILITY key. -Several options are available, as described in the -.Sx CLIENT HANDLES -section. -.Pp -Multi-threaded applications should create one client handle for each thread that logs messages. -A client may use NULL as a client handle, in which case a default handle managed by the library will be used. -A NULL handle may be used safely by multiple threads, but the threads will contend for a single internal lock when -sending log messages using a NULL handle. -.Pp -.Fo asl_close -.Fa asl -.Fc -closes the client handle -.Ar asl -and releases its associated resources. -.Pp -.Fo asl_add_log_file -.Fa asl -.Fa descriptor -.Fc -adds the file descriptor -.Ar descriptor -to the a set of file descriptors associated with the client handle -.Ar asl . -Each log message sent by that client handle is also written to these file descriptors. -Returns 0 on success, non-zero on failure. -.Pp -.Fo asl_remove_log_file -.Fa asl -.Fa descriptor -.Fc -removes a file descriptor from the set of file descriptors associated with a client handle. -Returns 0 on success, non-zero on failure. -.Pp -.Fo asl_new -.Fa type -.Fc -allocates and returns an aslmsg structure, or NULL in the case of a failure in the library. -The -.Ar type -argument must be ASL_TYPE_MSG or ASL_TYPE_QUERY. -.Pp -.Fo asl_free -.Fa msg -.Fc -frees an aslmsg and releases resources associated with the structure. -.Pp -.Fo asl_set -.Fa msg -.Fa key -.Fa value -.Fc -creates a new key and value in an aslmsg structure, or replaces the value of an existing key. -Returns 0 on success, non-zero on failure. -.Pp -.Fo asl_set_query -.Fa msg -.Fa key -.Fa op -.Fa value -.Fc -is used to construct searches. -It is similar to -.Fn asl_set , -except that it takes an additional -.Ar op -(operation) argument. -Creates a new (key, op, value) triple in an aslmsg structure, -or replaces the value and operation for an existing key. -See the -.Sx SEARCHING -section for more information. -Returns 0 on success, non-zero on failure. -.Pp -.Fo asl_unset -.Fa msg -.Fa key -.Fc -removes a key and its associated value from an aslmsg structure. -Returns 0 on success, non-zero on failure. -.Pp -.Fo asl_key -.Fa msg -.Fa n -.Fc -returns the nth key in an aslmsg (beginning at zero), -allowing an application to iterate through the keys. -Returns NULL if -.Ar n -indexes beyond the number of keys in -.Ar msg . -.Pp -.Fo asl_get -.Fa msg -.Fa key -.Fc -returns the value associated with -.Ar key -in the aslmsg -.Ar msg . -Returns NULL if -.Ar msg -does not contain -. Ar key . -.Pp -.Fo asl_set_filter -.Fa asl -.Fa f -.Fc -sets a filter for messages being sent to the server. -The filter is a bitmask representing priority levels. -Only messages having a priority level with a corresponding bit set in the filter mask are sent to the -.Nm syslogd -server. -The filter does not control writes to additional files associated with the client handle using -.Fn asl_add_log_file . -Returns the previous filter value. -.Pp -.Fo asl_log -.Fa asl -.Fa msg -.Fa level -.Fa format -.Fa args... -.Fc -sends a log to the server (subject to filtering, see -.Fn asl_set_filter -above) and to any file descriptors associated with the client handle -.Ar asl . -The -.Ar msg -argument may contain any keys and values, which will be formatted as part of the log message. -The value for ASL_KEY_LEVEL is supplied by the -.Ar level -argument. -The value for ASL_KEY_MESSAGE is computed from -.Ar format -and the associated arguments -.Ar args... . -Normal -.Fn printf -style argument processing is applied to the format and the arguments. -The format may also contain -.Dq %m -which will be substituted with the string value corresponding to the current -.Em errno . -.Pp -The ASL_PREFILTER_LOG(asl, msg, level, format, ...) macro may be used in -place of -.Fn asl_log . -The macro avoids processing the variable argument list in those cases where -the message would be filtered out due to filter settings, would not be -written to a log file associated with the aslclient, or would not be -written to stderr. -The macro may provide a performance benefit for some applications. -Details on filter setting, additional log files, and aslclient options -are described below in this manual. -.Pp -.Fo asl_vlog -.Fa asl -.Fa msg -.Fa level -.Fa format -.Fa ap -.Fc -is similar to -.Fn asl_log -except that it takes a va_list argument. -.Pp -.Fo asl_send -.Fa asl -.Fa msg -.Fc -is similar to -.Fn asl_log , -exceopt the value for ASL_KEY_MESSAGE is taken from -.Ar msg -rather than being constructed using a -.Fn printf -style syntax. -.Pp -.Fo asl_log_descriptor -.Fa asl -.Fa msg -.Fa level -.Fa descriptor -.Fa fd_type -.Fc -provides functionality to use file descriptors to send logging data to ASL. -.Ar asl -is retained by ASL and must still be closed by the caller by calling -.Fn asl_close -if the caller loses reference to it. -.Ar msg -is copied by ASL and similarly must still be freed by the caller by calling -.Fn asl_free -if the caller loses reference to it. Any changes made to it after calling -.Fn asl_log_descriptor() -are not applicable to the message used. -.Ar descriptor is treated differentlty based on the value of -.Ar fd_type . -.Pp -If -.Ar fd_type -is ASL_LOG_DESCRIPTOR_READ, the descriptor must be open for read access. ASL -uses -.Xr dispatch 2 -to read from the descriptor as data becomes available. These data are line -buffered and passed to -.Fn asl_log . -When EOF is read, ASL will -.Xr close 2 -.Ar descriptor .. -.Pp -If -.Ar fd_type -is ASL_LOG_DESCRIPTOR_WRITE, the descriptor is closed and a new writable -descriptor is created with the same fileno. Any data written to this new -descriptor are line buffered and passed to -.Fn asl_log . -When EOF is sent, no further data are read. The caller is responsible for -closing the new descriptor. One common use for this API is to redirect writes -to stdout or stderr to ASL by passing STDOUT_FILENO or STDERR_FILENO as -.Ar descriptor . -.Pp -.Fo asl_search -.Fa asl -.Fa msg -.Fc -searches for messages that match the keys and values in -.Ar msg , -subject to matching operations associated with those keys and values. -The -.Ar msg -argument should be constructed using -.Fn asl_set_query . -See the -.Sx SEARCHING -section for details on constructing queries. -Returns an aslresponse structure that contains matching log messages. -NULL is returned in case of error or if there are no matching messages in the ASL database. -.Pp -.Fo aslresponse_next -.Fa r -.Fc -iterates over an aslresponse structure returned by -.Fn asl_search . -Each call returns the next aslmsg in the response. -Returns NULL when there are no further messages. -.Pp -.Fo aslresponse_free -.Fa r -.Fc -frees the aslresponse structure -.Ar r -and all of its associated resources. -.Pp -.Fo asl_create_auxiliary_file -.Fa msg -.Fa title -.Fa uti -.Fa out_descriptor -.Fc -Creates an auxiliary file that may be used by the client to save arbitrary data. -When the file is closed using -.Fo asl_close_auxiliary_file -.Fc , -.Nm syslogd -will log the specified -.Fa msg -along with the -.Fa title -and the Uniform Type Identifier provided by -.Fa uti . -If a NULL value is supplied for -.Fa uti -the type -.Dq public.data -will be used. -The -.Nm Console -application will display the message with a link to the file. -.Pp -Auxiliary files are saved in the ASL data store. -They are automatically deleted at the same time that the log message expires. -Messages expire in 7 days by default. -A value set for the ASLExpireTime key will override the default. -Read access for the auxiliary file will be the same as read access for -.Fa msg . -By default, messages (and auxiliary files) are world-readable. -Access may be limited by setting values for the ReadUID and ReadGID keys. -.Pp -.Fo asl_close_auxiliary_file -.Fa descriptor -.Fc -closes the file descriptor -.Ar descriptor -previously returned by a call to -.Fn asl_create_auxiliary_file . -.Pp -.Fo asl_log_auxiliary_location -.Fa msg -.Fa title -.Fa uti -.Fa url -.Fc -will log the specified -.Fa msg -along with the -.Fa title , -the Uniform Type Identifier provided by -.Fa uti , -and the Uniform Resource Locator provided by -.Fa url . -The -.Nm Console -application will display the message with a link to the file. -This allows a client to save data in an auxiliary file, but unlike -.Fo asl_create_auxiliary_file -.Fc , -the life-cycle of this file must be managed by some external system. -The file will not be removed when the corresponding log message expired from the ASL data store. -.Pp -.Fo asl_open_from_file -.Fa descriptor -.Fa facility -.Fa opts -.Fc -creates a client handle for an open file descriptor -.Fa descriptor . -This routine may be used in conjunction with -.Fo asl_create_auxiliary_file -.Fc -or -.Fo asl_log_auxiliary_location -.Fc -to save ASL format log messages in an auxiliary file. -The UTI type -.Dq com.apple.asl-file -should be used for ASL format auxiliary files. -.Pp -Files with this format may be read from the command line using -.Nm syslog Fl f Ar file , -or from the -.Nm Console -utility. -.Pp -The file must be open for read and write access. -The file will be truncated and its existing contents will be lost. -.Fo asl_close -.Fc -must be called to close the client handle when logging to this file is complete. -The file should be closed using -.Fo asl_close_auxiliary_file -.Fc -if it was returned by -.Fo asl_create_auxiliary_file -.Fc , -or -.Fo close -.Fc -otherwise. -.Pp -The client handle may be used safely by multiple threads. -The threads will contend for a single internal lock when saving log messages to a file. -.Pp -Note that messages with ReadUID or ReadGID values will simply be saved to the file, -and will not effect read access to either the message or the file itself. -Similarly, messages with ASLExpireTime values will be saved, but will not effect the -life-cycle of either the individual messages or the file. -.Ss MESSAGES -At the core of this API is the aslmsg structure. -Although the structure is opaque and may not be directly manipulated, -it contains a list of key/value pairs. -All keys and values are NUL-character terminated C language strings. -UTF-8 encoding may be used for non-ASCII characters. -.Pp -Message structures are generally used to send log messages, -and are created thusly: -.Pp - aslmsg m = asl_new(ASL_TYPE_MSG); -.Pp -Another message type, ASL_TYPE_QUERY, -is used to create queries when searching the data store. -Query type messages and searching are described in detail in the -.Sx SEARCHING -section. -For the remainder of this section, -the messages described will be of the ASL_TYPE_MSG variety. -.Pp -Each aslmsg contains a default set of keys -and values that are associated with them. -These keys are listed in the asl.h header file. -They are: -.Pp - #define ASL_KEY_TIME "Time" - #define ASL_KEY_HOST "Host" - #define ASL_KEY_SENDER "Sender" - #define ASL_KEY_FACILITY "Facility" - #define ASL_KEY_PID "PID" - #define ASL_KEY_UID "UID" - #define ASL_KEY_GID "GID" - #define ASL_KEY_LEVEL "Level" - #define ASL_KEY_MSG "Message" -.Pp -Many of these correspond to equivalent parts of messages described in the -.Xr syslog 3 -API. -Values associated with these message keys are assigned appropriate defaults. -The value for ASL_KEY_HOST is the local host name, -the value associated with ASL_KEY_SENDER is the process name, -the ASL_KEY_PID is the client's process ID number, and so on. -.Pp -Note the addition of the UID and GID keys. -The values for UID and GID are set in library code by the message sender. -The server will attempt to confirm the values, -but no claim is made that these values cannot be maliciously overridden -in an attempt to deceive a log message reader -as to the identity of the sender of a message. -The contents of log messages must be regarded as insecure. -.Pp -The -.Xr asl 3 -API does not require a process to choose a facility name. -The -.Nm syslogd -server will use a default value of -.Dq user -if a facility is not set. -However, a client may set a facility name as an argument in the -.Nm asl_open -call, or by setting a specific value for the ASL_KEY_FACILITY in a message: -.Pp - asl_set(m, ASL_KEY_FACILITY, "com.somename.greatservice"); -.Pp -An application may choose any facility name at will. -Different facility names may be attached to different messages, perhaps to distinguish different subsystems in log messages. -Developers are encouraged to adopt a -.Dq Reverse ICANN -naming convention to avoid conflicting facility names. -.Pp -Default values are set in the message for each of the keys listed above, -except for ASL_KEY_MSG, -which may be explicitly set at any time using the -.Nm asl_set -routine, or implicitly set at the time the message is sent using the -.Nm asl_log -or -.Nm asl_vlog -routines. -These two routines also have an integer-level parameter -for specifying the log priority. -The ASL_KEY_LEVEL value is set accordingly. -Finally, the value associated with ASL_KEY_TIME -is set in the sending routine. -.Pp -Although it may appear that there is significant overhead required -to send a log message using this API, -the opposite is actually true. -A simple -.Dq Hello World -program requires only: -.Pp - #include - ... - asl_log(NULL, NULL, ASL_LEVEL_INFO, "Hello World!"); -.Pp -Both -.Nm asl_log -and -.Nm asl_vlog -will provide the appropriate default values -when passed a NULL aslmsg argument. -.Pp -.Pp -In this example, the aslclient argument is NULL. -This is sufficient for a single-threaded application, -or for an application which only sends log messages from a single thread. -When logging from multiple threads, -each thread -.Em should -open a separate client handle using -.Nm asl_open . -The client handle may then be closed when it is no longer required using -.Nm asl_close . -Multiple threads may log messages safely using a NULL aslclient argument, -but the library will use an internal lock, so that in fact only one thread -will log at a time. -.Pp -When an application requires additional keys and values -to be associated with each log message, -a single message structure may be allocated and set up as -.Dq template -message of sorts: -.Pp - aslmsg m = asl_new(ASL_TYPE_MSG); - asl_set(m, ASL_KEY_FACILITY, "com.secrets.r.us"); - asl_set(m, "Clearance", "Top Secret"); - ... - asl_log(NULL, m, ASL_LEVEL_NOTICE, "Message One"); - ... - asl_log(NULL, m, ASL_LEVEL_ERR, "Message Two"); -.Pp -The message structure will carry the values set for the -.Dq Facility -and -.Dq Clearance -keys so that they are used in each call to -.Nm asl_log , -while the log level and the message text -are taken from the calling parameters. -.Pp -The -.Ar format -argument to -.Nm asl_log -and -.Nm asl_vlog -is identical to -.Xr printf 3 , -and may include -.Ql %m , -which is replaced by the current error message -(as denoted by the global variable -.Va errno ; -see -.Xr strerror 3 . ) -.Pp -Key/value pairs may be removed from a message structure with -.Nm asl_unset . -A message may be freed using -.Nm asl_free . -.Pp -The -.Nm asl_send -routine is used by -.Nm asl_log -and -.Nm asl_vlog -to transmit a message to the server. -This routine sets the value associated with ASL_KEY_TIME -and sends the message. -It may be called directly if all of a message's key/value pairs -have been created using -.Nm asl_set . -.Ss SECURITY -Messages that are sent to the -.Nm syslogd -server may be saved in a message store. -The store may be searched using -.Nm asl_search , -as described below. -By default, all messages are readable by any user. -However, some applications may wish to restrict read access -for some messages. -To accomodate this, -a client may set a value for the "ReadUID" and "ReadGID" keys. -These keys may be associated with a value -containing an ASCII representation of a numeric UID or GID. -Only the root user (UID 0), -the user with the given UID, -or a member of the group with the given GID -may fetch access-controlled messages from the database. -.Pp -Although the ASL system does not require a "Facility" key in a message, -many processes specify a "Facility" value similar -to the common usage of the BSD -.Nm syslog -API, although developers are encouraged to adopt facility names that make sense for their application. -A -.Dq Reverse ICANN -naming convention (e.g. "com.apple.system.syslog") should be adopted to avoid conflicting names. -The ASL system generally allows any string to be used as a facility value, -with one exception. -The value "com.apple.system", -or any string that has "com.apple.system" as a prefix, -may only be used by processes running with the UID 0. -This allows system processes to log messages that can not be "spoofed" by user processes. -Non-UID 0 client processes that specify "com.apple.system" as a facility, will be assigned the value "user" -by the -.Nm syslogd -server. -.Ss CLIENT HANDLES -When logging is done from a single thread, -a NULL value may be used in any of the routines -that require an aslclient argument. -In this case, the library will open an internal client handle -on behalf of the application. -.Pp -If multiple threads must do logging, -or if client options are desired, -then the application should call -.Nm asl_open -to create a client handle for each thread. -As a convenience, -the -.Nm asl_open -routine may be given an ident argument, -which becomes the default value for the ASL_KEY_SENDER key, -and a facility argument, -which becomes the value associated with the ASL_KEY_FACILITY key. -.Pp -Several options are available when creating a client handle. -They are: -.Pp -.Bl -tag -width "ASL_OPT_NO_REMOTE" -compact -.It ASL_OPT_STDERR -adds stderr as an output file descriptor -.It ASL_OPT_NO_DELAY -connects to the server immediately -.It ASL_OPT_NO_REMOTE -disables remote-control filter adjustment -.El -.Pp -ASL_OPT_NO_DELAY makes the client library connect to the -.Nm syslogd -server at the time that -.Nm asl_open -is called, rather than waiting for the first message to be sent. -Opening the connection is quite fast, but some applications may want to avoid any unnecessary delays when calling -.Nm asl_log , -.Nm asl_vlog , -or -.Nm asl_send . -.Pp -See the FILTERING section below, and the -.Xr syslog 1 -for additional details on filter controls. -.Pp -A client handle is closed and it's resources released using -.Nm asl_close . -Note that if additional file descriptors were added to the handle, -either using the ASL_OPT_STDERR option -or afterwards with the -.Nm asl_add_log_file -routine, those file descriptors are not closed by -.Nm asl_close . -.Ss LOGGING TO ADDITIONAL FILES -If a client handle is opened with the ASL_OPT_STDERR option to -.Nm asl_open , -a copy of each log message will be sent to stderr. -Additional output streams may be include using -.Nm asl_add_log_file . -.Pp -Messages sent to stderr or other files are printed in the "standard" message format -also used as a default format by the -.Xr syslog 1 -command line utility. -Non-ASCII characters in a message are encoded using the -.Dq safe -encoding style used by -.Xr syslog 1 -with the -.Fl E Ar safe -option. -Backspace characters are printed as ^H. -Carriage returns are mapped to newlines. -A tab character is appended after newlines so that message text is indented. -.Pp -File descriptors may be removed from the list of outputs associated -with a client handle with -.Nm asl_remove_log_file . -This routine simply removes the file descriptor from the output list. -The file is not closed as a result. -.Pp -The ASL_OPT_STDERR option may not be unset -after a client handle has been opened. -.Ss SEARCHING -The -.Nm syslogd -server archives received messages in a data store -that may be searched using the -.Nm asl_search , -.Nm aslresponse_next , -and -.Nm aslresponse_free -routines. -A query message is created using: -.Pp - aslmsg q = asl_new(ASL_TYPE_QUERY); -.Pp -Search settings are made in the query using -.Nm asl_set_query . -A search is performed on the data store with -.Nm asl_search . -It returns an -.Ft aslresponse -structure. -The caller may then call -.Nm aslresponse_next -to iterate through matching messages. -The -.Ft aslresponse -structure may be freed with -.Nm aslresponse_free . -.Pp -Like other messages, ASL_TYPE_QUERY messages contain keys and values. -They also associate an operation with each key and value. -The operation is used to decide if a message matches the query. -The simplest operation is ASL_QUERY_OP_EQUAL, which tests for equality. -For example, the following code snippet searches for messages -with a Sender value equal to -.Dq MyApp . -.Pp - aslmsg m; - aslresponse r; - q = asl_new(ASL_TYPE_QUERY); - asl_set_query(q, ASL_KEY_SENDER, "MyApp", ASL_QUERY_OP_EQUAL); - r = asl_search(NULL, q); -.Pp -More complex searches may be performed using other query operations. -.Pp -.Bl -tag -width "ASL_QUERY_OP_GREATER_EQUAL" -compact -.It ASL_QUERY_OP_EQUAL -value equality -.It ASL_QUERY_OP_GREATER -value greater than -.It ASL_QUERY_OP_GREATER_EQUAL -value greater than or equal to -.It ASL_QUERY_OP_LESS -value less than -.It ASL_QUERY_OP_LESS_EQUAL -value less than or equal to -.It ASL_QUERY_OP_NOT_EQUAL -value not equal -.It ASL_QUERY_OP_REGEX -regular expression search -.It ASL_QUERY_OP_TRUE -always true - use to test for the existence of a key -.El -.Pp -Regular expression search uses -.Xr regex 3 -library. -Patterns are compiled using the REG_EXTENDED and REG_NOSUB options. -.Pp -Modifiers that change the behavior of these operations -may also be specified by ORing the modifier value with the operation. -The modifiers are: -.Pp -.Bl -tag -width "ASL_QUERY_OP_SUBSTRING" -compact -.It ASL_QUERY_OP_CASEFOLD -string comparisons are case-folded -.It ASL_QUERY_OP_PREFIX -match a leading substring -.It ASL_QUERY_OP_SUFFIX -match a trailing substring -.It ASL_QUERY_OP_SUBSTRING -match any substring -.It ASL_QUERY_OP_NUMERIC -values are converted to integer using -.Nm atoi -.El -.Pp -The only modifier that is checked -for ASL_QUERY_OP_REGEX search is ASL_QUERY_OP_CASEFOLD. -This causes the regular expression to be compiled -with the REG_ICASE option. -.Pp -If a query message contains more than one set of key/value/operation triples, -the result will be a logical AND. For example, to find messages from -.Dq MyApp -with a priority level less than or equal to -.Dq 3 : -.Pp - aslmsg q; - aslresponse r; - q = asl_new(ASL_TYPE_QUERY); - asl_set_query(q, ASL_KEY_SENDER, "MyApp", ASL_QUERY_OP_EQUAL); - asl_set_query(q, ASL_KEY_LEVEL, "3", - ASL_QUERY_OP_LESS_EQUAL | ASL_QUERY_OP_NUMERIC); - r = asl_search(NULL, q); -.Pp -After calling -.Nm asl_search -to get an -.Ft aslresponse -structure, use -.Nm aslresponse_next -to iterate through all matching messages. -To iterate through the keys and values in a message, use -.Nm asl_key -to iterate through the keys, then call -.Nm asl_get -to get the value associated with each key. -.Pp - aslmsg q, m; - int i; - const char *key, *val; -.Pp - ... - r = asl_search(NULL, q); - while (NULL != (m = aslresponse_next(r))) - { - for (i = 0; (NULL != (key = asl_key(m, i))); i++) - { - val = asl_get(m, key); - ... - } - } - aslresponse_free(r); -.Pp -.Ss FILTERING AND REMOTE CONTROL -Clients may set a filter mask value with -.Nm asl_set_filter . -The mask specifies which messages should be sent to the -.Nm syslogd -daemon by specifying a yes/no setting for each priority level. -Clients typically set a filter mask -to avoid sending relatively unimportant messages. -For example, Debug or Info priority level messages -are generally only useful for debugging operations. -By setting a filter mask, a process can improve performance -by avoiding sending messages that are in most cases unnecessary. -.Pp -.Nm asl_set_filter returns the previous value of the filter, i.e. the value of the filter before the routine was called. -.Pp -As a convenience, the macros ASL_FILTER_MASK(level) and ASL_FILTER_MASK_UPTO(level) -may be used to construct a bit mask corresponding to a given priority level, -or corresponding to a bit mask for all priority levels -from ASL_LEVEL_EMERG to a given input level. -.Pp -The default filter mask is ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE). -This means that by default, -and in the absence of remote-control changes (described below), -ASL_LEVEL_DEBUG and ASL_LEVEL_INFO priority level messages -are not sent to the -.Mn syslogd -server. -.Pp -Three different filters exist for each application. -The first is the filter mask set using -.Nm asl_set_filter -as described above. -The Apple System Log facility also manages a -.Dq master -filter mask. -The master filter mask usually has a value -that indicates to the library that it is -.Dq off , -and thus it has no effect. -However, the mask filter mask may be enabled -by giving it a value using the -.Nm syslog -command, using the -.Fl c -0 option. -When the master filter mask has been set, -it takes precedence over the client's filter mask. -The client's mask is unmodified, -and will become active again if remote-control filtering is disabled. -.Pp -In addition to the master filter mask, -The Apple System Log facility -also manages a per-client remote-control filter mask. -Like the master filter mask, the per-client mask is usually -.Dq off , -having no effect on a client. -If a per-client filter mask is set using the -.Nm syslog -command, using the -.Fl c Ar process -option, then it takes precedence -over both the client's filter mask and the master filter mask. -As is the case with the master filter mask, -a per-client mask ceases having any effect when if is disabled. -.Pp -The ASL_OPT_NO_REMOTE option to -.Nm asl_open -causes both the master and per-client remote-control masks -to be ignored in the library. -In that case, only the client's own filter mask -is used to determine which messages are sent to the server. -This may be useful for Applications that produce log messages -that should never be filtered, due to security considerations. -Note that root (administrator) access is required -to set or change the master filter mask, -and that only root may change a per-client remote-control filter mask -for a root (UID 0) process. -.Pp -The per-process remote control filter value is kept as a state value -associated with a key managed by -.Nm notifyd . -The key is protected by an access control mechanism that only permits the -filter value to be accessed and modified by the same effective UID as the -ASL client at the time that the first ASL connection was created. -Remote filter control using -.Nm syslog Fl c -will fail for processes that change effective UID after starting an ASL connection. -Those processes should close all ASL client handles and then re-open ASL connections -if remote filter control support is desired. -.Sh HISTORY -These functions first appeared in -Mac OS X 10.4. -.Sh SEE ALSO -.Xr syslog 1 , -.Xr strvis 3 , -.Xr syslogd 8 diff --git a/src/libc/gen/asl.c b/src/libc/gen/asl.c deleted file mode 100644 index 1948c9274..000000000 --- a/src/libc/gen/asl.c +++ /dev/null @@ -1,2187 +0,0 @@ -/* - * Copyright (c) 2004-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "asl_core.h" -#include "asl_msg.h" -#include "asl_store.h" -#include "asl_private.h" - -#define streq(A, B) (strcmp(A, B) == 0) -#define strcaseeq(A, B) (strcasecmp(A, B) == 0) - -#define forever for(;;) - -#define FETCH_BATCH 256 - -#define LEVEL_MASK 0x0000000f -#define EVAL_MASK 0x000000f0 -#define EVAL_IGNORE 0x00000000 -#define EVAL_ASLFILE 0x00000010 -#define EVAL_SEND 0x00000020 -#define EVAL_TUNNEL 0x00000040 -#define EVAL_FILE 0x00000080 - -/* forward */ -time_t asl_parse_time(const char *); -const char *asl_syslog_faciliy_num_to_name(int n); -static int _asl_send_message(aslclient ac, uint32_t eval, asl_msg_t *msg, const char *mstring); -__private_extern__ asl_client_t *_asl_open_default(); - -/* private asl_file SPI */ -__private_extern__ uint32_t asl_file_open_write_fd(int fd, asl_file_t **s); - -/* private asl_msg SPI */ -__private_extern__ asl_string_t *asl_msg_to_string_raw(uint32_t encoding, asl_msg_t *msg, int tf); - -/* notify SPI */ -uint32_t notify_register_plain(const char *name, int *out_token); - -/* fork handling in syslog.c */ -extern void _syslog_fork_child(); - -typedef struct -{ - int fd; - asl_msg_t *msg; - dispatch_semaphore_t sem; -} asl_aux_context_t; - -typedef struct -{ - int notify_count; - int rc_change_token; - int notify_token; - int master_token; - uint64_t proc_filter; - uint64_t master_filter; - dispatch_once_t port_lookup_once; - mach_port_t server_port; - char *sender; - pthread_mutex_t lock; - int aux_count; - asl_aux_context_t **aux_ctx; - asl_client_t *asl; -} _asl_global_t; - - -#ifndef BUILDING_VARIANT -__private_extern__ _asl_global_t _asl_global = {0, -1, -1, -1, 0LL, 0LL, 0, MACH_PORT_NULL, NULL, PTHREAD_MUTEX_INITIALIZER, 0, NULL, NULL}; - -#define ASL_SERVICE_NAME "com.apple.system.logger" - -/* - * Called from the child process inside fork() to clean up - * inherited state from the parent process. - * - * NB. A lock isn't required, since we're single threaded in this call. - */ -__private_extern__ void -_asl_fork_child() -{ - _asl_global.notify_count = 0; - _asl_global.rc_change_token = -1; - _asl_global.master_token = -1; - _asl_global.notify_token = -1; - - _asl_global.port_lookup_once = 0; - _asl_global.server_port = MACH_PORT_NULL; - - pthread_mutex_init(&(_asl_global.lock), NULL); -} - -/* - * asl_remote_notify_name: returns the notification key for remote-control filter - * changes for this process. - */ -char * -asl_remote_notify_name() -{ - pid_t pid = getpid(); - uid_t euid = geteuid(); - char *str = NULL; - - if (euid == 0) asprintf(&str, "%s.%d", NOTIFY_PREFIX_SYSTEM, pid); - else asprintf(&str, "user.uid.%d.syslog.%d", euid, pid); - - return str; -} - -static int -_asl_notify_open(int do_lock) -{ - char *notify_name; - uint32_t status; - - if (do_lock != 0) pthread_mutex_lock(&_asl_global.lock); - - _asl_global.notify_count++; - - if (_asl_global.notify_token != -1) - { - if (do_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return 0; - } - - if (_asl_global.rc_change_token == -1) - { - status = notify_register_check(NOTIFY_RC, &_asl_global.rc_change_token); - if (status != NOTIFY_STATUS_OK) _asl_global.rc_change_token = -1; - } - - if (_asl_global.master_token == -1) - { - status = notify_register_plain(NOTIFY_SYSTEM_MASTER, &_asl_global.master_token); - if (status != NOTIFY_STATUS_OK) _asl_global.master_token = -1; - } - - notify_name = asl_remote_notify_name(); - if (notify_name != NULL) - { - status = notify_register_plain(notify_name, &_asl_global.notify_token); - free(notify_name); - if (status != NOTIFY_STATUS_OK) _asl_global.notify_token = -1; - } - - if (do_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - - if (_asl_global.notify_token == -1) return -1; - return 0; -} - -static void -_asl_notify_close() -{ - pthread_mutex_lock(&_asl_global.lock); - - if (_asl_global.notify_count > 0) _asl_global.notify_count--; - - if (_asl_global.notify_count > 0) - { - pthread_mutex_unlock(&_asl_global.lock); - return; - } - - if (_asl_global.rc_change_token >= 0) notify_cancel(_asl_global.rc_change_token); - _asl_global.rc_change_token = -1; - - if (_asl_global.master_token >= 0) notify_cancel(_asl_global.master_token); - _asl_global.master_token = -1; - - if (_asl_global.notify_token >= 0) notify_cancel(_asl_global.notify_token); - _asl_global.notify_token = -1; - - pthread_mutex_unlock(&_asl_global.lock); -} - -static void -_asl_global_init() -{ - if (_asl_global.server_port == MACH_PORT_NULL) - { - mach_port_t newport = MACH_PORT_NULL; - char *str = getenv("ASL_DISABLE"); - if ((str == NULL) || strcmp(str, "1")) - { - bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &newport); - if (newport != MACH_PORT_NULL) - { - if (!OSAtomicCompareAndSwap32Barrier(MACH_PORT_NULL, newport, (int32_t *)&_asl_global.server_port)) - { - mach_port_deallocate(mach_task_self(), newport); - } - } - } - } -} - -static void -_asl_global_reset() -{ - mach_port_t tmp = _asl_global.server_port; - _asl_global.server_port = MACH_PORT_NULL; - mach_port_deallocate(mach_task_self(), tmp); -} - -aslclient -asl_open(const char *ident, const char *facility, uint32_t opts) -{ - char *name, *x; - asl_client_t *asl; - - asl = (asl_client_t *)calloc(1, sizeof(asl_client_t)); - if (asl == NULL) - { - errno = ENOMEM; - return NULL; - } - - asl->options = opts; - - asl->sock = -1; - - _asl_global_init(); - - asl->pid = getpid(); - asl->uid = getuid(); - asl->gid = getgid(); - - asl->filter = ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE); - - if (ident != NULL) - { - asl->name = strdup(ident); - if (asl->name == NULL) - { - if (asl->sock >= 0) close(asl->sock); - free(asl); - return NULL; - } - } - else - { - name = *(*_NSGetArgv()); - if (name != NULL) - { - x = strrchr(name, '/'); - if (x != NULL) x++; - else x = name; - asl->name = strdup(x); - if (asl->name == NULL) - { - if (asl->sock >= 0) close(asl->sock); - free(asl); - return NULL; - } - } - } - - asl->facility = NULL; - if (facility != NULL) asl->facility = strdup(facility); - else asl->facility = strdup(asl_syslog_faciliy_num_to_name(LOG_USER)); - if (asl->facility == NULL) - { - if (asl->sock >= 0) close(asl->sock); - if (asl->name != NULL) free(asl->name); - free(asl); - return NULL; - } - - if (!(asl->options & ASL_OPT_NO_REMOTE)) _asl_notify_open(1); - - if (asl->options & ASL_OPT_STDERR) asl_add_output((aslclient)asl, fileno(stderr), ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL, ASL_ENCODE_SAFE); - - asl->refcount = 1; - - return (aslclient)asl; -} - -aslclient -asl_open_from_file(int fd, const char *ident, const char *facility) -{ - char *name, *x; - asl_client_t *asl; - uint32_t status; - - asl = (asl_client_t *)calloc(1, sizeof(asl_client_t)); - if (asl == NULL) - { - errno = ENOMEM; - return NULL; - } - - asl->options = ASL_OPT_NO_REMOTE; - asl->sock = -1; - - asl->pid = getpid(); - asl->uid = getuid(); - asl->gid = getgid(); - - asl->filter = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG); - - if (ident != NULL) - { - asl->name = strdup(ident); - if (asl->name == NULL) - { - free(asl); - return NULL; - } - } - else - { - name = *(*_NSGetArgv()); - if (name != NULL) - { - x = strrchr(name, '/'); - if (x != NULL) x++; - else x = name; - asl->name = strdup(x); - if (asl->name == NULL) - { - free(asl); - return NULL; - } - } - } - - asl->facility = NULL; - if (facility != NULL) asl->facility = strdup(facility); - else asl->facility = strdup(asl_syslog_faciliy_num_to_name(LOG_USER)); - if (asl->facility == NULL) - { - if (asl->name != NULL) free(asl->name); - free(asl); - return NULL; - } - - status = asl_file_open_write_fd(fd, &(asl->aslfile)); - if (status != ASL_STATUS_OK) - { - if (asl->name != NULL) free(asl->name); - if (asl->facility != NULL) free(asl->facility); - free(asl); - return NULL; - } - - asl->aslfileid = 1; - asl->refcount = 1; - - return (aslclient)asl; -} - -__private_extern__ void -asl_client_release(asl_client_t *asl) -{ - uint32_t i; - - if (asl == NULL) return; - - if(OSAtomicDecrement32(&asl->refcount) > 0) - return; - - free(asl->name); - free(asl->facility); - - if (asl->sock >= 0) close(asl->sock); - if (!(asl->options & ASL_OPT_NO_REMOTE)) _asl_notify_close(); - if (asl->fd_list != NULL) free(asl->fd_list); - - if (asl->fd_mfmt != NULL) - { - for (i = 0; i < asl->fd_count; i++) if (asl->fd_mfmt[i] != NULL) free(asl->fd_mfmt[i]); - free(asl->fd_mfmt); - } - - if (asl->fd_tfmt != NULL) - { - for (i = 0; i < asl->fd_count; i++) if (asl->fd_tfmt[i] != NULL) free(asl->fd_tfmt[i]); - free(asl->fd_tfmt); - } - - if (asl->fd_encoding != NULL) free(asl->fd_encoding); - - memset(asl, 0, sizeof(asl_client_t)); - free(asl); -} - -void -asl_close(aslclient ac) -{ - asl_client_release((asl_client_t *)ac); -} - -__private_extern__ asl_client_t * -asl_client_retain(asl_client_t *asl) -{ - int32_t new; - - if (asl == NULL) return NULL; - - new = OSAtomicIncrement32(&asl->refcount); - assert(new >= 1); - - return asl; -} - -__private_extern__ asl_client_t * -_asl_open_default() -{ - static dispatch_once_t once; - - dispatch_once(&once, ^{ - /* - * Do a sleight-of-hand with ASL_OPT_NO_REMOTE to avoid a deadlock - * since asl_open(xxx, yyy, 0) calls _asl_notify_open(1) - * which locks _asl_global.lock. - */ - _asl_global.asl = asl_open(NULL, NULL, ASL_OPT_NO_REMOTE); - - /* Reset options to clear ASL_OPT_NO_REMOTE bit */ - if (_asl_global.asl != NULL) _asl_global.asl->options = 0; - - /* Now call _asl_notify_open(0) to finish the work */ - _asl_notify_open(0); - }); - - return _asl_global.asl; -} - -/* - * asl_add_file: write log messages to the given file descriptor - * Log messages will be written to this file as well as to the server. - */ -int -asl_add_output(aslclient ac, int fd, const char *mfmt, const char *tfmt, uint32_t text_encoding) -{ - uint32_t i; - int use_global_lock; - asl_client_t *asl; - - use_global_lock = 0; - asl = (asl_client_t *)ac; - if (asl == NULL) - { - asl = _asl_open_default(); - if (asl == NULL) return -1; - pthread_mutex_lock(&_asl_global.lock); - use_global_lock = 1; - } - - for (i = 0; i < asl->fd_count; i++) - { - if (asl->fd_list[i] == fd) - { - /* update message format, time format, and text encoding */ - if (asl->fd_mfmt[i] != NULL) free(asl->fd_mfmt[i]); - asl->fd_mfmt[i] = NULL; - if (mfmt != NULL) asl->fd_mfmt[i] = strdup(mfmt); - - if (asl->fd_tfmt[i] != NULL) free(asl->fd_tfmt[i]); - asl->fd_tfmt[i] = NULL; - if (tfmt != NULL) asl->fd_tfmt[i] = strdup(tfmt); - - asl->fd_encoding[i] = text_encoding; - - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return 0; - } - } - - if (asl->fd_count == 0) - { - asl->fd_list = (int *)calloc(1, sizeof(int)); - asl->fd_mfmt = (char **)calloc(1, sizeof(char *)); - asl->fd_tfmt = (char **)calloc(1, sizeof(char *)); - asl->fd_encoding = (uint32_t *)calloc(1, sizeof(int)); - } - else - { - asl->fd_list = (int *)reallocf(asl->fd_list, (1 + asl->fd_count) * sizeof(int)); - asl->fd_mfmt = (char **)reallocf(asl->fd_mfmt, (1 + asl->fd_count) * sizeof(char *)); - asl->fd_tfmt = (char **)reallocf(asl->fd_tfmt, (1 + asl->fd_count) * sizeof(char *)); - asl->fd_encoding = (uint32_t *)reallocf(asl->fd_encoding, (1 + asl->fd_count) * sizeof(uint32_t)); - } - - if ((asl->fd_list == NULL) || (asl->fd_mfmt == NULL) || (asl->fd_tfmt == NULL) || (asl->fd_encoding == NULL)) - { - if (asl->fd_list != NULL) free(asl->fd_list); - if (asl->fd_mfmt != NULL) free(asl->fd_mfmt); - if (asl->fd_tfmt != NULL) free(asl->fd_tfmt); - if (asl->fd_encoding != NULL) free(asl->fd_encoding); - - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return -1; - } - - asl->fd_list[asl->fd_count] = fd; - if (mfmt != NULL) asl->fd_mfmt[asl->fd_count] = strdup(mfmt); - if (tfmt != NULL) asl->fd_tfmt[asl->fd_count] = strdup(tfmt); - asl->fd_encoding[asl->fd_count] = text_encoding; - - asl->fd_count++; - - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return 0; -} - -int -asl_add_log_file(aslclient ac, int fd) -{ - return asl_add_output(ac, fd, ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL, ASL_ENCODE_SAFE); -} - -/* - * asl_remove_output: stop writing log messages to the given file descriptor - */ -int -asl_remove_output(aslclient ac, int fd) -{ - uint32_t i; - int x, use_global_lock; - asl_client_t *asl; - - use_global_lock = 0; - asl = (asl_client_t *)ac; - if (asl == NULL) - { - asl = _asl_open_default(); - if (asl == NULL) return -1; - pthread_mutex_lock(&_asl_global.lock); - use_global_lock = 1; - } - - if (asl->fd_count == 0) - { - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return 0; - } - - x = -1; - for (i = 0; i < asl->fd_count; i++) - { - if (asl->fd_list[i] == fd) - { - x = i; - break; - } - } - - if (x == -1) - { - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return 0; - } - - if (asl->fd_mfmt[x] != NULL) free(asl->fd_mfmt[x]); - if (asl->fd_tfmt[x] != NULL) free(asl->fd_tfmt[x]); - - for (i = x + 1; i < asl->fd_count; i++, x++) - { - asl->fd_list[x] = asl->fd_list[i]; - asl->fd_mfmt[x] = asl->fd_mfmt[i]; - asl->fd_tfmt[x] = asl->fd_tfmt[i]; - asl->fd_encoding[x] = asl->fd_encoding[i]; - } - - asl->fd_count--; - - if (asl->fd_count == 0) - { - free(asl->fd_list); - asl->fd_list = NULL; - - free(asl->fd_mfmt); - asl->fd_mfmt = NULL; - - free(asl->fd_tfmt); - asl->fd_tfmt = NULL; - - free(asl->fd_encoding); - asl->fd_encoding = NULL; - } - else - { - asl->fd_list = (int *)reallocf(asl->fd_list, asl->fd_count * sizeof(int)); - asl->fd_mfmt = (char **)reallocf(asl->fd_mfmt, asl->fd_count * sizeof(char *)); - asl->fd_tfmt = (char **)reallocf(asl->fd_tfmt, asl->fd_count * sizeof(char *)); - asl->fd_encoding = (uint32_t *)reallocf(asl->fd_encoding, asl->fd_count * sizeof(uint32_t)); - - if ((asl->fd_list == NULL) || (asl->fd_mfmt == NULL) || (asl->fd_tfmt == NULL) || (asl->fd_encoding == NULL)) - { - if (asl->fd_list != NULL) - { - free(asl->fd_list); - asl->fd_list = NULL; - } - - if (asl->fd_mfmt != NULL) - { - for (i = 0; i < asl->fd_count; i++) if (asl->fd_mfmt[i] != NULL) free(asl->fd_mfmt[i]); - free(asl->fd_mfmt); - asl->fd_mfmt = NULL; - } - - if (asl->fd_tfmt != NULL) - { - for (i = 0; i < asl->fd_count; i++) if (asl->fd_tfmt[i] != NULL) free(asl->fd_tfmt[i]); - free(asl->fd_tfmt); - asl->fd_tfmt = NULL; - } - - if (asl->fd_encoding != NULL) - { - free(asl->fd_encoding); - asl->fd_encoding = NULL; - } - - asl->fd_count = 0; - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return -1; - } - } - - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return 0; -} - -int -asl_remove_log_file(aslclient ac, int fd) -{ - return asl_remove_output(ac, fd); -} - -int -asl_set_filter(aslclient ac, int f) -{ - int last, use_global_lock; - asl_client_t *asl; - - use_global_lock = 0; - asl = (asl_client_t *)ac; - if (asl == NULL) - { - asl = _asl_open_default(); - if (asl == NULL) return -1; - pthread_mutex_lock(&_asl_global.lock); - use_global_lock = 1; - } - - last = asl->filter; - asl->filter = f; - - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return last; -} - -/* - * Evaluate client / message / level to determine what to do with a message. - * Checks filters, tunneling, and log files. Returns EVAL_IGNORE if the message - * can be ignored. Otherwise it returns the bits below, ORed with the level. - * - * EVAL_ASLFILE - will write to an asl file (see asl_open_from_file) - * EVAL_SEND - will send to syslogd - * EVAL_TUNNEL - will send to syslogd with tunneling enabled - * EVAL_FILE - will write to file - */ -uint32_t -_asl_evaluate_send(aslclient ac, aslmsg msg, int slevel) -{ - asl_client_t *asl = (asl_client_t *)ac; - uint32_t level, lmask, filter, status, tunnel; - int check, out; - uint64_t v64; - const char *val; - - if (asl == NULL) - { - asl = _asl_open_default(); - if (asl == NULL) return EVAL_IGNORE; - } - - check = ASL_LEVEL_DEBUG; - if (slevel >= 0) check = slevel; - - val = asl_get((aslmsg)msg, ASL_KEY_LEVEL); - if (val != NULL) check = atoi(val); - - if (check < ASL_LEVEL_EMERG) check = ASL_LEVEL_EMERG; - else if (check > ASL_LEVEL_DEBUG) check = ASL_LEVEL_DEBUG; - level = check; - - out = check; - - if (asl->aslfile != NULL) return (out | EVAL_ASLFILE); - - lmask = ASL_FILTER_MASK(level); - - if (!(asl->options & ASL_OPT_NO_REMOTE)) - { - pthread_mutex_lock(&_asl_global.lock); - - if (_asl_global.rc_change_token >= 0) - { - /* initialize or re-check process-specific and master filters */ - check = 0; - status = notify_check(_asl_global.rc_change_token, &check); - if ((status == NOTIFY_STATUS_OK) && (check != 0)) - { - if (_asl_global.master_token >= 0) - { - v64 = 0; - status = notify_get_state(_asl_global.master_token, &v64); - if (status == NOTIFY_STATUS_OK) _asl_global.master_filter = v64; - } - - if (_asl_global.notify_token >= 0) - { - v64 = 0; - status = notify_get_state(_asl_global.notify_token, &v64); - if (status == NOTIFY_STATUS_OK) _asl_global.proc_filter = v64; - } - } - } - - pthread_mutex_unlock(&_asl_global.lock); - } - - filter = asl->filter & 0xff; - tunnel = (asl->filter & ASL_FILTER_MASK_TUNNEL) >> 8; - - /* master filter overrides local filter */ - if (_asl_global.master_filter != 0) - { - filter = _asl_global.master_filter; - tunnel = 1; - } - - /* process-specific filter overrides local and master */ - if (_asl_global.proc_filter != 0) - { - filter = _asl_global.proc_filter; - tunnel = 1; - } - - if ((filter != 0) && ((filter & lmask) != 0)) - { - out |= EVAL_SEND; - if (tunnel != 0) out |= EVAL_TUNNEL; - if (asl->fd_count > 0) out |= EVAL_FILE; - - return out; - } - - if ((asl->options & ASL_OPT_SYSLOG_LEGACY) && (filter != 0) && ((filter & lmask) == 0)) - { - return EVAL_IGNORE; - } - - if (asl->fd_count > 0) return (out | EVAL_FILE); - - return EVAL_IGNORE; -} - -#endif /* BUILDING_VARIANT */ - -/* - * _asl_lib_vlog - * Internal routine used by asl_vlog. - * msg: an aslmsg - * eval: log level and send flags for the message - * format: A formating string - * ap: va_list for the format - * returns 0 for success, non-zero for failure - */ -static int -_asl_lib_vlog(aslclient ac, uint32_t eval, aslmsg msg, const char *format, va_list ap) -{ - int saved_errno = errno; - int status; - char *str, *fmt, estr[NL_TEXTMAX]; - uint32_t i, len, elen, expand; - asl_client_t *asl; - - asl = (asl_client_t *)ac; - if (asl == NULL) - { - /* - * Initialize _asl_global so that asl_new will have global data. - * Not strictly necessary, but helps performance. - */ - asl = _asl_open_default(); - if (asl == NULL) return -1; - } - - if (format == NULL) return -1; - - /* insert strerror for %m */ - len = 0; - elen = 0; - - expand = 0; - for (i = 0; format[i] != '\0'; i++) - { - if (format[i] == '%') - { - if (format[i+1] == '\0') len++; - else if (format[i+1] == 'm') - { - expand = 1; - strerror_r(saved_errno, estr, sizeof(estr)); - elen = strlen(estr); - len += elen; - i++; - } - else - { - len += 2; - i++; - } - } - else len++; - } - - fmt = (char *)format; - - if (expand != 0) - { - fmt = malloc(len + 1); - if (fmt == NULL) - { - if (estr != NULL) free(estr); - return -1; - } - - len = 0; - - for (i = 0; format[i] != '\0'; i++) - { - if (format[i] == '%') - { - if (format[i+1] == '\0') - { - } - else if ((format[i+1] == 'm') && (elen != 0)) - { - memcpy(fmt+len, estr, elen); - len += elen; - i++; - } - else - { - fmt[len++] = format[i++]; - fmt[len++] = format[i]; - } - } - else fmt[len++] = format[i]; - } - - fmt[len] = '\0'; - } - - vasprintf(&str, fmt, ap); - if (expand != 0) free(fmt); - - if (str == NULL) return -1; - - status = _asl_send_message(ac, eval, (asl_msg_t *)msg, str); - free(str); - - return status; -} - -/* - * asl_vlog - * Similar to asl_log, but take a va_list instead of a list of arguments. - * msg: an aslmsg - * level: the log level of the associated message - * format: A formating string - * ap: va_list for the format - * returns 0 for success, non-zero for failure - */ -int -asl_vlog(aslclient ac, aslmsg msg, int level, const char *format, va_list ap) -{ - uint32_t eval = _asl_evaluate_send(ac, msg, level); - if (eval == EVAL_IGNORE) return 0; - - return _asl_lib_vlog(ac, eval, msg, format, ap); -} - -/* - * _asl_lib_log - * SPI used by ASL_PREFILTER_LOG. Converts format arguments to a va_list and - * forwards the call to _asl_lib_vlog. - * msg: an aslmsg - * eval: log level and send flags for the message - * format: A formating string - * ... args for format - * returns 0 for success, non-zero for failure - */ -int -_asl_lib_log(aslclient ac, uint32_t eval, aslmsg msg, const char *format, ...) -{ - int status; - if (eval == EVAL_IGNORE) return 0; - - va_list ap; - va_start(ap, format); - status = _asl_lib_vlog(ac, eval, msg, format, ap); - va_end(ap); - - return status; -} - -/* - * asl_log - * Processes an ASL log message. - * msg: an aslmsg - * level: the log level of the associated message - * format: A formating string - * ... args for format - * returns 0 for success, non-zero for failure - */ -int -asl_log(aslclient ac, aslmsg msg, int level, const char *format, ...) -{ - int status; - uint32_t eval = _asl_evaluate_send(ac, msg, level); - if (eval == EVAL_IGNORE) return 0; - - va_list ap; - va_start(ap, format); - status = _asl_lib_vlog(ac, eval, msg, format, ap); - va_end(ap); - - return status; -} - -#ifndef BUILDING_VARIANT - -/* - * asl_get_filter: gets the values for the local, master, and remote filters, - * and indicates which one is active. - */ -int -asl_get_filter(aslclient ac, int *local, int *master, int *remote, int *active) -{ - asl_client_t *asl, *asl_default; - int l, m, r, x; - int status, check; - uint64_t v64; - - l = 0; - m = 0; - r = 0; - x = 0; - - asl_default = _asl_open_default(); - - asl = (asl_client_t *)ac; - if (asl == NULL) asl = asl_default; - if (asl != NULL) l = asl->filter & 0xff; - - if ((asl_default != NULL) && (!(asl_default->options & ASL_OPT_NO_REMOTE))) - { - pthread_mutex_lock(&_asl_global.lock); - - if (_asl_global.rc_change_token >= 0) - { - /* initialize or re-check process-specific and master filters */ - check = 0; - status = notify_check(_asl_global.rc_change_token, &check); - if ((status == NOTIFY_STATUS_OK) && (check != 0)) - { - if (_asl_global.master_token >= 0) - { - v64 = 0; - status = notify_get_state(_asl_global.master_token, &v64); - if (status == NOTIFY_STATUS_OK) _asl_global.master_filter = v64; - } - - if (_asl_global.notify_token >= 0) - { - v64 = 0; - status = notify_get_state(_asl_global.notify_token, &v64); - if (status == NOTIFY_STATUS_OK) _asl_global.proc_filter = v64; - } - } - } - - m = _asl_global.master_filter; - if (m != 0) x = 1; - - r = _asl_global.proc_filter; - if (r != 0) x = 2; - - pthread_mutex_unlock(&_asl_global.lock); - } - - if (local != NULL) *local = l; - if (master != NULL) *master = m; - if (remote != NULL) *remote = r; - if (active != NULL) *active = x; - - return 0; -} - -static int -_asl_send_message(aslclient ac, uint32_t eval, asl_msg_t *msg, const char *mstring) -{ - uint32_t i, len, level, lmask, outstatus, filter, fd_write; - uint64_t v64; - const char *val; - char *name, *x; - time_t tick; - struct timeval tval; - int status, check; - asl_client_t *asl; - int use_global_lock; - kern_return_t kstatus; - char aux_val[64]; - char aux_host[_POSIX_HOST_NAME_MAX]; - asl_msg_t *aux; - - if (eval == EVAL_IGNORE) return 0; - - level = eval & LEVEL_MASK; - eval &= EVAL_MASK; - - use_global_lock = 0; - asl = (asl_client_t *)ac; - if (asl == NULL) - { - asl = _asl_open_default(); - if (asl == NULL) return -1; - use_global_lock = 1; - } - - if (asl->aslfile != NULL) use_global_lock = 1; - - /* - * Time, TimeNanoSec, Host, PID, UID, and GID values get set here. - * Also sets Sender & Facility (if unset) and "ASLOption store" if remote control is active. - */ - aux = asl_msg_new(ASL_TYPE_MSG); - - if (mstring != NULL) asl_msg_set_key_val(aux, ASL_KEY_MSG, mstring); - - snprintf(aux_val, sizeof(aux_val), "%u", level); - asl_msg_set_key_val(aux, ASL_KEY_LEVEL, aux_val); - - memset(&tval, 0, sizeof(struct timeval)); - - status = gettimeofday(&tval, NULL); - if (status == 0) - { - snprintf(aux_val, sizeof(aux_val), "%lu", tval.tv_sec); - asl_msg_set_key_val(aux, ASL_KEY_TIME, aux_val); - snprintf(aux_val, sizeof(aux_val), "%d", tval.tv_usec * 1000); - asl_msg_set_key_val(aux, ASL_KEY_TIME_NSEC, aux_val); - } - else - { - tick = time(NULL); - snprintf(aux_val, sizeof(aux_val), "%lu", tick); - asl_msg_set_key_val(aux, ASL_KEY_TIME, aux_val); - } - - memset(&aux_host, 0, _POSIX_HOST_NAME_MAX); - if (gethostname(aux_host, _POSIX_HOST_NAME_MAX) == 0) - { - asl_msg_set_key_val(aux, ASL_KEY_HOST, aux_host); - } - - snprintf(aux_val, sizeof(aux_val), "%u", getpid()); - asl_msg_set_key_val(aux, ASL_KEY_PID, aux_val); - - snprintf(aux_val, sizeof(aux_val), "%d", getuid()); - asl_msg_set_key_val(aux, ASL_KEY_UID, aux_val); - - snprintf(aux_val, sizeof(aux_val), "%d", getgid()); - asl_msg_set_key_val(aux, ASL_KEY_GID, aux_val); - - /* - * Set Sender if needed - */ - status = asl_msg_lookup((asl_msg_t *)msg, ASL_KEY_SENDER, &val, NULL); - if ((status != 0) || (val == NULL)) - { - if ((ac != NULL) && (ac->name != NULL)) - { - /* Use the Sender name from the client handle */ - asl_msg_set_key_val(aux, ASL_KEY_SENDER, ac->name); - } - else - { - /* Get the value for ASL_KEY_SENDER from cache */ - if (_asl_global.sender == NULL) - { - name = *(*_NSGetArgv()); - if (name != NULL) - { - x = strrchr(name, '/'); - if (x != NULL) x++; - else x = name; - - pthread_mutex_lock(&_asl_global.lock); - if (_asl_global.sender == NULL) _asl_global.sender = strdup(x); - pthread_mutex_unlock(&_asl_global.lock); - } - } - - if (_asl_global.sender != NULL) asl_msg_set_key_val(aux, ASL_KEY_SENDER, _asl_global.sender); - else asl_msg_set_key_val(aux, ASL_KEY_SENDER, "Unknown"); - } - } - - /* - * Set Facility - */ - status = asl_msg_lookup((asl_msg_t *)msg, ASL_KEY_FACILITY, &val, NULL); - if ((status != 0) || (val == NULL)) - { - if ((ac != NULL) && (ac->facility != NULL)) - { - /* Use the Facility name from the client handle */ - asl_msg_set_key_val(aux, ASL_KEY_FACILITY, ac->facility); - } - } - - /* Set "ASLOption store" if tunneling */ - - if (eval & EVAL_TUNNEL) - { - val = asl_get((aslmsg)msg, ASL_KEY_OPTION); - if (val == NULL) - { - asl_msg_set_key_val(aux, ASL_KEY_OPTION, ASL_OPT_STORE); - } - else - { - char *aux_option = NULL; - asprintf(&aux_option, "%s %s", ASL_OPT_STORE, val); - asl_msg_set_key_val(aux, ASL_KEY_OPTION, aux_option); - free(aux_option); - } - } - - outstatus = -1; - - if (use_global_lock != 0) pthread_mutex_lock(&_asl_global.lock); - - aux = asl_msg_merge(aux, msg); - - /* - * If there is an aslfile this is a stand-alone file client. - * Just save to the file. - */ - if (asl->aslfile != NULL) - { - outstatus = ASL_STATUS_FAILED; - - if (aux != NULL) - { - outstatus = asl_file_save(asl->aslfile, (aslmsg)aux, &(asl->aslfileid)); - asl->aslfileid++; - } - - asl_msg_release(aux); - - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - return outstatus; - } - - _asl_global_init(); - outstatus = 0; - - if ((_asl_global.server_port != MACH_PORT_NULL) && (eval & EVAL_SEND)) - { - asl_string_t *send_str; - const char *str; - size_t vmsize; - - send_str = asl_msg_to_string_raw(ASL_STRING_MIG, aux, 0); - len = asl_string_length(send_str); - vmsize = asl_string_allocated_size(send_str); - str = asl_string_free_return_bytes(send_str); - - if (len != 0) - { - /* send a mach message to syslogd */ - kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)str, len); - if (kstatus != KERN_SUCCESS) - { - /* retry once if the call failed */ - _asl_global_reset(); - _asl_global_init(); - kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)str, len); - if (kstatus != KERN_SUCCESS) - { - _asl_global_reset(); - vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize); - outstatus = -1; - } - } - } - } - - /* messages from syslog() get filtered on the way out to stderr */ - fd_write = 1; - if ((asl->options & ASL_OPT_SYSLOG_LEGACY) && (filter != 0) && ((filter & lmask) == 0)) fd_write = 0; - - if ((fd_write != 0) && (asl->fd_count > 0)) - { - if (aux != NULL) - { - /* write to file descriptors */ - - for (i = 0; i < asl->fd_count; i++) - { - char *str; - - if (asl->fd_list[i] < 0) continue; - - len = 0; - str = asl_format_message(aux, asl->fd_mfmt[i], asl->fd_tfmt[i], asl->fd_encoding[i], &len); - if (str == NULL) continue; - - status = write(asl->fd_list[i], str, len - 1); - if (status < 0) - { - asl->fd_list[i] = -1; - outstatus = -1; - } - - free(str); - } - } - } - - asl_msg_release(aux); - - if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock); - - return outstatus; -} - -/* - * asl_send: send a message - * This routine may be used instead of asl_log() or asl_vlog() if asl_set() - * has been used to set all of a message's attributes. - * eval: hints about what to do with the message - * msg: an aslmsg - * returns 0 for success, non-zero for failure - */ -int -asl_send(aslclient ac, aslmsg msg) -{ - int status = 0; - uint32_t eval = _asl_evaluate_send(ac, msg, -1); - if (eval != 0) status = _asl_send_message(ac, eval, (asl_msg_t *)msg, NULL); - - return status; -} - -static int -_asl_aux_save_context(asl_aux_context_t *ctx) -{ - if (ctx == NULL) return -1; - - pthread_mutex_lock(&_asl_global.lock); - - _asl_global.aux_ctx = (asl_aux_context_t **)reallocf(_asl_global.aux_ctx, (_asl_global.aux_count + 1) * sizeof(asl_aux_context_t *)); - if (_asl_global.aux_ctx == NULL) - { - _asl_global.aux_count = 0; - return -1; - } - - _asl_global.aux_ctx[_asl_global.aux_count++] = ctx; - - pthread_mutex_unlock(&_asl_global.lock); - - return 0; -} - -/* - * Creates an auxiliary file that may be used to save arbitrary data. The ASL message msg - * will be saved at the time that the auxiliary file is created. The message will include - * any keys and values found in msg, and it will include the title and Uniform Type - * Identifier specified. Output parameter out_fd will contain the file descriptor of the - * new auxiliary file. - */ -static int -_asl_auxiliary(asl_msg_t *msg, const char *title, const char *uti, const char *url, int *out_fd) -{ - asl_msg_t *aux; - asl_string_t *send_str; - const char *str; - fileport_t fileport; - kern_return_t kstatus; - size_t len, vmsize; - uint32_t newurllen, where; - int status, fd, fdpair[2]; - caddr_t newurl; - dispatch_queue_t pipe_q; - dispatch_io_t pipe_channel; - dispatch_semaphore_t sem; - - aux = asl_msg_new(ASL_TYPE_MSG); - - if (title != NULL) - { - asl_msg_set_key_val(aux, ASL_KEY_AUX_TITLE, title); - } - - if (uti == NULL) - { - asl_msg_set_key_val(aux, ASL_KEY_AUX_UTI, "public.data"); - } - else - { - asl_msg_set_key_val(aux, ASL_KEY_AUX_UTI, uti); - } - - if (url != NULL) - { - asl_msg_set_key_val(aux, ASL_KEY_AUX_URL, url); - } - - aux = asl_msg_merge(aux, msg); - - /* if (out_fd == NULL), this is from asl_log_auxiliary_location */ - if (out_fd == NULL) - { - uint32_t eval = _asl_evaluate_send(NULL, (aslmsg)aux, -1); - status = _asl_send_message(NULL, eval, aux, NULL); - asl_msg_release(aux); - return status; - } - - where = asl_store_location(); - - if (where == ASL_STORE_LOCATION_MEMORY) - { - /* create a pipe */ - - asl_aux_context_t *ctx = (asl_aux_context_t *)calloc(1, sizeof(asl_aux_context_t)); - if (ctx == NULL) return -1; - - status = pipe(fdpair); - if (status < 0) - { - free(ctx); - return -1; - } - - /* give read end to dispatch_io_read */ - fd = fdpair[0]; - sem = dispatch_semaphore_create(0); - ctx->sem = sem; - ctx->fd = fdpair[1]; - - status = _asl_aux_save_context(ctx); - if (status != 0) - { - close(fdpair[0]); - close(fdpair[1]); - dispatch_release(sem); - free(ctx); - return -1; - } - - pipe_q = dispatch_queue_create("PipeQ", NULL); - pipe_channel = dispatch_io_create(DISPATCH_IO_STREAM, fd, pipe_q, ^(int err){ - close(fd); - }); - - *out_fd = fdpair[1]; - - dispatch_io_set_low_water(pipe_channel, SIZE_MAX); - - dispatch_io_read(pipe_channel, 0, SIZE_MAX, pipe_q, ^(bool done, dispatch_data_t pipedata, int err){ - if (err == 0) - { - size_t len = dispatch_data_get_size(pipedata); - if (len > 0) - { - const char *bytes = NULL; - char *encoded; - uint32_t eval; - - dispatch_data_t md = dispatch_data_create_map(pipedata, (const void **)&bytes, &len); - encoded = asl_core_encode_buffer(bytes, len); - asl_msg_set_key_val(aux, ASL_KEY_AUX_DATA, encoded); - free(encoded); - eval = _asl_evaluate_send(NULL, (aslmsg)aux, -1); - _asl_send_message(NULL, eval, aux, NULL); - asl_msg_release(aux); - dispatch_release(md); - } - } - - if (done) - { - dispatch_semaphore_signal(sem); - dispatch_release(pipe_channel); - dispatch_release(pipe_q); - } - }); - - return 0; - } - - _asl_global_init(); - if (_asl_global.server_port == MACH_PORT_NULL) return -1; - - send_str = asl_msg_to_string_raw(ASL_STRING_MIG, aux, 0); - len = asl_string_length(send_str); - vmsize = asl_string_allocated_size(send_str); - str = asl_string_free_return_bytes(send_str); - - if (len == 0) - { - asl_msg_release(aux); - vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize); - return -1; - } - - status = 0; - fileport = MACH_PORT_NULL; - status = KERN_SUCCESS; - - kstatus = _asl_server_create_aux_link(_asl_global.server_port, (caddr_t)str, len, &fileport, &newurl, &newurllen, &status); - if (kstatus != KERN_SUCCESS) - { - /* retry once if the call failed */ - _asl_global_reset(); - _asl_global_init(); - kstatus = _asl_server_create_aux_link(_asl_global.server_port, (caddr_t)str, len, &fileport, &newurl, &newurllen, &status); - if (kstatus != KERN_SUCCESS) - { - _asl_global_reset(); - vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize); - asl_msg_release(aux); - return -1; - } - } - - if (status != 0) - { - asl_msg_release(aux); - return status; - } - - if (newurl != NULL) - { - asl_msg_set_key_val(aux, ASL_KEY_AUX_URL, newurl); - vm_deallocate(mach_task_self(), (vm_address_t)newurl, newurllen); - } - - if (fileport == MACH_PORT_NULL) - { - asl_msg_release(aux); - return -1; - } - - fd = fileport_makefd(fileport); - mach_port_deallocate(mach_task_self(), fileport); - if (fd < 0) - { - asl_msg_release(aux); - status = -1; - } - else - { - asl_aux_context_t *ctx = (asl_aux_context_t *)calloc(1, sizeof(asl_aux_context_t)); - if (ctx == NULL) - { - status = -1; - } - else - { - *out_fd = fd; - - ctx->fd = fd; - ctx->msg = aux; - - status = _asl_aux_save_context(ctx); - } - } - - return status; -} - -int -asl_create_auxiliary_file(aslmsg msg, const char *title, const char *uti, int *out_fd) -{ - if (out_fd == NULL) return -1; - - return _asl_auxiliary((asl_msg_t *)msg, title, uti, NULL, out_fd); -} - -int -asl_log_auxiliary_location(aslmsg msg, const char *title, const char *uti, const char *url) -{ - return _asl_auxiliary((asl_msg_t *)msg, title, uti, url, NULL); -} - -/* - * Close an auxiliary file. - * Sends the cached auxiliary message to syslogd. - */ -int -asl_close_auxiliary_file(int fd) -{ - int i, j, status; - asl_msg_t *aux_msg; - dispatch_semaphore_t aux_sem; - - pthread_mutex_lock(&(_asl_global.lock)); - - aux_msg = NULL; - status = -1; - - for (i = 0; i < _asl_global.aux_count; i++) - { - if (_asl_global.aux_ctx[i]->fd == fd) - { - status = 0; - - aux_msg = _asl_global.aux_ctx[i]->msg; - aux_sem = _asl_global.aux_ctx[i]->sem; - - free(_asl_global.aux_ctx[i]); - - for (j = i + 1; j < _asl_global.aux_count; i++, j++) - { - _asl_global.aux_ctx[i] = _asl_global.aux_ctx[j]; - } - - _asl_global.aux_count--; - - if (_asl_global.aux_count == 0) - { - free(_asl_global.aux_ctx); - _asl_global.aux_ctx = NULL; - } - else - { - _asl_global.aux_ctx = (asl_aux_context_t **)reallocf(_asl_global.aux_ctx, _asl_global.aux_count * sizeof(asl_aux_context_t *)); - if (_asl_global.aux_ctx == NULL) - { - _asl_global.aux_count = 0; - status = -1; - } - } - - break; - } - } - - pthread_mutex_unlock(&(_asl_global.lock)); - - close(fd); - - if (aux_msg != NULL) - { - uint32_t eval = _asl_evaluate_send(NULL, (aslmsg)aux_msg, -1); - if (_asl_send_message(NULL, eval, aux_msg, NULL) != ASL_STATUS_OK) status = -1; - asl_msg_release(aux_msg); - } - - if (aux_sem != NULL) - { - dispatch_semaphore_wait(aux_sem, DISPATCH_TIME_FOREVER); - dispatch_release(aux_sem); - } - - return status; -} - -/* - * asl_search: Search for messages matching the criteria described - * by the aslmsg. The caller should set the attributes to match using - * asl_set_query() or asl_set(). The operatoin ASL_QUERY_OP_EQUAL is - * used for attributes set with asl_set(). - * a: an aslmsg - * returns: a set of messages that can be iterated over using aslresp_next(), - * and the values can be retrieved using aslresp_get. - */ - -/* - * This routine searches the ASL datastore on disk (/var/log/asl). - * It is called my asl_search if syslogd is not running or if syslogd - * indicates that an in-memory store is not being used. - */ -static aslresponse -_asl_search_store(aslclient ac, aslmsg a) -{ - asl_search_result_t query, *out; - asl_msg_t *q, *qlist[1]; - uint32_t status, op; - uint64_t last_id, start_id; - asl_store_t *store; - const char *val; - - if (a == NULL) return NULL; - - q = (asl_msg_t *)a; - - /* check for "ASLMessageId >[=] n" and set start_id */ - start_id = 0; - val = NULL; - - status = asl_msg_lookup(q, ASL_KEY_MSG_ID, &val, &op); - if ((status == 0) && (val != NULL) && (op & ASL_QUERY_OP_GREATER)) - { - if (op & ASL_QUERY_OP_EQUAL) start_id = atoll(val); - else start_id = atoll(val) + 1; - } - - store = NULL; - status = asl_store_open_read(NULL, &store); - if (status != 0) return NULL; - if (store == NULL) return NULL; - - out = NULL; - last_id = 0; - - qlist[0] = (asl_msg_t *)a; - memset(&query, 0, sizeof(asl_search_result_t)); - query.count = 1; - query.msg = qlist; - - status = asl_store_match(store, &query, &out, &last_id, start_id, 0, 1); - asl_store_close(store); - - return out; -} - -static uint32_t -_asl_search_concat_results(asl_search_result_t *batch, asl_search_result_t **out) -{ - uint32_t i, j; - - if (out == NULL) return ASL_STATUS_FAILED; - - /* nothing to do if batch is NULL or contains no messages */ - if (batch == NULL) return 0; - if (batch->count == 0) - { - aslresponse_free(batch); - return 0; - } - - if (*out == NULL) *out = (asl_search_result_t *)calloc(1, sizeof(asl_search_result_t)); - if (*out == NULL) - { - aslresponse_free(batch); - return ASL_STATUS_FAILED; - } - - if ((*out)->count == 0) - { - (*out)->msg = (asl_msg_t **)calloc(batch->count, sizeof(asl_msg_t *)); - } - else - { - (*out)->msg = (asl_msg_t **)reallocf((*out)->msg, ((*out)->count + batch->count) * sizeof(asl_msg_t *)); - } - - if ((*out)->msg == NULL) - { - aslresponse_free(batch); - free(*out); - *out = NULL; - return ASL_STATUS_FAILED; - } - - for (i = 0, j = (*out)->count; i < batch->count; i++, j++) (*out)->msg[j] = batch->msg[i]; - - (*out)->count += batch->count; - free(batch->msg); - free(batch); - return ASL_STATUS_OK; -} - -static aslresponse -_asl_search_memory(aslclient ac, aslmsg a) -{ - asl_search_result_t *batch, *out; - char *qstr, *str, *res; - uint32_t len, reslen, status; - uint64_t cmax, qmin; - kern_return_t kstatus; - security_token_t sec; - caddr_t vmstr; - - if (a == NULL) return 0; - - _asl_global_init(); - if (_asl_global.server_port == MACH_PORT_NULL) return NULL; - - len = 0; - qstr = asl_msg_to_string((asl_msg_t *)a, &len); - - str = NULL; - if (qstr == NULL) - { - asprintf(&str, "0\n"); - len = 3; - } - else - { - asprintf(&str, "1\n%s\n", qstr); - len += 3; - free(qstr); - } - - if (str == NULL) return NULL; - - /* - * Fetch a batch of results each time through the loop. - * Fetching small batches rebuces the load on syslogd. - */ - out = NULL; - qmin = 0; - cmax = 0; - - forever - { - res = NULL; - reslen = 0; - sec.val[0] = -1; - sec.val[1] = -1; - status = ASL_STATUS_OK; - - kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&vmstr, len, TRUE); - if (kstatus != KERN_SUCCESS) return NULL; - - memmove(vmstr, str, len); - - status = 0; - kstatus = _asl_server_query(_asl_global.server_port, vmstr, len, qmin, FETCH_BATCH, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec); - if (kstatus != KERN_SUCCESS) - { - /* retry once if the call failed */ - _asl_global_reset(); - _asl_global_init(); - kstatus = _asl_server_query(_asl_global.server_port, vmstr, len, qmin, FETCH_BATCH, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec); - if (kstatus != KERN_SUCCESS) - { - _asl_global_reset(); - break; - } - } - - if (res == NULL) break; - - batch = asl_list_from_string(res); - vm_deallocate(mach_task_self(), (vm_address_t)res, reslen); - - status = _asl_search_concat_results(batch, &out); - if (status != ASL_STATUS_OK) break; - if ((out == NULL) || (out->count < FETCH_BATCH)) break; - - if (cmax >= qmin) qmin = cmax + 1; - } - - free(str); - - return out; -} - -int -asl_store_location() -{ - kern_return_t kstatus; - char *res; - uint32_t reslen, status; - uint64_t cmax; - security_token_t sec; - - _asl_global_init(); - if (_asl_global.server_port == MACH_PORT_NULL) return ASL_STORE_LOCATION_FILE; - - res = NULL; - reslen = 0; - cmax = 0; - sec.val[0] = -1; - sec.val[1] = -1; - status = ASL_STATUS_OK; - - kstatus = _asl_server_query(_asl_global.server_port, NULL, 0, 0, -1, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec); - if (kstatus != KERN_SUCCESS) - { - /* retry once if the call failed */ - _asl_global_reset(); - _asl_global_init(); - kstatus = _asl_server_query(_asl_global.server_port, NULL, 0, 0, -1, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec); - } - - /* res should never be returned, but just to be certain we don't leak VM ... */ - if (res != NULL) vm_deallocate(mach_task_self(), (vm_address_t)res, reslen); - - if (kstatus != KERN_SUCCESS) - { - _asl_global_reset(); - return ASL_STORE_LOCATION_FILE; - } - - if (status == ASL_STATUS_OK) return ASL_STORE_LOCATION_MEMORY; - return ASL_STORE_LOCATION_FILE; -} - -aslresponse -asl_search(aslclient ac, aslmsg a) -{ - int where; - asl_search_result_t *out; - - _asl_global_init(); - - where = asl_store_location(); - if (where == ASL_STORE_LOCATION_FILE) out = _asl_search_store(ac, a); - else out = _asl_search_memory(ac, a); - - return out; -} - -int -asl_syslog_faciliy_name_to_num(const char *name) -{ - if (name == NULL) return -1; - - if (strcaseeq(name, "auth")) return LOG_AUTH; - if (strcaseeq(name, "authpriv")) return LOG_AUTHPRIV; - if (strcaseeq(name, "cron")) return LOG_CRON; - if (strcaseeq(name, "daemon")) return LOG_DAEMON; - if (strcaseeq(name, "ftp")) return LOG_FTP; - if (strcaseeq(name, "install")) return LOG_INSTALL; - if (strcaseeq(name, "kern")) return LOG_KERN; - if (strcaseeq(name, "lpr")) return LOG_LPR; - if (strcaseeq(name, "mail")) return LOG_MAIL; - if (strcaseeq(name, "netinfo")) return LOG_NETINFO; - if (strcaseeq(name, "remoteauth")) return LOG_REMOTEAUTH; - if (strcaseeq(name, "news")) return LOG_NEWS; - if (strcaseeq(name, "security")) return LOG_AUTH; - if (strcaseeq(name, "syslog")) return LOG_SYSLOG; - if (strcaseeq(name, "user")) return LOG_USER; - if (strcaseeq(name, "uucp")) return LOG_UUCP; - if (strcaseeq(name, "local0")) return LOG_LOCAL0; - if (strcaseeq(name, "local1")) return LOG_LOCAL1; - if (strcaseeq(name, "local2")) return LOG_LOCAL2; - if (strcaseeq(name, "local3")) return LOG_LOCAL3; - if (strcaseeq(name, "local4")) return LOG_LOCAL4; - if (strcaseeq(name, "local5")) return LOG_LOCAL5; - if (strcaseeq(name, "local6")) return LOG_LOCAL6; - if (strcaseeq(name, "local7")) return LOG_LOCAL7; - if (strcaseeq(name, "launchd")) return LOG_LAUNCHD; - - return -1; -} - -const char * -asl_syslog_faciliy_num_to_name(int n) -{ - if (n < 0) return NULL; - - if (n == LOG_AUTH) return "auth"; - if (n == LOG_AUTHPRIV) return "authpriv"; - if (n == LOG_CRON) return "cron"; - if (n == LOG_DAEMON) return "daemon"; - if (n == LOG_FTP) return "ftp"; - if (n == LOG_INSTALL) return "install"; - if (n == LOG_KERN) return "kern"; - if (n == LOG_LPR) return "lpr"; - if (n == LOG_MAIL) return "mail"; - if (n == LOG_NETINFO) return "netinfo"; - if (n == LOG_REMOTEAUTH) return "remoteauth"; - if (n == LOG_NEWS) return "news"; - if (n == LOG_AUTH) return "security"; - if (n == LOG_SYSLOG) return "syslog"; - if (n == LOG_USER) return "user"; - if (n == LOG_UUCP) return "uucp"; - if (n == LOG_LOCAL0) return "local0"; - if (n == LOG_LOCAL1) return "local1"; - if (n == LOG_LOCAL2) return "local2"; - if (n == LOG_LOCAL3) return "local3"; - if (n == LOG_LOCAL4) return "local4"; - if (n == LOG_LOCAL5) return "local5"; - if (n == LOG_LOCAL6) return "local6"; - if (n == LOG_LOCAL7) return "local7"; - if (n == LOG_LAUNCHD) return "launchd"; - - return NULL; -} - -/* - * utility for converting a time string into a time_t - * we only deal with the following formats: - * Canonical form YYYY.MM.DD hh:mm:ss UTC - * ctime() form Mth dd hh:mm:ss (e.g. Aug 25 09:54:37) - * absolute form - # seconds since the epoch (e.g. 1095789191) - * relative time - seconds before or after now (e.g. -300, +43200) - * relative time - days/hours/minutes/seconds before or after now (e.g. -1d, +6h, +30m, -10s) - */ - -#define CANONICAL_TIME_REX "^[0-9][0-9][0-9][0-9].[01]?[0-9].[0-3]?[0-9][ ]+[0-2]?[0-9]:[0-5][0-9]:[0-5][0-9][ ]+UTC$" -#define CTIME_REX "^[adfjmnos][aceopu][bcglnprtvy][ ]+[0-3]?[0-9][ ]+[0-2]?[0-9]:[0-5][0-9]:[0-5][0-9]$" -#define ABSOLUTE_TIME_REX "^[0-9]+[s]?$" -#define RELATIVE_TIME_REX "^[\\+-\\][0-9]+[smhdw]?$" - -#define SECONDS_PER_MINUTE 60 -#define SECONDS_PER_HOUR 3600 -#define SECONDS_PER_DAY 86400 -#define SECONDS_PER_WEEK 604800 - -static regex_t rex_canon, rex_ctime, rex_abs, rex_rel; -static int reg_status = 0; - -/* - * We use the last letter in the month name to determine - * the month number (0-11). There are two collisions: - * Jan and Jun both end in n - * Mar and Apr both end in r - * In these cases we check the second letter. - * - * The MTH_LAST array maps the last letter to a number. - */ -static const int8_t MTH_LAST[] = {-1, 1, 11, -1, -1, -1, 7, -1, -1, -1, -1, 6, -1, 5, -1, 8, -1, 3, -1, 9, -1, 10, -1, -1, 4, -1}; - -static int -_month_num(char *s) -{ - int i; - int8_t v8; - - v8 = -1; - if (s[2] > 90) v8 = s[2] - 'a'; - else v8 = s[2] - 'A'; - - if ((v8 < 0) || (v8 > 25)) return -1; - - v8 = MTH_LAST[v8]; - if (v8 < 0) return -1; - - i = v8; - if ((i == 5) && ((s[1] == 'a') || (s[1] == 'A'))) return 0; - if ((i == 3) && ((s[1] == 'a') || (s[1] == 'A'))) return 2; - return i; -} - -time_t -asl_parse_time(const char *in) -{ - int len, y; - struct tm t; - time_t tick, delta, factor; - char *str, *p, *x; - static dispatch_once_t once; - - if (in == NULL) return -1; - - dispatch_once(&once, ^{ - int status; - int rflags = REG_EXTENDED | REG_NOSUB | REG_ICASE; - - memset(&rex_canon, 0, sizeof(regex_t)); - status = regcomp(&rex_canon, CANONICAL_TIME_REX, rflags); - if (status != 0) reg_status = -1; - - memset(&rex_ctime, 0, sizeof(regex_t)); - status = regcomp(&rex_ctime, CTIME_REX, rflags); - if (status != 0) reg_status = -1; - - memset(&rex_abs, 0, sizeof(regex_t)); - status = regcomp(&rex_abs, ABSOLUTE_TIME_REX, rflags); - if (status != 0) reg_status = -1; - - memset(&rex_rel, 0, sizeof(regex_t)); - status = regcomp(&rex_rel, RELATIVE_TIME_REX, rflags); - if (status != 0) reg_status = -1; - }); - - if (reg_status < 0) return -1; - - len = strlen(in) + 1; - - if (regexec(&rex_abs, in, 0, NULL, 0) == 0) - { - /* - * Absolute time (number of seconds since the epoch) - */ - str = strdup(in); - if (str == NULL) return -1; - - if ((str[len-2] == 's') || (str[len-2] == 'S')) str[len-2] = '\0'; - - tick = atol(str); - free(str); - - return tick; - } - else if (regexec(&rex_rel, in, 0, NULL, 0) == 0) - { - /* - * Reletive time (number of seconds before or after right now) - */ - str = strdup(in); - if (str == NULL) return -1; - - factor = 1; - - if ((str[len-2] == 's') || (str[len-2] == 'S')) - { - str[len-2] = '\0'; - } - else if ((str[len-2] == 'm') || (str[len-2] == 'M')) - { - str[len-2] = '\0'; - factor = SECONDS_PER_MINUTE; - } - else if ((str[len-2] == 'h') || (str[len-2] == 'H')) - { - str[len-2] = '\0'; - factor = SECONDS_PER_HOUR; - } - else if ((str[len-2] == 'd') || (str[len-2] == 'D')) - { - str[len-2] = '\0'; - factor = SECONDS_PER_DAY; - } - else if ((str[len-2] == 'w') || (str[len-2] == 'W')) - { - str[len-2] = '\0'; - factor = SECONDS_PER_WEEK; - } - - tick = time(NULL); - delta = factor * atol(str); - tick += delta; - - free(str); - - return tick; - } - else if (regexec(&rex_canon, in, 0, NULL, 0) == 0) - { - memset(&t, 0, sizeof(struct tm)); - str = strdup(in); - if (str == NULL) return -1; - - /* Get year */ - x = str; - p = strchr(x, '.'); - *p = '\0'; - t.tm_year = atoi(x) - 1900; - - /* Get month */ - x = p + 1; - p = strchr(x, '.'); - *p = '\0'; - t.tm_mon = atoi(x) - 1; - - /* Get day */ - x = p + 1; - p = strchr(x, ' '); - *p = '\0'; - t.tm_mday = atoi(x); - - /* Get hour */ - for (x = p + 1; *x == ' '; x++); - p = strchr(x, ':'); - *p = '\0'; - t.tm_hour = atoi(x); - - /* Get minutes */ - x = p + 1; - p = strchr(x, ':'); - *p = '\0'; - t.tm_min = atoi(x); - - /* Get seconds */ - x = p + 1; - p = strchr(x, ' '); - *p = '\0'; - t.tm_sec = atoi(x); - - free(str); - return timegm(&t); - } - else if (regexec(&rex_ctime, in, 0, NULL, 0) == 0) - { - /* We assume it's in the current year */ - memset(&t, 0, sizeof(struct tm)); - tick = time(NULL); - gmtime_r(&tick, &t); - y = t.tm_year; - - memset(&t, 0, sizeof(struct tm)); - str = strdup(in); - if (str == NULL) return -1; - - t.tm_year = y; - t.tm_mon = _month_num(str); - if (t.tm_mon < 0) return -1; - - for (x = strchr(str, ' '); *x == ' '; x++); - p = strchr(x, ' '); - *p = '\0'; - t.tm_mday = atoi(x); - - /* Get hour */ - for (x = p + 1; *x == ' '; x++); - p = strchr(x, ':'); - *p = '\0'; - t.tm_hour = atoi(x); - - /* Get minutes */ - x = p + 1; - p = strchr(x, ':'); - *p = '\0'; - t.tm_min = atoi(x); - - /* Get seconds */ - x = p + 1; - t.tm_sec = atoi(x); - - t.tm_isdst = -1; - - free(str); - return mktime(&t); - } - - return -1; -} - -#endif /* BUILDING_VARIANT */ diff --git a/src/libc/gen/asl_core.c b/src/libc/gen/asl_core.c deleted file mode 100644 index 29e132d07..000000000 --- a/src/libc/gen/asl_core.c +++ /dev/null @@ -1,894 +0,0 @@ -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define ASL_STRING_QUANTUM 256 -static const char *cvis_7_13 = "abtnvfr"; - -/* - * Message ID generation - */ -static uint64_t _asl_core_msg_next_id = 1; -static pthread_mutex_t core_lock = PTHREAD_MUTEX_INITIALIZER; - -#define mix(a, b, c) \ -{ \ - a -= b; a -= c; a ^= (c>>13); \ - b -= c; b -= a; b ^= (a<< 8); \ - c -= a; c -= b; c ^= (b>>13); \ - a -= b; a -= c; a ^= (c>>12); \ - b -= c; b -= a; b ^= (a<<16); \ - c -= a; c -= b; c ^= (b>> 5); \ - a -= b; a -= c; a ^= (c>> 3); \ - b -= c; b -= a; b ^= (a<<10); \ - c -= a; c -= b; c ^= (b>>15); \ -} - -/* - * Hash is used to improve string search. - */ -uint32_t -asl_core_string_hash(const char *s, uint32_t inlen) -{ - uint32_t a, b, c, l, len; - - if (s == NULL) return 0; - - l = inlen; - if (l == 0) - { - if (s[0] == '\0') return 0; - l = strlen(s); - } - - len = l; - a = b = 0x9e3779b9; - c = 0; - - while (len >= 12) - { - a += (s[0] + ((uint32_t)s[1]<<8) + ((uint32_t)s[ 2]<<16) + ((uint32_t)s[ 3]<<24)); - b += (s[4] + ((uint32_t)s[5]<<8) + ((uint32_t)s[ 6]<<16) + ((uint32_t)s[ 7]<<24)); - c += (s[8] + ((uint32_t)s[9]<<8) + ((uint32_t)s[10]<<16) + ((uint32_t)s[11]<<24)); - - mix(a, b, c); - - s += 12; - len -= 12; - } - - c += l; - switch(len) - { - case 11: c += ((uint32_t)s[10]<<24); - case 10: c += ((uint32_t)s[9]<<16); - case 9 : c += ((uint32_t)s[8]<<8); - - case 8 : b += ((uint32_t)s[7]<<24); - case 7 : b += ((uint32_t)s[6]<<16); - case 6 : b += ((uint32_t)s[5]<<8); - case 5 : b += s[4]; - - case 4 : a += ((uint32_t)s[3]<<24); - case 3 : a += ((uint32_t)s[2]<<16); - case 2 : a += ((uint32_t)s[1]<<8); - case 1 : a += s[0]; - } - - mix(a, b, c); - - if (c == 0) c = 1; - return c; -} - -const char * -asl_core_error(uint32_t code) -{ - switch (code) - { - case ASL_STATUS_OK: return "Operation Succeeded"; - case ASL_STATUS_INVALID_ARG: return "Invalid Argument"; - case ASL_STATUS_INVALID_STORE: return "Invalid Data Store"; - case ASL_STATUS_INVALID_STRING: return "Invalid String"; - case ASL_STATUS_INVALID_ID: return "Invalid ID Number"; - case ASL_STATUS_INVALID_MESSAGE: return "Invalid Message"; - case ASL_STATUS_NOT_FOUND: return "Not Found"; - case ASL_STATUS_READ_FAILED: return "Read Operation Failed"; - case ASL_STATUS_WRITE_FAILED: return "Write Operation Failed"; - case ASL_STATUS_NO_MEMORY: return "System Memory Allocation Failed"; - case ASL_STATUS_ACCESS_DENIED: return "Access Denied"; - case ASL_STATUS_READ_ONLY: return "Read Only Access"; - case ASL_STATUS_WRITE_ONLY: return "Write Only Access"; - case ASL_STATUS_MATCH_FAILED: return "Match Failed"; - case ASL_STATUS_NO_RECORDS: return "No More Records"; - } - - return "Operation Failed"; -} - -static uint32_t -asl_core_check_user_access(int32_t msgu, int32_t readu) -{ - /* -1 means anyone may read */ - if (msgu == -1) return ASL_STATUS_OK; - - /* Check for exact match */ - if (msgu == readu) return ASL_STATUS_OK; - - return ASL_STATUS_ACCESS_DENIED; -} - -static uint32_t -asl_core_check_group_access(int32_t msgg, int32_t readu, int32_t readg) -{ - int check; - uuid_t uu, gu; - - /* -1 means anyone may read */ - if (msgg == -1) return ASL_STATUS_OK; - - /* Check for exact match */ - if (msgg == readg) return ASL_STATUS_OK; - - /* Check if user (u) is in read group (msgg) */ - mbr_uid_to_uuid(readu, uu); - mbr_gid_to_uuid(msgg, gu); - - check = 0; - mbr_check_membership(uu, gu, &check); - if (check != 0) return ASL_STATUS_OK; - - return ASL_STATUS_ACCESS_DENIED; -} - -uint32_t -asl_core_check_access(int32_t msgu, int32_t msgg, int32_t readu, int32_t readg, uint16_t flags) -{ - uint16_t uset, gset; - - /* root (uid 0) may always read */ - if (readu == 0) return ASL_STATUS_OK; - - uset = flags & ASL_MSG_FLAG_READ_UID_SET; - gset = flags & ASL_MSG_FLAG_READ_GID_SET; - - /* if no access controls are set, anyone may read */ - if ((uset | gset) == 0) return ASL_STATUS_OK; - - /* if only uid is set, then access is only by uid match */ - if ((uset != 0) && (gset == 0)) return asl_core_check_user_access(msgu, readu); - - /* if only gid is set, then access is only by gid match */ - if ((uset == 0) && (gset != 0)) return asl_core_check_group_access(msgg, readu, readg); - - /* both uid and gid are set - check user, then group */ - if ((asl_core_check_user_access(msgu, readu)) == ASL_STATUS_OK) return ASL_STATUS_OK; - return asl_core_check_group_access(msgg, readu, readg); -} - -uint64_t -asl_core_htonq(uint64_t n) -{ -#ifdef __BIG_ENDIAN__ - return n; -#else - u_int32_t t; - union - { - u_int64_t q; - u_int32_t l[2]; - } x; - - x.q = n; - t = x.l[0]; - x.l[0] = htonl(x.l[1]); - x.l[1] = htonl(t); - - return x.q; -#endif -} - -uint64_t -asl_core_ntohq(uint64_t n) -{ -#ifdef __BIG_ENDIAN__ - return n; -#else - u_int32_t t; - union - { - u_int64_t q; - u_int32_t l[2]; - } x; - - x.q = n; - t = x.l[0]; - x.l[0] = ntohl(x.l[1]); - x.l[1] = ntohl(t); - - return x.q; -#endif -} - -uint64_t -asl_core_new_msg_id(uint64_t start) -{ - uint64_t out; - - pthread_mutex_lock(&core_lock); - - if (start != 0) _asl_core_msg_next_id = start; - - out = _asl_core_msg_next_id; - _asl_core_msg_next_id++; - - pthread_mutex_unlock(&core_lock); - - return out; -} - -/* - * asl_core_encode_buffer - * encode arbitrary data as a C string without embedded zero (nul) characters - * - * The routine computes a histogram of the input buffer and finds - * the two least frequently used non-nul chars (L[0] and L[1]). - * - * L[0] is used to stand in for nul. - * L[1] is used as the escape character. - * Occurrences of nul in the data are encoded as L[0] - * Occurrences of L[0] in the data are encoded as the sequence L[1] 1. - * Occurrences of L[1] in the data are encoded as the sequence L[1] 2. - * - * The output string is preceded by L[0] L[1], and is nul terminated. - * The output length is 2 + n + N(L[0]) + N(L[1]) + 1 - * where N(x) is the number of occurrences of x in the input string. - * The worst case occurs when all characters are equally frequent, - * In that case the output size will less that 1% larger than the input. - */ -char * -asl_core_encode_buffer(const char *in, uint32_t len) -{ - char *str; - uint32_t i, j, k, outlen, breakit, min, hist[256]; - uint32_t lfu[2], save[2]; - uint8_t v; - - if (in == NULL) return NULL; - if (len == 0) return NULL; - - memset(hist, 0, sizeof(hist)); - save[0] = 0; - save[1] = 0; - - for (i = 0; i < len; i++) - { - v = in[i]; - hist[v]++; - } - - for (j = 0; j < 2; j++) - { - lfu[j] = 1; - min = hist[1]; - - for (i = 2; i < 256; i++) - { - if (hist[i] < min) - { - lfu[j] = i; - min = hist[i]; - - /* - * Stop if there are no occurances or character i in the input. - * The minimum will never be less than zero. - */ - if (min == 0) break; - - /* - * When looking for the second least frequently used character, - * stop scanning if we hit the same minimum as we saw in the first - * pass. There will be no smaller values. - */ - if ((j == 1) && (min == save[0])) break; - } - } - - save[j] = hist[lfu[j]]; - hist[lfu[j]] = (uint32_t)-1; - } - - outlen = 2 + len + save[0] + save[1] + 1; - - str = malloc(outlen); - if (str == NULL) return NULL; - - str[outlen - 1] = '\0'; - - str[0] = lfu[0]; - str[1] = lfu[1]; - - j = 2; - - for (i = 0; i < len; i++) - { - v = in[i]; - if (v == 0) - { - str[j++] = lfu[0]; - continue; - } - - breakit = 0; - for (k = 0; (k < 2) && (breakit == 0); k++) - { - if (v == lfu[k]) - { - str[j++] = lfu[1]; - str[j++] = k + 1; - breakit = 1; - } - } - - if (breakit == 1) continue; - - str[j++] = v; - } - - return str; -} - -/* - * asl_core_decode_buffer - * decode a string produced by asl_encode_buffer to recreate the original data - */ -int32_t -asl_core_decode_buffer(const char *in, char **buf, uint32_t *len) -{ - uint8_t v; - uint32_t i, j, n, outlen; - uint8_t lfu[2]; - char *out; - - if (buf == NULL) return -1; - if (len == NULL) return -1; - - lfu[0] = in[0]; - lfu[1] = in[1]; - - outlen = 0; - - /* strip trailing nul */ - n = strlen(in); - - /* determine output length and check for invalid input */ - for (i = 2; i < n; i++) - { - v = in[i]; - if (v == lfu[1]) - { - i++; - if (i == n) return -1; - - v = in[i]; - if ((v < 1) || (v > 2)) return -1; - - outlen++; - } - else outlen++; - } - - if (outlen == 0) return -1; - - out = malloc(outlen); - if (out == NULL) return -1; - - j = 0; - for (i = 2; i < n; i++) - { - v = in[i]; - if (v == lfu[0]) - { - out[j++] = 0; - } - else if (v == lfu[1]) - { - i++; - v = in[i]; - out[j++] = lfu[v - 1]; - } - else out[j++] = v; - } - - *len = outlen; - *buf = out; - return 0; -} - -/* asl_string_t support */ - -asl_string_t * -asl_string_new(uint32_t encoding) -{ - asl_string_t *str = (asl_string_t *)calloc(1, sizeof(asl_string_t)); - if (str == NULL) return NULL; - - str->encoding = encoding; - str->delta = ASL_STRING_QUANTUM; - if (encoding & ASL_STRING_VM) str->delta = PAGE_SIZE; - str->bufsize = 0; - str->cursor = 0; - - if (encoding & ASL_STRING_LEN) asl_string_append_no_encoding(str, " 0 "); - return str; -} - -void -asl_string_free(asl_string_t *str) -{ - if (str == NULL) return; - - if (str->encoding & ASL_STRING_VM) - { - vm_deallocate(mach_task_self(), (vm_address_t)str->buf, str->bufsize); - } - else - { - free(str->buf); - } - - free(str); -} - -char * -asl_string_free_return_bytes(asl_string_t *str) -{ - char *out; - if (str == NULL) return NULL; - - out = str->buf; - free(str); - return out; -} - -char * -asl_string_bytes(asl_string_t *str) -{ - if (str == NULL) return NULL; - return str->buf; -} - -/* length includes trailing nul */ -size_t -asl_string_length(asl_string_t *str) -{ - if (str == NULL) return 0; - if (str->cursor == 0) return 0; - - return str->cursor + 1; -} - -size_t -asl_string_allocated_size(asl_string_t *str) -{ - if (str == NULL) return 0; - return str->bufsize; -} - -static int -_asl_string_grow(asl_string_t *str, size_t len) -{ - size_t newlen = 0; - - if (str == NULL) return -1; - if (len == 0) return 0; - - if (str->bufsize == 0) - { - newlen = ((len + str->delta - 1) / str->delta) * str->delta; - } - else - { - /* used size is (str->cursor + 1) including tailiing nul */ - if (len <= (str->bufsize - (str->cursor + 1))) return 0; - - /* really this is ((str->cursor + 1) + len + (str->delta - 1)) */ - newlen = ((str->cursor + len + str->delta) / str->delta) * str->delta; - } - - if (str->encoding & ASL_STRING_VM) - { - kern_return_t kstatus; - vm_address_t new = 0; - - kstatus = vm_allocate(mach_task_self(), &new, newlen, TRUE); - if (kstatus != KERN_SUCCESS) - { - new = 0; - newlen = 0; - return -1; - } - - if (str->buf != NULL) - { - memcpy((void *)new, str->buf, str->bufsize); - vm_deallocate(mach_task_self(), (vm_address_t)str->buf, str->bufsize); - } - - str->buf = (char *)new; - str->bufsize = newlen; - } - else - { - str->buf = reallocf(str->buf, newlen); - if (str->buf == NULL) - { - str->cursor = 0; - str->bufsize = 0; - return -1; - } - - str->bufsize = newlen; - } - - return 0; -} - -asl_string_t * -asl_string_append_char_no_encoding(asl_string_t *str, const char c) -{ - size_t len; - - if (str == NULL) return NULL; - - len = 1; - if (str->bufsize == 0) len++; - - if (_asl_string_grow(str, len) < 0) return str; - - str->buf[str->cursor] = c; - str->cursor++; - str->buf[str->cursor] = '\0'; - - if (str->encoding & ASL_STRING_LEN) - { - char tmp[11]; - snprintf(tmp, sizeof(tmp), "%10lu", str->cursor - 10); - memcpy(str->buf, tmp, 10); - } - - return str; -} - -asl_string_t * -asl_string_append_no_encoding(asl_string_t *str, const char *app) -{ - size_t len, applen; - - if (str == NULL) return NULL; - if (app == NULL) return str; - - applen = strlen(app); - len = applen; - if (str->bufsize == 0) len++; - - if (_asl_string_grow(str, len) < 0) return str; - - memcpy(str->buf + str->cursor, app, applen); - - str->cursor += applen; - str->buf[str->cursor] = '\0'; - - if (str->encoding & ASL_STRING_LEN) - { - char tmp[11]; - snprintf(tmp, sizeof(tmp), "%10lu", str->cursor - 10); - memcpy(str->buf, tmp, 10); - } - - return str; -} - -static asl_string_t * -asl_string_append_internal(asl_string_t *str, const char *app, int encode_space) -{ - uint8_t x; - const char *p; - - if (str == NULL) return NULL; - if (app == NULL) return str; - - switch (str->encoding & ASL_ENCODE_MASK) - { - case ASL_ENCODE_NONE: - { - return asl_string_append_no_encoding(str, app); - } - case ASL_ENCODE_SAFE: - { - /* minor encoding to reduce the likelyhood of spoof attacks */ - const char *p; - - for (p = app; *p != '\0'; p++) - { - if ((*p == 10) || (*p == 13)) - { - asl_string_append_no_encoding(str, "\n\t"); - } - else if (*p == 8) - { - asl_string_append_no_encoding(str, "^H"); - } - else - { - asl_string_append_char_no_encoding(str, *p); - } - } - - return str; - } - case ASL_ENCODE_ASL: - { - for (p = app; *p != '\0'; p++) - { - int meta = 0; - - x = *p; - - /* Meta chars get \M prefix */ - if (x >= 128) - { - /* except meta-space, which is \240 */ - if (x == 160) - { - asl_string_append_no_encoding(str, "\\240"); - continue; - } - - asl_string_append_no_encoding(str, "\\M"); - x &= 0x7f; - meta = 1; - } - - /* space is either ' ' or \s */ - if (x == 32) - { - if (encode_space == 0) - { - asl_string_append_char_no_encoding(str, ' '); - continue; - } - - asl_string_append_no_encoding(str, "\\s"); - continue; - } - - /* \ is escaped */ - if ((meta == 0) && (x == 92)) - { - asl_string_append_no_encoding(str, "\\\\"); - continue; - } - - /* [ and ] are escaped in ASL encoding */ - if ((str->encoding & ASL_ENCODE_ASL) && (meta == 0) && ((*p == 91) || (*p == 93))) - { - if (*p == '[') asl_string_append_no_encoding(str, "\\["); - else asl_string_append_no_encoding(str, "\\]"); - continue; - } - - /* DEL is \^? */ - if (x == 127) - { - if (meta == 0) - { - asl_string_append_char_no_encoding(str, '\\'); - } - - asl_string_append_no_encoding(str, "^?"); - continue; - } - - /* 33-126 are printable (add a '-' prefix for meta) */ - if ((x >= 33) && (x <= 126)) - { - if (meta == 1) - { - asl_string_append_char_no_encoding(str, '-'); - } - - asl_string_append_char_no_encoding(str, x); - continue; - } - - /* non-meta BEL, BS, HT, NL, VT, NP, CR (7-13) are \a, \b, \t, \n, \v, \f, and \r */ - if ((meta == 0) && (x >= 7) && (x <= 13)) - { - asl_string_append_char_no_encoding(str, '\\'); - asl_string_append_char_no_encoding(str, cvis_7_13[x - 7]); - continue; - } - - /* 0 - 31 are ^@ - ^_ (non-meta get a leading \) */ - if (x <= 31) - { - if (meta == 0) - { - asl_string_append_char_no_encoding(str, '\\'); - } - - asl_string_append_char_no_encoding(str, '^'); - asl_string_append_char_no_encoding(str, 64 + x); - continue; - } - - asl_string_append_char_no_encoding(str, x); - } - - return str; - } - case ASL_ENCODE_XML: - { - for (p = app; *p != '\0'; p++) - { - x = *p; - - if (x == '&') - { - asl_string_append_no_encoding(str, "&"); - } - else if (x == '<') - { - asl_string_append_no_encoding(str, "<"); - } - else if (x == '>') - { - asl_string_append_no_encoding(str, ">"); - } - else if (x == '"') - { - asl_string_append_no_encoding(str, """); - } - else if (x == '\'') - { - asl_string_append_no_encoding(str, "'"); - } - else if (iscntrl(x)) - { - char tmp[8]; - snprintf(tmp, sizeof(tmp), "&#x%02hhx;", x); - asl_string_append_no_encoding(str, tmp); - } - else - { - asl_string_append_char_no_encoding(str, x); - } - } - } - default: - { - return str; - } - } - - return str; -} - -asl_string_t * -asl_string_append(asl_string_t *str, const char *app) -{ - return asl_string_append_internal(str, app, 0); -} - -asl_string_t * -asl_string_append_asl_key(asl_string_t *str, const char *app) -{ - return asl_string_append_internal(str, app, 1); -} - -asl_string_t * -asl_string_append_op(asl_string_t *str, uint32_t op) -{ - char opstr[8]; - uint32_t i; - - if (str == NULL) return NULL; - - if (op == ASL_QUERY_OP_NULL) - { - return asl_string_append_char_no_encoding(str, '.'); - } - - i = 0; - if (op & ASL_QUERY_OP_CASEFOLD) opstr[i++] = 'C'; - - if (op & ASL_QUERY_OP_REGEX) opstr[i++] = 'R'; - - if (op & ASL_QUERY_OP_NUMERIC) opstr[i++] = 'N'; - - if (op & ASL_QUERY_OP_PREFIX) - { - if (op & ASL_QUERY_OP_SUFFIX) opstr[i++] = 'S'; - else opstr[i++] = 'A'; - } - if (op & ASL_QUERY_OP_SUFFIX) opstr[i++] = 'Z'; - - switch (op & ASL_QUERY_OP_TRUE) - { - case ASL_QUERY_OP_EQUAL: - opstr[i++] = '='; - break; - case ASL_QUERY_OP_GREATER: - opstr[i++] = '>'; - break; - case ASL_QUERY_OP_GREATER_EQUAL: - opstr[i++] = '>'; - opstr[i++] = '='; - break; - case ASL_QUERY_OP_LESS: - opstr[i++] = '<'; - break; - case ASL_QUERY_OP_LESS_EQUAL: - opstr[i++] = '<'; - opstr[i++] = '='; - break; - case ASL_QUERY_OP_NOT_EQUAL: - opstr[i++] = '!'; - break; - case ASL_QUERY_OP_TRUE: - opstr[i++] = 'T'; - break; - default: - break; - } - - if (i == 0) - { - return asl_string_append_char_no_encoding(str, '.'); - } - - opstr[i] = '\0'; - return asl_string_append_no_encoding(str, opstr); -} - -asl_string_t * -asl_string_append_xml_tag(asl_string_t *str, const char *tag, const char *s) -{ - asl_string_append_no_encoding(str, "\t\t<"); - asl_string_append_no_encoding(str, tag); - asl_string_append_no_encoding(str, ">"); - asl_string_append_no_encoding(str, s); - asl_string_append_no_encoding(str, "\n"); - return str; -} diff --git a/src/libc/gen/asl_core.h b/src/libc/gen/asl_core.h deleted file mode 100644 index fdd5edbba..000000000 --- a/src/libc/gen/asl_core.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef __ASL_CORE_H__ -#define __ASL_CORE_H__ - -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -typedef struct -{ - uint32_t encoding; - size_t delta; - size_t bufsize; - size_t cursor; - char *buf; -} asl_string_t; - -#define ASL_STATUS_OK 0 -#define ASL_STATUS_INVALID_ARG 1 -#define ASL_STATUS_INVALID_STORE 2 -#define ASL_STATUS_INVALID_STRING 3 -#define ASL_STATUS_INVALID_ID 4 -#define ASL_STATUS_INVALID_MESSAGE 5 -#define ASL_STATUS_NOT_FOUND 6 -#define ASL_STATUS_READ_FAILED 7 -#define ASL_STATUS_WRITE_FAILED 8 -#define ASL_STATUS_NO_MEMORY 9 -#define ASL_STATUS_ACCESS_DENIED 10 -#define ASL_STATUS_READ_ONLY 11 -#define ASL_STATUS_WRITE_ONLY 12 -#define ASL_STATUS_MATCH_FAILED 13 -#define ASL_STATUS_NO_RECORDS 14 -#define ASL_STATUS_FAILED 9999 - -#define ASL_REF_NULL 0xffffffffffffffffLL - -#define ASL_MSG_FLAG_READ_UID_SET 0x0001 -#define ASL_MSG_FLAG_READ_GID_SET 0x0002 -#define ASL_MSG_FLAG_SEARCH_MATCH 0x8000 -#define ASL_MSG_FLAG_SEARCH_CLEAR 0x7fff - -#define ASL_QUERY_MATCH_SLOW 0x00000000 -#define ASL_QUERY_MATCH_MSG_ID 0x00000001 -#define ASL_QUERY_MATCH_TIME 0x00000002 -#define ASL_QUERY_MATCH_NANO 0x00000004 -#define ASL_QUERY_MATCH_LEVEL 0x00000008 -#define ASL_QUERY_MATCH_PID 0x00000010 -#define ASL_QUERY_MATCH_UID 0x00000020 -#define ASL_QUERY_MATCH_GID 0x00000040 -#define ASL_QUERY_MATCH_RUID 0x00000080 -#define ASL_QUERY_MATCH_RGID 0x00000100 -#define ASL_QUERY_MATCH_REF_PID 0x00000200 -#define ASL_QUERY_MATCH_HOST 0x00000400 -#define ASL_QUERY_MATCH_SENDER 0x00000800 -#define ASL_QUERY_MATCH_FACILITY 0x00001000 -#define ASL_QUERY_MATCH_MESSAGE 0x00002000 -#define ASL_QUERY_MATCH_REF_PROC 0x00004000 -#define ASL_QUERY_MATCH_SESSION 0x00008000 -#define ASL_QUERY_MATCH_TRUE 0x80000000 -#define ASL_QUERY_MATCH_FALSE 0x40000000 -#define ASL_QUERY_MATCH_ERROR 0x20000000 - -#define ASL_ENCODE_NONE 0 -#define ASL_ENCODE_SAFE 1 -#define ASL_ENCODE_ASL 2 -#define ASL_ENCODE_XML 3 -#define ASL_ENCODE_MASK 0x0000000f -#define ASL_STRING_VM 0x80000000 -#define ASL_STRING_LEN 0x40000000 - -#define ASL_STRING_MIG 0xc0000002 - -uint32_t asl_core_string_hash(const char *str, uint32_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -const char *asl_core_error(uint32_t code) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_core_check_access(int32_t msgu, int32_t msgg, int32_t readu, int32_t readg, uint16_t flags) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint64_t asl_core_htonq(uint64_t n) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint64_t asl_core_ntohq(uint64_t n)__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint64_t asl_core_new_msg_id(uint64_t start) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -char *asl_core_encode_buffer(const char *in, uint32_t len) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0); -int32_t asl_core_decode_buffer(const char *in, char **buf, uint32_t *len) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0); - -asl_string_t *asl_string_new(uint32_t encoding) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -char *asl_string_free_return_bytes(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -void asl_string_free(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -char *asl_string_bytes(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -size_t asl_string_length(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -size_t asl_string_allocated_size(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -asl_string_t *asl_string_append(asl_string_t *str, const char *app) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -asl_string_t *asl_string_append_asl_key(asl_string_t *str, const char *app) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -asl_string_t *asl_string_append_op(asl_string_t *str, uint32_t op) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -asl_string_t *asl_string_append_no_encoding(asl_string_t *str, const char *app) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -asl_string_t *asl_string_append_char_no_encoding(asl_string_t *str, const char c) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -asl_string_t *asl_string_append_xml_tag(asl_string_t *str, const char *tag, const char *s) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); - -#endif /* __ASL_CORE_H__ */ diff --git a/src/libc/gen/asl_fd.c b/src/libc/gen/asl_fd.c deleted file mode 100644 index 74e38380b..000000000 --- a/src/libc/gen/asl_fd.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* asl.c */ -__private_extern__ void asl_client_release(asl_client_t *asl); -__private_extern__ asl_client_t *asl_client_retain(asl_client_t *asl); - -#define BUF_SIZE 512 - -static dispatch_queue_t redirect_serial_q; -static dispatch_group_t read_source_group; - -typedef struct { - int level; - asl_client_t *asl; - asl_msg_t *msg; - - /* Buffered reading */ - char *buf; - char *w; - - dispatch_source_t read_source; -} asl_redirect_t; - -static asl_redirect_t *redirect_descriptors = NULL; -static int n_redirect_descriptors = 0; - -/* Read from the FD until there is no more to read and redirect to ASL. - * Preconditions: - * 1: called from the appropriate serial queue for operating on - * redirect_descriptors - * 2: descriptor corresponds to a valid entry in redirect_descriptors - * - * Return values: - * If the pipe is closed, EOF is returned regardless of how many bytes - * were processed. If the pipe is still open, the number of read bytes - * is returned. - */ -static inline int _read_redirect(int descriptor, int flush) { - int total_read = 0; - int nbytes; - asl_redirect_t *aslr = &redirect_descriptors[descriptor]; - - while ((nbytes = read(descriptor, aslr->w, BUF_SIZE - (aslr->w - aslr->buf) - 1)) > 0) { - char *s, *p; - - /* Increment our returned number read */ - total_read += nbytes; - - nbytes += (aslr->w - aslr->buf); - aslr->buf[nbytes] = '\0'; - - /* One line at a time */ - for (p=aslr->buf; *p && (p - aslr->buf) < nbytes; p = s + 1) { - // Find null or \n - for (s=p; *s && *s != '\n'; s++); - if (*s == '\n') { - *s='\0'; - asl_log((aslclient)aslr->asl, (aslmsg)aslr->msg, aslr->level, "%s", p); - } else if (aslr->buf != p) { - memmove(aslr->buf, p, BUF_SIZE - (p - aslr->buf)); - aslr->w = aslr->buf + (s - p); - break; - } else if (nbytes == BUF_SIZE - 1) { - asl_log((aslclient)aslr->asl, (aslmsg)aslr->msg, aslr->level, "%s", p); - aslr->w = aslr->buf; - break; - } - } - } - - /* Flush if requested or we're at EOF */ - if (flush || nbytes == 0) { - if (aslr->w > aslr->buf) { - *aslr->w = '\0'; - asl_log((aslclient)aslr->asl, (aslmsg)aslr->msg, aslr->level, "%s", aslr->buf); - } - } - - if (nbytes == 0) - return EOF; - return total_read; -} - -static void read_from_source(void *_source) { - dispatch_source_t source = (dispatch_source_t)_source; - int descriptor = dispatch_source_get_handle(source); - if (_read_redirect(descriptor, 0) == EOF) { - dispatch_source_cancel(source); - } -} - -static void cancel_source(void *_source) { - dispatch_source_t source = (dispatch_source_t)_source; - int descriptor = dispatch_source_get_handle(source); - asl_redirect_t *aslr = &redirect_descriptors[descriptor]; - - /* Flush the buffer */ - _read_redirect(descriptor, 1); - - close(descriptor); - - asl_client_release(aslr->asl); - asl_msg_release(aslr->msg); - free(aslr->buf); - - memset(aslr, 0, sizeof(*aslr)); - dispatch_release(source); - dispatch_group_leave(read_source_group); -} - - -static void redirect_atexit(void) { - int i; - - /* stdout is linebuffered, so flush the buffer */ - if (redirect_descriptors[STDOUT_FILENO].buf) - fflush(stdout); - - /* Cancel all of our dispatch sources, so they flush to ASL */ - for (i=0; i < n_redirect_descriptors; i++) - if (redirect_descriptors[i].read_source) - dispatch_source_cancel(redirect_descriptors[i].read_source); - - /* Wait at least three seconds for our sources to flush to ASL */ - dispatch_group_wait(read_source_group, dispatch_time(DISPATCH_TIME_NOW, 3LL * NSEC_PER_SEC)); -} - -static void asl_descriptor_init(void *ctx __unused) -{ - assert((redirect_descriptors = calloc(16, sizeof(*redirect_descriptors))) != NULL); - n_redirect_descriptors = 16; - - redirect_serial_q = dispatch_queue_create("com.apple.asl-redirect", NULL); - assert(redirect_serial_q != NULL); - - read_source_group = dispatch_group_create(); - assert(read_source_group != NULL); - - atexit(redirect_atexit); -} - -static int asl_log_from_descriptor(aslclient ac, aslmsg am, int level, int descriptor) { - int err __block = 0; - static dispatch_once_t once_control; - dispatch_once_f(&once_control, NULL, asl_descriptor_init); - asl_client_t *asl = (asl_client_t *)ac; - asl_msg_t *msg = (asl_msg_t *)am; - - if (descriptor < 0) - return EBADF; - - if (msg != NULL) { - msg = asl_msg_copy(msg); - if (msg == NULL) - return ENOMEM; - } - - dispatch_sync(redirect_serial_q, ^{ - dispatch_source_t read_source; - - /* Reallocate if we need more space */ - if (descriptor >= n_redirect_descriptors) { - size_t new_n = 1 << (ffs(descriptor) + 1); - asl_redirect_t *new_array = realloc(redirect_descriptors, new_n * sizeof(*redirect_descriptors)); - if (!new_array) { - err = errno; - return; - } - redirect_descriptors = new_array; - memset(redirect_descriptors + n_redirect_descriptors, 0, new_n - n_redirect_descriptors); - n_redirect_descriptors = new_n; - } - - /* If we're already listening on it, return error. */ - if (redirect_descriptors[descriptor].buf != NULL) { - err = EBADF; - return; - } - - /* Initialize our buffer */ - redirect_descriptors[descriptor].buf = (char *)malloc(BUF_SIZE); - if (redirect_descriptors[descriptor].buf == NULL) { - err = errno; - return; - } - redirect_descriptors[descriptor].w = redirect_descriptors[descriptor].buf; - - /* Store our ASL settings */ - redirect_descriptors[descriptor].level = level; - redirect_descriptors[descriptor].asl = asl_client_retain(asl); - redirect_descriptors[descriptor].msg = msg; - - /* Don't block on reads from this descriptor */ - (void)fcntl(descriptor, F_SETFL, O_NONBLOCK); - - /* Start listening */ - read_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, descriptor, 0, redirect_serial_q); - redirect_descriptors[descriptor].read_source = read_source; - dispatch_set_context(read_source, read_source); - dispatch_source_set_event_handler_f(read_source, read_from_source); - dispatch_source_set_cancel_handler_f(read_source, cancel_source); - dispatch_group_enter(read_source_group); - dispatch_resume(read_source); - }); - - if (err) { - asl_msg_release(msg); - } - - return err; -} - -int asl_log_descriptor(aslclient ac, aslmsg am, int level, int descriptor, uint32_t fd_type) { - int pipepair[2]; - int retval; - int oerrno = errno; - - if (fd_type == ASL_LOG_DESCRIPTOR_READ) - return asl_log_from_descriptor(ac, am, level, descriptor); - - assert(fd_type == ASL_LOG_DESCRIPTOR_WRITE); - - /* Create pipe */ - if (pipe(pipepair) == -1) { - retval = errno; - errno = oerrno; - return retval; - } - - /* Close the read descriptor but not the write descriptor on exec */ - if (fcntl(pipepair[0], F_SETFD, FD_CLOEXEC) == -1) { - retval = errno; - errno = oerrno; - return retval; - } - - /* Replace the existing descriptor */ - if (dup2(pipepair[1], descriptor) == -1) { - close(pipepair[0]); - close(pipepair[1]); - retval = errno; - errno = oerrno; - return retval; - } - - /* If we capture STDOUT_FILENO, make sure we linebuffer stdout */ - if (descriptor == STDOUT_FILENO) - setlinebuf(stdout); - - /* Close the duplicate descriptors since they've been reassigned */ - close(pipepair[1]); - - /* Hand off the read end of our pipe to asl_log_descriptor */ - return asl_log_from_descriptor(ac, am, level, pipepair[0]); -} diff --git a/src/libc/gen/asl_file.c b/src/libc/gen/asl_file.c deleted file mode 100644 index 7a8c4cbed..000000000 --- a/src/libc/gen/asl_file.c +++ /dev/null @@ -1,2136 +0,0 @@ -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern time_t asl_parse_time(const char *str); -extern int asl_msg_cmp(aslmsg a, aslmsg b); - -#define forever for(;;) -#define MILLION 1000000 - -/* - * MSG and STR records have (at least) a type (uint16_t) and a length (uint32_t) - * type and level are both 16 bit fields so that alignment isn't a pain. - */ -#define RECORD_COMMON_LEN 6 -#define RECORD_TYPE_LEN 2 -#define BUFFER_OFFSET_KVCOUNT 56 - -#define SCRATCH_BUFFER_SIZE (MSG_RECORD_FIXED_LENGTH + (20 * sizeof(uint64_t))) - -typedef struct -{ - uint64_t next; - uint64_t mid; - uint64_t time; - uint32_t nano; - uint16_t level; - uint16_t flags; - uint32_t pid; - uint32_t uid; - uint32_t gid; - uint32_t ruid; - uint32_t rgid; - uint32_t refpid; - uint32_t kvcount; - uint64_t host; - uint64_t sender; - uint64_t facility; - uint64_t message; - uint64_t refproc; - uint64_t session; - uint64_t prev; -} file_record_t; - -typedef struct -{ - asl_file_list_t *list; - int dir; -} asl_file_match_token_t; - -static uint16_t -_asl_get_16(char *h) -{ - uint16_t x; - - memcpy(&x, h, 2); - return ntohs(x); -} - -static void -_asl_put_16(uint16_t i, char *h) -{ - uint16_t x; - - x = htons(i); - memcpy(h, &x, 2); -} - -static uint32_t -_asl_get_32(char *h) -{ - uint32_t x; - - memcpy(&x, h, 4); - return ntohl(x); -} - -static void -_asl_put_32(uint32_t i, char *h) -{ - uint32_t x; - - x = htonl(i); - memcpy(h, &x, 4); -} - -static uint64_t -_asl_get_64(char *h) -{ - uint64_t x; - - memcpy(&x, h, 8); - return asl_core_ntohq(x); -} - -static void -_asl_put_64(uint64_t i, char *h) -{ - uint64_t x; - - x = asl_core_htonq(i); - memcpy(h, &x, 8); -} - -static uint32_t -asl_file_read_uint32(asl_file_t *s, off_t off, uint32_t *out) -{ - uint32_t status, val; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (s->store == NULL) return ASL_STATUS_INVALID_STORE; - if ((off + sizeof(uint32_t)) > s->file_size) return ASL_STATUS_READ_FAILED; - - status = fseeko(s->store, off, SEEK_SET); - if (status != 0) return ASL_STATUS_READ_FAILED; - - val = 0; - - status = fread(&val, sizeof(uint32_t), 1, s->store); - if (status != 1) return ASL_STATUS_READ_FAILED; - - if (out != NULL) *out = ntohl(val); - return ASL_STATUS_OK; -} - -static uint32_t -asl_file_read_uint64(asl_file_t *s, off_t off, uint64_t *out) -{ - uint32_t status; - uint64_t val; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (s->store == NULL) return ASL_STATUS_INVALID_STORE; - if ((off + sizeof(uint64_t)) > s->file_size) return ASL_STATUS_READ_FAILED; - - status = fseeko(s->store, off, SEEK_SET); - if (status != 0) return ASL_STATUS_READ_FAILED; - - val = 0; - - status = fread(&val, sizeof(uint64_t), 1, s->store); - if (status != 1) return ASL_STATUS_READ_FAILED; - - if (out != NULL) *out = asl_core_ntohq(val); - return ASL_STATUS_OK; -} - -uint32_t -asl_file_close(asl_file_t *s) -{ - file_string_t *x; - - if (s == NULL) return ASL_STATUS_OK; - - if (s->version == 1) - { - return asl_legacy1_close((asl_legacy1_t *)s->legacy); - } - - while (s->string_list != NULL) - { - x = s->string_list->next; - free(s->string_list); - s->string_list = x; - } - - if (s->store != NULL) fclose(s->store); - if (s->scratch != NULL) free(s->scratch); - - memset(s, 0, sizeof(asl_file_t)); - free(s); - - return ASL_STATUS_OK; -} - -__private_extern__ uint32_t -asl_file_open_write_fd(int fd, asl_file_t **s) -{ - time_t now; - int status; - char buf[DB_HEADER_LEN]; - asl_file_t *out; - - if (fd < 0) return ASL_STATUS_FAILED; - if (s == NULL) return ASL_STATUS_FAILED; - - out = (asl_file_t *)calloc(1, sizeof(asl_file_t)); - if (out == NULL) return ASL_STATUS_NO_MEMORY; - - out->store = fdopen(fd, "w+"); - if (out->store == NULL) - { - free(out); - return ASL_STATUS_FAILED; - } - - memset(buf, 0, sizeof(buf)); - memcpy(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN); - - _asl_put_32(DB_VERSION, buf + DB_HEADER_VERS_OFFSET); - - now = time(NULL); - out->dob = now; - _asl_put_64(out->dob, buf + DB_HEADER_TIME_OFFSET); - - _asl_put_32(CACHE_SIZE, buf + DB_HEADER_CSIZE_OFFSET); - - status = fwrite(buf, sizeof(buf), 1, out->store); - if (status != 1) - { - fclose(out->store); - free(out); - return ASL_STATUS_FAILED; - } - - /* flush data */ - fflush(out->store); - - out->file_size = sizeof(buf); - - /* scratch buffer for file writes (we test for NULL before using it) */ - out->scratch = malloc(SCRATCH_BUFFER_SIZE); - - *s = out; - - return ASL_STATUS_OK; -} - -__private_extern__ int -asl_file_create(const char *path, uid_t uid, gid_t gid, mode_t mode) -{ -#if TARGET_OS_EMBEDDED - return open(path, O_RDWR | O_CREAT | O_EXCL, mode); -#else - acl_t acl; - uuid_t uuid; - acl_entry_t entry; - acl_permset_t perms; - int status; - int fd = -1; - - /* -1 means don't set ACL for uid or gid */ - if ((uid == -1) && (gid == -1)) - { - return open(path, O_RDWR | O_CREAT | O_EXCL, mode); - } - - acl = acl_init(1); - - if ((gid != 0) && (gid != -1)) - { - status = mbr_gid_to_uuid(gid, uuid); - if (status != 0) goto asl_file_create_return; - - status = acl_create_entry_np(&acl, &entry, ACL_FIRST_ENTRY); - if (status != 0) goto asl_file_create_return; - - status = acl_set_tag_type(entry, ACL_EXTENDED_ALLOW); - if (status != 0) goto asl_file_create_return; - - status = acl_set_qualifier(entry, &uuid); - if (status != 0) goto asl_file_create_return; - - status = acl_get_permset(entry, &perms); - if (status != 0) goto asl_file_create_return; - - status = acl_add_perm(perms, ACL_READ_DATA); - if (status != 0) goto asl_file_create_return; - } - - if ((uid != 0) && (uid != -1)) - { - status = mbr_uid_to_uuid(uid, uuid); - if (status != 0) goto asl_file_create_return; - - status = acl_create_entry_np(&acl, &entry, ACL_FIRST_ENTRY); - if (status != 0) goto asl_file_create_return; - - status = acl_set_tag_type(entry, ACL_EXTENDED_ALLOW); - if (status != 0) goto asl_file_create_return; - - status = acl_set_qualifier(entry, &uuid); - if (status != 0) goto asl_file_create_return; - - status = acl_get_permset(entry, &perms); - if (status != 0) goto asl_file_create_return; - - status = acl_add_perm(perms, ACL_READ_DATA); - if (status != 0) goto asl_file_create_return; - } - - fd = open(path, O_RDWR | O_CREAT | O_EXCL, mode); - if (fd < 0) goto asl_file_create_return; - - status = acl_set_fd(fd, acl); - if (status != 0) - { - close(fd); - fd = -1; - unlink(path); - } - -asl_file_create_return: - - acl_free(acl); - return fd; -#endif -} - -uint32_t -asl_file_open_write(const char *path, mode_t mode, uid_t uid, gid_t gid, asl_file_t **s) -{ - int i, status, fd; - struct stat sb; - char buf[DB_HEADER_LEN]; - asl_file_t *out; - uint32_t aslstatus, vers, last_len; - off_t off; - - memset(&sb, 0, sizeof(struct stat)); - - status = stat(path, &sb); - if (status == 0) - { - /* must be a plain file */ - if (!S_ISREG(sb.st_mode)) return ASL_STATUS_INVALID_STORE; - - if (sb.st_size == 0) - { - fd = open(path, O_RDWR | O_EXCL, mode); - if (fd < 0) return ASL_STATUS_FAILED; - - return asl_file_open_write_fd(fd, s); - } - else - { - /* XXX Check that mode, uid, and gid are correct */ - out = (asl_file_t *)calloc(1, sizeof(asl_file_t)); - if (out == NULL) return ASL_STATUS_NO_MEMORY; - - out->store = fopen(path, "r+"); - if (out->store == NULL) - { - free(out); - return ASL_STATUS_FAILED; - } - - i = fread(buf, DB_HEADER_LEN, 1, out->store); - if (i < 1) - { - asl_file_close(out); - return ASL_STATUS_READ_FAILED; - } - - /* check cookie */ - if (strncmp(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN)) - { - asl_file_close(out); - return ASL_STATUS_INVALID_STORE; - } - - /* check version */ - vers = _asl_get_32(buf + DB_HEADER_VERS_OFFSET); - if (vers != DB_VERSION) - { - asl_file_close(out); - return ASL_STATUS_INVALID_STORE; - } - - out->dob = _asl_get_64(buf + DB_HEADER_TIME_OFFSET); - out->first = _asl_get_64(buf + DB_HEADER_FIRST_OFFSET); - out->last = _asl_get_64(buf + DB_HEADER_LAST_OFFSET); - out->file_size = (size_t)sb.st_size; - - /* - * Detect bogus last pointer and check for odd-sized files. - * Setting out->last to zero forces asl_file_read_set_position to - * follow the linked list of records in the file to the last record. - * It's slower, but it's better at preventing crashes in corrupt files. - */ - - /* records are at least MSG_RECORD_FIXED_LENGTH bytes */ - if ((out->last + MSG_RECORD_FIXED_LENGTH) > out->file_size) - { - out->last = 0; - } - else - { - /* read last record length and make sure the file is at least that large */ - off = out->last + RECORD_TYPE_LEN; - status = asl_file_read_uint32(out, off, &last_len); - if (status != ASL_STATUS_OK) - { - asl_file_close(out); - return status; - } - - if ((out->last + last_len) > out->file_size) out->last = 0; - } - - aslstatus = asl_file_read_set_position(out, ASL_FILE_POSITION_LAST); - if (aslstatus != ASL_STATUS_OK) - { - asl_file_close(out); - return aslstatus; - } - - out->prev = out->cursor; - status = fseeko(out->store, 0, SEEK_END); - if (status != 0) - { - asl_file_close(out); - return ASL_STATUS_READ_FAILED; - } - - out->file_size = (size_t)ftello(out->store); - - /* scratch buffer for file writes (we test for NULL before using it) */ - out->scratch = malloc(SCRATCH_BUFFER_SIZE); - - *s = out; - - return ASL_STATUS_OK; - } - } - else if (errno != ENOENT) - { - /* unexpected status */ - return ASL_STATUS_FAILED; - } - - /* the file does not exist */ - fd = asl_file_create(path, uid, gid, mode); - if (fd < 0) return ASL_STATUS_FAILED; - - aslstatus = asl_file_open_write_fd(fd, s); - if (aslstatus != ASL_STATUS_OK) unlink(path); - - return aslstatus; -} - -uint32_t -asl_file_compact(asl_file_t *s, const char *path, mode_t mode, uid_t uid, gid_t gid) -{ - asl_file_t *new; - struct stat sb; - aslmsg m; - uint64_t xid; - uint32_t status; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (path == NULL) return ASL_STATUS_INVALID_ARG; - - if (s->version == 1) return ASL_STATUS_FAILED; - - memset(&sb, 0, sizeof(struct stat)); - - if (stat(path, &sb) == 0) return ASL_STATUS_FAILED; - if (errno != ENOENT) return ASL_STATUS_FAILED; - - status = asl_file_read_set_position(s, ASL_FILE_POSITION_FIRST); - if (status != ASL_STATUS_OK) return status; - - new = NULL; - status = asl_file_open_write(path, mode, uid, gid, &new); - if (status != ASL_STATUS_OK) return status; - new->flags = ASL_FILE_FLAG_UNLIMITED_CACHE | ASL_FILE_FLAG_PRESERVE_MSG_ID; - - while ((status == ASL_STATUS_OK) && (s->cursor != 0)) - { - m = NULL; - status = asl_file_fetch_next(s, &m); - if (status != ASL_STATUS_OK) break; - - xid = 0; - status = asl_file_save(new, m, &xid); - asl_free(m); - } - - asl_file_close(new); - return status; -} - -static uint32_t -asl_file_string_encode(asl_file_t *s, const char *str, uint64_t *out) -{ - uint32_t i, hash, len, x32; - file_string_t *sp, *sx, *sl; - uint64_t x64; - uint8_t inls; - uint16_t type; - off_t off; - char *p; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (str == NULL) return ASL_STATUS_INVALID_ARG; - - len = strlen(str); - - /* inline strings */ - if (len < 8) - { - /* inline string */ - inls = len; - inls |= 0x80; - - x64 = 0; - p = (char *)&x64; - memcpy(p, &inls, 1); - memcpy(p + 1, str, len); - *out = asl_core_ntohq(x64); - return ASL_STATUS_OK; - } - - /* check the cache */ - hash = asl_core_string_hash(str, len); - - sp = NULL; - for (sx = s->string_list; sx != NULL; sx = sx->next) - { - if ((hash == sx->hash) && (!strcmp(str, sx->str))) - { - /* Move this string to the head of the list */ - if (sp != NULL) - { - sl = s->string_list; - sp->next = sx->next; - sx->next = sl; - s->string_list = sx; - } - - *out = sx->where; - return ASL_STATUS_OK; - } - - sp = sx; - } - - off = ftello(s->store); - - /* Type */ - type = htons(ASL_FILE_TYPE_STR); - i = fwrite(&type, sizeof(uint16_t), 1, s->store); - if (i != 1) return ASL_STATUS_WRITE_FAILED; - - /* Length (includes trailing nul) */ - x32 = htonl(len + 1); - i = fwrite(&x32, sizeof(uint32_t), 1, s->store); - if (i != 1) return ASL_STATUS_WRITE_FAILED; - - /* String data (nul terminated) */ - i = fwrite(str, len + 1, 1, s->store); - if (i != 1) return ASL_STATUS_WRITE_FAILED; - - /* flush data */ - fflush(s->store); - - /* create file_string_t and insert into the cache */ - sx = (file_string_t *)calloc(1, offsetof(file_string_t, str) + len + 1); - if (sx == NULL) return ASL_STATUS_NO_MEMORY; - - sx->where = off; - sx->hash = hash; - sx->next = s->string_list; - memcpy(sx->str, str, len); - - s->string_list = sx; - - if (((s->flags & ASL_FILE_FLAG_UNLIMITED_CACHE) == 0) && (s->string_count == CACHE_SIZE)) - { - /* drop last (lru) string from cache */ - sp = s->string_list; - sx = sp->next; - - /* NB CACHE_SIZE must be > 1 */ - while (sx->next != NULL) - { - sp = sx; - sx = sx->next; - } - - sp->next = NULL; - free(sx); - } - else - { - s->string_count++; - } - - *out = off; - return ASL_STATUS_OK; -} - -/* - * Encode an aslmsg as a record structure. - * Creates and caches strings. - */ -uint32_t -asl_file_save(asl_file_t *s, aslmsg in, uint64_t *mid) -{ - char *buf, *p; - uint32_t i, len, x, status; - file_record_t r; - uint64_t k, v; - uint64_t *kvlist; - off_t off; - asl_msg_t *msg; - const char *key, *val; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (in == NULL) return ASL_STATUS_INVALID_MESSAGE; - - if (s->flags & ASL_FILE_FLAG_READ_ONLY) return ASL_STATUS_READ_ONLY; - - msg = (asl_msg_t *)in; - - memset(&r, 0, sizeof(file_record_t)); - - r.flags = 0; - r.level = ASL_LEVEL_DEBUG; - r.pid = -1; - r.uid = -2; - r.gid = -2; - r.ruid = -1; - r.rgid = -1; - r.time = 0; - r.nano = 0; - r.prev = s->prev; - kvlist = NULL; - - key = NULL; - val = NULL; - - for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL)) - { - if (key == NULL) - { - continue; - } - else if (!strcmp(key, ASL_KEY_TIME)) - { - if (val != NULL) r.time = asl_parse_time(val); - } - else if (!strcmp(key, ASL_KEY_TIME_NSEC)) - { - if (val != NULL) r.nano = atoi(val); - } - else if (!strcmp(key, ASL_KEY_HOST)) - { - if (val != NULL) - { - status = asl_file_string_encode(s, val, &(r.host)); - if (status != ASL_STATUS_OK) - { - if (kvlist != NULL) free(kvlist); - return status; - } - } - } - else if (!strcmp(key, ASL_KEY_SENDER)) - { - if (val != NULL) - { - status = asl_file_string_encode(s, val, &(r.sender)); - if (status != ASL_STATUS_OK) - { - if (kvlist != NULL) free(kvlist); - return status; - } - } - } - else if (!strcmp(key, ASL_KEY_PID)) - { - if (val != NULL) r.pid = atoi(val); - } - else if (!strcmp(key, ASL_KEY_REF_PID)) - { - if (val != NULL) r.refpid = atoi(val); - } - else if (!strcmp(key, ASL_KEY_UID)) - { - if (val != NULL) r.uid = atoi(val); - } - else if (!strcmp(key, ASL_KEY_GID)) - { - if (val != NULL) r.gid = atoi(val); - } - else if (!strcmp(key, ASL_KEY_LEVEL)) - { - if (val != NULL) r.level = atoi(val); - } - else if (!strcmp(key, ASL_KEY_MSG)) - { - if (val != NULL) - { - status = asl_file_string_encode(s, val, &(r.message)); - if (status != ASL_STATUS_OK) - { - if (kvlist != NULL) free(kvlist); - return status; - } - } - } - else if (!strcmp(key, ASL_KEY_FACILITY)) - { - if (val != NULL) - { - status = asl_file_string_encode(s, val, &(r.facility)); - if (status != ASL_STATUS_OK) - { - if (kvlist != NULL) free(kvlist); - return status; - } - } - } - else if (!strcmp(key, ASL_KEY_REF_PROC)) - { - if (val != NULL) - { - status = asl_file_string_encode(s, val, &(r.refproc)); - if (status != ASL_STATUS_OK) - { - if (kvlist != NULL) free(kvlist); - return status; - } - } - } - else if (!strcmp(key, ASL_KEY_SESSION)) - { - if (val != NULL) - { - status = asl_file_string_encode(s, val, &(r.session)); - if (status != ASL_STATUS_OK) - { - if (kvlist != NULL) free(kvlist); - return status; - } - } - } - else if (!strcmp(key, ASL_KEY_READ_UID)) - { - if (((r.flags & ASL_MSG_FLAG_READ_UID_SET) == 0) && (val != NULL)) - { - r.ruid = atoi(val); - r.flags |= ASL_MSG_FLAG_READ_UID_SET; - } - } - else if (!strcmp(key, ASL_KEY_READ_GID)) - { - if (((r.flags & ASL_MSG_FLAG_READ_GID_SET) == 0) && (val != NULL)) - { - r.rgid = atoi(val); - r.flags |= ASL_MSG_FLAG_READ_GID_SET; - } - } - else if (!strcmp(key, ASL_KEY_MSG_ID)) - { - if (s->flags & ASL_FILE_FLAG_PRESERVE_MSG_ID) *mid = atoll(val); - } - else if (!strcmp(key, ASL_KEY_OPTION)) - { - /* ignore - we don't save ASLOption */ - } - else - { - status = asl_file_string_encode(s, key, &k); - if (status != ASL_STATUS_OK) - { - if (kvlist != NULL) free(kvlist); - return status; - } - - v = 0; - if (val != NULL) - { - status = asl_file_string_encode(s, val, &v); - if (status != ASL_STATUS_OK) - { - if (kvlist != NULL) free(kvlist); - return status; - } - } - - if (r.kvcount == 0) - { - kvlist = (uint64_t *)calloc(2, sizeof(uint64_t)); - } - else - { - kvlist = (uint64_t *)reallocf(kvlist, (r.kvcount + 2) * sizeof(uint64_t)); - } - - if (kvlist == NULL) - { - return ASL_STATUS_NO_MEMORY; - } - - kvlist[r.kvcount++] = k; - kvlist[r.kvcount++] = v; - } - } - - len = MSG_RECORD_FIXED_LENGTH + (r.kvcount * sizeof(uint64_t)); - buf = NULL; - - /* use the scratch buffer if it exists and is large enough */ - if ((s->scratch != NULL) && (len <= SCRATCH_BUFFER_SIZE)) - { - memset(s->scratch, 0, SCRATCH_BUFFER_SIZE); - buf = s->scratch; - } - else - { - buf = calloc(1, len); - } - - if (buf == NULL) return ASL_STATUS_NO_MEMORY; - - if (*mid != 0) - { - r.mid = *mid; - } - else - { - r.mid = asl_core_new_msg_id(0); - *mid = r.mid; - } - - p = buf; - - /* Type */ - _asl_put_16(ASL_FILE_TYPE_MSG, p); - p += sizeof(uint16_t); - - /* Length of message (excludes type and length fields) */ - _asl_put_32(len - RECORD_COMMON_LEN, p); - p += sizeof(uint32_t); - - /* Message data... */ - - _asl_put_64(r.next, p); - p += sizeof(uint64_t); - - _asl_put_64(r.mid, p); - p += sizeof(uint64_t); - - _asl_put_64(r.time, p); - p += sizeof(uint64_t); - - _asl_put_32(r.nano, p); - p += sizeof(uint32_t); - - _asl_put_16(r.level, p); - p += sizeof(uint16_t); - - _asl_put_16(r.flags, p); - p += sizeof(uint16_t); - - _asl_put_32(r.pid, p); - p += sizeof(uint32_t); - - _asl_put_32(r.uid, p); - p += sizeof(uint32_t); - - _asl_put_32(r.gid, p); - p += sizeof(uint32_t); - - _asl_put_32(r.ruid, p); - p += sizeof(uint32_t); - - _asl_put_32(r.rgid, p); - p += sizeof(uint32_t); - - _asl_put_32(r.refpid, p); - p += sizeof(uint32_t); - - _asl_put_32(r.kvcount, p); - p += sizeof(uint32_t); - - _asl_put_64(r.host, p); - p += sizeof(uint64_t); - - _asl_put_64(r.sender, p); - p += sizeof(uint64_t); - - _asl_put_64(r.facility, p); - p += sizeof(uint64_t); - - _asl_put_64(r.message, p); - p += sizeof(uint64_t); - - _asl_put_64(r.refproc, p); - p += sizeof(uint64_t); - - _asl_put_64(r.session, p); - p += sizeof(uint64_t); - - for (i = 0; i < r.kvcount; i++) - { - _asl_put_64(kvlist[i], p); - p += sizeof(uint64_t); - } - - _asl_put_64(r.prev, p); - p += sizeof(uint64_t); - - free(kvlist); - kvlist = NULL; - - /* write record at end of file */ - status = fseeko(s->store, 0, SEEK_END); - if (status != 0) return ASL_STATUS_WRITE_FAILED; - - s->last = (uint64_t)ftello(s->store); - - v = asl_core_htonq(s->last); - - status = fwrite(buf, len, 1, s->store); - fflush(s->store); - - /* free the buffer if it was allocated here */ - if (buf != s->scratch) free(buf); - - /* seek to "next" field of previous record, write last offset */ - off = s->prev + RECORD_COMMON_LEN; - if (s->prev == 0) off = DB_HEADER_FIRST_OFFSET; - - status = fseeko(s->store, off, SEEK_SET); - if (status != 0) return ASL_STATUS_WRITE_FAILED; - - status = fwrite(&v, sizeof(uint64_t), 1, s->store); - if (status != 1) return ASL_STATUS_WRITE_FAILED; - - /* seek to DB_HEADER_LAST_OFFSET, write last record offset */ - off = DB_HEADER_LAST_OFFSET; - - status = fseeko(s->store, off, SEEK_SET); - if (status != 0) return ASL_STATUS_WRITE_FAILED; - - status = fwrite(&v, sizeof(uint64_t), 1, s->store); - if (status != 1) return ASL_STATUS_WRITE_FAILED; - - /* return to the end of the store (this is expected by other routines) */ - status = fseeko(s->store, 0, SEEK_END); - if (status != 0) return ASL_STATUS_WRITE_FAILED; - - /* flush data */ - fflush(s->store); - - s->file_size = (size_t)ftello(s->store); - - s->prev = s->last; - - return ASL_STATUS_OK; -} - -static uint32_t -asl_file_fetch_object(asl_file_t *s, uint64_t where, char **out, uint32_t *outlen) -{ - static char ils[9]; - char *p; - uint32_t len; - int status; - uint64_t x64; - uint8_t inls; - uint16_t type; - off_t off; - - *out = NULL; - *outlen = 0; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (out == NULL) return ASL_STATUS_INVALID_ARG; - if (where == 0) return ASL_STATUS_INVALID_ARG; - - inls = 0; - x64 = asl_core_htonq(where); - memcpy(&inls, &x64, 1); - if (inls & 0x80) - { - /* inline string */ - inls &= 0x0f; - if (inls > 7) return ASL_STATUS_INVALID_STORE; - - p = 1 + (char *)&x64; - memset(ils, 0, sizeof(ils)); - memcpy(ils, p, inls); - *out = strdup(ils); - if (*out == NULL) return ASL_STATUS_NO_MEMORY; - - *outlen = inls; - return ASL_STATUS_OK; - } - - off = where; - if ((off + sizeof(uint16_t) + sizeof(uint32_t)) > s->file_size) return ASL_STATUS_READ_FAILED; - - status = fseeko(s->store, off, SEEK_SET); - if (status != 0) return ASL_STATUS_READ_FAILED; - - /* Type */ - status = fread(&type, sizeof(uint16_t), 1, s->store); - if (status != 1) return ASL_STATUS_READ_FAILED; - off += sizeof(uint16_t); - - /* Length */ - len = 0; - status = fread(&len, sizeof(uint32_t), 1, s->store); - if (status != 1) return ASL_STATUS_READ_FAILED; - off += sizeof(uint32_t); - - len = ntohl(len); - if ((off + len) > s->file_size) return ASL_STATUS_READ_FAILED; - - *out = calloc(1, len); - if (*out == NULL) return ASL_STATUS_NO_MEMORY; - - status = fread(*out, len, 1, s->store); - if (status != 1) - { - free(*out); - return ASL_STATUS_READ_FAILED; - } - - *outlen = len; - return ASL_STATUS_OK; -} - -static uint16_t -asl_file_fetch_helper_16(asl_file_t *s, char **p, aslmsg m, const char *key) -{ - uint16_t out; - char str[256]; - - out = _asl_get_16(*p); - *p += sizeof(uint16_t); - - if ((m == NULL) || (key == NULL)) return out; - - snprintf(str, sizeof(str), "%hu", out); - asl_set(m, key, str); - - return out; -} - -static uint32_t -asl_file_fetch_helper_32(asl_file_t *s, char **p, aslmsg m, const char *key, int ignore, uint32_t ignoreval) -{ - uint32_t out, doit; - char str[256]; - - out = _asl_get_32(*p); - *p += sizeof(uint32_t); - - if ((m == NULL) || (key == NULL)) return out; - - doit = 1; - if ((ignore != 0) && (out == ignoreval)) doit = 0; - if (doit != 0) - { - snprintf(str, sizeof(str), "%u", out); - asl_set(m, key, str); - } - - return out; -} - -static uint64_t -asl_file_fetch_helper_64(asl_file_t *s, char **p, aslmsg m, const char *key) -{ - uint64_t out; - char str[256]; - - out = _asl_get_64(*p); - *p += sizeof(uint64_t); - - if ((m == NULL) || (key == NULL)) return out; - - snprintf(str, sizeof(str), "%llu", out); - asl_set(m, key, str); - - return out; -} - -static uint64_t -asl_file_fetch_helper_str(asl_file_t *s, char **p, aslmsg m, const char *key, uint32_t *err) -{ - uint64_t out; - char *val; - uint32_t status, len; - - out = _asl_get_64(*p); - *p += sizeof(uint64_t); - - val = NULL; - len = 0; - status = ASL_STATUS_OK; - if (out != 0) status = asl_file_fetch_object(s, out, &val, &len); - - if (err != NULL) *err = status; - if ((status == ASL_STATUS_OK) && (val != NULL)) - { - asl_set(m, key, val); - free(val); - } - - return out; -} - -static uint32_t -asl_file_fetch_pos(asl_file_t *s, uint64_t where, int dir, aslmsg *msg) -{ - char *buf, *p, *k, *v; - file_record_t r; - uint32_t i, status, len, buflen, kvn; - uint64_t x64, kv; - aslmsg out; - off_t off; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (msg == NULL) return ASL_STATUS_INVALID_ARG; - if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY; - - buf = NULL; - buflen = 0; - status = asl_file_fetch_object(s, where, &buf, &buflen); - if ((status != ASL_STATUS_OK) || (buf == NULL)) - { - s->cursor = 0; - s->cursor_xid = 0; - return status; - } - - /* check buffer size */ - kvn = _asl_get_32(buf + BUFFER_OFFSET_KVCOUNT); - if (buflen < (MSG_RECORD_FIXED_LENGTH - RECORD_COMMON_LEN + (kvn * sizeof(uint64_t)))) - { - free(buf); - s->cursor = 0; - s->cursor_xid = 0; - return ASL_STATUS_READ_FAILED; - } - - out = asl_new(ASL_TYPE_MSG); - if (out == NULL) return ASL_STATUS_NO_MEMORY; - - memset(&r, 0, sizeof(file_record_t)); - p = buf; - - r.next = asl_file_fetch_helper_64(s, &p, NULL, NULL); - r.mid = asl_file_fetch_helper_64(s, &p, out, ASL_KEY_MSG_ID); - r.time = asl_file_fetch_helper_64(s, &p, out, ASL_KEY_TIME); - r.nano = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_TIME_NSEC, 0, 0); - r.level = asl_file_fetch_helper_16(s, &p, out, ASL_KEY_LEVEL); - r.flags = asl_file_fetch_helper_16(s, &p, NULL, NULL); - r.pid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_PID, 0, 0); - r.uid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_UID, 1, (uint32_t)-1); - r.gid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_GID, 1, (uint32_t)-1); - r.ruid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_READ_UID, 1, (uint32_t)-1); - r.rgid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_READ_GID, 1, (uint32_t)-1); - r.refpid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_REF_PID, 1, 0); - r.kvcount = asl_file_fetch_helper_32(s, &p, NULL, NULL, 0, 0); - - status = ASL_STATUS_OK; - r.host = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_HOST, &status); /* 68 */ - if (status == ASL_STATUS_OK) r.sender = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_SENDER, &status); /* 76 */ - if (status == ASL_STATUS_OK) r.facility = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_FACILITY, &status); /* 84 */ - if (status == ASL_STATUS_OK) r.message = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_MSG, &status); /* 92 */ - if (status == ASL_STATUS_OK) r.refproc = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_REF_PROC, &status); /* 100 */ - if (status == ASL_STATUS_OK) r.session = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_SESSION, &status); /* 108 */ - - if (status != ASL_STATUS_OK) - { - asl_free(out); - free(buf); - s->cursor = 0; - s->cursor_xid = 0; - return status; - } - - kvn = r.kvcount / 2; - - for (i = 0; i < kvn; i++) - { - kv = _asl_get_64(p); - p += sizeof(uint64_t); - k = NULL; - len = 0; - status = asl_file_fetch_object(s, kv, &k, &len); - if (status != ASL_STATUS_OK) - { - asl_free(out); - free(buf); - s->cursor = 0; - s->cursor_xid = 0; - return status; - } - - kv = _asl_get_64(p); - p += sizeof(uint64_t); - v = NULL; - len = 0; - - if (kv != 0) - { - status = asl_file_fetch_object(s, kv, &v, &len); - if (status != ASL_STATUS_OK) - { - asl_free(out); - free(buf); - s->cursor = 0; - s->cursor_xid = 0; - return status; - } - } - - if ((status == ASL_STATUS_OK) && (k != NULL)) - { - asl_set(out, k, v); - if (v != NULL) free(v); - free(k); - } - } - - r.prev = asl_file_fetch_helper_64(s, &p, NULL, NULL); /* 116 */ - - free(buf); - - if (dir >= 0) s->cursor = r.next; - else s->cursor = r.prev; - - s->cursor_xid = 0; - - if (s->cursor != 0) - { - off = s->cursor + RECORD_COMMON_LEN + sizeof(uint64_t); - if (off > s->file_size) - { - asl_free(out); - s->cursor = 0; - s->cursor_xid = 0; - /* - * Next record offset is past the end of the file. - * This is an error, but we allow it to fail quietly - * so that the current record fetch succeeds. - */ - return ASL_STATUS_OK; - } - - status = fseeko(s->store, off, SEEK_SET); - if (status != 0) - { - asl_free(out); - s->cursor = 0; - s->cursor_xid = 0; - return ASL_STATUS_READ_FAILED; - } - - status = fread(&x64, sizeof(uint64_t), 1, s->store); - if (status != 1) - { - asl_free(out); - s->cursor = 0; - s->cursor_xid = 0; - return ASL_STATUS_READ_FAILED; - } - - s->cursor_xid = asl_core_ntohq(x64); - } - - *msg = out; - return ASL_STATUS_OK; -} - -uint32_t -asl_file_open_read(const char *path, asl_file_t **s) -{ - asl_file_t *out; - FILE *f; - int i; - uint32_t status, vers, last_len; - char buf[DB_HEADER_LEN]; - off_t off; - asl_legacy1_t *legacy; - struct stat sb; - - memset(&sb, 0, sizeof(struct stat)); - if (stat(path, &sb) != 0) return ASL_STATUS_FAILED; - - f = fopen(path, "r"); - if (f == NULL) - { - if (errno == EACCES) return ASL_STATUS_ACCESS_DENIED; - return ASL_STATUS_FAILED; - } - - i = fread(buf, DB_HEADER_LEN, 1, f); - if (i < 1) - { - fclose(f); - return ASL_STATUS_INVALID_STORE; - } - - /* validate header */ - if (strncmp(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN)) - { - fclose(f); - return ASL_STATUS_INVALID_STORE; - } - - legacy = NULL; - - vers = _asl_get_32(buf + DB_HEADER_VERS_OFFSET); - if (vers == DB_VERSION_LEGACY_1) - { - fclose(f); - status = asl_legacy1_open(path, &legacy); - if (status != ASL_STATUS_OK) return status; - } - - out = (asl_file_t *)calloc(1, sizeof(asl_file_t)); - if (out == NULL) - { - fclose(f); - return ASL_STATUS_NO_MEMORY; - } - - out->store = f; - out->flags = ASL_FILE_FLAG_READ_ONLY; - out->version = vers; - - if (legacy != NULL) - { - out->flags |= ASL_FILE_FLAG_LEGACY_STORE; - out->legacy = (void *)legacy; - - *s = out; - return ASL_STATUS_OK; - } - - out->first = _asl_get_64(buf + DB_HEADER_FIRST_OFFSET); - out->last = _asl_get_64(buf + DB_HEADER_LAST_OFFSET); - out->file_size = (size_t)sb.st_size; - - /* - * Detect bogus last pointer and check for odd-sized files. - * Setting out->last to zero forces us to follow the linked - * list of records in the file to the last record. That's - * done in the set_position code. It's a bit slower, but it's - * better at preventing crashes in corrupt files. - */ - - /* records are at least MSG_RECORD_FIXED_LENGTH bytes */ - if ((out->last + MSG_RECORD_FIXED_LENGTH) > out->file_size) - { - out->last = 0; - } - else - { - /* read last record length and make sure the file is at least that large */ - off = out->last + RECORD_TYPE_LEN; - status = asl_file_read_uint32(out, off, &last_len); - if (status != ASL_STATUS_OK) - { - fclose(out->store); - free(out); - return status; - } - - if ((out->last + last_len) > out->file_size) out->last = 0; - } - - out->cursor = out->first; - if (out->cursor != 0) - { - off = out->cursor + RECORD_COMMON_LEN + sizeof(uint64_t); - status = asl_file_read_uint64(out, off, &(out->cursor_xid)); - if (status != ASL_STATUS_OK) - { - fclose(out->store); - free(out); - return status; - } - } - - *s = out; - return ASL_STATUS_OK; -} - -static uint32_t -asl_file_read_set_position_first(asl_file_t *s) -{ - uint32_t status; - off_t off; - - s->cursor = s->first; - s->cursor_xid = 0; - - if (s->cursor == 0) return ASL_STATUS_OK; - - /* read ID of the first record */ - off = s->cursor + RECORD_COMMON_LEN + sizeof(uint64_t); - status = asl_file_read_uint64(s, off, &(s->cursor_xid)); - return status; -} - -static uint32_t -asl_file_read_set_position_last(asl_file_t *s) -{ - uint64_t next; - uint32_t status; - off_t off; - - /* - * If the file has the offset of the last record, we just go there. - * The last record offset was added to improve performance, so it may - * or may not be there. If we don't have the last record offset, we - * just iterate down the record links to find the last one. - * - * Note that s->last may be zero if the file is empty. - */ - - if (s->last != 0) - { - s->cursor = s->last; - off = s->last + RECORD_COMMON_LEN + sizeof(uint64_t); - - /* read ID of the last record */ - status = asl_file_read_uint64(s, off, &(s->cursor_xid)); - return status; - } - - /* start at the first record and iterate */ - s->cursor = s->first; - s->cursor_xid = 0; - - forever - { - off = s->cursor + RECORD_COMMON_LEN; - next = 0; - - /* read next offset */ - status = asl_file_read_uint64(s, off, &next); - if (status != ASL_STATUS_OK) return status; - - /* detect bogus next pointer */ - if (((next + MSG_RECORD_FIXED_LENGTH) > s->file_size) || (next <= s->cursor)) next = 0; - - if (next == 0) - { - if (s->cursor == 0) return ASL_STATUS_OK; - - off = s->cursor + RECORD_COMMON_LEN + sizeof(uint64_t); - status = asl_file_read_uint64(s, off, &(s->cursor_xid)); - return ASL_STATUS_OK; - } - - s->cursor = next; - } -} - -uint32_t -asl_file_read_set_position(asl_file_t *s, uint32_t pos) -{ - uint64_t next; - uint32_t len, status; - off_t off; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (s->version == 1) return ASL_STATUS_FAILED; - - if (pos == ASL_FILE_POSITION_FIRST) return asl_file_read_set_position_first(s); - if (pos == ASL_FILE_POSITION_LAST) return asl_file_read_set_position_last(s); - - off = 0; - - if (pos == ASL_FILE_POSITION_PREVIOUS) - { - if (s->cursor == s->first) return ASL_STATUS_NO_RECORDS; - if (s->cursor == 0) return ASL_STATUS_NO_RECORDS; - - off = s->cursor + RECORD_TYPE_LEN; - status = asl_file_read_uint32(s, off, &len); - if (status != ASL_STATUS_OK) return status; - - /* set offset to read the "previous" field at the end of the record */ - off = s->cursor + RECORD_COMMON_LEN + len - sizeof(uint64_t); - } - else if (pos == ASL_FILE_POSITION_NEXT) - { - if (s->cursor == s->last) return ASL_STATUS_NO_RECORDS; - if (s->cursor == 0) return ASL_STATUS_NO_RECORDS; - - /* set offset to read the "next" field in the current record */ - off = s->cursor + RECORD_COMMON_LEN; - } - else return ASL_STATUS_INVALID_ARG; - - s->cursor_xid = 0; - - /* - * read offset of next / previous - */ - next = 0; - status = asl_file_read_uint64(s, off, &next); - if (status != ASL_STATUS_OK) return ASL_STATUS_READ_FAILED; - - /* detect bogus next pointer */ - if ((next + MSG_RECORD_FIXED_LENGTH) > s->file_size) next = 0; - else if ((pos == ASL_FILE_POSITION_PREVIOUS) && (next >= s->cursor)) next = 0; - else if ((pos == ASL_FILE_POSITION_NEXT) && (next <= s->cursor)) next = 0; - - s->cursor = next; - if (s->cursor == 0) return ASL_STATUS_NO_RECORDS; - - /* read ID of the record */ - off = s->cursor + RECORD_COMMON_LEN + sizeof(uint64_t); - status = asl_file_read_uint64(s, off, &(s->cursor_xid)); - return status; -} - -uint32_t -asl_file_fetch_next(asl_file_t *s, aslmsg *msg) -{ - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (s->version == 1) return ASL_STATUS_FAILED; - - return asl_file_fetch_pos(s, s->cursor, 1, msg); -} - -uint32_t -asl_file_fetch_previous(asl_file_t *s, aslmsg *msg) -{ - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (s->version == 1) return ASL_STATUS_FAILED; - - return asl_file_fetch_pos(s, s->cursor, -1, msg); -} - -uint32_t -asl_file_fetch(asl_file_t *s, uint64_t mid, aslmsg *msg) -{ - uint32_t status; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (msg == NULL) return ASL_STATUS_INVALID_ARG; - if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY; - - if (s->version == 1) - { - return asl_legacy1_fetch((asl_legacy1_t *)s->legacy, mid, msg); - } - - if (s->cursor_xid == 0) - { - status = asl_file_read_set_position(s, ASL_FILE_POSITION_FIRST); - if (status != ASL_STATUS_OK) return status; - if (s->cursor_xid == 0) return ASL_STATUS_INVALID_ID; - } - - while (s->cursor_xid < mid) - { - status = asl_file_read_set_position(s, ASL_FILE_POSITION_NEXT); - if (status != ASL_STATUS_OK) return status; - if (s->cursor_xid > mid) return ASL_STATUS_INVALID_ID; - if (s->cursor_xid == 0) return ASL_STATUS_INVALID_ID; - } - - while (s->cursor_xid > mid) - { - status = asl_file_read_set_position(s, ASL_FILE_POSITION_PREVIOUS); - if (status != ASL_STATUS_OK) return status; - if (s->cursor_xid < mid) return ASL_STATUS_INVALID_ID; - if (s->cursor_xid == 0) return ASL_STATUS_INVALID_ID; - } - - if (s->cursor_xid != mid) return ASL_STATUS_INVALID_ID; - - return asl_file_fetch_pos(s, s->cursor, 1, msg); -} - -__private_extern__ uint64_t -asl_file_cursor(asl_file_t *s) -{ - if (s == NULL) return 0; - if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return 0; - if (s->version == 1) return 0; - - return s->cursor_xid; -} - -__private_extern__ uint32_t -asl_file_match_start(asl_file_t *s, uint64_t start_id, int32_t direction) -{ - uint32_t status, d; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (s->version == 1) return ASL_STATUS_INVALID_STORE; - if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY; - - d = ASL_FILE_POSITION_NEXT; - if (direction < 0) d = ASL_FILE_POSITION_PREVIOUS; - - /* - * find starting point - */ - status = ASL_STATUS_OK; - if (direction >= 0) status = asl_file_read_set_position(s, ASL_FILE_POSITION_FIRST); - else status = asl_file_read_set_position(s, ASL_FILE_POSITION_LAST); - if (status != ASL_STATUS_OK) return status; - - while ((status == ASL_STATUS_OK) && (((direction >= 0) && (s->cursor_xid < start_id)) || ((direction < 0) && (s->cursor_xid > start_id)))) - { - status = asl_file_read_set_position(s, d); - } - - return status; -} - -__private_extern__ uint32_t -asl_file_match_next(asl_file_t *s, aslresponse query, aslmsg *msg, uint64_t *last_id, int32_t direction) -{ - uint32_t status, d, i, do_match, did_match; - aslmsg m; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (msg == NULL) return ASL_STATUS_INVALID_ARG; - if (s->version == 1) return ASL_STATUS_INVALID_STORE; - if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY; - if (s->cursor == 0) return ASL_STATUS_NO_RECORDS; - - *msg = NULL; - do_match = 1; - - d = ASL_FILE_POSITION_NEXT; - if (direction < 0) d = ASL_FILE_POSITION_PREVIOUS; - - if ((query == NULL) || ((query != NULL) && (query->count == 0))) do_match = 0; - - m = NULL; - - *last_id = s->cursor_xid; - - status = asl_file_fetch_pos(s, s->cursor, direction, &m); - if (status == ASL_STATUS_ACCESS_DENIED) return ASL_STATUS_MATCH_FAILED; - if ((status == ASL_STATUS_INVALID_ARG) && (s->cursor == 0)) return ASL_STATUS_NO_RECORDS; - if (status != ASL_STATUS_OK) return status; - - did_match = 1; - - if (do_match != 0) - { - did_match = 0; - - for (i = 0; (i < query->count) && (did_match == 0); i++) - { - did_match = asl_msg_cmp((aslmsg)(query->msg[i]), m); - } - } - - if (did_match != 0) - { - *msg = m; - return ASL_STATUS_OK; - } - - asl_free(m); - return ASL_STATUS_MATCH_FAILED; -} - -uint32_t -asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) -{ - uint32_t status, d, i, do_match, did_match, rescount; - aslmsg m; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (res == NULL) return ASL_STATUS_INVALID_ARG; - if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY; - - if (s->version == 1) - { - return asl_legacy1_match((asl_legacy1_t *)s->legacy, query, res, last_id, start_id, count, direction); - } - - do_match = 1; - rescount = 0; - - d = ASL_FILE_POSITION_NEXT; - if (direction < 0) d = ASL_FILE_POSITION_PREVIOUS; - - if ((query == NULL) || ((query != NULL) && (query->count == 0))) do_match = 0; - - /* - * find starting point - */ - status = ASL_STATUS_OK; - if (direction >= 0) status = asl_file_read_set_position(s, ASL_FILE_POSITION_FIRST); - else status = asl_file_read_set_position(s, ASL_FILE_POSITION_LAST); - if (status != ASL_STATUS_OK) return status; - - while ((status == ASL_STATUS_OK) && (((direction >= 0) && (s->cursor_xid < start_id)) || ((direction < 0) && (s->cursor_xid > start_id)))) - { - status = asl_file_read_set_position(s, d); - } - - /* - * loop through records - */ - forever - { - m = NULL; - status = asl_file_fetch_pos(s, s->cursor, direction, &m); - if (status == ASL_STATUS_ACCESS_DENIED) continue; - if (status != ASL_STATUS_OK) break; - - *last_id = s->cursor_xid; - - did_match = 1; - - if (do_match != 0) - { - did_match = 0; - - for (i = 0; (i < query->count) && (did_match == 0); i++) - { - did_match = asl_msg_cmp((aslmsg)query->msg[i], m); - } - } - - if (did_match == 1) - { - /* append m to res */ - if (*res == NULL) - { - *res = (aslresponse)calloc(1, sizeof(aslresponse)); - if (*res == NULL) return ASL_STATUS_NO_MEMORY; - (*res)->msg = (asl_msg_t **)calloc(1, sizeof(aslmsg)); - if ((*res)->msg == NULL) - { - free(*res); - return ASL_STATUS_NO_MEMORY; - } - } - else - { - (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(aslmsg)); - if ((*res)->msg == NULL) - { - free(*res); - return ASL_STATUS_NO_MEMORY; - } - } - - (*res)->msg[(*res)->count] = (asl_msg_t *)m; - (*res)->count++; - - rescount++; - if ((count != 0) && (rescount >= count)) break; - } - else - { - asl_free(m); - } - } - - /* NOT REACHED */ - return ASL_STATUS_OK; -} - -size_t -asl_file_size(asl_file_t *s) -{ - if (s == NULL) return 0; - return s->file_size; -} - -uint64_t -asl_file_ctime(asl_file_t *s) -{ - if (s == NULL) return 0; - return s->dob; -} - -void -asl_file_list_close(asl_file_list_t *head) -{ - asl_file_list_t *next; - - while (head != NULL) - { - next = head->next; - asl_file_close(head->file); - free(head); - head = next; - } -} - -static void -asl_file_list_free(asl_file_list_t *head) -{ - asl_file_list_t *next; - - while (head != NULL) - { - next = head->next; - free(head); - head = next; - } -} - -static asl_file_list_t * -asl_file_list_insert(asl_file_list_t *list, asl_file_t *f, int32_t dir) -{ - asl_file_list_t *a, *b, *tmp; - - if (f == NULL) return list; - - tmp = (asl_file_list_t *)calloc(1, sizeof(asl_file_list_t)); - if (tmp == NULL) return NULL; - tmp->file = f; - - if (list == NULL) return tmp; - - a = list; - if (((dir < 0) && (f->cursor_xid > a->file->cursor_xid)) || ((dir >= 0) && (f->cursor_xid < a->file->cursor_xid))) - { - tmp->next = list; - return tmp; - } - - b = a->next; - while (b != NULL) - { - if (((dir < 0) && (f->cursor_xid > b->file->cursor_xid)) || ((dir >= 0) && (f->cursor_xid < b->file->cursor_xid))) - { - tmp->next = b; - a->next = tmp; - return list; - } - - a = b; - b = a->next; - } - - a->next = tmp; - return list; -} - -asl_file_list_t * -asl_file_list_add(asl_file_list_t *list, asl_file_t *f) -{ - asl_file_list_t *tmp; - - if (f == NULL) return list; - if (f->version == 1) return list; - - tmp = (asl_file_list_t *)calloc(1, sizeof(asl_file_list_t)); - if (tmp == NULL) return NULL; - tmp->file = f; - - tmp->next = list; - return tmp; -} - -void * -asl_file_list_match_start(asl_file_list_t *list, uint64_t start_id, int32_t direction) -{ - uint32_t status; - asl_file_list_t *n; - asl_file_match_token_t *out; - - if (list == NULL) return NULL; - - out = (asl_file_match_token_t *)calloc(1, sizeof(asl_file_match_token_t)); - if (out == NULL) return NULL; - - for (n = list; n != NULL; n = n->next) - { - /* init file for the search */ - status = asl_file_match_start(n->file, start_id, direction); - if (status != ASL_STATUS_OK) continue; - if (n->file->cursor_xid == 0) continue; - - out->list = asl_file_list_insert(out->list, n->file, direction); - } - - out->dir = direction; - return out; -} - -uint32_t -asl_file_list_match_next(void *token, aslresponse query, aslresponse *res, uint32_t count) -{ - uint32_t status, rescount; - asl_file_list_t *n; - aslmsg m; - asl_file_match_token_t *work; - uint64_t last_id; - - if (token == NULL) return ASL_STATUS_OK; - if (res == NULL) return ASL_STATUS_INVALID_ARG; - - work = (asl_file_match_token_t *)token; - - rescount = 0; - last_id = 0; - - while ((work->list != NULL) && ((rescount < count) || (count == 0))) - { - m = NULL; - status = asl_file_match_next(work->list->file, query, &m, &last_id, work->dir); - if (m != NULL) - { - if (*res == NULL) *res = (aslresponse)calloc(1, sizeof(asl_search_result_t)); - if (*res == NULL) - { - asl_file_list_free(work->list); - work->list = NULL; - return ASL_STATUS_NO_MEMORY; - } - - if ((*res)->msg == NULL) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(aslmsg)); - else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(aslmsg)); - if ((*res)->msg == NULL) - { - free(*res); - *res = NULL; - asl_file_list_free(work->list); - work->list = NULL; - return ASL_STATUS_NO_MEMORY; - } - - (*res)->msg[(*res)->count] = (asl_msg_t *)m; - (*res)->count++; - rescount++; - } - - if ((status != ASL_STATUS_OK) || (work->list->file->cursor_xid == 0)) - { - n = work->list->next; - free(work->list); - work->list = n; - } - - if (work->list != NULL) - { - n = work->list->next; - if (n != NULL) - { - if (((work->dir < 0) && (work->list->file->cursor_xid <= n->file->cursor_xid)) || ((work->dir >= 0) && (work->list->file->cursor_xid > n->file->cursor_xid))) - { - n = work->list; - work->list = work->list->next; - n->next = NULL; - work->list = asl_file_list_insert(work->list, n->file, work->dir); - free(n); - } - } - } - } - - return ASL_STATUS_OK; -} - -void -asl_file_list_match_end(void *token) -{ - asl_file_match_token_t *work; - - if (token == NULL) return; - - work = (asl_file_match_token_t *)token; - asl_file_list_free(work->list); - work->list = NULL; - - free(token); -} - -uint32_t -asl_file_list_match_timeout(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec) -{ - uint32_t status, rescount; - asl_file_list_t *files, *n; - aslmsg m; - struct timeval now, finish; - - if (list == NULL) return ASL_STATUS_INVALID_ARG; - if (res == NULL) return ASL_STATUS_INVALID_ARG; - if (last_id == NULL) return ASL_STATUS_INVALID_ARG; - - files = NULL; - - for (n = list; n != NULL; n = n->next) - { - /* init file for the search */ - status = asl_file_match_start(n->file, start_id, direction); - if (status != ASL_STATUS_OK) continue; - if (n->file->cursor_xid == 0) continue; - - files = asl_file_list_insert(files, n->file, direction); - } - - if (files == NULL) - { - asl_file_list_free(files); - return ASL_STATUS_OK; - } - - /* start the timer if a timeout was specified */ - memset(&finish, 0, sizeof(struct timeval)); - if (usec != 0) - { - if (gettimeofday(&finish, NULL) == 0) - { - finish.tv_sec += (usec / MILLION); - finish.tv_usec += (usec % MILLION); - if (finish.tv_usec > MILLION) - { - finish.tv_usec -= MILLION; - finish.tv_sec += 1; - } - } - else - { - /* shouldn't happen, but if gettimeofday failed we just run without a timeout */ - memset(&finish, 0, sizeof(struct timeval)); - } - } - - rescount = 0; - while ((files != NULL) && ((rescount < count) || (count == 0))) - { - m = NULL; - status = asl_file_match_next(files->file, query, &m, last_id, direction); - if (m != NULL) - { - if (*res == NULL) *res = (aslresponse)calloc(1, sizeof(asl_search_result_t)); - if (*res == NULL) - { - asl_file_list_free(files); - return ASL_STATUS_NO_MEMORY; - } - - if ((*res)->msg == NULL) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(aslmsg)); - else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(aslmsg)); - if ((*res)->msg == NULL) - { - free(*res); - *res = NULL; - asl_file_list_free(files); - return ASL_STATUS_NO_MEMORY; - } - - (*res)->msg[(*res)->count] = (asl_msg_t *)m; - (*res)->count++; - rescount++; - } - - if (files->file->cursor_xid == 0) - { - n = files->next; - free(files); - files = n; - } - - if (files != NULL) - { - n = files->next; - if (n != NULL) - { - if (((direction < 0) && (files->file->cursor_xid <= n->file->cursor_xid)) || ((direction >= 0) && (files->file->cursor_xid > n->file->cursor_xid))) - { - n = files; - files = files->next; - n->next = NULL; - files = asl_file_list_insert(files, n->file, direction); - free(n); - } - } - } - - /* check the timer */ - if ((finish.tv_sec != 0) && (gettimeofday(&now, NULL) == 0)) - { - if ((now.tv_sec > finish.tv_sec) || ((now.tv_sec == finish.tv_sec) && (now.tv_usec > finish.tv_usec))) break; - } - } - - asl_file_list_free(files); - return ASL_STATUS_OK; -} - -uint32_t -asl_file_list_match(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) -{ - return asl_file_list_match_timeout(list, query, res, last_id, start_id, count, direction, 0); -} diff --git a/src/libc/gen/asl_file.h b/src/libc/gen/asl_file.h deleted file mode 100644 index d550d8d96..000000000 --- a/src/libc/gen/asl_file.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __ASL_FILE_H__ -#define __ASL_FILE_H__ - -#include -#include -#include -#include -#include - -#define DB_HEADER_LEN 80 -#define DB_HEADER_COOKIE_OFFSET 0 -#define DB_HEADER_VERS_OFFSET 12 -#define DB_HEADER_FIRST_OFFSET 16 -#define DB_HEADER_TIME_OFFSET 24 -#define DB_HEADER_CSIZE_OFFSET 32 -#define DB_HEADER_LAST_OFFSET 36 - -/* - * Magic Cookie for database files. - * MAXIMUM 12 CHARS! (DB_HEADER_VERS_OFFSET) - */ -#define ASL_DB_COOKIE "ASL DB" -#define ASL_DB_COOKIE_LEN 6 -#define DB_VERSION 2 -#define DB_VERSION_LEGACY_1 1 - -#define ASL_FILE_FLAG_READ_ONLY 0x00000001 -#define ASL_FILE_FLAG_UNLIMITED_CACHE 0x00000002 -#define ASL_FILE_FLAG_PRESERVE_MSG_ID 0x00000004 -#define ASL_FILE_FLAG_LEGACY_STORE 0x00000008 - -#define ASL_FILE_TYPE_MSG 0 -#define ASL_FILE_TYPE_STR 1 - -#define ASL_FILE_POSITION_FIRST 0 -#define ASL_FILE_POSITION_PREVIOUS 1 -#define ASL_FILE_POSITION_NEXT 2 -#define ASL_FILE_POSITION_LAST 3 - -/* NB CACHE_SIZE must be > 1 */ -#define CACHE_SIZE 256 - -/* Size of the fixed-length part of a MSG record */ -#define MSG_RECORD_FIXED_LENGTH 122 - -/* - * The first record (header) in the database has the format: - * - * | 12 | 4 | 8 | 8 | 4 | 8 | 36 | (80 bytes) - * | Cookie | Vers | First | Time | String cache size | Last | Zero | - * - * MSG records have the format: - * - * | 2 | 4 | 8 | 8 | 8 | 4 | 2 | 2 | 4 | 4 | 4 | 4 | 4 | 4 | 4 - * | 00 | Len | Next | ID | Time | Nano | Level | Flags | PID | UID | GID | RUID | RGID | RefPID | KV count ... - * - * | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | | 8 - * | Host | Sender | Facility | Message | RefProc | Session | Key0 | Val0 | ... | Previous | - * - * STR records have the format: - * - * | 2 | 4 | Len | (Len + 6 bytes) - * | 01 | Len | Data+NUL | - * - */ - -typedef struct file_string_s -{ - uint64_t where; - uint32_t hash; - struct file_string_s *next; - char str[]; -} file_string_t; - -typedef struct -{ - uint32_t flags; - uint32_t version; - uint32_t string_count; - file_string_t *string_list; - uint64_t first; - uint64_t last; - uint64_t prev; - uint64_t cursor; - uint64_t cursor_xid; - uint64_t dob; - size_t file_size; - FILE *store; - void *legacy; - char *scratch; -} asl_file_t; - -typedef struct asl_file_list_s -{ - asl_file_t *file; - struct asl_file_list_s *next; -} asl_file_list_t; - -asl_file_list_t *asl_file_list_add(asl_file_list_t *list, asl_file_t *f) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -void asl_file_list_close(asl_file_list_t *list) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -uint32_t asl_file_open_write(const char *path, mode_t mode, uid_t uid, gid_t gid, asl_file_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_close(asl_file_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -uint32_t asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -uint32_t asl_file_open_read(const char *path, asl_file_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_fetch(asl_file_t *s, uint64_t mid, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -uint32_t asl_file_read_set_position(asl_file_t *s, uint32_t pos) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_fetch_next(asl_file_t *s, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_fetch_previous(asl_file_t *s, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -uint32_t asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_list_match_timeout(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); -uint32_t asl_file_list_match(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -void *asl_file_list_match_start(asl_file_list_t *list, uint64_t start_id, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_file_list_match_next(void *token, aslresponse query, aslresponse *res, uint32_t count) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -void asl_file_list_match_end(void *token) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -size_t asl_file_size(asl_file_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint64_t asl_file_ctime(asl_file_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -uint32_t asl_file_compact(asl_file_t *s, const char *path, mode_t mode, uid_t uid, gid_t gid) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -#endif /* __ASL_FILE_H__ */ diff --git a/src/libc/gen/asl_ipc.defs b/src/libc/gen/asl_ipc.defs deleted file mode 100644 index 537bbe2ac..000000000 --- a/src/libc/gen/asl_ipc.defs +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -subsystem asl_ipc 114; -serverprefix _; - -import ; - -type ooline_data = ^ array [] of MACH_MSG_TYPE_BYTE - ctype : caddr_t; - -routine _asl_server_query -( - server : mach_port_t; - request : ooline_data, dealloc; - startid : uint64_t; - count : int; - flags : int; - out reply : ooline_data, dealloc; - out lastid : uint64_t; - out status : int; - SecToken token : security_token_t -); - -routine _asl_server_query_timeout -( - server : mach_port_t; - request : ooline_data, dealloc; - startid : uint64_t; - count : int; - flags : int; - WaitTime timeout: natural_t; - out reply : ooline_data, dealloc; - out lastid : uint64_t; - out status : int; - SecToken token : security_token_t -); - -routine _asl_server_prune -( - server : mach_port_t; - request : ooline_data, dealloc; - out status : int; - SecToken token : security_token_t -); - -routine _asl_server_create_aux_link -( - server : mach_port_t; - message : ooline_data, dealloc; - out fileport : mach_port_move_send_t; - out url : ooline_data, dealloc; - out status : int; - ServerAuditToken token : audit_token_t -); - -simpleroutine _asl_server_message -( - server : mach_port_t; - message : ooline_data, dealloc; - ServerAuditToken token : audit_token_t -); - -simpleroutine _asl_server_register_direct_watch -( - server : mach_port_t; - port : int; - ServerAuditToken token : audit_token_t -); - -simpleroutine _asl_server_cancel_direct_watch -( - server : mach_port_t; - port : int; - ServerAuditToken token : audit_token_t -); diff --git a/src/libc/gen/asl_legacy1.c b/src/libc/gen/asl_legacy1.c deleted file mode 100644 index 8bd9ba1ac..000000000 --- a/src/libc/gen/asl_legacy1.c +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define forever for(;;) - -#define FILE_MODE 0600 - -#define DB_RECORD_LEN 80 - -#define DB_HEADER_COOKIE_OFFSET 0 -#define DB_HEADER_VERS_OFFSET 12 - -#define DB_TYPE_EMPTY 0 -#define DB_TYPE_HEADER 1 -#define DB_TYPE_MESSAGE 2 -#define DB_TYPE_KVLIST 3 -#define DB_TYPE_STRING 4 -#define DB_TYPE_STRCONT 5 - -/* - * Magic Cookie for database files. - * MAXIMUM 12 CHARS! (DB_HEADER_VERS_OFFSET) - */ -#define ASL_DB_COOKIE "ASL DB" -#define ASL_DB_COOKIE_LEN 6 - -#define ASL_INDEX_NULL 0xffffffff - -#define DB_HLEN_EMPTY 0 -#define DB_HLEN_HEADER 13 -#define DB_HLEN_MESSAGE 13 -#define DB_HLEN_KVLIST 9 -#define DB_HLEN_STRING 25 -#define DB_HLEN_STRCONT 5 - -#define MSG_OFF_KEY_TYPE 0 -#define MSG_OFF_KEY_NEXT 1 -#define MSG_OFF_KEY_ID 5 -#define MSG_OFF_KEY_RUID 13 -#define MSG_OFF_KEY_RGID 17 -#define MSG_OFF_KEY_TIME 21 -#define MSG_OFF_KEY_HOST 29 -#define MSG_OFF_KEY_SENDER 37 -#define MSG_OFF_KEY_FACILITY 45 -#define MSG_OFF_KEY_LEVEL 53 -#define MSG_OFF_KEY_PID 57 -#define MSG_OFF_KEY_UID 61 -#define MSG_OFF_KEY_GID 65 -#define MSG_OFF_KEY_MSG 69 -#define MSG_OFF_KEY_FLAGS 77 - -extern time_t asl_parse_time(const char *str); -extern int asl_msg_cmp(aslmsg a, aslmsg b); - -#define asl_msg_list_t asl_search_result_t - -#define Q_NULL 100001 -#define Q_FAST 100002 -#define Q_SLOW 100003 -#define Q_FAIL 100004 - -static uint64_t -_asl_htonq(uint64_t n) -{ -#ifdef __BIG_ENDIAN__ - return n; -#else - u_int32_t t; - union - { - u_int64_t q; - u_int32_t l[2]; - } x; - - x.q = n; - t = x.l[0]; - x.l[0] = htonl(x.l[1]); - x.l[1] = htonl(t); - - return x.q; -#endif -} - -static uint64_t -_asl_ntohq(uint64_t n) -{ -#ifdef __BIG_ENDIAN__ - return n; -#else - u_int32_t t; - union - { - u_int64_t q; - u_int32_t l[2]; - } x; - - x.q = n; - t = x.l[0]; - x.l[0] = ntohl(x.l[1]); - x.l[1] = ntohl(t); - - return x.q; -#endif -} - -static uint16_t -_asl_get_16(char *h) -{ - uint16_t x; - - memcpy(&x, h, 2); - return ntohs(x); -} - -static uint32_t -_asl_get_32(char *h) -{ - uint32_t x; - - memcpy(&x, h, 4); - return ntohl(x); -} - -static uint64_t -_asl_get_64(char *h) -{ - uint64_t x; - - memcpy(&x, h, 8); - return _asl_ntohq(x); -} - -#define header_get_next(h) _asl_get_32(h + 1) -#define header_get_id(h) _asl_get_64(h + 5) -#define header_get_hash(h) _asl_get_32(h + 17) - -/* - * callback for sorting slotlist - * primary sort is by xid - * secondary sort is by slot, which happens when xid is 0 - * this allows us to quickly find xids (using binary search on the xid key) - * it's also used to find slots quickly from record_chain_free() - */ -static int -slot_comp(const void *a, const void *b) -{ - asl_legacy1_slot_info_t *ai, *bi; - - if (a == NULL) - { - if (b == NULL) return 0; - return -1; - } - - if (b == NULL) return 1; - - ai = (asl_legacy1_slot_info_t *)a; - bi = (asl_legacy1_slot_info_t *)b; - - if (ai->xid < bi->xid) return -1; - - if (ai->xid == bi->xid) - { - if (ai->slot < bi->slot) return -1; - if (ai->slot == bi->slot) return 0; - return 1; - } - - return 1; -} - -/* find an xid in the slot list */ -static uint32_t -slotlist_find(asl_legacy1_t *s, uint64_t xid, int32_t direction) -{ - uint32_t top, bot, mid, range; - - if (s == NULL) return ASL_INDEX_NULL; - if (s->slotlist_count == 0) return ASL_INDEX_NULL; - if (xid == 0) return ASL_INDEX_NULL; - - top = s->slotlist_count - 1; - bot = 0; - mid = top / 2; - - range = top - bot; - while (range > 1) - { - if (xid == s->slotlist[mid].xid) return mid; - else if (xid < s->slotlist[mid].xid) top = mid; - else bot = mid; - - range = top - bot; - mid = bot + (range / 2); - } - - if (xid == s->slotlist[top].xid) return top; - if (xid == s->slotlist[bot].xid) return bot; - - if (direction == 0) return ASL_INDEX_NULL; - if (direction < 0) return bot; - return top; -} - -static uint32_t -slotlist_init(asl_legacy1_t *s, uint32_t count) -{ - uint32_t i, si, status, hash, addslot; - uint64_t xid; - uint8_t t; - size_t rcount; - char tmp[DB_RECORD_LEN]; - - /* Start at first slot after the header */ - status = fseek(s->db, DB_RECORD_LEN, SEEK_SET); - if (status != 0) return ASL_STATUS_READ_FAILED; - - s->slotlist = (asl_legacy1_slot_info_t *)calloc(count, sizeof(asl_legacy1_slot_info_t)); - if (s->slotlist == NULL) return ASL_STATUS_NO_MEMORY; - - si = 0; - - for (i = 1; i < count; i++) - { - rcount = fread(tmp, DB_RECORD_LEN, 1, s->db); - if (rcount != 1) return ASL_STATUS_READ_FAILED; - - t = tmp[0]; - addslot = 0; - xid = 0; - hash = 0; - - if (t == DB_TYPE_EMPTY) addslot = 1; - - if (t == DB_TYPE_STRING) - { - addslot = 1; - xid = header_get_id(tmp); - hash = header_get_hash(tmp); - } - - if (t == DB_TYPE_MESSAGE) - { - addslot = 1; - xid = header_get_id(tmp); - } - - if (addslot == 1) - { - s->slotlist[si].type = t; - s->slotlist[si].slot = i; - s->slotlist[si].xid = xid; - s->slotlist[si].hash = hash; - si++; - } - } - - s->slotlist = (asl_legacy1_slot_info_t *)reallocf(s->slotlist, si * sizeof(asl_legacy1_slot_info_t)); - if (s->slotlist == NULL) return ASL_STATUS_NO_MEMORY; - s->slotlist_count = si; - - /* slotlist is sorted by xid */ - qsort((void *)s->slotlist, s->slotlist_count, sizeof(asl_legacy1_slot_info_t), slot_comp); - - return ASL_STATUS_OK; -} - -uint32_t -asl_legacy1_open(const char *path, asl_legacy1_t **out) -{ - asl_legacy1_t *s; - struct stat sb; - int status; - size_t rcount; - char cbuf[DB_RECORD_LEN]; - off_t fsize; - uint32_t count; - - memset(&sb, 0, sizeof(struct stat)); - status = stat(path, &sb); - if (status < 0) return ASL_STATUS_FAILED; - - fsize = sb.st_size; - - s = (asl_legacy1_t *)calloc(1, sizeof(asl_legacy1_t)); - if (s == NULL) return ASL_STATUS_NO_MEMORY; - - s->db = fopen(path, "r"); - if (s->db == NULL) - { - free(s); - return ASL_STATUS_INVALID_STORE; - } - - memset(cbuf, 0, DB_RECORD_LEN); - rcount = fread(cbuf, DB_RECORD_LEN, 1, s->db); - if (rcount != 1) - { - fclose(s->db); - free(s); - return ASL_STATUS_READ_FAILED; - } - - /* Check the database Magic Cookie */ - if (strncmp(cbuf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN)) - { - fclose(s->db); - free(s); - return ASL_STATUS_INVALID_STORE; - } - - count = fsize / DB_RECORD_LEN; - - status = slotlist_init(s, count); - - *out = s; - return ASL_STATUS_OK; -} - -uint32_t -asl_legacy1_close(asl_legacy1_t *s) -{ - if (s == NULL) return ASL_STATUS_INVALID_STORE; - - if (s->slotlist != NULL) free(s->slotlist); - if (s->db != NULL) fclose(s->db); - free(s); - - return ASL_STATUS_OK; -} - -static uint32_t -string_fetch_slot(asl_legacy1_t *s, uint32_t slot, char **out) -{ - off_t offset; - uint8_t type; - uint32_t next, x, remaining; - size_t rcount, len; - int status; - char *outstr, *p, tmp[DB_RECORD_LEN]; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (out == NULL) return ASL_STATUS_INVALID_ARG; - - *out = NULL; - offset = slot * DB_RECORD_LEN; - status = fseek(s->db, offset, SEEK_SET); - - if (status < 0) return ASL_STATUS_READ_FAILED; - - rcount = fread(tmp, DB_RECORD_LEN, 1, s->db); - if (rcount != 1) return ASL_STATUS_READ_FAILED; - - type = tmp[0]; - if (type != DB_TYPE_STRING) return ASL_STATUS_INVALID_STRING; - - len = _asl_get_32(tmp + 21); - if (len == 0) return ASL_STATUS_OK; - - next = header_get_next(tmp); - - outstr = calloc(1, len); - if (outstr == NULL) return ASL_STATUS_NO_MEMORY; - - p = outstr; - remaining = len; - - x = DB_RECORD_LEN - DB_HLEN_STRING; - if (x > remaining) x = remaining; - - memcpy(p, tmp + DB_HLEN_STRING, x); - p += x; - remaining -= x; - - while ((next != 0) && (remaining > 0)) - { - offset = next * DB_RECORD_LEN; - status = fseek(s->db, offset, SEEK_SET); - - if (status < 0) - { - free(outstr); - return ASL_STATUS_READ_FAILED; - } - - rcount = fread(tmp, DB_RECORD_LEN, 1, s->db); - if (rcount != 1) - { - free(outstr); - return ASL_STATUS_READ_FAILED; - } - - next = header_get_next(tmp); - - x = DB_RECORD_LEN - DB_HLEN_STRCONT; - if (x > remaining) x = remaining; - - memcpy(p, tmp + DB_HLEN_STRCONT, x); - p += x; - remaining -= x; - } - - if ((next != 0) || (remaining != 0)) - { - free(outstr); - return ASL_STATUS_READ_FAILED; - } - - *out = outstr; - return ASL_STATUS_OK; -} - -static uint32_t -string_fetch_sid(asl_legacy1_t *s, uint64_t sid, char **out) -{ - uint32_t i, len, ref; - uint64_t nsid; - uint8_t inls; - char *p; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (out == NULL) return ASL_STATUS_INVALID_ARG; - - *out = NULL; - if (sid == ASL_REF_NULL) return ASL_STATUS_OK; - - ref = 0; - - inls = 0; - nsid = _asl_htonq(sid); - memcpy(&inls, &nsid, 1); - if (inls & 0x80) - { - /* inline string */ - inls &= 0x0f; - len = inls; - *out = calloc(1, len); - if (*out == NULL) return ASL_STATUS_NO_MEMORY; - p = 1 + (char *)&nsid; - memcpy(*out, p, len); - return ASL_STATUS_OK; - } - - /* Find the string in the database */ - i = slotlist_find(s, sid, 0); - if (i == ASL_INDEX_NULL) return ASL_STATUS_NOT_FOUND; - - return string_fetch_slot(s, s->slotlist[i].slot, out); -} - -static uint32_t -asl_legacy1_fetch_helper_32(asl_legacy1_t *s, char **p, aslmsg m, const char *key, int ignore, uint32_t ignoreval) -{ - uint32_t out, doit; - char str[256]; - - out = _asl_get_32(*p); - *p += sizeof(uint32_t); - - if ((m == NULL) || (key == NULL)) return out; - - doit = 1; - if ((ignore != 0) && (out == ignoreval)) doit = 0; - if (doit != 0) - { - snprintf(str, sizeof(str), "%u", out); - asl_set(m, key, str); - } - - return out; -} - -static uint64_t -asl_legacy1_fetch_helper_64(asl_legacy1_t *s, char **p, aslmsg m, const char *key) -{ - uint64_t out; - char str[256]; - - out = _asl_get_64(*p); - *p += sizeof(uint64_t); - - if ((m == NULL) || (key == NULL)) return out; - - snprintf(str, sizeof(str), "%llu", out); - asl_set(m, key, str); - - return out; -} - -static uint64_t -asl_legacy1_fetch_helper_str(asl_legacy1_t *s, char **p, aslmsg m, const char *key, uint32_t *err) -{ - uint64_t out; - char *val; - uint32_t status; - - out = _asl_get_64(*p); - *p += sizeof(uint64_t); - - val = NULL; - status = ASL_STATUS_OK; - if (out != 0) status = string_fetch_sid(s, out, &val); - - if (err != NULL) *err = status; - if ((status == ASL_STATUS_OK) && (val != NULL)) - { - asl_set(m, key, val); - free(val); - } - - return out; -} - -static uint32_t -msg_fetch(asl_legacy1_t *s, uint32_t slot, aslmsg *out) -{ - off_t offset; - uint32_t status, i, n, kvcount, next; - uint16_t flags; - uint64_t sid; - size_t rcount; - aslmsg msg; - int fstatus; - char *p, tmp[DB_RECORD_LEN], *key, *val; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (out == NULL) return ASL_STATUS_INVALID_ARG; - - *out = NULL; - - offset = slot * DB_RECORD_LEN; - fstatus = fseek(s->db, offset, SEEK_SET); - - if (fstatus < 0) return ASL_STATUS_READ_FAILED; - - rcount = fread(tmp, DB_RECORD_LEN, 1, s->db); - if (rcount != 1) return ASL_STATUS_READ_FAILED; - - flags = _asl_get_16(tmp + MSG_OFF_KEY_FLAGS); - - msg = asl_new(ASL_TYPE_MSG); - if (msg == NULL) return ASL_STATUS_NO_MEMORY; - - p = tmp + 5; - - asl_legacy1_fetch_helper_64(s, &p, msg, ASL_KEY_MSG_ID); - asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_READ_UID, 1, (uint32_t)-1); - asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_READ_GID, 1, (uint32_t)-1); - asl_legacy1_fetch_helper_64(s, &p, msg, ASL_KEY_TIME); - asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_HOST, &status); - asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_SENDER, &status); - asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_FACILITY, &status); - asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_LEVEL, 0, 0); - asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_PID, 0, 0); - asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_UID, 0, 0); - asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_GID, 0, 0); - asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_MSG, &status); - - next = header_get_next(tmp); - - kvcount = 0; - n = 0; - - while (next != 0) - { - offset = next * DB_RECORD_LEN; - fstatus = fseek(s->db, offset, SEEK_SET); - if (fstatus < 0) - { - free(out); - return ASL_STATUS_READ_FAILED; - } - - rcount = fread(tmp, DB_RECORD_LEN, 1, s->db); - if (rcount != 1) - { - free(out); - return ASL_STATUS_READ_FAILED; - } - - if (kvcount == 0) kvcount = _asl_get_32(tmp + 5); - - p = tmp + 9; - - for (i = 0; (i < 4) && (n < kvcount); i++) - { - key = NULL; - sid = _asl_get_64(p); - p += 8; - status = string_fetch_sid(s, sid, &key); - - val = NULL; - sid = _asl_get_64(p); - p += 8; - if (status == ASL_STATUS_OK) status = string_fetch_sid(s, sid, &val); - - if ((status == ASL_STATUS_OK) && (key != NULL)) asl_set(msg, key, val); - if (key != NULL) free(key); - if (val != NULL) free(val); - - n++; - } - - next = header_get_next(tmp); - } - - *out = msg; - return ASL_STATUS_OK; -} - -uint32_t -asl_legacy1_fetch(asl_legacy1_t *s, uint64_t msgid, aslmsg *out) -{ - uint32_t i, status; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (msgid == ASL_REF_NULL) return ASL_STATUS_INVALID_ARG; - if (out == NULL) return ASL_STATUS_INVALID_ARG; - - i = slotlist_find(s, msgid, 0); - if (i == ASL_INDEX_NULL) return ASL_STATUS_INVALID_ID; - - /* read the message */ - status = msg_fetch(s, s->slotlist[i].slot, out); - if (status != ASL_STATUS_OK) return status; - if (*out == NULL) return ASL_STATUS_FAILED; - - return status; -} - -static uint32_t -next_search_slot(asl_legacy1_t *s, uint32_t last_si, int32_t direction) -{ - uint32_t i; - - if (direction >= 0) - { - for (i = last_si + 1; i < s->slotlist_count; i++) - { - if (s->slotlist[i].type == DB_TYPE_MESSAGE) return i; - } - - return ASL_INDEX_NULL; - } - - if (last_si == 0) return ASL_INDEX_NULL; - if (last_si > s->slotlist_count) return ASL_INDEX_NULL; - - for (i = last_si - 1; i > 0; i--) - { - if (s->slotlist[i].type == DB_TYPE_MESSAGE) return i; - } - - if (s->slotlist[0].type == DB_TYPE_MESSAGE) return 0; - - return ASL_INDEX_NULL; -} - -static void -match_worker_cleanup(asl_msg_list_t **res) -{ - uint32_t i; - - if (res != NULL) - { - for (i = 0; i < (*res)->count; i++) asl_free((aslmsg)(*res)->msg[i]); - free(*res); - } -} - -/* - * Input to asl_legacy1_match is a list of queries. - * A record in the store matches if it matches any query (i.e. query list is "OR"ed) - * - * If counting up (direction is positive) find first record with ID > start_id. - * Else if counting down (direction is negative) find first record with ID < start_id. - * - * Set match flag on. - * If any query is NULL, set match flog off (skips matching below). - * Else if all queries only check "standard" keys, set std flag to on. - * - * If all queries are marked as "never matches", return NULL. - * - * match loop: - * fetch record (with std flag) - * if match flag is off, decode record and add it to result. - * else for each query: - * if query is NULL (shouldn't happen) decode record and add it to result. Return to match loop. - * else if query never matches, ignore it. - * else decode record and use asl_cmp. If it succeeds, add record to result. Return to match loop. - * - * return results. - */ -static uint32_t -match_worker(asl_legacy1_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint64_t *last_id, uint64_t **idlist, uint32_t *idcount, uint64_t start_id, int32_t count, int32_t direction) -{ - uint32_t mx, si, slot, i, qcount, match, didmatch, status; - uint64_t xid; - aslmsg msg; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if ((res == NULL) && (idlist == NULL)) return ASL_STATUS_INVALID_ARG; - if (last_id == NULL) return ASL_STATUS_INVALID_ARG; - if (idcount == NULL) return ASL_STATUS_INVALID_ARG; - - if (res != NULL) *res = NULL; - if (idlist != NULL) *idlist = NULL; - - mx = 0; - - if (direction < 0) direction = -1; - else direction = 1; - - si = ASL_INDEX_NULL; - if ((direction == -1) && (start_id == ASL_REF_NULL)) si = s->slotlist_count; - else si = slotlist_find(s, start_id, direction); - - si = next_search_slot(s, si, direction); - if (si == ASL_INDEX_NULL) return ASL_STATUS_OK; - if (si >= s->slotlist_count) return ASL_STATUS_FAILED; - - slot = s->slotlist[si].slot; - - match = 1; - qcount = 0; - - if (query == NULL) match = 0; - else if (query->count == 0) match = 0; - else qcount = query->count; - - /* - * initialize result list if we've been asked to return messages - */ - if (res != NULL) - { - *res = (asl_msg_list_t *)calloc(1, sizeof(asl_msg_list_t)); - if (*res == NULL) return ASL_STATUS_NO_MEMORY; - } - - status = ASL_STATUS_OK; - - /* - * loop through records - */ - *idcount = 0; - while ((count == 0) || (*idcount < count)) - { - if (si == ASL_INDEX_NULL) break; - if (si >= s->slotlist_count) break; - - slot = s->slotlist[si].slot; - xid = s->slotlist[si].xid; - - *last_id = xid; - - status = msg_fetch(s, slot, &msg); - - didmatch = 0; - if (match == 0) - { - didmatch = 1; - } - else - { - for (i = 0; i < qcount; i++) - { - didmatch = asl_msg_cmp((aslmsg)(query->msg[i]), msg); - if (didmatch == 1) break; - } - } - - if (didmatch == 1) - { - if ((*res)->count == 0) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *)); - else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, (1 + (*res)->count) * sizeof(asl_msg_t *)); - if ((*res)->msg == NULL) - { - match_worker_cleanup(res); - return ASL_STATUS_NO_MEMORY; - } - - (*res)->msg[(*res)->count++] = (asl_msg_t *)msg; - } - else - { - asl_free(msg); - } - - si = next_search_slot(s, si, direction); - } - - return status; -} - -uint32_t -asl_legacy1_match(asl_legacy1_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) -{ - uint32_t idcount; - - idcount = 0; - return match_worker(s, query, res, last_id, NULL, &idcount, start_id, count, direction); -} diff --git a/src/libc/gen/asl_legacy1.h b/src/libc/gen/asl_legacy1.h deleted file mode 100644 index a2efcde1a..000000000 --- a/src/libc/gen/asl_legacy1.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef __ASL_LEGACY1_H__ -#define __ASL_LEGACY1_H__ - -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ */ - -/* - * ASL Database VERSION 1 (LEGACY) - * - * Log messages are stored in 80 byte records of the form: - * - * | 1 | 4 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 4 | 4 | 4 | 4 | 8 | 2 | 1 | (80 bytes) - * | Type | Next | ID | RUID | RGID | Time | Host | Sender | Facility | LEVEL | PID | UID | GID | Message | Flags | Zero | - * - * If there are no additional key/value pairs in the message, Next will be zero. If there are additional - * key/value pairs in the database, Next is a record number for a record with the format: - * - * | 1 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 7 | (80 bytes) - * | Type | Next | Count | Key1 | Val1 | Key2 | Val2 | Key3 | Val3 | Key4 | Val4 | Zero | - * - * Additional records will be chained using the Next field, with the count field left zero. - * - * Strings stored in records of the form: - * - * | 1 | 4 | 8 | 4 | 4 | 4 | 55 | (80 bytes) - * | Type | Next | ID | Refcount | Hash | Length | String | - * - * If the string is longer than 55 bytes, Next is a record number for a record with the format: - * - * | 1 | 4 | 75 | (80 bytes) - * | Type | Next | String | - * - * The first record (header) in the database has the format: - * - * | 12 | 4 | 8 | 56 | (80 bytes) - * | Cookie | Vers | Max ID | Zero | - * - */ - -#include -#include -#include -#include -#include - -typedef struct -{ - uint8_t type; - uint32_t slot; - uint64_t xid; - uint32_t hash; -} asl_legacy1_slot_info_t; - -typedef struct -{ - asl_legacy1_slot_info_t *slotlist; - uint32_t slotlist_count; - FILE *db; -} asl_legacy1_t; - -uint32_t asl_legacy1_open(const char *path, asl_legacy1_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_legacy1_close(asl_legacy1_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_legacy1_fetch(asl_legacy1_t *s, uint64_t msgid, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_legacy1_match(asl_legacy1_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -#endif /*__ASL_LEGACY1_H__*/ diff --git a/src/libc/gen/asl_msg.c b/src/libc/gen/asl_msg.c deleted file mode 100644 index 5c611b9fe..000000000 --- a/src/libc/gen/asl_msg.c +++ /dev/null @@ -1,2613 +0,0 @@ -/* - * Copyright (c) 2009-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "asl_msg.h" - -#define TOKEN_NULL 0 -#define TOKEN_OPEN 1 -#define TOKEN_CLOSE 2 -#define TOKEN_WORD 3 -#define TOKEN_INT 4 - -#define MFMT_RAW 0 -#define MFMT_STD 1 -#define MFMT_BSD 2 -#define MFMT_XML 3 -#define MFMT_STR 4 -#define MFMT_MSG 5 - -#define SEC_PER_HOUR 3600 - -#define forever for(;;) - -#define streq(A, B) (strcmp(A, B) == 0) -#define streq_len(A, B, C) (strncmp(A, B, C) == 0) -#define strneq(A, B) (strcmp(A, B) != 0) -#define strcaseeq(A, B) (strcasecmp(A, B) == 0) -#define strcaseneq(A, B) (strcasecmp(A, B) != 0) - -#ifndef ASL_KEY_OPTION -#define ASL_KEY_OPTION "ASLOption" -#endif - -#ifndef ASL_QUERY_OP_FALSE -#define ASL_QUERY_OP_FALSE 0 -#endif - -#define AUX_0_TIME 0x00000001 -#define AUX_0_TIME_NSEC 0x00000002 -#define AUX_0_HOST 0x00000004 -#define AUX_0_SENDER 0x00000008 -#define AUX_0_FACILITY 0x00000010 -#define AUX_0_PID 0x00000020 -#define AUX_0_UID 0x00000040 -#define AUX_0_GID 0x00000080 -#define AUX_0_MSG 0x00000100 -#define AUX_0_OPTION 0x00000200 -#define AUX_0_LEVEL 0x00000400 - -extern time_t asl_parse_time(const char *in); - -/* from asl_util.c */ -int asl_is_utf8(const char *str); -uint8_t *asl_b64_encode(const uint8_t *buf, size_t len); - -static const char *ASLStandardKey[] = -{ - ASL_KEY_TIME, - ASL_KEY_TIME_NSEC, - ASL_KEY_HOST, - ASL_KEY_SENDER, - ASL_KEY_FACILITY, - ASL_KEY_PID, - ASL_KEY_UID, - ASL_KEY_GID, - ASL_KEY_LEVEL, - ASL_KEY_MSG, - ASL_KEY_READ_UID, - ASL_KEY_READ_GID, - ASL_KEY_SESSION, - ASL_KEY_REF_PID, - ASL_KEY_REF_PROC, - ASL_KEY_MSG_ID, - ASL_KEY_EXPIRE_TIME, - ASL_KEY_OPTION -}; - -static const char *MTStandardKey[] = -{ - "com.apple.message.domain", - "com.apple.message.domain_scope", - "com.apple.message.result", - "com.apple.message.signature", - "com.apple.message.signature2", - "com.apple.message.signature3", - "com.apple.message.success", - "com.apple.message.uuid", - "com.apple.message.value", - "com.apple.message.value2", - "com.apple.message.value3", - "com.apple.message.value4", - "com.apple.message.value5" -}; - -static uint16_t -_asl_msg_std_key(const char *s, uint32_t len) -{ - if ((len > 18) && (streq_len(s, "com.apple.message.", 18))) - { - if (streq(s + 18, "domain")) return ASL_MT_KEY_DOMAIN; - else if (streq(s + 18, "domain_scope")) return ASL_MT_KEY_SCOPE; - else if (streq(s + 18, "result")) return ASL_MT_KEY_RESULT; - else if (streq(s + 18, "signature")) return ASL_MT_KEY_SIG; - else if (streq(s + 18, "signature2")) return ASL_MT_KEY_SIG2; - else if (streq(s + 18, "signature3")) return ASL_MT_KEY_SIG3; - else if (streq(s + 18, "success")) return ASL_MT_KEY_SUCCESS; - else if (streq(s + 18, "uuid")) return ASL_MT_KEY_UUID; - else if (streq(s + 18, "value")) return ASL_MT_KEY_VAL; - else if (streq(s + 18, "value2")) return ASL_MT_KEY_VAL2; - else if (streq(s + 18, "value3")) return ASL_MT_KEY_VAL3; - else if (streq(s + 18, "value4")) return ASL_MT_KEY_VAL4; - else if (streq(s + 18, "value5")) return ASL_MT_KEY_VAL5; - - return 0; - } - - switch (len) - { - case 3: - { - if streq(s, ASL_KEY_PID) return ASL_STD_KEY_PID; - else if streq(s, ASL_KEY_UID) return ASL_STD_KEY_UID; - else if streq(s, ASL_KEY_GID) return ASL_STD_KEY_GID; - } - case 4: - { - if streq(s, ASL_KEY_TIME) return ASL_STD_KEY_TIME; - else if streq(s, ASL_KEY_HOST) return ASL_STD_KEY_HOST; - } - case 5: - { - if streq(s, ASL_KEY_LEVEL) return ASL_STD_KEY_LEVEL; - } - case 6: - { - if streq(s, ASL_KEY_SENDER) return ASL_STD_KEY_SENDER; - else if streq(s, ASL_KEY_REF_PID) return ASL_STD_KEY_REF_PID; - } - case 7: - { - if streq(s, ASL_KEY_MSG) return ASL_STD_KEY_MESSAGE; - else if streq(s, ASL_KEY_SESSION) return ASL_STD_KEY_SESSION; - else if streq(s, ASL_KEY_READ_UID) return ASL_STD_KEY_READ_UID; - else if streq(s, ASL_KEY_READ_GID) return ASL_STD_KEY_READ_GID; - else if streq(s, ASL_KEY_REF_PROC) return ASL_STD_KEY_REF_PROC; - } - case 8: - { - if streq(s, ASL_KEY_FACILITY) return ASL_STD_KEY_FACILITY; - } - case 9: - { - if streq(s, ASL_KEY_OPTION) return ASL_STD_KEY_OPTION; - } - case 11: - { - if streq(s, ASL_KEY_TIME_NSEC) return ASL_STD_KEY_NANO; - } - case 12: - { - if streq(s, ASL_KEY_MSG_ID) return ASL_STD_KEY_MSG_ID; - } - case 13: - { - if streq(s, ASL_KEY_EXPIRE_TIME) return ASL_STD_KEY_EXPIRE; - } - default: - { - return 0; - } - } - - return 0; -} - -static asl_msg_t * -_asl_msg_make_page() -{ - asl_msg_t *out; - int i; - - out = calloc(1, sizeof(asl_msg_t)); - if (out == NULL) return NULL; - - for (i = 0; i < ASL_MSG_PAGE_SLOTS; i++) - { - out->key[i] = ASL_MSG_SLOT_FREE; - out->val[i] = ASL_MSG_SLOT_FREE; - } - - return out; -} - -static const char * -_asl_msg_slot_key(asl_msg_t *page, uint32_t slot) -{ - const char *out; - uint16_t x; - - if (page == NULL) return NULL; - if (slot >= ASL_MSG_PAGE_SLOTS) return NULL; - - if (page->key[slot] == ASL_MSG_SLOT_FREE) return NULL; - - switch (page->key[slot] & ASL_MSG_KV_MASK) - { - case ASL_MSG_KV_INLINE: - { - return page->data + page->key[slot]; - } - case ASL_MSG_KV_DICT: - { - if ((page->key[slot] > ASL_STD_KEY_BASE) && (page->key[slot] <= ASL_STD_KEY_LAST)) - { - x = page->key[slot] - ASL_STD_KEY_BASE - 1; - return ASLStandardKey[x]; - } - else if ((page->key[slot] > ASL_MT_KEY_BASE) && (page->key[slot] <= ASL_MT_KEY_LAST)) - { - x = page->key[slot] - ASL_MT_KEY_BASE - 1; - return MTStandardKey[x]; - } - - return NULL; - } - case ASL_MSG_KV_EXTERN: - { - x = page->key[slot] & ASL_MSG_OFFSET_MASK; - memcpy(&out, page->data + x, sizeof(char *)); - return out; - } - } - - return NULL; -} - -static const char * -_asl_msg_slot_val(asl_msg_t *page, uint32_t slot) -{ - const char *out; - uint16_t x, type; - - if (page == NULL) return NULL; - if (slot >= ASL_MSG_PAGE_SLOTS) return NULL; - - if (page->val[slot] == ASL_MSG_SLOT_FREE) return NULL; - - type = page->val[slot] & ASL_MSG_KV_MASK; - - if (type == ASL_MSG_KV_INLINE) - { - return page->data + page->val[slot]; - } - else if (type == ASL_MSG_KV_EXTERN) - { - x = page->val[slot] & ASL_MSG_OFFSET_MASK; - memcpy(&out, page->data + x, sizeof(char *)); - return out; - } - - return NULL; -} - -/* - * asl_new: create a new log message. - */ -asl_msg_t * -asl_msg_new(uint32_t type) -{ - asl_msg_t *out; - - out = _asl_msg_make_page(); - if (out == NULL) return NULL; - - out->type = type; - out->refcount = 1; - - return out; -} - -asl_msg_t * -asl_msg_retain(asl_msg_t *msg) -{ - int32_t new; - - if (msg == NULL) return NULL; - - new = OSAtomicIncrement32Barrier(&msg->refcount); - assert(new >= 1); - - return msg; -} - -static void -_asl_msg_free(asl_msg_t *page) -{ - uint32_t i; - char *p; - - if (page == NULL) return; - - for (i = 0; i < ASL_MSG_PAGE_SLOTS; i++) - { - if ((page->key[i] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) - { - memcpy(&p, page->data + (page->key[i] & ASL_MSG_OFFSET_MASK), sizeof(char *)); - free(p); - } - - if ((page->val[i] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) - { - memcpy(&p, page->data + (page->val[i] & ASL_MSG_OFFSET_MASK), sizeof(char *)); - free(p); - } - } - - free(page); -} - -void -asl_msg_release(asl_msg_t *msg) -{ - int32_t new; - asl_msg_t *next; - - if (msg == NULL) return; - - new = OSAtomicDecrement32Barrier(&msg->refcount); - assert(new >= 0); - - if (new > 0) return; - - while (msg != NULL) - { - next = msg->next; - _asl_msg_free(msg); - msg = next; - } -} - -static uint32_t -_asl_msg_index(asl_msg_t *msg, const char *key, uint32_t *oslot, asl_msg_t **opage) -{ - uint32_t i, len, slot; - uint16_t kx; - asl_msg_t *page; - const char *kp; - - if (msg == NULL) return IndexNull; - if (key == NULL) return IndexNull; - - i = 0; - slot = 0; - if (oslot != NULL) *oslot = slot; - - page = msg; - if (opage != NULL) *opage = page; - - len = strlen(key); - kx = _asl_msg_std_key(key, len); - - forever - { - if (page->key[slot] != ASL_MSG_SLOT_FREE) - { - if (kx != 0) - { - if (page->key[slot] == kx) return i; - } - else if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_DICT) - { - /* page->key[slot] is a dictionary key, but key is not (kx == 0) so skip this slot */ - } - else if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) - { - memcpy(&kp, page->data + (page->key[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *)); - if (streq(key, kp)) return i; - } - else - { - kp = page->data + page->key[slot]; - if (streq(key, kp)) return i; - } - } - - i++; - slot++; - if (oslot != NULL) *oslot = slot; - - if (slot >= ASL_MSG_PAGE_SLOTS) - { - if (page->next == NULL) return IndexNull; - - slot = 0; - if (oslot != NULL) *oslot = slot; - - page = page->next; - if (opage != NULL) *opage = page; - } - } - - return IndexNull; -} - -/* - * asl_msg_key: iterate over entries - * initial value of n should be 0 - * after that, the value of n should be previously returned value - * sets the pointers for the next key, value, and op in the msgionary - * returns IndexNull when there are no more entries - */ -static uint32_t -_asl_msg_fetch_internal(asl_msg_t *msg, uint32_t n, const char **keyout, const char **valout, uint32_t *opout, asl_msg_t **outpage, uint32_t *outslot) -{ - uint32_t slot; - asl_msg_t *page; - - if (msg == NULL) return IndexNull; - if (outpage != NULL) *outpage = NULL; - if (outslot != NULL) *outslot = IndexNull; - - slot = n; - page = msg; - - while (slot >= ASL_MSG_PAGE_SLOTS) - { - if (page->next == NULL) return IndexNull; - page = page->next; - slot -= ASL_MSG_PAGE_SLOTS; - } - - while (page->key[slot] == ASL_MSG_SLOT_FREE) - { - slot++; - n++; - - if (slot >= ASL_MSG_PAGE_SLOTS) - { - if (page->next == NULL) return IndexNull; - page = page->next; - slot = 0; - } - } - - n++; - - if (keyout != NULL) *keyout = _asl_msg_slot_key(page, slot); - if (valout != NULL) *valout = _asl_msg_slot_val(page, slot); - if (opout != NULL) *opout = page->op[slot]; - - if (outpage != NULL) *outpage = page; - if (outslot != NULL) *outslot = slot; - - return n; -} - -uint32_t -asl_msg_fetch(asl_msg_t *msg, uint32_t n, const char **keyout, const char **valout, uint32_t *opout) -{ - return _asl_msg_fetch_internal(msg, n, keyout, valout, opout, NULL, NULL); -} - -static int -_asl_msg_new_key_val_op(asl_msg_t *msg, const char *key, const char *val, uint32_t op) -{ - uint32_t slot, keylen, vallen, total; - uint16_t kx; - asl_msg_t *page, *last; - char *extkey, *extval; - - if (msg == NULL) return -1; - if (key == NULL) return -1; - - extkey = NULL; - extval = NULL; - - keylen = strlen(key); - kx = _asl_msg_std_key(key, keylen); - - if (kx == 0) keylen++; - else keylen = 0; - - total = keylen; - - vallen = 0; - if (val != NULL) - { - vallen = strlen(val) + 1; - total += vallen; - } - - /* check if one or both of key and value must be "external" (in its own malloced space) */ - if (keylen > ASL_MSG_PAGE_DATA_SIZE) - { - extkey = strdup(key); - keylen = sizeof(char *); - } - - if (vallen > ASL_MSG_PAGE_DATA_SIZE) - { - extval = strdup(val); - vallen = sizeof(char *); - } - - total = keylen + vallen; - if ((total > ASL_MSG_PAGE_DATA_SIZE) && (extval == NULL) && (keylen > 0)) - { - extval = strdup(val); - vallen = sizeof(char *); - total = keylen + vallen; - } - - if ((total > ASL_MSG_PAGE_DATA_SIZE) && (extkey == NULL)) - { - extkey = strdup(key); - keylen = sizeof(char *); - total = keylen + vallen; - } - - if (total > ASL_MSG_PAGE_DATA_SIZE) - { - /* can't happen, but... */ - if (extkey != NULL) free(extkey); - if (extval != NULL) free(extval); - return -1; - } - - /* find a page with space for the key and value and a free slot*/ - slot = 0; - last = msg; - - for (page = msg; page != NULL; page = page->next) - { - last = page; - - if (total <= (ASL_MSG_PAGE_DATA_SIZE - page->data_size)) - { - /* check for a free slot */ - for (slot = 0; (slot < ASL_MSG_PAGE_SLOTS) && (page->key[slot] != ASL_MSG_SLOT_FREE); slot++); - if (slot < ASL_MSG_PAGE_SLOTS) break; - } - } - - if (page == NULL) - { - /* allocate a new page and attach it */ - page = _asl_msg_make_page(); - if (page == NULL) - { - if (extkey != NULL) free(extkey); - if (extval != NULL) free(extval); - return -1; - } - - last->next = page; - slot = 0; - } - - /* copy key or external key pointer into page data */ - if (kx != 0) - { - page->key[slot] = kx; - } - else if (extkey == NULL) - { - page->key[slot] = page->data_size; - memcpy(page->data + page->data_size, key, keylen); - } - else - { - page->key[slot] = page->data_size | ASL_MSG_KV_EXTERN; - memcpy(page->data + page->data_size, &extkey, keylen); - } - - page->data_size += keylen; - - /* copy val or external val pointer into page data */ - page->val[slot] = ASL_MSG_SLOT_FREE; - - if (val != NULL) - { - if (extval == NULL) - { - page->val[slot] = page->data_size; - memcpy(page->data + page->data_size, val, vallen); - } - else - { - page->val[slot] = page->data_size | ASL_MSG_KV_EXTERN; - memcpy(page->data + page->data_size, &extval, vallen); - } - - page->data_size += vallen; - } - - /* set op */ - page->op[slot] = op; - - /* update page count */ - page->count++; - - return 0; -} - -/* - * Most of the code in asl_msg_set_key_val_op is concerned with trying to re-use - * space in an asl_msg_t page when given a new value for an existing key. - * If the key is new, we just call _asl_msg_new_key_val_op. - * - * Note that queries can have duplicate keys, so for ASL_TYPE_QUERY we just - * call through to _asl_msg_new_key_val_op. - */ -static int -_asl_msg_set_kvo(asl_msg_t *msg, const char *key, const char *val, uint32_t op) -{ - uint32_t i, slot, newexternal; - asl_msg_t *page; - uint32_t intvallen, extvallen, newvallen; - char *intval, *extval, *newval; - - if (msg == NULL) return -1; - if (key == NULL) return -1; - - slot = IndexNull; - page = NULL; - - if ((msg->type == ASL_TYPE_QUERY) || (IndexNull == _asl_msg_index(msg, key, &slot, &page))) - { - /* add key */ - return _asl_msg_new_key_val_op(msg, key, val, op); - } - - intval = NULL; - intvallen = 0; - - extval = NULL; - extvallen = 0; - - if (page->val[slot] != ASL_MSG_SLOT_FREE) - { - if ((page->val[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) - { - i = page->val[slot] & ASL_MSG_OFFSET_MASK; - memcpy(&extval, page->data + i, sizeof(char *)); - extvallen = sizeof(char *); - } - else - { - intval = page->data + page->val[slot]; - intvallen = strlen(intval) + 1; - } - } - - /* replace val and op for existing entry */ - - /* easy case - remove val */ - if (val == NULL) - { - if (extval != NULL) free(extval); - page->val[slot] = ASL_MSG_SLOT_FREE; - if (op != IndexNull) page->op[slot] = op; - return 0; - } - - /* trivial case - internal val doesn't change */ - if ((intval != NULL) && (streq(val, intval))) - { - if (op != IndexNull) page->op[slot] = op; - return 0; - } - - /* trivial case - external val doesn't change */ - if ((extval != NULL) && (streq(val, extval))) - { - if (op != IndexNull) page->op[slot] = op; - return 0; - } - - /* - * special case: we generally don't compress out holes in the data - * space, but if this is the last string in the currently used data space - * we can just back up the data_size and reset page->val[slot] - */ - i = page->val[slot] & ASL_MSG_OFFSET_MASK; - if ((intval != NULL) && ((i + intvallen) == page->data_size)) - { - page->val[slot] = ASL_MSG_SLOT_FREE; - page->data_size -= intvallen; - intval = NULL; - intvallen = 0; - } - else if ((extval != NULL) && ((i + extvallen) == page->data_size)) - { - page->val[slot] = ASL_MSG_SLOT_FREE; - page->data_size -= extvallen; - free(extval); - extval = NULL; - extvallen = 0; - } - - /* val changes - see if it needs to be external */ - newvallen = strlen(val) + 1; - newexternal = 0; - - if (newvallen > ASL_MSG_PAGE_DATA_SIZE) - { - newexternal = 1; - newvallen = sizeof(char *); - } - - /* check if there is room to change val in place */ - if (((extval != NULL) && (newvallen <= extvallen)) || ((extval == NULL) && (newvallen <= intvallen))) - { - if (extval != NULL) free(extval); - extval = NULL; - - /* we can re-use the space of the old value */ - i = page->val[slot] & ASL_MSG_OFFSET_MASK; - - if (newexternal == 1) - { - /* create an external val and copy in the new pointer */ - newval = strdup(val); - if (newval == NULL) return -1; - - page->val[slot] = i | ASL_MSG_KV_EXTERN; - memcpy(page->data + i, &newval, sizeof(char *)); - } - else - { - /* new internal value */ - page->val[slot] = i; - memcpy(page->data + i, val, newvallen); - } - - if (op != IndexNull) page->op[slot] = op; - return 0; - } - - /* we're done with the old value if it is external - free it now */ - if (extval != NULL) free(extval); - extval = NULL; - - if (newvallen <= (ASL_MSG_PAGE_DATA_SIZE - page->data_size)) - { - /* can't re-use the old space, but there's room on the page */ - i = page->data_size; - page->data_size += newvallen; - - if (newexternal == 1) - { - /* create an external val and copy in the new pointer */ - newval = strdup(val); - if (newval == NULL) return -1; - - page->val[slot] = i | ASL_MSG_KV_EXTERN; - memcpy(page->data + i, &newval, sizeof(char *)); - } - else - { - /* new internal value */ - page->val[slot] = i; - memcpy(page->data + i, val, newvallen); - } - - if (op != IndexNull) page->op[slot] = op; - return 0; - - } - - /* no room on this page - free up existing entry and treat this as a new entry */ - if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) - { - memcpy(&extval, page->data + (page->key[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *)); - free(extval); - } - - page->key[slot] = ASL_MSG_SLOT_FREE; - page->val[slot] = ASL_MSG_SLOT_FREE; - page->op[slot] = 0; - - return _asl_msg_new_key_val_op(msg, key, val, op); -} - -int -asl_msg_set_key_val_op(asl_msg_t *msg, const char *key, const char *val, uint32_t op) -{ - char *special, buf[512]; - uint32_t i, len; - int status; - - /* Special case handling */ - special = NULL; - - /* convert "Level" values to "0" through "7" */ - if (streq(key, ASL_KEY_LEVEL)) - { - if (val == NULL) val = "7"; - else if ((val[0] >= '0') && (val[0] <= '7') && (val[1] == '\0')) /* do nothing */; - else if (strcaseeq(val, ASL_STRING_EMERG)) val = "0"; - else if (strcaseeq(val, ASL_STRING_ALERT)) val = "1"; - else if (strcaseeq(val, ASL_STRING_CRIT)) val = "2"; - else if (strcaseeq(val, ASL_STRING_ERR)) val = "3"; - else if (strcaseeq(val, ASL_STRING_WARNING)) val = "4"; - else if (strcaseeq(val, ASL_STRING_NOTICE)) val = "5"; - else if (strcaseeq(val, ASL_STRING_INFO)) val = "6"; - else if (strcaseeq(val, ASL_STRING_DEBUG)) val = "7"; - else val = "7"; - } - - /* strip trailing newlines from "Message" values */ - if ((streq(key, ASL_KEY_MSG)) && (val != NULL)) - { - len = strlen(val); - i = len; - while ((i > 0) && (val[i - 1] == '\n')) i--; - if (i == 0) val = NULL; - else if (i < len) - { - /* use buf if it is big enough, else malloc a temporary buffer */ - if (i < sizeof(buf)) - { - memcpy(buf, val, i); - buf[i] = 0; - val = (const char *)buf; - } - else - { - special = malloc(i + 1); - if (special == NULL) return -1; - memcpy(special, val, i); - special[i] = 0; - val = (const char *)special; - } - } - } - - status = _asl_msg_set_kvo(msg, key, val, op); - - if (special != NULL) free(special); - return status; -} - -int -asl_msg_set_key_val(asl_msg_t *msg, const char *key, const char *val) -{ - return asl_msg_set_key_val_op(msg, key, val, 0); -} - -/* - * Merge a key / val into a message (only ASL_TYPE_MSG). - * Adds the key / val if the key is not found. - * Does not replace the value if the key is found. - */ -static void -_asl_msg_merge_key_val(asl_msg_t *msg, const char *key, const char *val) -{ - uint32_t i, slot; - asl_msg_t *page; - - if (msg == NULL) return; - if (key == NULL) return; - - slot = IndexNull; - page = NULL; - - i = _asl_msg_index(msg, key, &slot, &page); - if (i != IndexNull) return; - - asl_msg_set_key_val_op(msg, key, val, 0); -} - -/* - * Merge msg into target (does not replace existing keys). - * Creates a new asl_msg_t if target is NULL. - * Returns target. - */ -asl_msg_t * -asl_msg_merge(asl_msg_t *target, asl_msg_t *msg) -{ - uint32_t x, slot, op, isnew = 0; - const char *key, *val; - asl_msg_t *page; - - if (msg == NULL) return target; - - if (target == NULL) - { - isnew = 1; - target = asl_msg_new(ASL_TYPE_MSG); - } - - for (x = _asl_msg_fetch_internal(msg, 0, &key, &val, &op, &page, &slot); x != IndexNull; x = _asl_msg_fetch_internal(msg, x, &key, &val, &op, &page, &slot)) - { - if (isnew == 1) asl_msg_set_key_val_op(target, key, val, 0); - else _asl_msg_merge_key_val(target, key, val); - } - - return target; -} - -/* - * Copy msg. - */ -asl_msg_t * -asl_msg_copy(asl_msg_t *msg) -{ - return asl_msg_merge(NULL, msg); -} - -/* - * asl_msg_unset - * Frees external key and val strings, but does not try to reclaim data space. - */ -void -asl_msg_unset(asl_msg_t *msg, const char *key) -{ - uint32_t i, slot; - asl_msg_t *page; - char *ext; - - if (msg == NULL) return; - if (key == NULL) return; - - slot = IndexNull; - page = NULL; - - i = _asl_msg_index(msg, key, &slot, &page); - if (i == IndexNull) return; - - if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) - { - memcpy(&ext, page->data + (page->key[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *)); - free(ext); - } - - if ((page->val[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN) - { - memcpy(&ext, page->data + (page->val[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *)); - free(ext); - } - - page->key[slot] = ASL_MSG_SLOT_FREE; - page->val[slot] = ASL_MSG_SLOT_FREE; - page->op[slot] = 0; - - page->count--; -} - -int -asl_msg_lookup(asl_msg_t *msg, const char *key, const char **valout, uint32_t *opout) -{ - uint32_t i, slot; - asl_msg_t *page; - - slot = IndexNull; - page = NULL; - - i = _asl_msg_index(msg, key, &slot, &page); - if (i == IndexNull) return -1; - - if (valout != NULL) *valout = _asl_msg_slot_val(page, slot); - if (opout != NULL) *opout = page->op[slot]; - - return 0; -} - -uint32_t -asl_msg_type(asl_msg_t *msg) -{ - if (msg == NULL) return 0; - return msg->type; -} - -uint32_t -asl_msg_count(asl_msg_t *msg) -{ - uint32_t total; - - total = 0; - - for (; msg != NULL; msg = msg->next) total += msg->count; - return total; -} - -/* - * Compare messages - */ -static int -_asl_msg_equal(asl_msg_t *a, asl_msg_t *b) -{ - uint32_t x, oa, ob; - const char *key, *va, *vb; - - if (asl_msg_count(a) != asl_msg_count(b)) return 0; - - key = NULL; - va = NULL; - oa = 0; - - - for (x = asl_msg_fetch(a, 0, &key, &va, &oa); x != IndexNull; x = asl_msg_fetch(a, x, &key, &va, &oa)) - { - if (asl_msg_lookup(b, key, &vb, &ob) != 0) return 0; - if (strcmp(va, vb)) return 0; - if ((a->type == ASL_TYPE_QUERY) && (oa != ob)) return 0; - } - - return 1; -} - -static int -_asl_isanumber(const char *s) -{ - int i; - - if (s == NULL) return 0; - - i = 0; - if ((s[0] == '-') || (s[0] == '+')) i = 1; - - if (s[i] == '\0') return 0; - - for (; s[i] != '\0'; i++) - { - if (!isdigit(s[i])) return 0; - } - - return 1; -} - -static int -_asl_msg_basic_test(uint32_t op, const char *q, const char *m, uint32_t n) -{ - int cmp; - uint32_t t; - int64_t nq, nm; - int rflags; - regex_t rex; - - t = op & ASL_QUERY_OP_TRUE; - - /* NULL value from query or message string fails */ - if ((q == NULL) || (m == NULL)) return (t & ASL_QUERY_OP_NOT_EQUAL); - - if (op & ASL_QUERY_OP_REGEX) - { - /* greater than or less than make no sense in substring search */ - if ((t == ASL_QUERY_OP_GREATER) || (t == ASL_QUERY_OP_LESS)) return 0; - - memset(&rex, 0, sizeof(regex_t)); - - rflags = REG_EXTENDED | REG_NOSUB; - if (op & ASL_QUERY_OP_CASEFOLD) rflags |= REG_ICASE; - - /* A bad reqular expression matches nothing */ - if (regcomp(&rex, q, rflags) != 0) return (t & ASL_QUERY_OP_NOT_EQUAL); - - cmp = regexec(&rex, m, 0, NULL, 0); - regfree(&rex); - - if (t == ASL_QUERY_OP_NOT_EQUAL) return (cmp != 0); - return (cmp == 0); - } - - if (op & ASL_QUERY_OP_NUMERIC) - { - if (_asl_isanumber(q) == 0) return (t == ASL_QUERY_OP_NOT_EQUAL); - if (_asl_isanumber(m) == 0) return (t == ASL_QUERY_OP_NOT_EQUAL); - - nq = atoll(q); - nm = atoll(m); - - switch (t) - { - case ASL_QUERY_OP_EQUAL: return (nm == nq); - case ASL_QUERY_OP_GREATER: return (nm > nq); - case ASL_QUERY_OP_GREATER_EQUAL: return (nm >= nq); - case ASL_QUERY_OP_LESS: return (nm < nq); - case ASL_QUERY_OP_LESS_EQUAL: return (nm <= nq); - case ASL_QUERY_OP_NOT_EQUAL: return (nm != nq); - default: return (t == ASL_QUERY_OP_NOT_EQUAL); - } - } - - cmp = 0; - if (op & ASL_QUERY_OP_CASEFOLD) - { - if (n == 0) cmp = strcasecmp(m, q); - else cmp = strncasecmp(m, q, n); - } - else - { - if (n == 0) cmp = strcmp(m, q); - else cmp = strncmp(m, q, n); - } - - switch (t) - { - case ASL_QUERY_OP_EQUAL: return (cmp == 0); - case ASL_QUERY_OP_GREATER: return (cmp > 0); - case ASL_QUERY_OP_GREATER_EQUAL: return (cmp >= 0); - case ASL_QUERY_OP_LESS: return (cmp < 0); - case ASL_QUERY_OP_LESS_EQUAL: return (cmp <= 0); - case ASL_QUERY_OP_NOT_EQUAL: return (cmp != 0); - } - - return (t == ASL_QUERY_OP_NOT_EQUAL); -} - -static int -_asl_msg_test_substring(uint32_t op, const char *q, const char *m) -{ - uint32_t t, i, d, lm, lq, match, newop; - - t = op & ASL_QUERY_OP_TRUE; - - lm = 0; - if (m != NULL) lm = strlen(m); - - lq = 0; - if (q != NULL) lq = strlen(q); - - /* NULL is a substring of any string */ - if (lq == 0) return (t & ASL_QUERY_OP_EQUAL); - - /* A long string is defined to be not equal to a short string */ - if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL); - - /* greater than or less than make no sense in substring search */ - if ((t == ASL_QUERY_OP_GREATER) || (t == ASL_QUERY_OP_LESS)) return 0; - - /* - * We scan the string doing an equality test. - * If the input test is equality, we stop as soon as we hit a match. - * Otherwise we keep scanning the whole message string. - */ - newop = op & 0xff0; - newop |= ASL_QUERY_OP_EQUAL; - - match = 0; - d = lm - lq; - for (i = 0; i <= d; i++) - { - if (_asl_msg_basic_test(newop, q, m + i, lq) != 0) - { - if (t & ASL_QUERY_OP_EQUAL) return 1; - match++; - } - } - - /* If the input test was for equality, no matches were found */ - if (t & ASL_QUERY_OP_EQUAL) return 0; - - /* The input test was for not equal. Return true if no matches were found */ - return (match == 0); -} - -static int -_asl_msg_test_prefix(uint32_t op, const char *q, const char *m) -{ - uint32_t lm, lq, t; - - t = op & ASL_QUERY_OP_TRUE; - - lm = 0; - if (m != NULL) lm = strlen(m); - - lq = 0; - if (q != NULL) lq = strlen(q); - - /* NULL is a prefix of any string */ - if (lq == 0) return (t & ASL_QUERY_OP_EQUAL); - - /* A long string is defined to be not equal to a short string */ - if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL); - - /* Compare two equal-length strings */ - return _asl_msg_basic_test(op, q, m, lq); -} - -static int -_asl_msg_test_suffix(uint32_t op, const char *q, const char *m) -{ - uint32_t lm, lq, d, t; - - t = op & ASL_QUERY_OP_TRUE; - - lm = 0; - if (m != NULL) lm = strlen(m); - - lq = 0; - if (q != NULL) lq = strlen(q); - - /* NULL is a suffix of any string */ - if (lq == 0) return (t & ASL_QUERY_OP_EQUAL); - - /* A long string is defined to be not equal to a short string */ - if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL); - - /* Compare two equal-length strings */ - d = lm - lq; - return _asl_msg_basic_test(op, q, m + d, lq); -} - -/* - * Splits out prefix, suffix, and substring tests. - * Sends the rest to _asl_msg_basic_test(). - */ -static int -_asl_msg_test_expression(uint32_t op, const char *q, const char *m) -{ - uint32_t t; - - t = op & ASL_QUERY_OP_TRUE; - if (t == ASL_QUERY_OP_TRUE) return 1; - - if (op & ASL_QUERY_OP_PREFIX) - { - if (op & ASL_QUERY_OP_SUFFIX) return _asl_msg_test_substring(op, q, m); - return _asl_msg_test_prefix(op, q, m); - } - if (op & ASL_QUERY_OP_SUFFIX) return _asl_msg_test_suffix(op, q, m); - - return _asl_msg_basic_test(op, q, m, 0); -} - -/* - * Special case for comparing time values. - * If both inputs are time strings, this compares the time - * value in seconds. Otherwise it just does normal matching. - */ -static int -_asl_msg_test_time_expression(uint32_t op, const char *q, const char *m) -{ - time_t tq, tm; - uint32_t t; - - if ((op & ASL_QUERY_OP_PREFIX) || (op & ASL_QUERY_OP_SUFFIX) || (op & ASL_QUERY_OP_REGEX)) return _asl_msg_test_expression(op, q, m); - if ((q == NULL) || (m == NULL)) return _asl_msg_test_expression(op, q, m); - - tq = asl_parse_time(q); - if (tq < 0) return _asl_msg_test_expression(op, q, m); - - tm = asl_parse_time(m); - if (tm < 0) return _asl_msg_test_expression(op, q, m); - - t = op & ASL_QUERY_OP_TRUE; - - switch (t) - { - case ASL_QUERY_OP_FALSE: - { - return 0; - } - case ASL_QUERY_OP_EQUAL: - { - if (tm == tq) return 1; - return 0; - } - case ASL_QUERY_OP_GREATER: - { - if (tm > tq) return 1; - return 0; - } - case ASL_QUERY_OP_GREATER_EQUAL: - { - if (tm >= tq) return 1; - return 0; - } - case ASL_QUERY_OP_LESS: - { - if (tm < tq) return 1; - return 0; - } - case ASL_QUERY_OP_LESS_EQUAL: - { - if (tm <= tq) return 1; - return 0; - } - case ASL_QUERY_OP_NOT_EQUAL: - { - if (tm != tq) return 1; - return 0; - } - case ASL_QUERY_OP_TRUE: - { - return 1; - } - } - - /* NOTREACHED */ - return 0; -} - -/* test a query against a message */ -static int -_asl_msg_test(asl_msg_t *q, asl_msg_t *m) -{ - uint32_t i, t, x, op; - int cmp; - const char *kq, *vq, *vm; - - /* - * Check each simple expression (key op val) separately. - * The query suceeds (returns 1) if all simple expressions - * succeed (i.e. AND the simple expressions). - */ - - kq = NULL; - vq = NULL; - op = 0; - - for (x = asl_msg_fetch(q, 0, &kq, &vq, &op); x != IndexNull; x = asl_msg_fetch(q, x, &kq, &vq, &op)) - { - /* Find query key in the message */ - vm = NULL; - i = asl_msg_lookup(m, kq, &vm, NULL); - - /* ASL_QUERY_OP_TRUE tests if key is present in the message */ - t = op & ASL_QUERY_OP_TRUE; - if (t == ASL_QUERY_OP_TRUE) - { - if (i != 0) return 0; - continue; - } - - /* ASL_QUERY_OP_FALSE tests if the key is NOT present in the message */ - if (t == ASL_QUERY_OP_FALSE) - { - if (i == 0) return 0; - continue; - } - - if (i != 0) - { - /* the message does NOT have query key - fail unless we are testing not equal */ - if (t == ASL_QUERY_OP_NOT_EQUAL) continue; - return 0; - } - - cmp = 1; - if (streq(kq, ASL_KEY_TIME)) - { - cmp = _asl_msg_test_time_expression(op, vq, vm); - } - else - { - cmp = _asl_msg_test_expression(op, vq, vm); - } - - if (cmp == 0) return 0; - } - - return 1; -} - -int -asl_msg_cmp(asl_msg_t *a, asl_msg_t *b) -{ - - if (a == NULL) return 0; - if (b == NULL) return 0; - - if (a->type == b->type) return _asl_msg_equal(a, b); - if (a->type == ASL_TYPE_QUERY) return _asl_msg_test(a, b); - return _asl_msg_test(b, a); -} - - -static char * -_asl_time_string(const char *fmt, const char *str) -{ - time_t tick, off; - struct tm stm; - char *ltime; - char *out; - char ltbuf[32]; - out = NULL; - time_t min; - const char *p = fmt; - - tick = 0; - if (str != NULL) tick = asl_parse_time(str); - - /* default format is local time zone */ - if ((fmt == NULL) || (!strcasecmp(fmt, "lcl")) || (!strcasecmp(fmt, "local"))) - { - ltime = ctime_r(&tick, ltbuf); - if (ltime == NULL) return NULL; - ltime[19] = '\0'; - asprintf(&out, "%s", ltime + 4); - return out; - } - - if ((!strcasecmp(fmt, "sec")) || (!strcasecmp(fmt, "raw"))) - { - asprintf(&out, "%lu", tick); - return out; - } - - if (!strcasecmp(fmt, "j")) - { - if (NULL == localtime_r(&tick, &stm)) return NULL; - asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec); - return out; - } - - if ((!strcasecmp(fmt, "utc")) || (!strcasecmp(fmt, "zulu"))) - { - if (NULL == gmtime_r(&tick, &stm)) return NULL; - asprintf(&out, "%d-%02d-%02d %02d:%02d:%02dZ", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec); - return out; - } - - if ((fmt[1] == '\0') && (((fmt[0] >= 'a') && (fmt[0] <= 'z')) || ((fmt[0] >= 'A') && (fmt[0] <= 'Z')))) - { - char z = fmt[0]; - if (z >= 'a') z -= 32; - - if (z == 'Z') off = 0; - else if ((z >= 'A') && (z <= 'I')) off = ((z - 'A') + 1) * SEC_PER_HOUR; - else if ((z >= 'K') && (z <= 'M')) off = (z - 'A') * SEC_PER_HOUR; - else if ((z >= 'N') && (z <= 'Y')) off = ('M' - z) * SEC_PER_HOUR; - else return NULL; - } - else - { - if ((*p == '-') || (*p == '+')) p++; - if ((*p) >= '0' && (*p <= '9')) - { - off = atoi(p); - if (fmt[0] == '-') off *= -1; - off *= SEC_PER_HOUR; - - p = strchr(p, ':'); - if (p != NULL) - { - min = atoi(p + 1); - if (fmt[0] == '-') min *= -1; - min *= 60; - off += min; - } - } - else - { - return NULL; - } - } - - tick += off; - - memset(&stm, 0, sizeof (struct tm)); - if (NULL == gmtime_r(&tick, &stm)) return NULL; - - if ((fmt[0] >= 'A') && (fmt[0] <= 'Z')) - { - asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d%c", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, fmt[0]); - } - else if ((fmt[0] >= 'a') && (fmt[0] <= 'z')) - { - asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d%c", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, fmt[0] - 32); - } - else if ((fmt[0] >= '0') && (fmt[0] <= '9')) - { - asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d+%s", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, fmt); - } - else - { - asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d%s", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, fmt); - } - - return out; -} - -/* called from asl_format_message and _asl_send_message */ -__private_extern__ asl_string_t * -asl_msg_to_string_raw(uint32_t encoding, asl_msg_t *msg, const char *tfmt) -{ - uint32_t i, x, count; - char *vtime; - const char *key, *val; - asl_string_t *str; - - if (msg == NULL) return NULL; - - count = asl_msg_count(msg); - if (count == 0) return NULL; - - str = asl_string_new(encoding); - if (str == NULL) return NULL; - - key = NULL; - val = NULL; - i = 0; - - for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL)) - { - if (key == NULL) continue; - - if (i > 0) asl_string_append_char_no_encoding(str, ' '); - - asl_string_append_char_no_encoding(str, '['); - asl_string_append_asl_key(str, key); - - if (!strcmp(key, ASL_KEY_TIME)) - { - asl_string_append_char_no_encoding(str, ' '); - vtime = NULL; - - if (val != NULL) vtime = _asl_time_string(tfmt, val); - - if (vtime != NULL) - { - asl_string_append_no_encoding(str, vtime); - free(vtime); - } - else - { - asl_string_append_char_no_encoding(str, '0'); - } - } - else if (val != NULL) - { - asl_string_append_char_no_encoding(str, ' '); - asl_string_append(str, val); - } - - asl_string_append_char_no_encoding(str, ']'); - - i++; - } - - return str; -} - -static asl_string_t * -_asl_string_append_asl_msg(asl_string_t *str, asl_msg_t *msg) -{ - const char *key, *val; - uint32_t i, op, n; - - if (msg == NULL) return str; - - if (msg->type == ASL_TYPE_QUERY) asl_string_append(str, "Q "); - - i = 0; - n = 0; - - forever - { - key = NULL; - val = NULL; - - i = asl_msg_fetch(msg, i, &key, &val, &op); - if (key != NULL) - { - if (n != 0) asl_string_append_char_no_encoding(str, ' '); - n++; - - asl_string_append_char_no_encoding(str, '['); - - if (msg->type == ASL_TYPE_QUERY) - { - asl_string_append_op(str, op); - asl_string_append_char_no_encoding(str, ' '); - } - - asl_string_append_asl_key(str, key); - - if (val != NULL) - { - asl_string_append_char_no_encoding(str, ' '); - asl_string_append(str, val); - } - - asl_string_append_char_no_encoding(str, ']'); - } - - if (i == IndexNull) break; - } - - return str; -} - -char * -asl_msg_to_string(asl_msg_t *msg, uint32_t *len) -{ - char *out; - asl_string_t *str = asl_string_new(ASL_ENCODE_ASL); - if (str == NULL) return NULL; - - str = _asl_string_append_asl_msg(str, msg); - *len = asl_string_length(str); - out = asl_string_free_return_bytes(str); - return out; -} - -static uint32_t -_asl_msg_op_from_string(char *o) -{ - uint32_t op, i; - - op = ASL_QUERY_OP_NULL; - - if (o == NULL) return op; - - for (i = 0; o[i] != '\0'; i++) - { - if (o[i] == '.') return ASL_QUERY_OP_NULL; - if (o[i] == 'C') op |= ASL_QUERY_OP_CASEFOLD; - if (o[i] == 'R') op |= ASL_QUERY_OP_REGEX; - if (o[i] == 'N') op |= ASL_QUERY_OP_NUMERIC; - if (o[i] == 'S') op |= ASL_QUERY_OP_SUBSTRING; - if (o[i] == 'A') op |= ASL_QUERY_OP_PREFIX; - if (o[i] == 'Z') op |= ASL_QUERY_OP_SUFFIX; - if (o[i] == '<') op |= ASL_QUERY_OP_LESS; - if (o[i] == '>') op |= ASL_QUERY_OP_GREATER; - if (o[i] == '=') op |= ASL_QUERY_OP_EQUAL; - if (o[i] == '!') op |= ASL_QUERY_OP_NOT_EQUAL; - if (o[i] == 'T') op |= ASL_QUERY_OP_TRUE; - } - - return op; -} - -static char * -_asl_msg_get_next_word(char **p, uint32_t *tt, uint32_t spacedel) -{ - char *str, *out, c, oval; - uint32_t i, len, n, outlen; - - *tt = TOKEN_NULL; - - if (p == NULL) return NULL; - if (*p == NULL) return NULL; - if (**p == '\0') return NULL; - - /* skip one space if it's there (word separator) */ - if (**p == ' ') (*p)++; - - /* skip leading white space */ - if (spacedel != 0) - { - while ((**p == ' ') || (**p == '\t')) (*p)++; - } - - if (**p == '\0') return NULL; - if (**p == '\n') return NULL; - - str = *p; - - /* opening [ */ - if (**p == '[') - { - *tt = TOKEN_OPEN; - - (*p)++; - out = malloc(2); - if (out == NULL) return NULL; - - out[0] = '['; - out[1] = '\0'; - return out; - } - - /* scan for token and calulate it's length (input and decoded output len) */ - len = 0; - outlen = 0; - - forever - { - c = str[len]; - - /* stop scanning when we hit a delimiter */ - if (((spacedel != 0) && (c == ' ')) || (c == ']') || (c == '\0')) break; - - if (c == '\\') - { - len++; - c = str[len]; - if ((c == 'a') || (c == 'b') || (c == 't') || (c == 'n') || (c == 'v') || (c == 'f') || (c == 'r') || (c == 's') || (c == '[') || (c == '\\') || (c == ']')) - { - } - else if (c == '^') - { - if (str[++len] == '\0') return NULL; - } - else if (c == 'M') - { - if (str[++len] == '\0') return NULL; - if (str[++len] == '\0') return NULL; - } - else if ((c >= '0') && (c <= '3')) - { - if (str[++len] == '\0') return NULL; - if (str[++len] == '\0') return NULL; - } - else - { - return NULL; - } - } - - len++; - outlen++; - } - - (*p) += len; - - if ((len == 0) && (**p == ']')) - { - *tt = TOKEN_CLOSE; - (*p)++; - out = malloc(2); - if (out == NULL) return NULL; - - out[0] = ']'; - out[1] = '\0'; - return out; - } - - *tt = TOKEN_INT; - - out = malloc(outlen + 1); - if (out == NULL) return NULL; - - n = 0; - for (i = 0; i < len; i++) - { - c = str[i]; - - if (c == '\\') - { - *tt = TOKEN_WORD; - - i++; - c = str[i]; - if (c == 'a') - { - out[n++] = '\a'; - } - else if (c == 'b') - { - out[n++] = '\b'; - } - else if (c == 't') - { - out[n++] = '\t'; - } - else if (c == 'n') - { - out[n++] = '\n'; - } - else if (c == 'v') - { - out[n++] = '\v'; - } - else if (c == 'f') - { - out[n++] = '\f'; - } - else if (c == 'r') - { - out[n++] = '\r'; - } - else if (c == 's') - { - out[n++] = ' '; - } - else if (c == '[') - { - out[n++] = '['; - } - else if (c == '\\') - { - out[n++] = '\\'; - } - else if (c == ']') - { - out[n++] = ']'; - } - else if (c == '^') - { - i++; - if (str[i] == '?') out[n++] = 127; - else out[n++] = str[i] - 64; - } - else if (c == 'M') - { - i++; - c = str[i]; - if (c == '^') - { - i++; - if (str[i] == '?') out[n++] = 255; - else out[n++] = str[i] + 64; - } - else if (c == '-') - { - i++; - out[n++] = str[i] + 128; - } - else - { - *tt = TOKEN_NULL; - free(out); - return NULL; - } - - } - else if ((c >= '0') && (c <= '3')) - { - oval = (c - '0') * 64; - - i++; - c = str[i]; - if ((c < '0') || (c > '7')) - { - *tt = TOKEN_NULL; - free(out); - return NULL; - } - - oval += ((c - '0') * 8); - - i++; - c = str[i]; - if ((c < '0') || (c > '7')) - { - *tt = TOKEN_NULL; - free(out); - return NULL; - } - - oval += (c - '0'); - - out[n++] = oval; - } - else - { - *tt = TOKEN_NULL; - free(out); - return NULL; - } - } - else - { - - if ((c < '0') || (c > '9')) *tt = TOKEN_WORD; - out[n++] = c; - } - } - - out[n] = '\0'; - - return out; -} - -asl_msg_t * -asl_msg_from_string(const char *buf) -{ - uint32_t tt, type, op; - char *k, *v, *o, *p; - asl_msg_t *out; - - if (buf == NULL) return NULL; - - type = ASL_TYPE_MSG; - p = (char *)buf; - - k = _asl_msg_get_next_word(&p, &tt, 1); - if (k == NULL) return NULL; - - if (streq(k, "Q")) - { - type = ASL_TYPE_QUERY; - free(k); - - k = _asl_msg_get_next_word(&p, &tt, 1); - } - else if (tt == TOKEN_INT) - { - /* Leading integer is a string length - skip it */ - free(k); - k = _asl_msg_get_next_word(&p, &tt, 1); - if (k == NULL) return NULL; - } - - out = asl_msg_new(ASL_TYPE_MSG); - if (out == NULL) return NULL; - - out->type = type; - - /* OPEN WORD [WORD [WORD]] CLOSE */ - while (k != NULL) - { - op = ASL_QUERY_OP_NULL; - - if (tt != TOKEN_OPEN) - { - asl_msg_release(out); - return NULL; - } - - free(k); - - /* get op for query type */ - if (type == ASL_TYPE_QUERY) - { - o = _asl_msg_get_next_word(&p, &tt, 1); - if ((o == NULL) || (tt != TOKEN_WORD)) - { - if (o != NULL) free(o); - asl_msg_release(out); - return NULL; - } - - op = _asl_msg_op_from_string(o); - free(o); - } - - k = _asl_msg_get_next_word(&p, &tt, 1); - if (tt == TOKEN_INT) tt = TOKEN_WORD; - if ((k == NULL) || (tt != TOKEN_WORD)) - { - if (k != NULL) free(k); - asl_msg_release(out); - return NULL; - } - - v = _asl_msg_get_next_word(&p, &tt, 0); - if (tt == TOKEN_INT) tt = TOKEN_WORD; - if (v == NULL) - { - asl_msg_set_key_val_op(out, k, NULL, op); - free(k); - break; - } - - if (tt == TOKEN_CLOSE) - { - asl_msg_set_key_val_op(out, k, NULL, op); - } - else if (tt == TOKEN_WORD) - { - asl_msg_set_key_val_op(out, k, v, op); - } - else - { - if (k != NULL) free(k); - if (v != NULL) free(v); - asl_msg_release(out); - return NULL; - } - - if (k != NULL) free(k); - if (v != NULL) free(v); - - if (tt != TOKEN_CLOSE) - { - k = _asl_msg_get_next_word(&p, &tt, 1); - if (k == NULL) break; - - if (tt != TOKEN_CLOSE) - { - asl_msg_release(out); - return NULL; - } - - free(k); - } - - k = _asl_msg_get_next_word(&p, &tt, 1); - if (k == NULL) break; - } - - return out; -} - -char * -asl_list_to_string(asl_search_result_t *list, uint32_t *len) -{ - uint32_t i; - char tmp[16]; - char *out; - asl_string_t *str = asl_string_new(ASL_ENCODE_ASL); - if (str == NULL) return NULL; - - if (list == NULL) return NULL; - if (list->count == 0) return NULL; - if (list->msg == NULL) return NULL; - - snprintf(tmp, sizeof(tmp), "%u", list->count); - asl_string_append(str, tmp); - asl_string_append_char_no_encoding(str, '\n'); - - for (i = 0; i < list->count; i++) - { - _asl_string_append_asl_msg(str, list->msg[i]); - asl_string_append_char_no_encoding(str, '\n'); - } - - *len = asl_string_length(str); - out = asl_string_free_return_bytes(str); - return out; -} - -asl_search_result_t * -asl_list_from_string(const char *buf) -{ - uint32_t i, n; - const char *p; - asl_search_result_t *out; - asl_msg_t *m; - - if (buf == NULL) return NULL; - p = buf; - - n = atoi(buf); - if (n == 0) return NULL; - - out = (asl_search_result_t *)calloc(1, sizeof(asl_search_result_t)); - if (out == NULL) return NULL; - - out->msg = (asl_msg_t **)calloc(n, sizeof(asl_msg_t *)); - if (out->msg == NULL) - { - free(out); - return NULL; - } - - for (i = 0; i < n; i++) - { - p = strchr(p, '\n'); - if (p == NULL) - { - aslresponse_free((aslresponse)out); - return NULL; - } - - p++; - - m = asl_msg_from_string(p); - if (m == NULL) - { - aslresponse_free((aslresponse)out); - return NULL; - } - - out->msg[i] = (asl_msg_t *)m; - out->count += 1; - } - - return out; -} - -static const char * -_asl_level_string(int level) -{ - if (level == ASL_LEVEL_EMERG) return ASL_STRING_EMERG; - if (level == ASL_LEVEL_ALERT) return ASL_STRING_ALERT; - if (level == ASL_LEVEL_CRIT) return ASL_STRING_CRIT; - if (level == ASL_LEVEL_ERR) return ASL_STRING_ERR; - if (level == ASL_LEVEL_WARNING) return ASL_STRING_WARNING; - if (level == ASL_LEVEL_NOTICE) return ASL_STRING_NOTICE; - if (level == ASL_LEVEL_INFO) return ASL_STRING_INFO; - if (level == ASL_LEVEL_DEBUG) return ASL_STRING_DEBUG; - return "unknown"; -} - -/* - * Find the value for a key in a message and append a formatted value to str. - * kf may be a simple (no embedded white space) key, or one of (key) or ((key)(format)). - * WARNING: modifies kf! - */ -static asl_string_t * -_asl_string_append_value_for_key_format(asl_string_t *str, asl_msg_t *msg, char *kf, const char *tfmt) -{ - uint32_t i, get_fmt; - char *key, *fmt; - const char *mval; - - if (str == NULL) return NULL; - if (msg == NULL) return str; - if (kf == NULL) return str; - - key = NULL; - fmt = NULL; - get_fmt = 0; - - for (i = 0; kf[i] != '\0'; i++) - { - if (kf[i] == ')') - { - kf[i] = '\0'; - get_fmt = 1; - } - else if (kf[i] != '(') - { - if (key == NULL) key = kf + i; - else if ((get_fmt == 1) && (fmt == NULL)) fmt = kf + i; - } - } - - if (key == NULL) return str; - - asl_msg_lookup(msg, key, &mval, NULL); - if (mval == NULL) return str; - - if (!strcmp(key, ASL_KEY_TIME)) - { - char *fval = NULL; - - /* format in $((Time)(fmt)) overrides tfmt */ - if (fmt == NULL) - { - fval = _asl_time_string(tfmt, mval); - } - else - { - fval = _asl_time_string(fmt, mval); - } - - if (fval != NULL) - { - asl_string_append_no_encoding(str, fval); - free(fval); - } - else - { - asl_string_append_char_no_encoding(str, '0'); - } - - return str; - } - - /* Level: num str */ - if (!strcmp(key, ASL_KEY_LEVEL)) - { - if (fmt == NULL) - { - asl_string_append_no_encoding(str, mval); - } - else if (!strcmp(fmt, "str")) - { - mval = _asl_level_string(atoi(mval)); - asl_string_append_no_encoding(str, mval); - } - else - { - asl_string_append_no_encoding(str, mval); - } - - return str; - } - - return asl_string_append(str, mval); -} - -/* - * format a message for printing - * out parameter len returns string length including trailing NUL - */ -char * -asl_format_message(asl_msg_t *msg, const char *mfmt, const char *tfmt, uint32_t text_encoding, uint32_t *len) -{ - char *out, *vtime, *k, c, skey[512]; - const char *vhost, *vpid, *vsender, *vmessage, *vlevel, *vrefproc, *vrefpid, *v, *key, *val; - int i, j, l, mf, paren, oval, level; - uint32_t x, cursor; - asl_string_t *str; - uint8_t *b64; - - out = NULL; - *len = 0; - - if (msg == NULL) return NULL; - - mf = MFMT_RAW; - - if (mfmt == NULL) mf = MFMT_RAW; - else if (!strcmp(mfmt, ASL_MSG_FMT_RAW)) mf = MFMT_RAW; - else if (!strcmp(mfmt, ASL_MSG_FMT_STD)) mf = MFMT_STD; - else if (!strcmp(mfmt, ASL_MSG_FMT_BSD)) mf = MFMT_BSD; - else if (!strcmp(mfmt, ASL_MSG_FMT_XML)) mf = MFMT_XML; - else if (!strcmp(mfmt, ASL_MSG_FMT_MSG)) mf = MFMT_MSG; - else mf = MFMT_STR; - - if (mf == MFMT_RAW) - { - str = asl_msg_to_string_raw(text_encoding, msg, tfmt); - asl_string_append_char_no_encoding(str, '\n'); - - *len = asl_string_length(str); - out = asl_string_free_return_bytes(str); - return out; - } - - if (mf == MFMT_MSG) - { - vmessage = NULL; - - if (asl_msg_lookup(msg, ASL_KEY_MSG, &vmessage, NULL) != 0) return NULL; - - str = asl_string_new(text_encoding); - if (str == NULL) return NULL; - - asl_string_append(str, vmessage); - asl_string_append_char_no_encoding(str, '\n'); - - *len = asl_string_length(str); - out = asl_string_free_return_bytes(str); - return out; - } - - if ((mf == MFMT_STD) || (mf == MFMT_BSD)) - { - /* COMMON: Mth dd hh:mm:ss host sender[pid] (refproc[refpid])*/ - /* BSD: : message */ - /* STD: : message */ - - v = NULL; - vhost = NULL; - vsender = NULL; - vpid = NULL; - vmessage = NULL; - vlevel = NULL; - vrefproc = NULL; - vrefpid = NULL; - - asl_msg_lookup(msg, ASL_KEY_TIME, &v, NULL); - vtime = _asl_time_string(tfmt, v); - - level = 7; - asl_msg_lookup(msg, ASL_KEY_LEVEL, &vlevel, NULL); - if (vlevel != NULL) level = atoi(vlevel); - - asl_msg_lookup(msg, ASL_KEY_HOST, &vhost, NULL); - if (vhost == NULL) vhost = "unknown"; - - asl_msg_lookup(msg, ASL_KEY_SENDER, &vsender, NULL); - if (vsender == NULL) vsender = "unknown"; - - asl_msg_lookup(msg, ASL_KEY_PID, &vpid, NULL); - asl_msg_lookup(msg, ASL_KEY_MSG, &vmessage, NULL); - asl_msg_lookup(msg, ASL_KEY_REF_PROC, &vrefproc, NULL); - asl_msg_lookup(msg, ASL_KEY_REF_PID, &vrefpid, NULL); - - /* COMMON */ - str = asl_string_new(text_encoding); - if (str == NULL) return NULL; - - if (vtime != NULL) - { - asl_string_append(str, vtime); - free(vtime); - } - else - { - asl_string_append_char_no_encoding(str, '0'); - } - - asl_string_append_char_no_encoding(str, ' '); - asl_string_append(str, vhost); - asl_string_append_char_no_encoding(str, ' '); - asl_string_append(str, vsender); - - if ((vpid != NULL) && (strcmp(vpid, "-1"))) - { - asl_string_append_char_no_encoding(str, '['); - asl_string_append(str, vpid); - asl_string_append_char_no_encoding(str, ']'); - } - - if ((vrefproc != NULL) || (vrefpid != NULL)) asl_string_append_no_encoding(str, " ("); - - if (vrefproc != NULL) asl_string_append(str, vrefproc); - if (vrefpid != NULL) - { - asl_string_append_char_no_encoding(str, '['); - asl_string_append(str, vrefpid); - asl_string_append_char_no_encoding(str, ']'); - } - - if ((vrefproc != NULL) || (vrefpid != NULL)) asl_string_append_char_no_encoding(str, ')'); - - if (mf == MFMT_STD) - { - asl_string_append_no_encoding(str, " <"); - asl_string_append(str, _asl_level_string(level)); - asl_string_append_char_no_encoding(str, '>'); - } - - asl_string_append_no_encoding(str, ": "); - if (vmessage != NULL) asl_string_append(str, vmessage); - asl_string_append_char_no_encoding(str, '\n'); - - *len = asl_string_length(str); - out = asl_string_free_return_bytes(str); - return out; - } - - if (mf == MFMT_XML) - { - str = asl_string_new(text_encoding); - if (str == NULL) return NULL; - - asl_string_append_char_no_encoding(str, '\t'); - asl_string_append(str, ""); - asl_string_append_char_no_encoding(str, '\n'); - - for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL)) - { - if (asl_is_utf8(key) == 1) - { - asl_string_append_xml_tag(str, "key", key); - if (!strcmp(key, ASL_KEY_TIME)) - { - vtime = _asl_time_string(tfmt, val); - if (vtime != NULL) - { - asl_string_append_xml_tag(str, "string", vtime); - free(vtime); - } - else - { - asl_string_append_xml_tag(str, "string", "0"); - } - } - else - { - if (asl_is_utf8(val) == 1) asl_string_append_xml_tag(str, "string", val); - else - { - b64 = asl_b64_encode((uint8_t *)val, strlen(val)); - asl_string_append_xml_tag(str, "data", (char *)b64); - free(b64); - } - } - } - } - - asl_string_append_char_no_encoding(str, '\t'); - asl_string_append(str, ""); - asl_string_append_char_no_encoding(str, '\n'); - - *len = asl_string_length(str); - out = asl_string_free_return_bytes(str); - return out; - } - - /* - * Custom format - * The format string may contain arbitrary characters. - * Keys are identified by $Key or $(Key). The value for - * that key is substituted. If there are alterate formats - * for the value (for example a time may be formatted as - * raw seconds, in UTC, or a local timezone), then the - * key may be $((Key)(Format)). "\$" prints a plain "$". - */ - - str = asl_string_new(text_encoding); - if (str == NULL) return NULL; - - /* - * We need enough space to copy any keys found in mfmt. - * The key obviously can't be longer than strlen(mfmt), - * in fact, keys must be shorter, since there's at least a '$' - * in front of the key, so we allocate a buffer with strlen(mfmt). - * If strlen(mfmt) <= sizeof(skey), we use skey to avoid a malloc. - */ - - x = strlen(mfmt); - if (x <= sizeof(skey)) - { - k = skey; - } - else - { - k = malloc(x); - if (k == NULL) return NULL; - } - - cursor = 0; - - for (i = 0; mfmt[i] != '\0'; i++) - { - if (mfmt[i] == '$') - { - paren = 0; - - /* scan key, (key) or ((key)(format)) */ - for (j = i + 1; mfmt[j] != 0; j++) - { - if (mfmt[j] == '(') - { - paren++; - } - else if (mfmt[j] == ')') - { - if (paren > 0) paren--; - if (paren == 0) - { - j++; - break; - } - } - else if (((mfmt[j] == ' ') || (mfmt[j] == '\t')) && (paren == 0)) break; - } - - /* mfmt[i + 1] is the first char of the key or a '('. mfmt[j] is one char past the end. */ - l = j - (i + 1); - memcpy(k, mfmt+i+1, l); - k[l] = '\0'; - _asl_string_append_value_for_key_format(str, msg, k, tfmt); - - i = j - 1; - continue; - } - - if (mfmt[i] == '\\') - { - i++; - if (mfmt[i] == '$') asl_string_append_char_no_encoding(str, '$'); - else if (mfmt[i] == 'e') asl_string_append_char_no_encoding(str, '\e'); - else if (mfmt[i] == 's') asl_string_append_char_no_encoding(str, ' '); - else if (mfmt[i] == 'a') asl_string_append_char_no_encoding(str, '\a'); - else if (mfmt[i] == 'b') asl_string_append_char_no_encoding(str, '\b'); - else if (mfmt[i] == 'f') asl_string_append_char_no_encoding(str, '\f'); - else if (mfmt[i] == 'n') asl_string_append_char_no_encoding(str, '\n'); - else if (mfmt[i] == 'r') asl_string_append_char_no_encoding(str, '\r'); - else if (mfmt[i] == 't') asl_string_append_char_no_encoding(str, '\t'); - else if (mfmt[i] == 'v') asl_string_append_char_no_encoding(str, '\v'); - else if (mfmt[i] == '\'') asl_string_append_char_no_encoding(str, '\''); - else if (mfmt[i] == '\\') asl_string_append_char_no_encoding(str, '\\'); - else if (isdigit(mfmt[i])) - { - oval = mfmt[i] - '0'; - if (isdigit(mfmt[i+1])) - { - i++; - oval = (oval * 8) + (mfmt[i] - '0'); - if (isdigit(mfmt[i+1])) - { - i++; - oval = (oval * 8) + (mfmt[i] - '0'); - } - } - c = oval; - asl_string_append_char_no_encoding(str, c); - } - continue; - } - - if (mfmt[i] == '\0') break; - asl_string_append_char_no_encoding(str, mfmt[i]); - } - - if (k != skey) free(k); - - asl_string_append_char_no_encoding(str, '\n'); - - *len = asl_string_length(str); - out = asl_string_free_return_bytes(str); - return out; -} - -/* - * OLD ASLMSG COMPATIBILITY - */ -const char * -asl_key(aslmsg msg, uint32_t n) -{ - uint32_t slot, i; - asl_msg_t *page; - - i = 0; - for (page = (asl_msg_t *)msg; page != NULL; page = page->next) - { - for (slot = 0; slot < ASL_MSG_PAGE_SLOTS; slot++) - { - if (page->key[slot] != ASL_MSG_SLOT_FREE) - { - if (i == n) return _asl_msg_slot_key(page, slot); - i++; - } - } - } - - return NULL; -} - -aslmsg -asl_new(uint32_t type) -{ - return (aslmsg)asl_msg_new(type); -} - -int -asl_set(aslmsg msg, const char *key, const char *value) -{ - return asl_msg_set_key_val_op((asl_msg_t *)msg, key, value, IndexNull); -} - -int -asl_set_query(aslmsg msg, const char *key, const char *value, uint32_t op) -{ - return asl_msg_set_key_val_op((asl_msg_t *)msg, key, value, op); -} - -int -asl_unset(aslmsg msg, const char *key) -{ - asl_msg_unset((asl_msg_t *)msg, key); - return 0; -} - -const char * -asl_get(aslmsg msg, const char *key) -{ - const char *val; - int status; - - val = NULL; - status = asl_msg_lookup((asl_msg_t *)msg, key, &val, NULL); - if (status != 0) return NULL; - return val; -} - -void -asl_free(aslmsg msg) -{ - asl_msg_release((asl_msg_t *)msg); -} - -/* aslresponse */ - -/* - * aslresponse_next: Iterate over responses returned from asl_search() - * a: a response returned from asl_search(); - * returns: The next log message (an aslmsg) or NULL on failure - */ -aslmsg -aslresponse_next(aslresponse r) -{ - asl_search_result_t *res; - asl_msg_t *m; - - res = (asl_search_result_t *)r; - if (res == NULL) return NULL; - - if (res->curr >= res->count) return NULL; - m = res->msg[res->curr]; - res->curr++; - - return (aslmsg)m; -} - -/* - * aslresponse_free: Free a response returned from asl_search() - * a: a response returned from asl_search() - */ -void -aslresponse_free(aslresponse r) -{ - asl_search_result_t *res; - uint32_t i; - - res = (asl_search_result_t *)r; - if (res == NULL) return; - - for (i = 0; i < res->count; i++) asl_msg_release(res->msg[i]); - free(res->msg); - free(res); -} diff --git a/src/libc/gen/asl_msg.h b/src/libc/gen/asl_msg.h deleted file mode 100644 index dc9a9dc95..000000000 --- a/src/libc/gen/asl_msg.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2009-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __ASL_MSG_H__ -#define __ASL_MSG_H__ - -#include -#include - -#define IndexNull ((uint32_t)-1) - -#define ASL_MSG_PAGE_DATA_SIZE 800 -#define ASL_MSG_PAGE_SLOTS 24 - -#define ASL_MSG_OFFSET_MASK 0x3fff -#define ASL_MSG_KV_MASK 0xc000 -#define ASL_MSG_KV_INLINE 0x0000 -#define ASL_MSG_KV_DICT 0x8000 -#define ASL_MSG_KV_EXTERN 0x4000 - -#define ASL_MSG_SLOT_FREE 0xffff - -#define ASL_STD_KEY_BASE 0x8000 -#define ASL_STD_KEY_TIME 0x8001 -#define ASL_STD_KEY_NANO 0x8002 -#define ASL_STD_KEY_HOST 0x8003 -#define ASL_STD_KEY_SENDER 0x8004 -#define ASL_STD_KEY_FACILITY 0x8005 -#define ASL_STD_KEY_PID 0x8006 -#define ASL_STD_KEY_UID 0x8007 -#define ASL_STD_KEY_GID 0x8008 -#define ASL_STD_KEY_LEVEL 0x8009 -#define ASL_STD_KEY_MESSAGE 0x800a -#define ASL_STD_KEY_READ_UID 0x800b -#define ASL_STD_KEY_READ_GID 0x800c -#define ASL_STD_KEY_SESSION 0x800d -#define ASL_STD_KEY_REF_PID 0x800e -#define ASL_STD_KEY_REF_PROC 0x800f -#define ASL_STD_KEY_MSG_ID 0x8010 -#define ASL_STD_KEY_EXPIRE 0x8011 -#define ASL_STD_KEY_OPTION 0x8012 -#define ASL_STD_KEY_LAST ASL_STD_KEY_OPTION - -#define ASL_MT_KEY_BASE 0x8100 -#define ASL_MT_KEY_DOMAIN 0x8101 -#define ASL_MT_KEY_SCOPE 0x8102 -#define ASL_MT_KEY_RESULT 0x8103 -#define ASL_MT_KEY_SIG 0x8104 -#define ASL_MT_KEY_SIG2 0x8105 -#define ASL_MT_KEY_SIG3 0x8106 -#define ASL_MT_KEY_SUCCESS 0x8107 -#define ASL_MT_KEY_UUID 0x8108 -#define ASL_MT_KEY_VAL 0x8109 -#define ASL_MT_KEY_VAL2 0x810a -#define ASL_MT_KEY_VAL3 0x810b -#define ASL_MT_KEY_VAL4 0x810c -#define ASL_MT_KEY_VAL5 0x810d -#define ASL_MT_KEY_LAST ASL_MT_KEY_VAL5 - -#define ASL_PRIVATE_KEY_BASE 0x8200 - -typedef struct asl_msg_s -{ - uint32_t type; - int32_t refcount; - uint32_t count; - uint32_t data_size; - struct asl_msg_s *next; - uint16_t key[ASL_MSG_PAGE_SLOTS]; - uint16_t val[ASL_MSG_PAGE_SLOTS]; - uint32_t op[ASL_MSG_PAGE_SLOTS]; - char data[ASL_MSG_PAGE_DATA_SIZE]; -} asl_msg_t; - -typedef struct __aslresponse -{ - uint32_t count; - uint32_t curr; - asl_msg_t **msg; -} asl_msg_list_t; - -#define asl_search_result_t asl_msg_list_t - -asl_msg_t *asl_msg_new(uint32_t type) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -asl_msg_t *asl_msg_retain(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -void asl_msg_release(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); - -int asl_msg_set_key_val(asl_msg_t *msg, const char *key, const char *val) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -int asl_msg_set_key_val_op(asl_msg_t *msg, const char *key, const char *val, uint32_t op) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -void asl_msg_unset(asl_msg_t *msg, const char *key) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); - -asl_msg_t *asl_msg_copy(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); -asl_msg_t *asl_msg_merge(asl_msg_t *target, asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1); - -int asl_msg_lookup(asl_msg_t *msg, const char *key, const char **valout, uint32_t *opout) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -uint32_t asl_msg_fetch(asl_msg_t *msg, uint32_t n, const char **keyout, const char **valout, uint32_t *opout) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); - -uint32_t asl_msg_type(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -uint32_t asl_msg_count(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); - -char *asl_msg_to_string(asl_msg_t *in, uint32_t *len) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0); -char *asl_list_to_string(asl_search_result_t *, uint32_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -asl_search_result_t *asl_list_from_string(const char *buf) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -char *asl_format_message(asl_msg_t *msg, const char *msg_fmt, const char *time_fmt, uint32_t text_encoding, uint32_t *outlen) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -#endif /* __ASL_MSG_H__ */ diff --git a/src/libc/gen/asl_private.h b/src/libc/gen/asl_private.h deleted file mode 100644 index be092c797..000000000 --- a/src/libc/gen/asl_private.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __ASL_PRIVATE_H__ -#define __ASL_PRIVATE_H__ - -#include -#include -#include -#include -#include -#include "asl_file.h" -#include "asl_msg.h" -#include - -#define ASL_QUERY_OP_NULL 0x00000 - -#define NOTIFY_SYSTEM_MASTER "com.apple.system.syslog.master" -#define NOTIFY_SYSTEM_ASL_FILTER "com.apple.system.syslog.asl_filter" -#define NOTIFY_PREFIX_SYSTEM "com.apple.system.syslog" -#define NOTIFY_PREFIX_USER "user.syslog" -#define NOTIFY_RC "com.apple.asl.remote" - -#define ASL_MSG_FMT_RAW "raw" -#define ASL_MSG_FMT_STD "std" -#define ASL_MSG_FMT_BSD "bsd" -#define ASL_MSG_FMT_XML "xml" -#define ASL_MSG_FMT_MSG "msg" - -#define ASL_TIME_FMT_SEC "sec" -#define ASL_TIME_FMT_UTC "utc" -#define ASL_TIME_FMT_LCL "lcl" - -#define ASL_OPT_IGNORE "ignore" -#define ASL_OPT_STORE "store" - -#define ASL_STORE_LOCATION_FILE 0 -#define ASL_STORE_LOCATION_MEMORY 1 - -#define ASL_OPT_SYSLOG_LEGACY 0x00010000 - -/* SPI to enable ASL filter tunneling using asl_set_filter() */ -#define ASL_FILTER_MASK_TUNNEL 0x100 - -typedef struct __aslclient -{ - uint32_t options; - struct sockaddr_un server; - int sock; - pid_t pid; - uid_t uid; - gid_t gid; - char *name; - char *facility; - uint32_t filter; - int notify_token; - int notify_master_token; - uint32_t fd_count; - int *fd_list; - char **fd_mfmt; - char **fd_tfmt; - uint32_t *fd_encoding; - asl_file_t *aslfile; - uint64_t aslfileid; - uint32_t reserved1; - void *reserved2; - int32_t refcount; -} asl_client_t; - -__BEGIN_DECLS - -int asl_add_output(aslclient asl, int fd, const char *msg_fmt, const char *time_fmt, uint32_t text_encoding) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int asl_remove_output(aslclient asl, int fd) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int asl_store_location() __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -int asl_get_filter(aslclient asl, int *local, int *master, int *remote, int *active) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -char *asl_remote_notify_name() __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); - -__END_DECLS - -#endif /* __ASL_PRIVATE_H__ */ diff --git a/src/libc/gen/asl_store.c b/src/libc/gen/asl_store.c deleted file mode 100644 index a4d0fcace..000000000 --- a/src/libc/gen/asl_store.c +++ /dev/null @@ -1,935 +0,0 @@ -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern time_t asl_parse_time(const char *str); -extern uint64_t asl_file_cursor(asl_file_t *s); -extern uint32_t asl_file_match_start(asl_file_t *s, uint64_t start_id, int32_t direction); -extern uint32_t asl_file_match_next(asl_file_t *s, aslresponse query, asl_msg_t **msg, uint64_t *last_id, int32_t direction, int32_t ruid, int32_t rgid); -extern int asl_file_create(const char *path, uid_t uid, gid_t gid, mode_t mode); - -#define SECONDS_PER_DAY 86400 - -/* - * The ASL Store is organized as a set of files in a common directory. - * Files are prefixed by the date (YYYY.MM.DD) of their contents. - * - * Messages with no access controls are saved in YYYY.MM.DD.asl - * Messages with access limited to UID uuu are saved in YYYY.MM.DD.Uuuu.asl - * Messages with access limited to GID ggg are saved in YYYY.MM.DD.Gggg.asl - * Messages with access limited to UID uuu and GID ggg are saved in YYYY.MM.DD.Uuuu.Gggg.asl - * - * Messages that have a value for ASLExpireTime are saved in BB.YYYY.MM.DD.asl - * where the timestamp is the "Best Before" date of the file. Access controls - * are implemented as above with Uuuu and Gggg in the file name. Note that the - * Best Before files are for the last day of the month, so a single file contains - * messages that expire in that month. - * - * An external tool runs daily and deletes "old" files. - */ - -static time_t -_asl_start_today() -{ - time_t now; - struct tm ctm; - - memset(&ctm, 0, sizeof(struct tm)); - now = time(NULL); - - if (localtime_r((const time_t *)&now, &ctm) == NULL) return 0; - - ctm.tm_sec = 0; - ctm.tm_min = 0; - ctm.tm_hour = 0; - - return mktime(&ctm); -} - -/* - * The base directory contains a data file which stores - * the last record ID. - * - * | MAX_ID (uint64_t) | - * - */ -uint32_t -asl_store_open_write(const char *basedir, asl_store_t **s) -{ - asl_store_t *out; - struct stat sb; - uint32_t i, flags; - char *path; - FILE *sd; - uint64_t last_id; - time_t start; - - if (s == NULL) return ASL_STATUS_INVALID_ARG; - - start = _asl_start_today(); - if (start == 0) return ASL_STATUS_FAILED; - - if (basedir == NULL) basedir = PATH_ASL_STORE; - - memset(&sb, 0, sizeof(struct stat)); - if (stat(basedir, &sb) != 0) return ASL_STATUS_INVALID_STORE; - if (!S_ISDIR(sb.st_mode)) return ASL_STATUS_INVALID_STORE; - - path = NULL; - asprintf(&path, "%s/%s", basedir, FILE_ASL_STORE_DATA); - if (path == NULL) return ASL_STATUS_NO_MEMORY; - - sd = NULL; - - memset(&sb, 0, sizeof(struct stat)); - if (stat(path, &sb) != 0) - { - if (errno != ENOENT) - { - free(path); - return ASL_STATUS_FAILED; - } - - sd = fopen(path, "w+"); - free(path); - - if (sd == NULL) return ASL_STATUS_FAILED; - - last_id = 0; - - /* Create new StoreData file (8 bytes ID + 4 bytes flags) */ - - if (fwrite(&last_id, sizeof(uint64_t), 1, sd) != 1) - { - fclose(sd); - return ASL_STATUS_WRITE_FAILED; - } - - flags = 0; - if (fwrite(&flags, sizeof(uint32_t), 1, sd) != 1) - { - fclose(sd); - return ASL_STATUS_WRITE_FAILED; - } - - /* flush data */ - fflush(sd); - } - else - { - sd = fopen(path, "r+"); - free(path); - - if (sd == NULL) return ASL_STATUS_FAILED; - if (fread(&last_id, sizeof(uint64_t), 1, sd) != 1) - { - fclose(sd); - return ASL_STATUS_READ_FAILED; - } - - last_id = asl_core_ntohq(last_id); - } - - out = (asl_store_t *)calloc(1, sizeof(asl_store_t)); - if (out == NULL) - { - fclose(sd); - return ASL_STATUS_NO_MEMORY; - } - - if (basedir == NULL) out->base_dir = strdup(PATH_ASL_STORE); - else out->base_dir = strdup(basedir); - - if (out->base_dir == NULL) - { - fclose(sd); - free(out); - return ASL_STATUS_NO_MEMORY; - } - - out->start_today = start; - out->start_tomorrow = out->start_today + SECONDS_PER_DAY; - out->storedata = sd; - out->next_id = last_id + 1; - - for (i = 0; i < FILE_CACHE_SIZE; i++) - { - memset(&out->file_cache[i], 0, sizeof(asl_cached_file_t)); - out->file_cache[i].u = -1; - out->file_cache[i].g = -1; - } - - *s = out; - return ASL_STATUS_OK; -} - -uint32_t -asl_store_statistics(asl_store_t *s, aslmsg *msg) -{ - aslmsg out; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (msg == NULL) return ASL_STATUS_INVALID_ARG; - - out = asl_new(ASL_TYPE_MSG); - if (out == NULL) return ASL_STATUS_NO_MEMORY; - - /* does nothing for now */ - - *msg = out; - return ASL_STATUS_OK; -} - -uint32_t -asl_store_open_read(const char *basedir, asl_store_t **s) -{ - asl_store_t *out; - struct stat sb; - - if (s == NULL) return ASL_STATUS_INVALID_ARG; - - if (basedir == NULL) basedir = PATH_ASL_STORE; - - memset(&sb, 0, sizeof(struct stat)); - if (stat(basedir, &sb) != 0) return ASL_STATUS_INVALID_STORE; - if (!S_ISDIR(sb.st_mode)) return ASL_STATUS_INVALID_STORE; - - out = (asl_store_t *)calloc(1, sizeof(asl_store_t)); - if (out == NULL) return ASL_STATUS_NO_MEMORY; - - if (basedir == NULL) out->base_dir = strdup(PATH_ASL_STORE); - else out->base_dir = strdup(basedir); - - if (out->base_dir == NULL) - { - free(out); - return ASL_STATUS_NO_MEMORY; - } - - *s = out; - return ASL_STATUS_OK; -} - -uint32_t -asl_store_max_file_size(asl_store_t *s, size_t max) -{ - if (s == NULL) return ASL_STATUS_INVALID_STORE; - - s->max_file_size = max; - return ASL_STATUS_OK; -} - -__private_extern__ void -asl_store_file_closeall(asl_store_t *s) -{ - uint32_t i; - - if (s == NULL) return; - - for (i = 0; i < FILE_CACHE_SIZE; i++) - { - if (s->file_cache[i].f != NULL) asl_file_close(s->file_cache[i].f); - s->file_cache[i].f = NULL; - if (s->file_cache[i].path != NULL) free(s->file_cache[i].path); - s->file_cache[i].path = NULL; - s->file_cache[i].u = -1; - s->file_cache[i].g = -1; - s->file_cache[i].bb = 0; - s->file_cache[i].ts = 0; - } -} - -uint32_t -asl_store_close(asl_store_t *s) -{ - if (s == NULL) return ASL_STATUS_OK; - - if (s->base_dir != NULL) free(s->base_dir); - s->base_dir = NULL; - asl_store_file_closeall(s); - if (s->storedata != NULL) fclose(s->storedata); - - free(s); - - return ASL_STATUS_OK; -} - -uint32_t -asl_store_signal_sweep(asl_store_t *s) -{ - char *str; - int semfd; - uint64_t xid; - uint32_t status; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - - asprintf(&str, "%s/%s", s->base_dir, FILE_ASL_STORE_SWEEP_SEMAPHORE); - if (str == NULL) return ASL_STATUS_NO_MEMORY; - - semfd = open(str, O_WRONLY | O_CREAT | O_NONBLOCK, 0644); - free(str); - - if (semfd < 0) return ASL_STATUS_WRITE_FAILED; - - status = ASL_STATUS_OK; - - /* write the current message ID in the SweepStore file */ - xid = asl_core_htonq(s->next_id - 1); - if (write(semfd, &xid, sizeof(uint64_t)) != sizeof(uint64_t)) status = ASL_STATUS_WRITE_FAILED; - - close(semfd); - return status; -} - -/* - * Sweep the file cache. - * Close any files that have not been used in the last FILE_CACHE_TTL seconds. - * Returns least recently used or unused cache slot. - */ -static uint32_t -asl_store_file_cache_lru(asl_store_t *s, time_t now, uint32_t ignorex) -{ - time_t min; - uint32_t i, x; - - if (s == NULL) return 0; - - x = 0; - min = now - FILE_CACHE_TTL; - - for (i = 0; i < FILE_CACHE_SIZE; i++) - { - if ((i != ignorex) && (s->file_cache[i].ts < min)) - { - asl_file_close(s->file_cache[i].f); - s->file_cache[i].f = NULL; - if (s->file_cache[i].path != NULL) free(s->file_cache[i].path); - s->file_cache[i].path = NULL; - s->file_cache[i].u = -1; - s->file_cache[i].g = -1; - s->file_cache[i].bb = 0; - s->file_cache[i].ts = 0; - } - - if (s->file_cache[i].ts < s->file_cache[x].ts) x = i; - } - - return x; -} - -uint32_t -asl_store_sweep_file_cache(asl_store_t *s) -{ - if (s == NULL) return ASL_STATUS_INVALID_STORE; - - asl_store_file_cache_lru(s, time(NULL), FILE_CACHE_SIZE); - return ASL_STATUS_OK; -} - -static char * -asl_store_make_ug_path(const char *dir, const char *base, const char *ext, uid_t ruid, gid_t rgid, uid_t *u, gid_t *g, mode_t *m) -{ - char *path = NULL; - - *u = 0; - *g = 0; - *m = 0644; - - if (ruid == -1) - { - if (rgid == -1) - { - if (ext == NULL) asprintf(&path, "%s/%s", dir, base); - else asprintf(&path, "%s/%s.%s", dir, base, ext); - } - else - { - *g = rgid; - *m = 0600; - if (ext == NULL) asprintf(&path, "%s/%s.G%d", dir, base, *g); - else asprintf(&path, "%s/%s.G%d.%s", dir, base, *g, ext); - } - } - else - { - *u = ruid; - if (rgid == -1) - { - *m = 0600; - if (ext == NULL) asprintf(&path, "%s/%s.U%d", dir, base, *u); - else asprintf(&path, "%s/%s.U%d.%s", dir, base, *u, ext); - } - else - { - *g = rgid; - *m = 0600; - if (ext == NULL) asprintf(&path, "%s/%s.U%d.G%d", dir, base, *u, *g); - else asprintf(&path, "%s/%s.U%d.G%u.%s", dir, base, *u, *g, ext); - } - } - - return path; -} - -static uint32_t -asl_store_file_open_write(asl_store_t *s, char *tstring, int32_t ruid, int32_t rgid, time_t bb, asl_file_t **f, time_t now, uint32_t check_cache) -{ - char *path; - mode_t m; - int32_t i, x; - uid_t u; - gid_t g; - uint32_t status; - asl_file_t *out; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - - /* see if the file is already open and in the cache */ - for (i = 0; i < FILE_CACHE_SIZE; i++) - { - if ((s->file_cache[i].u == ruid) && (s->file_cache[i].g == rgid) && (s->file_cache[i].bb == bb) && (s->file_cache[i].f != NULL)) - { - s->file_cache[i].ts = now; - *f = s->file_cache[i].f; - if (check_cache == 1) asl_store_file_cache_lru(s, now, i); - return ASL_STATUS_OK; - } - } - - u = 0; - g = 0; - m = 0644; - path = asl_store_make_ug_path(s->base_dir, tstring, "asl", (uid_t)ruid, (gid_t)rgid, &u, &g, &m); - if (path == NULL) return ASL_STATUS_NO_MEMORY; - - out = NULL; - status = asl_file_open_write(path, m, u, g, &out); - if (status != ASL_STATUS_OK) - { - free(path); - return status; - } - - x = asl_store_file_cache_lru(s, now, FILE_CACHE_SIZE); - if (s->file_cache[x].f != NULL) asl_file_close(s->file_cache[x].f); - if (s->file_cache[x].path != NULL) free(s->file_cache[x].path); - - s->file_cache[x].f = out; - s->file_cache[x].path = path; - s->file_cache[x].u = ruid; - s->file_cache[x].g = rgid; - s->file_cache[x].bb = bb; - s->file_cache[x].ts = time(NULL); - - *f = out; - - return ASL_STATUS_OK; -} - -__private_extern__ char * -asl_store_file_path(asl_store_t *s, asl_file_t *f) -{ - uint32_t i; - - if (s == NULL) return NULL; - - for (i = 0; i < FILE_CACHE_SIZE; i++) - { - if (s->file_cache[i].f == f) - { - if (s->file_cache[i].path == NULL) return NULL; - return strdup(s->file_cache[i].path); - } - } - - return NULL; -} - -__private_extern__ void -asl_store_file_close(asl_store_t *s, asl_file_t *f) -{ - uint32_t i; - - if (s == NULL) return; - if (f == NULL) return; - - for (i = 0; i < FILE_CACHE_SIZE; i++) - { - if (s->file_cache[i].f == f) - { - asl_file_close(s->file_cache[i].f); - s->file_cache[i].f = NULL; - if (s->file_cache[i].path != NULL) free(s->file_cache[i].path); - s->file_cache[i].path = NULL; - s->file_cache[i].u = -1; - s->file_cache[i].g = -1; - s->file_cache[i].bb = 0; - s->file_cache[i].ts = 0; - return; - } - } -} - -uint32_t -asl_store_save(asl_store_t *s, aslmsg msg) -{ - struct tm ctm; - time_t msg_time, now, bb; - char *path, *tmp_path, *tstring, *scratch; - const char *val; - uid_t ruid; - gid_t rgid; - asl_file_t *f; - uint32_t status, check_cache, signal_sweep, len; - uint64_t xid, ftime; - size_t fsize; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (msg == NULL) return ASL_STATUS_INVALID_ARG; - - now = time(NULL); - - check_cache = 0; - if ((s->last_write + FILE_CACHE_TTL) <= now) check_cache = 1; - - signal_sweep = 0; - - msg_time = 0; - val = asl_get(msg, ASL_KEY_TIME); - if (val == NULL) msg_time = now; - else msg_time = asl_parse_time(val); - - if (msg_time >= s->start_tomorrow) - { - if (now >= s->start_tomorrow) - { - /* new day begins */ - check_cache = 0; - signal_sweep = 1; - asl_store_file_closeall(s); - - /* - * _asl_start_today should never fail, but if it does, - * just push forward one day. That will probably be correct, and if - * it isn't, the next message that gets saved will push it ahead again - * until we get to the right date. - */ - s->start_today = _asl_start_today(); - if (s->start_today == 0) s->start_today = s->start_tomorrow; - - s->start_tomorrow = s->start_today + SECONDS_PER_DAY; - } - } - - val = asl_get(msg, ASL_KEY_READ_UID); - ruid = -1; - if (val != NULL) ruid = atoi(val); - - val = asl_get(msg, ASL_KEY_READ_GID); - rgid = -1; - if (val != NULL) rgid = atoi(val); - - bb = 0; - val = asl_get(msg, ASL_KEY_EXPIRE_TIME); - if (val != NULL) - { - bb = 1; - msg_time = asl_parse_time(val); - } - - if (fseeko(s->storedata, 0, SEEK_SET) != 0) return ASL_STATUS_WRITE_FAILED; - - xid = asl_core_htonq(s->next_id); - if (fwrite(&xid, sizeof(uint64_t), 1, s->storedata) != 1) return ASL_STATUS_WRITE_FAILED; - - /* flush data */ - fflush(s->storedata); - - xid = s->next_id; - s->next_id++; - - s->last_write = now; - - if (localtime_r((const time_t *)&msg_time, &ctm) == NULL) return ASL_STATUS_FAILED; - - tstring = NULL; - if (bb == 1) - { - /* - * This supports 12 monthly "Best Before" buckets. - * We advance the actual expiry time to day zero of the following month. - * mktime() is clever enough to know that you actually mean the last day - * of the previous month. What we get back from localtime is the last - * day of the month in which the message expires, which we use in the name. - */ - ctm.tm_sec = 0; - ctm.tm_min = 0; - ctm.tm_hour = 0; - ctm.tm_mday = 0; - ctm.tm_mon += 1; - - bb = mktime(&ctm); - - if (localtime_r((const time_t *)&bb, &ctm) == NULL) return ASL_STATUS_FAILED; - asprintf(&tstring, "BB.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday); - } - else - { - asprintf(&tstring, "%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday); - } - - if (tstring == NULL) return ASL_STATUS_NO_MEMORY; - - status = asl_store_file_open_write(s, tstring, ruid, rgid, bb, &f, now, check_cache); - free(tstring); - tstring = NULL; - - if (status != ASL_STATUS_OK) return status; - - status = asl_file_save(f, msg, &xid); - if (status != ASL_STATUS_OK) return status; - - fsize = asl_file_size(f); - ftime = asl_file_ctime(f); - - /* if file is larger than max_file_size, rename it and touch semaphore file in the store */ - if ((s->max_file_size != 0) && (fsize > s->max_file_size)) - { - signal_sweep = 1; - status = ASL_STATUS_OK; - - path = asl_store_file_path(s, f); - - asl_store_file_close(s, f); - - if (path != NULL) - { - tmp_path = NULL; - - len = strlen(path); - if ((len >= 4) && (!strcmp(path + len - 4, ".asl"))) - { - /* rename xxxxxxx.asl to xxxxxxx.timestamp.asl */ - scratch = strdup(path); - if (scratch != NULL) - { - scratch[len - 4] = '\0'; - asprintf(&tmp_path, "%s.%llu.asl", scratch, ftime); - free(scratch); - - } - } - else - { - /* append timestamp */ - asprintf(&tmp_path, "%s.%llu", path, ftime); - } - - if (tmp_path == NULL) - { - status = ASL_STATUS_NO_MEMORY; - } - else - { - if (rename(path, tmp_path) != 0) status = ASL_STATUS_FAILED; - free(tmp_path); - } - - free(path); - } - } - - if (signal_sweep != 0) asl_store_signal_sweep(s); - - return status; -} - -static uint32_t -asl_store_mkdir(asl_store_t *s, const char *dir, mode_t m) -{ - char *tstring = NULL; - int status; - struct stat sb; - - asprintf(&tstring, "%s/%s", s->base_dir, dir); - if (tstring == NULL) return ASL_STATUS_NO_MEMORY; - - memset(&sb, 0, sizeof(struct stat)); - status = stat(tstring, &sb); - - if (status == 0) - { - /* must be a directory */ - if (!S_ISDIR(sb.st_mode)) - { - free(tstring); - return ASL_STATUS_INVALID_STORE; - } - } - else - { - if (errno == ENOENT) - { - /* doesn't exist - create it */ - if (mkdir(tstring, m) != 0) - { - free(tstring); - return ASL_STATUS_WRITE_FAILED; - } - } - else - { - /* stat failed for some other reason */ - free(tstring); - return ASL_STATUS_FAILED; - } - } - - free(tstring); - return ASL_STATUS_OK; -} - -uint32_t -asl_store_open_aux(asl_store_t *s, aslmsg msg, int *out_fd, char **url) -{ - struct tm ctm; - time_t msg_time, bb; - char *path, *dir, *tstring; - const char *val; - uid_t ruid, u; - gid_t rgid, g; - mode_t m; - uint32_t status; - uint64_t fid; - int fd; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (msg == NULL) return ASL_STATUS_INVALID_ARG; - if (out_fd == NULL) return ASL_STATUS_INVALID_ARG; - if (url == NULL) return ASL_STATUS_INVALID_ARG; - - msg_time = time(NULL); - - val = asl_get(msg, ASL_KEY_READ_UID); - ruid = -1; - if (val != NULL) ruid = atoi(val); - - val = asl_get(msg, ASL_KEY_READ_GID); - rgid = -1; - if (val != NULL) rgid = atoi(val); - - bb = 0; - val = asl_get(msg, ASL_KEY_EXPIRE_TIME); - if (val != NULL) - { - bb = 1; - msg_time = asl_parse_time(val); - } - - if (localtime_r((const time_t *)&msg_time, &ctm) == NULL) return ASL_STATUS_FAILED; - - dir = NULL; - if (bb == 1) - { - /* - * This supports 12 monthly "Best Before" buckets. - * We advance the actual expiry time to day zero of the following month. - * mktime() is clever enough to know that you actually mean the last day - * of the previous month. What we get back from localtime is the last - * day of the month in which the message expires, which we use in the name. - */ - ctm.tm_sec = 0; - ctm.tm_min = 0; - ctm.tm_hour = 0; - ctm.tm_mday = 0; - ctm.tm_mon += 1; - - bb = mktime(&ctm); - - if (localtime_r((const time_t *)&bb, &ctm) == NULL) return ASL_STATUS_FAILED; - asprintf(&dir, "BB.AUX.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday); - } - else - { - asprintf(&dir, "AUX.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday); - } - - if (dir == NULL) return ASL_STATUS_NO_MEMORY; - - status = asl_store_mkdir(s, dir, 0755); - if (status != ASL_STATUS_OK) - { - free(dir); - return status; - } - - fid = s->next_id; - s->next_id++; - tstring = NULL; - - asprintf(&tstring, "%s/%llu", dir, fid); - free(dir); - if (tstring == NULL) return ASL_STATUS_NO_MEMORY; - - u = 0; - g = 0; - m = 0644; - path = asl_store_make_ug_path(s->base_dir, tstring, NULL, ruid, rgid, &u, &g, &m); - free(tstring); - if (path == NULL) return ASL_STATUS_NO_MEMORY; - - fd = asl_file_create(path, u, g, m); - if (fd < 0) - { - free(path); - *out_fd = -1; - return ASL_STATUS_WRITE_FAILED; - } - - /* URL is file:// */ - *url = NULL; - asprintf(url, "file://%s", path); - free(path); - - *out_fd = fd; - - return status; -} - -uint32_t -asl_store_match_timeout(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec) -{ - DIR *dp; - struct dirent *dent; - uint32_t status; - asl_file_t *f; - char *path; - asl_file_list_t *files; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (res == NULL) return ASL_STATUS_INVALID_ARG; - - files = NULL; - - /* - * Open all readable files - */ - dp = opendir(s->base_dir); - if (dp == NULL) return ASL_STATUS_READ_FAILED; - - while ((dent = readdir(dp)) != NULL) - { - if (dent->d_name[0] == '.') continue; - - path = NULL; - asprintf(&path, "%s/%s", s->base_dir, dent->d_name); - - /* NB asl_file_open_read will fail if path is NULL, if the file is not an ASL store file, or if it isn't readable */ - status = asl_file_open_read(path, &f); - if (path != NULL) free(path); - if ((status != ASL_STATUS_OK) || (f == NULL)) continue; - - files = asl_file_list_add(files, f); - } - - closedir(dp); - - status = asl_file_list_match_timeout(files, query, res, last_id, start_id, count, direction, usec); - asl_file_list_close(files); - return status; -} - -uint32_t -asl_store_match(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) -{ - return asl_store_match_timeout(s, query, res, last_id, start_id, count, direction, 0); -} - -uint32_t -asl_store_match_start(asl_store_t *s, uint64_t start_id, int32_t direction) -{ - DIR *dp; - struct dirent *dent; - uint32_t status; - asl_file_t *f; - char *path; - asl_file_list_t *files; - - if (s == NULL) return ASL_STATUS_INVALID_STORE; - - if (s->work != NULL) asl_file_list_match_end(s->work); - s->work = NULL; - - files = NULL; - - /* - * Open all readable files - */ - dp = opendir(s->base_dir); - if (dp == NULL) return ASL_STATUS_READ_FAILED; - - while ((dent = readdir(dp)) != NULL) - { - if (dent->d_name[0] == '.') continue; - - path = NULL; - asprintf(&path, "%s/%s", s->base_dir, dent->d_name); - - /* NB asl_file_open_read will fail if path is NULL, if the file is not an ASL store file, or if it isn't readable */ - status = asl_file_open_read(path, &f); - if (path != NULL) free(path); - if ((status != ASL_STATUS_OK) || (f == NULL)) continue; - - files = asl_file_list_add(files, f); - } - - closedir(dp); - - s->work = asl_file_list_match_start(files, start_id, direction); - if (s->work == NULL) return ASL_STATUS_FAILED; - - return ASL_STATUS_OK; -} - -uint32_t -asl_store_match_next(asl_store_t *s, aslresponse query, aslresponse *res, uint32_t count) -{ - if (s == NULL) return ASL_STATUS_INVALID_STORE; - if (s->work == NULL) return ASL_STATUS_OK; - - return asl_file_list_match_next(s->work, query, res, count); -} diff --git a/src/libc/gen/asl_store.h b/src/libc/gen/asl_store.h deleted file mode 100644 index d56d152e9..000000000 --- a/src/libc/gen/asl_store.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2007-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __ASL_STORE_H__ -#define __ASL_STORE_H__ - -#include -#include -#include -#include -#include "asl_file.h" -#include - -#define PATH_ASL_STORE "/var/log/asl" -#define PATH_ASL_ARCHIVE "/var/log/asl.archive" -#define FILE_ASL_STORE_DATA "StoreData" -#define FILE_ASL_STORE_SWEEP_SEMAPHORE "SweepStore" - -#define FILE_CACHE_SIZE 64 -#define FILE_CACHE_TTL 300 - -typedef struct -{ - time_t ts; - uid_t u; - gid_t g; - time_t bb; - char *path; - asl_file_t *f; -} asl_cached_file_t; - -typedef struct -{ - char *base_dir; - FILE *storedata; - uint64_t next_id; - asl_cached_file_t file_cache[FILE_CACHE_SIZE]; - void *work; - time_t start_today; - time_t start_tomorrow; - time_t last_write; - size_t max_file_size; -} asl_store_t; - -uint32_t asl_store_open_write(const char *basedir, asl_store_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_store_open_read(const char *basedir, asl_store_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_store_close(asl_store_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_store_statistics(asl_store_t *s, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -uint32_t asl_store_save(asl_store_t *s, aslmsg msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -uint32_t asl_store_match(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_store_match_timeout(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); - -uint32_t asl_store_match_start(asl_store_t *s, uint64_t start_id, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_store_match_next(asl_store_t *s, aslresponse query, aslresponse *res, uint32_t count) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -uint32_t asl_store_max_file_size(asl_store_t *s, size_t max) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_store_signal_sweep(asl_store_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -uint32_t asl_store_sweep_file_cache(asl_store_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); - -uint32_t asl_store_open_aux(asl_store_t *s, aslmsg msg, int *fd, char **url) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); - -#endif /* __ASL_STORE_H__ */ diff --git a/src/libc/gen/asl_util.c b/src/libc/gen/asl_util.c deleted file mode 100644 index 108fa175e..000000000 --- a/src/libc/gen/asl_util.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2006-2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * These routines needs to be separate from asl.c, so that dyld can build - * and suck in these without the rest of asl. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static uint8_t *b64charset = (uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -__private_extern__ const char * -_asl_escape(unsigned char c) -{ - switch(c) - { - case '\\': - return "\\\\"; - case '[': - return "\\["; - case ']': - return "\\]"; - case '\n': - return "\\n"; - } - return NULL; -} - -static int -asl_is_utf8_char(const unsigned char *p, int *state, int *ctype) -{ - switch (*state) - { - case 0: - { - *ctype = 0; - - if (*p >= 0x80) - { - *state = 1; - if ((*p >= 0xc2) && (*p <= 0xdf)) *ctype = 1; - else if (*p == 0xe0) *ctype = 2; - else if ((*p >= 0xe1) && (*p <= 0xef)) *ctype = 3; - else if (*p == 0xf0) *ctype = 4; - else if ((*p >= 0xf1) && (*p <= 0xf3)) *ctype = 5; - else if (*p == 0xf4) *ctype = 6; - else return 0; - } - - break; - } - - case 1: - { - switch (*ctype) - { - case 1: - { - if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0; - else return 0; - break; - } - - case 2: - { - if ((*p >= 0xa0) && (*p <= 0xbf)) *state = 2; - else return 0; - break; - } - - case 3: - { - if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2; - else return 0; - break; - } - - case 4: - { - if ((*p >= 0x90) && (*p <= 0xbf)) *state = 2; - else return 0; - break; - } - - case 5: - { - if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2; - else return 0; - break; - } - - case 6: - { - if ((*p >= 0x80) && (*p <= 0x8f)) *state = 2; - else return 0; - break; - } - - default: return 0; - } - - break; - } - - case 2: - { - if ((*ctype >= 2) && (*ctype <= 3)) - { - if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0; - else return 0; - } - else if ((*ctype >= 4) && (*ctype <= 6)) - { - if ((*p >= 0x80) && (*p <= 0xbf)) *state = 3; - else return 0; - } - else - { - return 0; - } - - break; - } - - case 3: - { - if ((*ctype >= 4) && (*ctype <= 6)) - { - if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0; - else return 0; - } - else - { - return 0; - } - - break; - } - - default: return 0; - } - - return 1; -} - -__private_extern__ int -asl_is_utf8(const char *str) -{ - const unsigned char *p; - int flag = 1; - int state = 0; - int ctype = 0; - - if (str == NULL) return flag; - - for (p = (const unsigned char *)str; (*p != '\0') && (flag == 1); p++) - { - flag = asl_is_utf8_char(p, &state, &ctype); - } - - return flag; -} - -__private_extern__ uint8_t * -asl_b64_encode(const uint8_t *buf, size_t len) -{ - uint8_t *out; - uint8_t b; - size_t i0, i1, i2, j, outlen; - - if (buf == NULL) return NULL; - if (len == 0) return NULL; - - outlen = ((len + 2) / 3) * 4; - out = (uint8_t *)malloc(outlen + 1); - if (out == NULL) - { - errno = ENOMEM; - return NULL; - } - - out[outlen] = 0; - - i0 = 0; - i1 = 1; - i2 = 2; - j = 0; - - while (i2 < len) - { - b = buf[i0] >> 2; - out[j++] = b64charset[b]; - - b = ((buf[i0] & 0x03) << 4) | (buf[i1] >> 4); - out[j++] = b64charset[b]; - - b = ((buf[i1] & 0x0f) << 2) | ((buf[i2] & 0xc0) >> 6); - out[j++] = b64charset[b]; - - b = buf[i2] & 0x3f; - out[j++] = b64charset[b]; - - i0 += 3; - i1 = i0 + 1; - i2 = i1 + 1; - } - - if (i0 < len) - { - b = buf[i0] >> 2; - out[j++] = b64charset[b]; - - b = (buf[i0] & 0x03) << 4; - - if (i1 < len) b |= (buf[i1] >> 4); - out[j++] = b64charset[b]; - - if (i1 >= len) - { - out[j++] = '='; - out[j++] = '='; - return out; - } - - b = (buf[i1] & 0x0f) << 2; - out[j++] = b64charset[b]; - out[j++] = '='; - } - - return out; -} diff --git a/src/libc/gen/assumes.c b/src/libc/gen/assumes.c deleted file mode 100644 index 444c629cd..000000000 --- a/src/libc/gen/assumes.c +++ /dev/null @@ -1,305 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "assumes.h" - -#define OSX_ASSUME_LOG_REDIRECT_SECT_NAME "__osx_log_func" -#define osx_atomic_cmpxchg(p, o, n) __sync_bool_compare_and_swap((p), (o), (n)) - -static bool _osx_should_abort_on_assumes = false; - -static const char * -_osx_basename(const char *p) -{ - return ((strrchr(p, '/') ? : p - 1) + 1); -} - -static void -_osx_get_build(char *build, size_t sz) -{ - /* Get the build every time. We used to cache it, but if PID 1 experiences - * an assumes() failure before the build has been set, that would mean that - * all future failures would get bad build info. So we fetch it every time. - * Since assumes() failures are on the slow path anyway, not a huge deal. - */ - int mib[] = { CTL_KERN, KERN_OSVERSION }; - - size_t oldsz = sz; - int r = sysctl(mib, 2, build, &sz, NULL, 0); - if (r == 0 && sz == 1) { - (void)strlcpy(build, "99Z999", oldsz); - } -} - -static void -_osx_get_image_uuid(void *hdr, uuid_t uuid) -{ -#if __LP64__ - struct mach_header_64 *hdr32or64 = (struct mach_header_64 *)hdr; -#else - struct mach_header *hdr32or64 = (struct mach_header *)hdr; -#endif /* __LP64__ */ - - size_t i = 0; - size_t next = sizeof(*hdr32or64); - struct load_command *cur = NULL; - for (i = 0; i < hdr32or64->ncmds; i++) { - cur = (struct load_command *)((uintptr_t)hdr32or64 + next); - if (cur->cmd == LC_UUID) { - struct uuid_command *cmd = (struct uuid_command *)cur; - uuid_copy(uuid, cmd->uuid); - break; - } - - next += cur->cmdsize; - } - - if (i == hdr32or64->ncmds) { - uuid_clear(uuid); - } -} - -static void -_osx_abort_on_assumes_once(void) -{ - /* Embedded boot-args can get pretty long. Let's just hope this is big - * enough. - */ - char bootargs[2048]; - size_t len = sizeof(bootargs) - 1; - - if (sysctlbyname("kern.bootargs", bootargs, &len, NULL, 0) == 0) { - if (strnstr(bootargs, "-osx_assumes_fatal", len)) { - _osx_should_abort_on_assumes = true; - } - } -} - -static bool -_osx_abort_on_assumes(void) -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - bool result = false; - - if (getpid() != 1) { - if (getenv("OSX_ASSUMES_FATAL")) { - result = true; - } else { - pthread_once(&once, _osx_abort_on_assumes_once); - result = _osx_should_abort_on_assumes; - } - } else { - if (getenv("OSX_ASSUMES_FATAL_PID1")) { - result = true; - } - } - - return result; -} - -#if __LP64__ -static osx_redirect_t -_osx_find_log_redirect_func(struct mach_header_64 *hdr) -{ - osx_redirect_t result = NULL; - - char name[128]; - unsigned long size = 0; - uint8_t *data = getsectiondata(hdr, "__TEXT", OSX_ASSUME_LOG_REDIRECT_SECT_NAME, &size); - if (data && size < sizeof(name) - 2) { - /* Ensure NUL termination. */ - (void)strlcpy(name, (const char *)data, size + 1); - result = dlsym(RTLD_DEFAULT, name); - } - - return result; -} -#else -static osx_redirect_t -_osx_find_log_redirect_func(struct mach_header *hdr) -{ - osx_redirect_t result = NULL; - - char name[128]; - unsigned long size = 0; - uint8_t *data = getsectiondata(hdr, "__TEXT", OSX_ASSUME_LOG_REDIRECT_SECT_NAME, &size); - if (data && size < sizeof(name) - 2) { - (void)strlcpy(name, (const char *)data, size + 1); - result = dlsym(RTLD_DEFAULT, name); - } - - return result; -} -#endif - -static bool -_osx_log_redirect(void *hdr, const char *msg) -{ - bool result = false; - - osx_redirect_t redirect_func = _osx_find_log_redirect_func(hdr); - if (redirect_func) { - result = redirect_func(msg); - } - - return result; -} - -__attribute__((always_inline)) -static void -_osx_construct_message(const char *prefix, uint64_t code, aslmsg asl_message, Dl_info *info, char *buff, size_t sz) -{ - const char *image_name = NULL; - uintptr_t offset = 0; - uuid_string_t uuid_str; - - void *ret = __builtin_return_address(0); - if (dladdr(ret, info)) { - uuid_t uuid; - _osx_get_image_uuid(info->dli_fbase, uuid); - - uuid_unparse(uuid, uuid_str); - image_name = _osx_basename(info->dli_fname); - - offset = ret - info->dli_fbase; - } - - char name[256]; - (void)snprintf(name, sizeof(name), "com.apple.assumes.%s", image_name); - - char sig[64]; - (void)snprintf(sig, sizeof(sig), "%s:%lu", uuid_str, offset); - - char result[24]; - (void)snprintf(result, sizeof(result), "0x%llx", code); - - char build[16]; - size_t bsz = sizeof(build); - _osx_get_build(build, bsz); - - (void)snprintf(buff, sz, "%s: %s: %s + %lu [%s]: %s", prefix, build, image_name, offset, uuid_str, result); - - (void)asl_set(asl_message, "com.apple.message.domain", name); - (void)asl_set(asl_message, "com.apple.message.signature", sig); - (void)asl_set(asl_message, "com.apple.message.value", result); -} - -void -_osx_assumes_log(uint64_t code) -{ - aslmsg asl_message = asl_new(ASL_TYPE_MSG); - if (asl_message) { - Dl_info info; - char message[256]; - _osx_construct_message("Bug", code, asl_message, &info, message, sizeof(message)); - if (!_osx_log_redirect(info.dli_fbase, message)) { - /* MessageTracer messages aren't logged to the regular syslog store, - * so we log the message without any MessageTracer attributes so - * that we can see it in our regular syslog. - */ - (void)asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s", message); - (void)asl_log(NULL, asl_message, ASL_LEVEL_ERR, "%s", message); - } - - asl_free(asl_message); - } - - if (_osx_abort_on_assumes()) { - __builtin_trap(); - } -} - -char * -_osx_assert_log(uint64_t code) -{ - char *result = NULL; - - aslmsg asl_message = asl_new(ASL_TYPE_MSG); - if (asl_message) { - Dl_info info; - char message[256]; - _osx_construct_message("Fatal bug", code, asl_message, &info, message, sizeof(message)); - if (!_osx_log_redirect(info.dli_fbase, message)) { - (void)asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s", message); - (void)asl_log(NULL, asl_message, ASL_LEVEL_ERR, "%s", message); - } - - asl_free(asl_message); - result = strdup(message); - } - -#if LIBC_NO_LIBCRASHREPORTERCLIENT - /* There is no crash report information facility on embedded, which is - * really regrettable. Fortunately, all we need to capture is the value - * which tripped up the assertion. We can just stuff that into the thread's - * name. - */ - char name[64]; - (void)pthread_getname_np(pthread_self(), name, sizeof(name)); - - char newname[64]; - if (strlen(name) == 0) { - (void)snprintf(newname, sizeof(newname), "[Fatal bug: 0x%llx]", code); - } else { - (void)snprintf(newname, sizeof(newname), "%s [Fatal bug: 0x%llx]", name, code); - } - - (void)pthread_setname_np(newname); -#endif - - return result; -} - -void -_osx_assumes_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code) -{ - aslmsg asl_message = asl_new(ASL_TYPE_MSG); - if (asl_message) { - Dl_info info; - char message[256]; - _osx_construct_message("Bug", code, asl_message, &info, message, sizeof(message)); - - (void)callout(asl_message, ctx, message); - asl_free(asl_message); - } - - if (_osx_abort_on_assumes()) { - __builtin_trap(); - } -} - -char * -_osx_assert_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code) -{ - char *result = NULL; - - aslmsg asl_message = asl_new(ASL_TYPE_MSG); - if (asl_message) { - Dl_info info; - char message[256]; - _osx_construct_message("Fatal bug", code, asl_message, &info, message, sizeof(message)); - - (void)callout(asl_message, ctx, message); - asl_free(asl_message); - result = strdup(message); - } -} - -extern void -_osx_avoid_tail_call(void) -{ - // no-op -} diff --git a/src/libc/gen/assumes.h b/src/libc/gen/assumes.h deleted file mode 100644 index 70eb97d0f..000000000 --- a/src/libc/gen/assumes.h +++ /dev/null @@ -1,227 +0,0 @@ -#ifndef __OSX_ASSUMES_H__ -#define __OSX_ASSUMES_H__ - -#include - -__BEGIN_DECLS - -#include -#include -#include -#include -#include -#include -#include - -#if __GNUC__ -#define osx_fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l)) -#define osx_slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l)) -#define osx_constant(x) __builtin_constant_p((x)) -#define osx_hardware_trap() __builtin_trap() - -#define __OSX_COMPILETIME_ASSERT__(e) ({ \ - char __compile_time_assert__[(e) ? 1 : -1]; \ - (void)__compile_time_assert__; \ -}) -#else -#define osx_fastpath(x) (x) -#define osx_slowpath(x) (x) -#define osx_constant(x) ((long)0) -#define osx_hardware_trap() abort() - -#define __OSX_COMPILETIME_ASSERT__(e) (e) -#endif /* __GNUC__ */ - -typedef bool (*osx_redirect_t)(const char *); - -/* The asl_message argument is an aslmsg that, when given to asl_log(), will - * direct the message to the MessageTracer diagnostic messages store rather than - * the default system log store. - */ -typedef bool (*osx_log_callout_t)(aslmsg asl_message, void *ctx, const char *); - -#if TARGET_OS_IPHONE -#define osx_set_crash_message(arg) /* no-op */ -#else -#include -#define osx_set_crash_message(arg) _crc_make_setter(message, (arg)) -#endif - -#define osx_assumes(e) ({ \ - typeof(e) _e = osx_fastpath(e); /* Force evaluation of 'e' */ \ - if (!_e) { \ - if (osx_constant(e)) { \ - __OSX_COMPILETIME_ASSERT__(e); \ - } \ - _osx_assumes_log((uint64_t)(uintptr_t)_e); \ - _osx_avoid_tail_call(); \ - } \ - _e; \ -}) - -#define osx_assumes_zero(e) ({ \ - typeof(e) _e = osx_slowpath(e); \ - if (_e) { \ - if (osx_constant(e)) { \ - __OSX_COMPILETIME_ASSERT__(!e); \ - } \ - _osx_assumes_log((uint64_t)(uintptr_t)_e); \ - _osx_avoid_tail_call(); \ - } \ - _e; \ -}) - -/* This variant is for use with old-style POSIX APIs that return -1 on failure - * and set errno. If the return code is -1, the value logged will be as though - * osx_assumes_zero(errno) was used. It encapsulates the following pattern: - * - * int tubes[2]; - * if (pipe(tubes) == -1) { - * (void)osx_assumes_zero(errno); - * } - */ -#define posix_assumes_zero(e) ({ \ - typeof(e) _e = osx_slowpath(e); \ - if (_e == (typeof(e))-1) { \ - _osx_assumes_log((uint64_t)(uintptr_t)errno); \ - _osx_avoid_tail_call(); \ - } \ - _e; \ -}) - -#define osx_assert(e) ({ \ - typeof(e) _e = osx_fastpath(e); \ - if (!_e) { \ - if (osx_constant(e)) { \ - __OSX_COMPILETIME_ASSERT__(e); \ - } \ -\ - char *message = _osx_assert_log((uint64_t)(uintptr_t)_e); \ - osx_set_crash_message(message); \ - osx_hardware_trap(); \ - free(message); \ - } \ -}) - -#define osx_assert_zero(e) ({ \ - typeof(e) _e = osx_slowpath(e); \ - if (_e) { \ - if (osx_constant(e)) { \ - __OSX_COMPILETIME_ASSERT__(!e); \ - } \ -\ - char *message = _osx_assert_log((uint64_t)(uintptr_t)_e); \ - osx_set_crash_message(message); \ - osx_hardware_trap(); \ - free(message); \ - } \ -}) - -#define posix_assert_zero(e) ({ \ - typeof(e) _e = osx_slowpath(e); \ - if (_e == (typeof(e))-1) { \ - char *message = _osx_assert_log((uint64_t)(uintptr_t)errno); \ - osx_set_crash_message(message); \ - osx_hardware_trap(); \ - free(message); \ - } \ -}) - -/* These are for defining your own assumes()-like wrapper calls so that you can - * log additional information, such as the about-PID, sender, etc. They're - * generally not useful for direct inclusion in your code. - */ -#define osx_assumes_ctx(f, ctx, e) ({ \ - typeof(e) _e = osx_fastpath(e); \ - if (!_e) { \ - if (osx_constant(e)) { \ - __OSX_COMPILETIME_ASSERT__(e); \ - } \ - _osx_assumes_log_ctx(f, ctx, (uintptr_t)_e); \ - _osx_avoid_tail_call(); \ - } \ - _e; \ -}) - -#define osx_assumes_zero_ctx(f, ctx, e) ({ \ - typeof(e) _e = osx_slowpath(e); \ - if (_e) { \ - if (osx_constant(e)) { \ - __OSX_COMPILETIME_ASSERT__(!e); \ - } \ - _osx_assumes_log_ctx((f), (ctx), (uintptr_t)_e); \ - _osx_avoid_tail_call(); \ - } \ - _e; \ -}) - -#define posix_assumes_zero_ctx(f, ctx, e) ({ \ - typeof(e) _e = osx_slowpath(e); \ - if (_e == (typeof(e))-1) { \ - _osx_assumes_log_ctx((f), (ctx), (uintptr_t)errno); \ - _osx_avoid_tail_call(); \ - } \ - _e; \ -}) - -#define osx_assert_ctx(f, ctx, e) ({ \ - typeof(e) _e = osx_fastpath(e); \ - if (!_e) { \ - if (osx_constant(e)) { \ - __OSX_COMPILETIME_ASSERT__(e); \ - } \ -\ - char *message = _osx_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)_e); \ - osx_set_crash_message(message); \ - osx_hardware_trap(); \ - free(message); \ - } \ -}) - -#define osx_assert_zero_ctx(f, ctx, e) ({ \ - typeof(e) _e = osx_slowpath(e); \ - if (_e) { \ - if (osx_constant(e)) { \ - __OSX_COMPILETIME_ASSERT__(!e); \ - } \ -\ - char *message = _osx_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)_e); \ - osx_set_crash_message(message); \ - osx_hardware_trap(); \ - free(message); \ - } \ -}) - -#define posix_assert_zero_ctx(f, ctx, e) ({ \ - typeof(e) _e = osx_slowpath(e); \ - if (_e == (typeof(e))-1) { \ - char *message = _osx_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)errno); \ - osx_set_crash_message(message); \ - osx_hardware_trap(); \ - free(message); \ - } \ -}) - -__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3) -extern void -_osx_assumes_log(uint64_t code); - -__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0) -extern char * -_osx_assert_log(uint64_t code); - -__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0) -extern void -_osx_assumes_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code); - -__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0) -extern char * -_osx_assert_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code); - -__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0) -extern void -_osx_avoid_tail_call(void); - -__END_DECLS - -#endif /* __OSX_ASSUMES_H__ */ diff --git a/src/libc/gen/backtrace.c b/src/libc/gen/backtrace.c index c075de253..925dcb47b 100644 --- a/src/libc/gen/backtrace.c +++ b/src/libc/gen/backtrace.c @@ -84,7 +84,7 @@ static int _backtrace_snprintf(char* buf, size_t size, int frame, const void* ad image, (uintptr_t)addr, symbol, - symbol_offset) + 1; + symbol_offset); } char** backtrace_symbols(void* const* buffer, int size) { @@ -110,9 +110,9 @@ char** backtrace_symbols(void* const* buffer, int size) { if (info[i].dli_sname) { total_bytes += strlen(info[i].dli_sname); } else if(info[i].dli_fname) { - const char *tmp = strrchr(info->dli_fname, '/'); + const char *tmp = strrchr(info[i].dli_fname, '/'); if(tmp == NULL) - total_bytes += strlen(info->dli_fname); + total_bytes += strlen(info[i].dli_fname); else total_bytes += strlen(tmp + 1); } else { @@ -142,7 +142,7 @@ char** backtrace_symbols(void* const* buffer, int size) { } ptrs[i] = (char*)strs; - strs += chk; + strs += chk + 1; // Step over the '\0' } free(info); diff --git a/src/libc/gen/clock_gettime.3 b/src/libc/gen/clock_gettime.3 new file mode 100644 index 000000000..e340b6441 --- /dev/null +++ b/src/libc/gen/clock_gettime.3 @@ -0,0 +1,186 @@ +.\" +.\" Copyright (c) 1980, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd January 26, 2016 +.Dt CLOCK_GETTIME 3 +.Os +.Sh NAME +.Nm clock_gettime , +.Nm clock_settime , +.Nm clock_getres , +.Nm clock_gettime_nsec_np +.Nd get/set date and time +.Sh SYNOPSIS +.Fd #include +.Ft int +.Fn clock_gettime "clockid_t clock_id" "struct timespec *tp" +.Ft int +.Fn clock_settime "clockid_t clock_id" "const struct timespec *tp" +.Ft int +.Fn clock_getres "clockid_t clock_id" "struct timespec *tp" +.Ft uint64_t +.Fn clock_gettime_nsec_np "clockid_t clock_id" +.Sh DESCRIPTION +The +.Fn clock_gettime +and +.Fn clock_settime +functions +allow the calling process to retrieve or set the value used by a clock +which is specified by +.Fa clock_id . +.Pp +.Fa clock_id +can be a value from +one of 5 predefined values: +.Bl -tag -width Er +.It Dv CLOCK_REALTIME +the system's real time (i.e. wall time) clock, expressed as the amount of time +since the Epoch. +This is the same as the value returned by +.Xr gettimeofday 2 . +.It Dv CLOCK_MONOTONIC +clock that increments monotonically, tracking the time since an arbitrary +point, and will continue to increment while the system is asleep. +.It Dv CLOCK_MONOTONIC_RAW +clock that increments monotonically, tracking the time since an arbitrary point +like CLOCK_MONOTONIC. However, this clock is unaffected by frequency or time +adjustments. It should not be compared to other system time sources. +.It Dv CLOCK_MONOTONIC_RAW_APPROX +like CLOCK_MONOTONIC_RAW, but reads a value cached by the system at context +switch. This can be read faster, but at a loss of accuracy as it may return +values that are milliseconds old. +.It Dv CLOCK_UPTIME_RAW +clock that increments monotonically, in the same manner as +.Dv CLOCK_MONOTONIC_RAW, +but that does not increment while the system is asleep. +The returned value is identical to the result of +.Fn mach_absolute_time +after the appropriate mach_timebase conversion is applied. +.It Dv CLOCK_UPTIME_RAW_APPROX +like CLOCK_UPTIME_RAW, but reads a value cached by the system at context +switch. This can be read faster, but at a loss of accuracy as it may return +values that are milliseconds old. +.It Dv CLOCK_PROCESS_CPUTIME_ID +clock that tracks the amount of CPU (in user- or kernel-mode) used by the +calling process. +.It Dv CLOCK_THREAD_CPUTIME_ID +clock that tracks the amount of CPU (in user- or kernel-mode) used by the +calling thread. +.El +.Pp +The structure pointed to by +.Fa tp +is defined in +.In sys/time.h +as: +.Bd -literal -offset indent +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; +.Ed +.Pp +Only the +.Dv CLOCK_REALTIME +clock can be set, and only the superuser may do so. +.Pp +The resolution of a clock is returned by the +.Fn clock_getres +call. +This value is placed in a (non-null) +.Fa *tp . +This value may be smaller than the actual precision of the underlying clock, +but represents a lower bound on the resolution. +.Pp +As a non-portable extension, the +.Fn clock_gettime_nsec_np +function will return the clock value in 64-bit nanoseconds. +.Sh RETURN VALUES +A 0 return value indicates that the call succeeded. +A \-1 return value indicates an error occurred, and in this +case an error code is stored into the global variable +.Va errno . +For +.Fn clock_gettime_nsec_np +a return value of non-0 indicates success. A 0 return value indicates an error +occurred and an error code is stored in +.Va errno . +.Sh ERRORS +.Fn clock_gettime , +.Fn clock_settime , +.Fn clock_getres , +and +.Fn clock_gettime_nsec_np +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +.Fa clock_id +is not a valid value. +.It Bq Er EFAULT +The +.Fa tp +argument address referenced invalid memory. +.El +.Pp +In addition, +.Fn clock_settime +may return the following errors: +.Bl -tag -width Er +.It Bq Er EPERM +A user other than the superuser attempted to set the time. +.It Bq Er EINVAL +.Fa clock_id +specifies a clock that isn't settable, +.Fa tp +specifies a nanosecond value less than zero or greater than 1000 million, +or a value outside the range of the specified clock. +.El +.Sh SEE ALSO +.Xr date 1 , +.Xr getitimer 2 , +.Xr gettimeofday 2 , +.Sh HISTORY +These functions first appeared +in +Mac OSX 10.12 +.Sh STANDARDS +The +.Fn clock_gettime , +.Fn clock_settime , +and +.Fn clock_getres +system calls conform to +.St -p1003.1b-93 . +.Fn cleck_gettime_nsec_np +is a non-portable Darwin extension. +The clock IDs +.Fa CLOCK_MONOTONIC_RAW +and +.Fa CLOCK_UPTIME_RAW +are extensions to the POSIX interface. diff --git a/src/libc/gen/clock_gettime.c b/src/libc/gen/clock_gettime.c new file mode 100644 index 000000000..7be0ad78a --- /dev/null +++ b/src/libc/gen/clock_gettime.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern uint64_t __thread_selfusage(void); + +#define timeval2nsec(tv) (tv.tv_sec * NSEC_PER_SEC + tv.tv_usec * NSEC_PER_USEC) + +static uint64_t +_boottime_fallback_usec(void) +{ + struct timeval tv; + size_t len = sizeof(tv); + int ret = sysctlbyname("kern.boottime", &tv, &len, NULL, 0); + if (ret == -1) return 0; + return (uint64_t)tv.tv_sec * USEC_PER_SEC + (uint64_t)tv.tv_usec; +} + +static int +_mach_boottime_usec(uint64_t *boottime, struct timeval *realtime) +{ + uint64_t bt1 = 0, bt2 = 0; + int ret; + do { + bt1 = mach_boottime_usec(); + if (os_slowpath(bt1 == 0)) bt1 = _boottime_fallback_usec(); + + atomic_thread_fence(memory_order_seq_cst); + + ret = gettimeofday(realtime, NULL); + if (ret != 0) return ret; + + atomic_thread_fence(memory_order_seq_cst); + + bt2 = mach_boottime_usec(); + if (os_slowpath(bt2 == 0)) bt2 = _boottime_fallback_usec(); + } while (os_slowpath(bt1 != bt2)); + *boottime = bt1; + return 0; +} + +uint64_t +clock_gettime_nsec_np(clockid_t clock_id) +{ + switch(clock_id){ + case CLOCK_REALTIME: { + struct timeval tv; + int ret = gettimeofday(&tv, NULL); + if (ret) return 0; + return timeval2nsec(tv); + } + case CLOCK_MONOTONIC: { + struct timeval tv; + uint64_t boottime; + int ret = _mach_boottime_usec(&boottime, &tv); + if (ret) return 0; + boottime *= NSEC_PER_USEC; + return timeval2nsec(tv) - boottime; + } + case CLOCK_PROCESS_CPUTIME_ID: { + struct rusage ru; + int ret = getrusage(RUSAGE_SELF, &ru); + if (ret) return 0; + return timeval2nsec(ru.ru_utime) + timeval2nsec(ru.ru_stime); + } + default: + // calls that use mach_absolute_time units fall through into a common path + break; + } + + // Mach Absolute Time unit-based calls + mach_timebase_info_data_t tb_info; + if (mach_timebase_info(&tb_info)) return 0; + uint64_t mach_time; + + switch(clock_id){ + case CLOCK_MONOTONIC_RAW: + mach_time = mach_continuous_time(); + break; + case CLOCK_MONOTONIC_RAW_APPROX: + mach_time = mach_continuous_approximate_time(); + break; + case CLOCK_UPTIME_RAW: + mach_time = mach_absolute_time(); + break; + case CLOCK_UPTIME_RAW_APPROX: + mach_time = mach_approximate_time(); + break; + case CLOCK_THREAD_CPUTIME_ID: + mach_time = __thread_selfusage(); + break; + default: + errno = EINVAL; + return 0; + } + + return (mach_time * tb_info.numer) / tb_info.denom; +} + +int +clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + switch(clk_id){ + case CLOCK_REALTIME: { + struct timeval tv; + int ret = gettimeofday(&tv, NULL); + TIMEVAL_TO_TIMESPEC(&tv, tp); + return ret; + } + case CLOCK_MONOTONIC: { + struct timeval tv; + uint64_t boottime_usec; + int ret = _mach_boottime_usec(&boottime_usec, &tv); + struct timeval boottime = { + .tv_sec = boottime_usec / USEC_PER_SEC, + .tv_usec = boottime_usec % USEC_PER_SEC + }; + timersub(&tv, &boottime, &tv); + TIMEVAL_TO_TIMESPEC(&tv, tp); + return ret; + } + case CLOCK_PROCESS_CPUTIME_ID: { + struct rusage ru; + int ret = getrusage(RUSAGE_SELF, &ru); + timeradd(&ru.ru_utime, &ru.ru_stime, &ru.ru_utime); + TIMEVAL_TO_TIMESPEC(&ru.ru_utime, tp); + return ret; + } + case CLOCK_MONOTONIC_RAW: + case CLOCK_MONOTONIC_RAW_APPROX: + case CLOCK_UPTIME_RAW: + case CLOCK_UPTIME_RAW_APPROX: + case CLOCK_THREAD_CPUTIME_ID: { + uint64_t ns = clock_gettime_nsec_np(clk_id); + if (!ns) return -1; + + tp->tv_sec = ns/NSEC_PER_SEC; + tp->tv_nsec = ns % NSEC_PER_SEC; + return 0; + } + default: + errno = EINVAL; + return -1; + } +} + +int +clock_getres(clockid_t clk_id, struct timespec *res) +{ + switch(clk_id){ + case CLOCK_REALTIME: + case CLOCK_MONOTONIC: + case CLOCK_PROCESS_CPUTIME_ID: + res->tv_nsec = NSEC_PER_USEC; + res->tv_sec = 0; + return 0; + + case CLOCK_MONOTONIC_RAW: + case CLOCK_MONOTONIC_RAW_APPROX: + case CLOCK_UPTIME_RAW: + case CLOCK_UPTIME_RAW_APPROX: + case CLOCK_THREAD_CPUTIME_ID: { + mach_timebase_info_data_t tb_info; + if (mach_timebase_info(&tb_info)){ + return -1; + } + res->tv_nsec = tb_info.numer / tb_info.denom + (tb_info.numer % tb_info.denom != 0); + res->tv_sec = 0; + return 0; + } + + default: + errno = EINVAL; + return -1; + } +} + +int +clock_settime(clockid_t clk_id, const struct timespec *tp) +{ + switch(clk_id){ + case CLOCK_REALTIME: { + struct timeval tv; + TIMESPEC_TO_TIMEVAL(&tv,tp) + return settimeofday(&tv, NULL); + } + default: + errno = EINVAL; + return -1; + } +} diff --git a/src/libc/gen/compat.5 b/src/libc/gen/compat.5 index fbae91217..b711c0432 100644 --- a/src/libc/gen/compat.5 +++ b/src/libc/gen/compat.5 @@ -136,7 +136,6 @@ T} >= 10.4 strict SUSv3 conformance $UNIX2003 _ .T& c s s s s -c s s s s c c | c c c c c | c c c l c | c c c diff --git a/src/libc/gen/confstr.3 b/src/libc/gen/confstr.3 index e5fff633d..224e7d18e 100644 --- a/src/libc/gen/confstr.3 +++ b/src/libc/gen/confstr.3 @@ -85,6 +85,38 @@ The available values are as follows: .Pp .Bl -tag -width 6n .Pp +.It Li _CS_DARWIN_USER_DIR +Provides the path to a user's folder. The directory will be created if it +does not already exist. +.Pp +This directory is created with access permissions of 0755 and restricted by +the +.Xr umask 2 +of the calling process and is not intended to be used for +sensitive or temporary file storage, as all users can see files created here. +If the user's umask allows it, files created here will be world readable, +which could lead to information disclosure. +.Pp +.It Li _CS_DARWIN_USER_TEMP_DIR +Provides the path to a user's temporary items directory. The directory will be +created it if does not already exist. This directory is created with access +permissions of 0700 and restricted by the +.Xr umask 2 +of the calling process and is a good location for temporary files. +.Pp +By default, files in this location may be cleaned (removed) by the system if +they are not accessed in 3 days. +.Pp +.It Li _CS_DARWIN_USER_CACHE_DIR +Provides the path to the user's cache directory. The directory will be created +if it does not already exist. This directory is created with access permissions +of 0700 and restricted by the +.Xr umask 2 +of the calling process and is a good location for user cache data as it will not +be automatically cleaned by the system. +.Pp +Files in this location will be removed during safe boot. +.Pp .It Li _CS_PATH Return a value for the .Ev PATH diff --git a/src/libc/gen/confstr.c b/src/libc/gen/confstr.c index 196d195c4..a7f9613ae 100644 --- a/src/libc/gen/confstr.c +++ b/src/libc/gen/confstr.c @@ -64,9 +64,47 @@ #include #include /* for P_tmpdir */ +#ifndef __has_include #include +#else +#if __has_include() +#include +#else +typedef enum { + DIRHELPER_USER_LOCAL = 0, + DIRHELPER_USER_LOCAL_TEMP, + DIRHELPER_USER_LOCAL_CACHE, + DIRHELPER_USER_LOCAL_LAST = DIRHELPER_USER_LOCAL_CACHE +} dirhelper_which_t; +#endif +#endif + +#include "libc_private.h" + +#if __DARWIN_UNIX03 +static char *(*__dirhelper_func)(int, char *, size_t); + +__attribute__((__visibility__("hidden"))) +void +__confstr_init(const struct _libc_functions *funcs) +{ + __dirhelper_func = funcs->dirhelper; +} -extern char *_dirhelper(dirhelper_which_t which, char *path, size_t pathlen); +__attribute__((__visibility__("hidden"))) +char * +__dirhelper(dirhelper_which_t which, char *path, size_t pathlen) +{ + if (__dirhelper_func) { + return __dirhelper_func(which, path, pathlen); + } else { + return NULL; + } +} +#else // !__DARWIN_UNIX03 +__attribute__((__visibility__("hidden"))) +char *__dirhelper(dirhelper_which_t which, char *path, size_t pathlen); +#endif // !__DARWIN_UNIX03 #if __DARWIN_UNIX03 #define CONFSTR_ERR_RET 0 @@ -176,7 +214,7 @@ docopy: errno = ENOMEM; return (CONFSTR_ERR_RET); } - if (_dirhelper(DIRHELPER_USER_LOCAL, p, PATH_MAX) == NULL) { + if (__dirhelper(DIRHELPER_USER_LOCAL, p, PATH_MAX) == NULL) { if (errno != ENOMEM) errno = EIO; return (CONFSTR_ERR_RET); @@ -188,10 +226,10 @@ docopy: errno = ENOMEM; return (CONFSTR_ERR_RET); } - if (_dirhelper(DIRHELPER_USER_LOCAL_TEMP, p, PATH_MAX) == NULL) { + if (__dirhelper(DIRHELPER_USER_LOCAL_TEMP, p, PATH_MAX) == NULL) { int dh_errno = errno; /* - * If _dirhelper() fails, try TMPDIR and P_tmpdir, + * If __dirhelper() fails, try TMPDIR and P_tmpdir, * finally failing otherwise. */ if ((p = getenv("TMPDIR")) && access(p, W_OK) == 0) @@ -211,7 +249,7 @@ docopy: errno = ENOMEM; return (CONFSTR_ERR_RET); } - if (_dirhelper(DIRHELPER_USER_LOCAL_CACHE, p, PATH_MAX) == NULL) { + if (__dirhelper(DIRHELPER_USER_LOCAL_CACHE, p, PATH_MAX) == NULL) { if (errno != ENOMEM) errno = EIO; return (CONFSTR_ERR_RET); diff --git a/src/libc/gen/crypt.c b/src/libc/gen/crypt.c index f1edfd975..6743885d6 100644 --- a/src/libc/gen/crypt.c +++ b/src/libc/gen/crypt.c @@ -352,7 +352,7 @@ __private_extern__ int __crypt_des_setkey_called; /* ===== (mostly) Standard DES Tables ==================== */ #ifndef BUILDING_VARIANT -static unsigned char IP[] = { /* initial permutation */ +static const unsigned char IP[] = { /* initial permutation */ 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, @@ -365,7 +365,7 @@ static unsigned char IP[] = { /* initial permutation */ /* The final permutation is the inverse of IP - no table is necessary */ -static unsigned char ExpandTr[] = { /* expansion operation */ +static const unsigned char ExpandTr[] = { /* expansion operation */ 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, @@ -376,7 +376,7 @@ static unsigned char ExpandTr[] = { /* expansion operation */ 28, 29, 30, 31, 32, 1, }; -static unsigned char PC1[] = { /* permuted choice table 1 */ +static const unsigned char PC1[] = { /* permuted choice table 1 */ 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, @@ -388,12 +388,12 @@ static unsigned char PC1[] = { /* permuted choice table 1 */ 21, 13, 5, 28, 20, 12, 4, }; -static unsigned char Rotates[] = { /* PC1 rotation schedule */ +static const unsigned char Rotates[] = { /* PC1 rotation schedule */ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, }; /* note: each "row" of PC2 is left-padded with bits that make it invertible */ -static unsigned char PC2[] = { /* permuted choice table 2 */ +static const unsigned char PC2[] = { /* permuted choice table 2 */ 9, 18, 14, 17, 11, 24, 1, 5, 22, 25, 3, 28, 15, 6, 21, 10, 35, 38, 23, 19, 12, 4, 26, 8, @@ -456,7 +456,7 @@ static const unsigned char S[8][64] = { /* 48->32 bit substitution tables */ }, }; -static unsigned char P32Tr[] = { /* 32-bit permutation function */ +static const unsigned char P32Tr[] = { /* 32-bit permutation function */ 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, @@ -467,7 +467,7 @@ static unsigned char P32Tr[] = { /* 32-bit permutation function */ 22, 11, 4, 25, }; -static unsigned char CIFP[] = { /* compressed/interleaved permutation */ +static const unsigned char CIFP[] = { /* compressed/interleaved permutation */ 1, 2, 3, 4, 17, 18, 19, 20, 5, 6, 7, 8, 21, 22, 23, 24, 9, 10, 11, 12, 25, 26, 27, 28, @@ -479,14 +479,24 @@ static unsigned char CIFP[] = { /* compressed/interleaved permutation */ 45, 46, 47, 48, 61, 62, 63, 64, }; -static unsigned char itoa64[] = /* 0..63 => ascii-64 */ +static const unsigned char itoa64[] = /* 0..63 => ascii-64 */ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; /* ===== Tables that are initialized at run time ==================== */ -static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ +/* ascii-64 => 0..63 */ +static const unsigned char a64toi[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, + 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 0, 0, 0, 0, + 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0, +}; /* Initial key schedule permutation */ // static C_block PC1ROT[64/CHUNKBITS][1<> 0) &01) << 5)| (((j >> 1) &01) << 3)| (((j >> 2) &01) << 2)| @@ -903,8 +906,6 @@ STATIC void init_des() (((k >> 2)&01) << 1)| (((k >> 1)&01) << 2)| (((k >> 0)&01) << 3); - for (i = 0; i < 32; i++) - tmp32[i] = 0; for (i = 0; i < 4; i++) tmp32[4 * tableno + i] = (k >> i) & 01; k = 0; diff --git a/src/libc/gen/directory.3 b/src/libc/gen/directory.3 index 4faf967b2..b94998bea 100644 --- a/src/libc/gen/directory.3 +++ b/src/libc/gen/directory.3 @@ -9,10 +9,6 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. @@ -30,84 +26,130 @@ .\" SUCH DAMAGE. .\" .\" @(#)directory.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/directory.3,v 1.12 2001/10/01 16:08:50 ru Exp $ +.\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd April 16, 2008 .Dt DIRECTORY 3 .Os .Sh NAME -.Nm closedir , -.Nm dirfd , .Nm opendir , +.Nm fdopendir , .Nm readdir , .Nm readdir_r , -.Nm rewinddir , +.Nm telldir , .Nm seekdir , -.Nm telldir +.Nm rewinddir , +.Nm closedir , +.Nm dirfd .Nd directory operations .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In dirent.h -.Ft int -.Fn closedir "DIR *dirp" -.Ft int -.Fn dirfd "DIR *dirp" .Ft DIR * -.Fn opendir "const char *dirname" +.Fn opendir "const char *filename" +.Ft DIR * +.Fn fdopendir "int fd" .Ft struct dirent * .Fn readdir "DIR *dirp" .Ft int -.Fn readdir_r "DIR *restrict dirp" "struct dirent *restrict entry" \ - "struct dirent **restrict result" -.Ft void -.Fn rewinddir "DIR *dirp" -.Ft void -.Fn seekdir "DIR *dirp" "long loc" +.Fn readdir_r "DIR *dirp" "struct dirent *entry" "struct dirent **result" .Ft long .Fn telldir "DIR *dirp" +.Ft void +.Fn seekdir "DIR *dirp" "long loc" +.Ft void +.Fn rewinddir "DIR *dirp" +.Ft int +.Fn closedir "DIR *dirp" +.Ft int +.Fn dirfd "DIR *dirp" .Sh DESCRIPTION The .Fn opendir function opens the directory named by -.Fa dirname , +.Fa filename , associates a .Em directory stream -with it, -and returns a pointer to be used to identify the +with it +and +returns a pointer to be used to identify the .Em directory stream -in subsequent operations. The pointer +in subsequent operations. +The pointer .Dv NULL is returned if -.Fa dirname -cannot be accessed or if it cannot +.Fa filename +cannot be accessed, or if it cannot .Xr malloc 3 -enough memory to hold the whole thing. +enough memory to hold the whole thing, +and sets the global variable +.Va errno +to indicate the error. +.Pp +The +.Fn fdopendir +function is equivalent to the +.Fn opendir +function except that the directory is specified by a file descriptor +.Fa fd +rather than by a name. +./"The file offset associated with the file descriptor at the time of the call +./"determines which entries are returned. +.Pp +Upon successful return from +.Fn fdopendir , +the file descriptor is under the control of the system, +and if any attempt is made to close the file descriptor, +or to modify the state of the associated description other than by means +of +.Fn closedir , +.Fn readdir , +.Fn readdir_r , +or +.Fn rewinddir , +the behavior is undefined. +Upon calling +.Fn closedir +the file descriptor is closed. +The +.Dv FD_CLOEXEC +flag is set on the file descriptor by a successful call to +.Fn fdopendir . .Pp The .Fn readdir function -returns a pointer to the next directory entry. It returns +returns a pointer to the next directory entry. +It returns .Dv NULL -upon reaching the end of the directory or detecting an invalid -.Fn seekdir -operation. +upon reaching the end of the directory or on error. +In the event of an error, +.Va errno +may be set to any of the values documented for the +.Xr getdirentries 2 +system call. .Pp +The .Fn readdir_r +function provides the same functionality as .Fn readdir , but the caller must provide a directory .Fa entry -buffer to store the results in. If the read succeeds, +buffer to store the results in. +If the read succeeds, .Fa result is pointed at the .Fa entry ; -upon reaching the end of the directory, +upon reaching the end of the directory .Fa result is set to .Dv NULL . +The .Fn readdir_r +function returns 0 on success or an error number to indicate failure. .Pp The @@ -119,9 +161,10 @@ Values returned by .Fn telldir are good only for the lifetime of the .Dv DIR -pointer (e.g., -.Fa dirp ) -from which they are derived. If the directory is closed and then +pointer, +.Fa dirp , +from which they are derived. +If the directory is closed and then reopened, prior values returned by .Fn telldir will no longer be valid. @@ -163,8 +206,8 @@ The .Fn dirfd function returns the integer file descriptor associated with the named -.Em directory stream -on success, see +.Em directory stream , +see .Xr open 2 . On failure, \-1 is returned and the global variable .Va errno @@ -172,38 +215,38 @@ is set to indicate the error. .Pp Sample code which searches a directory for entry ``name'' is: .Bd -literal -offset indent -len = strlen(name); dirp = opendir("."); -while ((dp = readdir(dirp)) != NULL) - if (dp->d_namlen == len && !strcmp(dp->d_name, name)) { +if (dirp == NULL) + return (ERROR); +len = strlen(name); +while ((dp = readdir(dirp)) != NULL) { + if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) { (void)closedir(dirp); - return FOUND; + return (FOUND); } +} (void)closedir(dirp); -return NOT_FOUND; +return (NOT_FOUND); .Ed -.Sh LEGACY SYNOPSIS -.Fd #include -.Fd #include -.Pp -.In sys/types.h -is necessary for these functions. .Sh SEE ALSO .Xr close 2 , .Xr lseek 2 , .Xr open 2 , .Xr read 2 , -.Xr compat 5 , .Xr dir 5 .Sh HISTORY The -.Fn closedir , -.Fn dirfd , .Fn opendir , .Fn readdir , -.Fn rewinddir , +.Fn telldir , .Fn seekdir , +.Fn rewinddir , +.Fn closedir , and -.Fn telldir +.Fn dirfd functions appeared in .Bx 4.2 . +The +.Fn fdopendir +function appeared in +.Fx 8.0 . diff --git a/src/libc/gen/disklabel.c b/src/libc/gen/disklabel.c index 75e7cb8de..b88f91d0c 100644 --- a/src/libc/gen/disklabel.c +++ b/src/libc/gen/disklabel.c @@ -76,12 +76,10 @@ static int error(int); static int gettype(char *, char **); struct disklabel * -getdiskbyname(name) - const char *name; +getdiskbyname(const char *name) { - static struct disklabel disk; - register struct disklabel *dp = &disk; - register struct partition *pp; + static struct disklabel *dp = NULL; + struct partition *pp; char *buf; char *db_array[2] = { _PATH_DISKTAB, 0 }; char *cp, *cq; /* can't be register */ @@ -92,7 +90,14 @@ getdiskbyname(name) if (cgetent(&buf, db_array, (char *) name) < 0) return NULL; - bzero((char *)&disk, sizeof(disk)); + if (dp == NULL) { + dp = malloc(sizeof(struct disklabel)); + if (dp == NULL) { + return NULL; + } + } + memset(dp, 0, sizeof(struct disklabel)); + /* * typename */ diff --git a/src/libc/gen/fts.3 b/src/libc/gen/fts.3 index 260a1e293..9b7274782 100644 --- a/src/libc/gen/fts.3 +++ b/src/libc/gen/fts.3 @@ -32,7 +32,7 @@ .\" @(#)fts.3 8.5 (Berkeley) 4/16/94 .\" $FreeBSD: src/lib/libc/gen/fts.3,v 1.13 2001/09/20 12:32:45 ru Exp $ .\" -.Dd May 20, 2008 +.Dd Sept 24, 2012 .Dt FTS 3 .Os .Sh NAME @@ -372,7 +372,7 @@ must be specified. The options are selected by .Em or Ns 'ing the following values: -.Bl -tag -width "FTS_PHYSICAL" +.Bl -tag -width "FTS_NOSTAT_TYPE" .It Dv FTS_COMFOLLOW This option causes any symbolic link specified as a root path to be followed immediately whether or not @@ -421,15 +421,41 @@ structures reference file characteristic information (the .Fa statp field) for each file visited. This option relaxes that requirement as a performance optimization, -allowing the +not calling +.Xr stat 2 +whenever possible. +If +.Xr stat 2 +doesn't need to be called, the .Nm -functions to set the +functions will set the .Fa fts_info field to -.Dv FTS_NSOK -and leave the contents of the +.Dv FTS_NSOK ; +otherwise +.Fa fts_info +will be set to the correct file information value corresponding to the +.Xr stat 2 +information. +In any case, the .Fa statp -field undefined. +field will always be undefined. +Note that because +.Nm +detects directory cycles and dangling symbolic links, +.Xr stat 2 +is always called for directories and is called for symbolic links when +.Dv FTS_LOGICAL +is set. +.It Dv FTS_NOSTAT_TYPE +Like +.Dv FTS_NOSTAT +but if the file type is returned by +.Xr readdir 3 , +the corresponding file information value is returned in +.Fa fts_info +instead of +.Dv FTS_NSOK . .It Dv FTS_PHYSICAL This option causes the .Nm diff --git a/src/libc/gen/fts.c b/src/libc/gen/fts.c index 9b854889d..729ec7934 100644 --- a/src/libc/gen/fts.c +++ b/src/libc/gen/fts.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2000, 2003, 2005, 2008 Apple Inc. All rights reserved. + * Copyright (c) 1999, 2000, 2003, 2005, 2008, 2012, 2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -32,11 +32,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -53,37 +49,47 @@ * SUCH DAMAGE. */ +/* $OpenBSD: fts.c,v 1.51 2015/09/12 13:32:24 guenther Exp $ */ #include #include +#include #include #include #include #include +#include #include #include #include +#include +#include +#include + #ifdef __BLOCKS__ #include #endif /* __BLOCKS__ */ +#include static FTSENT *fts_alloc(FTS *, char *, int); static FTSENT *fts_build(FTS *, int); static void fts_lfree(FTSENT *); static void fts_load(FTS *, FTSENT *); static size_t fts_maxarglen(char * const *); -static void fts_padjust(FTS *, void *); +static void fts_padjust(FTS *, FTSENT *); static int fts_palloc(FTS *, size_t); static FTSENT *fts_sort(FTS *, FTSENT *, int); -static u_short fts_stat(FTS *, FTSENT *, int); +static u_short fts_stat(FTS *, FTSENT *, int, int); +static u_short fts_stat2(FTS *, FTSENT *, int, int, struct stat *); +static int fts_safe_changedir(FTS *, FTSENT *, int, char *); -#define ISDOT(a) (a[0] == '.' && (!a[1] || a[1] == '.' && !a[2])) +#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) -#define ISSET(opt) (sp->fts_options & opt) -#define SET(opt) (sp->fts_options |= opt) +#define CLR(opt) (sp->fts_options &= ~(opt)) +#define ISSET(opt) (sp->fts_options & (opt)) +#define SET(opt) (sp->fts_options |= (opt)) -#define CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path)) #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) /* fts_build flags */ @@ -126,15 +132,15 @@ static u_short fts_stat(FTS *, FTSENT *, int); #define F_STATDIRSYM (1 << F_SHIFT) /* only stat directories and symlinks (and unknowns) */ #define F_ALWAYSSTAT (2 << F_SHIFT) /* always stat */ #define F_STATDIR (3 << F_SHIFT) /* only stat directories (and unknowns) */ +#define F_D_TYPE (4 << F_SHIFT) /* only stat directories but use d_type */ +#define F_D_TYPESYM (5 << F_SHIFT) /* only stat directories and symlinks but use d_type */ static FTS * -__fts_open(argv, sp) - char * const *argv; - register FTS *sp; +__fts_open(char * const *argv, FTS *sp) { - register FTSENT *p, *root; - register int nitems; - FTSENT *parent, *tmp = NULL; + FTSENT *p, *root; + int nitems; + FTSENT *parent, *tmp; int len; /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ @@ -145,7 +151,7 @@ __fts_open(argv, sp) * Start out with 1K of path space, and enough, in any case, * to hold the user's paths. */ - if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) + if (fts_palloc(sp, MAX(fts_maxarglen(argv), PATH_MAX))) goto mem1; /* Allocate/initialize root's parent. */ @@ -161,11 +167,12 @@ __fts_open(argv, sp) goto mem3; } - p = fts_alloc(sp, *argv, len); + if ((p = fts_alloc(sp, *argv, len)) == NULL) + goto mem3; p->fts_level = FTS_ROOTLEVEL; p->fts_parent = parent; p->fts_accpath = p->fts_name; - p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOWDIR) ? -1 : ISSET(FTS_COMFOLLOW)); + p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOWDIR) ? -1 : ISSET(FTS_COMFOLLOW), -1); /* Command-line "." and ".." are real directories. */ if (p->fts_info == FTS_DOT) @@ -202,15 +209,19 @@ __fts_open(argv, sp) sp->fts_cur->fts_info = FTS_INIT; /* - * If using chdir(2), grab a file descriptor pointing to dot to insure + * If using chdir(2), grab a file descriptor pointing to dot to ensure * that we can get back here; this could be avoided for some paths, * but almost certainly not worth the effort. Slashes, symbolic links, * and ".." are all fairly nasty problems. Note, if we can't get the * descriptor we run anyway, just more slowly. */ - if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0) + if (!ISSET(FTS_NOCHDIR) && + (sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) < 0) SET(FTS_NOCHDIR); + if (nitems == 0) + free(parent); + return (sp); mem3: fts_lfree(root); @@ -221,23 +232,20 @@ mem1: free(sp); } FTS * -fts_open(argv, options, compar) - char * const *argv; - int options; - int (*compar)(); +fts_open(char * const *argv, int options, int (*compar)()) { - register FTS *sp; + FTS *sp; /* Options check. */ if (options & ~FTS_OPTIONMASK) { errno = EINVAL; return (NULL); } + if (options & FTS_NOSTAT_TYPE) options |= FTS_NOSTAT; /* Allocate/initialize the stream */ - if ((sp = malloc((u_int)sizeof(FTS))) == NULL) + if ((sp = calloc(1, sizeof(FTS))) == NULL) return (NULL); - memset(sp, 0, sizeof(FTS)); sp->fts_compar = compar; sp->fts_options = options; @@ -246,23 +254,20 @@ fts_open(argv, options, compar) #ifdef __BLOCKS__ FTS * -fts_open_b(argv, options, compar) - char * const *argv; - int options; - int (^compar)(const FTSENT **, const FTSENT **); +fts_open_b(char * const *argv, int options, int (^compar)(const FTSENT **, const FTSENT **)) { - register FTS *sp; + FTS *sp; /* Options check. */ if (options & ~FTS_OPTIONMASK) { errno = EINVAL; return (NULL); } + if (options & FTS_NOSTAT_TYPE) options |= FTS_NOSTAT; /* Allocate/initialize the stream */ - if ((sp = malloc((u_int)sizeof(FTS))) == NULL) + if ((sp = calloc(1, sizeof(FTS))) == NULL) return (NULL); - memset(sp, 0, sizeof(FTS)); sp->fts_compar_b = (int (^)())Block_copy(compar); sp->fts_options = options | FTS_BLOCK_COMPAR; @@ -271,12 +276,10 @@ fts_open_b(argv, options, compar) #endif /* __BLOCKS__ */ static void -fts_load(sp, p) - FTS *sp; - register FTSENT *p; +fts_load(FTS *sp, FTSENT *p) { - register int len; - register char *cp; + int len; + char *cp; /* * Load the stream structure for the next traversal. Since we don't @@ -297,11 +300,10 @@ fts_load(sp, p) } int -fts_close(sp) - FTS *sp; +fts_close(FTS *sp) { - register FTSENT *freep, *p; - int saved_errno = 0; + FTSENT *freep, *p; + int rfd, error = 0; /* * This still works if we haven't read anything -- the dummy structure @@ -317,20 +319,15 @@ fts_close(sp) free(p); } - /* Free up child linked list, sort array, path buffer. */ - if (sp->fts_child) + /* Stash the original directory fd if needed. */ + rfd = ISSET(FTS_NOCHDIR) ? -1 : sp->fts_rfd; + + /* Free up child linked list, sort array, path buffer, stream ptr.*/ + if (sp->fts_child){ fts_lfree(sp->fts_child); - if (sp->fts_array) - free(sp->fts_array); - free(sp->fts_path); - - /* Return to original directory, save errno if necessary. */ - if (!ISSET(FTS_NOCHDIR)) { - if (fchdir(sp->fts_rfd)) { - saved_errno = errno; - } - (void)close(sp->fts_rfd); } + free(sp->fts_array); sp->fts_array = NULL; + free(sp->fts_path); sp->fts_path = NULL; #ifdef __BLOCKS__ /* Free up any block pointer. */ @@ -341,12 +338,21 @@ fts_close(sp) /* Free up the stream pointer. */ free(sp); - /* Set errno and return. */ - if (saved_errno) { + /* Return to original directory, checking for error. */ + if (rfd != -1) { + int saved_errno = errno; + if (fchdir(rfd) != 0){ + error = -1; + saved_errno = errno; + } + if (close(rfd) != 0){ + error = -1; + saved_errno = errno; + } errno = saved_errno; - return (-1); } - return (0); + + return (error); } /* @@ -358,12 +364,11 @@ fts_close(sp) p->fts_path[0] == '/' ? 0 : p->fts_pathlen) FTSENT * -fts_read(sp) - register FTS *sp; +fts_read(FTS *sp) { - register FTSENT *p, *tmp; - register int instr; - register char *t; + FTSENT *p, *tmp; + int instr; + char *t; int saved_errno; /* If finished or unrecoverable error, return NULL. */ @@ -379,7 +384,7 @@ fts_read(sp) /* Any type of file may be re-visited; re-stat and re-turn. */ if (instr == FTS_AGAIN) { - p->fts_info = fts_stat(sp, p, 0); + p->fts_info = fts_stat(sp, p, 0, -1); return (p); } @@ -391,13 +396,16 @@ fts_read(sp) */ if (instr == FTS_FOLLOW && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { - p->fts_info = fts_stat(sp, p, 1); - if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) - if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) { + p->fts_info = fts_stat(sp, p, 1, -1); + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { + if ((p->fts_symfd = + open(".", O_RDONLY | O_CLOEXEC)) < 0) { p->fts_errno = errno; p->fts_info = FTS_ERR; - } else + } else { p->fts_flags |= FTS_SYMFOLLOW; + } + } return (p); } @@ -405,7 +413,7 @@ fts_read(sp) if (p->fts_info == FTS_D) { /* If skipped or crossed mount point, do post-order visit. */ if (instr == FTS_SKIP || - ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev) { + (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) { if (p->fts_flags & FTS_SYMFOLLOW) (void)close(p->fts_symfd); if (sp->fts_child) { @@ -414,11 +422,11 @@ fts_read(sp) } p->fts_info = FTS_DP; return (p); - } + } /* Rebuild if only read the names and now traversing. */ - if (sp->fts_child && sp->fts_options & FTS_NAMEONLY) { - sp->fts_options &= ~FTS_NAMEONLY; + if (sp->fts_child && ISSET(FTS_NAMEONLY)) { + CLR(FTS_NAMEONLY); fts_lfree(sp->fts_child); sp->fts_child = NULL; } @@ -436,7 +444,7 @@ fts_read(sp) * FTS_STOP or the fts_info field of the node. */ if (sp->fts_child) { - if (CHDIR(sp, p->fts_accpath)) { + if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) { p->fts_errno = errno; p->fts_flags |= FTS_DONTCHDIR; for (p = sp->fts_child; p; p = p->fts_link) @@ -455,18 +463,19 @@ fts_read(sp) /* Move to the next node on this level. */ next: tmp = p; - if (p = p->fts_link) { + if ((p = p->fts_link)) { + free(tmp); + /* - * If reached the top, return to the original directory, and - * load the paths for the next root. + * If reached the top, return to the original directory (or + * the root of the tree), and load the paths for the next root. */ if (p->fts_level == FTS_ROOTLEVEL) { - if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) { + if (FCHDIR(sp, sp->fts_rfd)) { SET(FTS_STOP); return (NULL); } fts_load(sp, p); - free(tmp); return (sp->fts_cur = p); } @@ -476,22 +485,22 @@ next: tmp = p; * get back if necessary. */ if (p->fts_instr == FTS_SKIP) { - free(tmp); goto next; } if (p->fts_instr == FTS_FOLLOW) { - p->fts_info = fts_stat(sp, p, 1); - if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) + p->fts_info = fts_stat(sp, p, 1, -1); + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { if ((p->fts_symfd = - open(".", O_RDONLY, 0)) < 0) { + open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { p->fts_errno = errno; p->fts_info = FTS_ERR; - } else + } else { p->fts_flags |= FTS_SYMFOLLOW; + } + } p->fts_instr = FTS_NOINSTR; } - free(tmp); name: t = sp->fts_path + NAPPEND(p->fts_parent); *t++ = '/'; memmove(t, p->fts_name, p->fts_namelen + 1); @@ -512,7 +521,7 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); return (sp->fts_cur = NULL); } - /* Nul terminate the pathname. */ + /* NUL terminate the pathname. */ sp->fts_path[p->fts_pathlen] = '\0'; /* @@ -521,8 +530,9 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); * one directory. */ if (p->fts_level == FTS_ROOTLEVEL) { - if (!ISSET(FTS_NOCHDIR) && FCHDIR(sp, sp->fts_rfd)) { + if (FCHDIR(sp, sp->fts_rfd)) { SET(FTS_STOP); + sp->fts_cur = p; return (NULL); } } else if (p->fts_flags & FTS_SYMFOLLOW) { @@ -531,14 +541,15 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); (void)close(p->fts_symfd); errno = saved_errno; SET(FTS_STOP); + sp->fts_cur = p; return (NULL); } (void)close(p->fts_symfd); - } else if (!(p->fts_flags & FTS_DONTCHDIR)) { - if (CHDIR(sp, "..")) { - SET(FTS_STOP); - return (NULL); - } + } else if (!(p->fts_flags & FTS_DONTCHDIR) && + fts_safe_changedir(sp, p->fts_parent, -1, "..")) { + SET(FTS_STOP); + sp->fts_cur = p; + return (NULL); } p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; return (sp->fts_cur = p); @@ -552,10 +563,7 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); */ /* ARGSUSED */ int -fts_set(sp, p, instr) - FTS *sp; - FTSENT *p; - int instr; +fts_set(FTS __unused *sp, FTSENT *p, int instr) { if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW && instr != FTS_NOINSTR && instr != FTS_SKIP) { @@ -567,11 +575,9 @@ fts_set(sp, p, instr) } FTSENT * -fts_children(sp, instr) - register FTS *sp; - int instr; +fts_children(FTS *sp, int instr) { - register FTSENT *p; + FTSENT *p; int fd; if (instr && instr != FTS_NAMEONLY) { @@ -609,9 +615,9 @@ fts_children(sp, instr) fts_lfree(sp->fts_child); if (instr == FTS_NAMEONLY) { - sp->fts_options |= FTS_NAMEONLY; + SET(FTS_NAMEONLY); instr = BNAMES; - } else + } else instr = BCHILD; /* @@ -625,15 +631,341 @@ fts_children(sp, instr) ISSET(FTS_NOCHDIR)) return (sp->fts_child = fts_build(sp, instr)); - if ((fd = open(".", O_RDONLY, 0)) < 0) + if ((fd = open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) return (NULL); sp->fts_child = fts_build(sp, instr); - if (fchdir(fd)) + if (fchdir(fd)) { + (void)close(fd); return (NULL); + } (void)close(fd); return (sp->fts_child); } +typedef struct __attribute__((packed)) { + uint32_t length; + + /* common attributes */ + attribute_set_t attrset; + attrreference_t name; + dev_t st_dev; + fsobj_type_t objtype; + struct timespec st_birthtimespec; + struct timespec st_mtimespec; + struct timespec st_ctimespec; + struct timespec st_atimespec; + uid_t st_uid; + gid_t st_gid; + uint32_t accessmask; + uint32_t st_flags; + uint64_t st_ino; + + /* non-directory attributes */ + uint32_t st_nlink; + off_t allocsize; + uint32_t st_blksize; + uint32_t st_rdev; + off_t st_size; +} attrListAttributes; + +typedef struct __attribute__((packed)) { + uint32_t length; + + /* common attributes */ + attribute_set_t attrset; + attrreference_t name; + dev_t st_dev; + fsobj_type_t objtype; + uint64_t st_ino; + + /* non-directory attributes */ + uint32_t st_nlink; + uint32_t st_rdev; +} attrListAttributes_nostat; + +#define ATTR_BUF_SIZE (32*1024) + +typedef struct { + DIR *dirp; + + struct attrlist requested_attrs; + void *attrbuf; + union { + attrListAttributes *curattr; + attrListAttributes_nostat *curattr_nostat; + }; + int dirfd; + bool done; + bool nostat; + bool needs_dot; + bool needs_dotdot; + + int entry_count; + int cur_entry; +} dir_handle; + +typedef struct { + char *d_name; + size_t d_namlen; + struct stat sb; + int d_type; + bool stat_valid; +} dir_entry; + +static bool +advance_directory(dir_handle *handle) +{ + if (handle->done) return true; + + assert(handle->dirfd != -1); + handle->entry_count = getattrlistbulk(handle->dirfd, &handle->requested_attrs, + handle->attrbuf, ATTR_BUF_SIZE, FSOPT_PACK_INVAL_ATTRS); + if (handle->entry_count == -1) { + goto error; + } else if (handle->entry_count == 0) { + /* No more entries. */ + handle->done = true; + } + handle->cur_entry = 0; + handle->curattr = handle->attrbuf; + return true; + +error: { + int saved_errno = errno; + close(handle->dirfd); + handle->dirfd = -1; + errno = saved_errno; + return false; + } +} + +static bool +open_directory(FTS *sp, dir_handle *handle, const char *path) +{ + memset(handle, 0, sizeof(*handle)); + + handle->nostat = ISSET(FTS_NOSTAT); + handle->needs_dot = handle->needs_dotdot = ISSET(FTS_SEEDOT); + + handle->dirfd = open(path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC); + if (handle->dirfd == -1) goto fallback; + + handle->attrbuf = malloc(ATTR_BUF_SIZE); + if (!handle->attrbuf) goto fallback; + + handle->requested_attrs.bitmapcount = ATTR_BIT_MAP_COUNT; + if (!handle->nostat) { + handle->requested_attrs.commonattr = + ATTR_CMN_RETURNED_ATTRS| + ATTR_CMN_NAME|ATTR_CMN_DEVID|ATTR_CMN_OBJTYPE| + ATTR_CMN_CRTIME|ATTR_CMN_MODTIME|ATTR_CMN_CHGTIME|ATTR_CMN_ACCTIME| + ATTR_CMN_OWNERID|ATTR_CMN_GRPID|ATTR_CMN_ACCESSMASK|ATTR_CMN_FLAGS| + ATTR_CMN_FILEID; + handle->requested_attrs.fileattr = ATTR_FILE_LINKCOUNT|ATTR_FILE_ALLOCSIZE| + ATTR_FILE_IOBLOCKSIZE|ATTR_FILE_DEVTYPE|ATTR_FILE_DATALENGTH; + } else { + handle->requested_attrs.commonattr = ATTR_CMN_RETURNED_ATTRS| + ATTR_CMN_NAME|ATTR_CMN_DEVID|ATTR_CMN_OBJTYPE| + ATTR_CMN_FILEID; + handle->requested_attrs.fileattr = ATTR_FILE_LINKCOUNT; + } + + if (advance_directory(handle)) { + /* + * We successfully read the first attribute buffer, + * so we'll use getdirentriesattr/getattrlistbulk. + */ + return true; + } + +fallback: + if (handle->dirfd != -1) close(handle->dirfd); + handle->dirfd = -1; + free(handle->attrbuf); + handle->attrbuf = NULL; + handle->dirp = opendir(path); + return (handle->dirp != NULL); +} + +static bool +read_dirent(dir_handle *handle, dir_entry *entry) +{ + if (handle->dirp) { + struct dirent *de = readdir(handle->dirp); + if (de == NULL) return false; + entry->d_name = de->d_name; + entry->d_namlen = de->d_namlen; + entry->d_type = de->d_type; + entry->stat_valid = false; + return true; + } + + /* + * There are three states that our dir_handle can be in: + * - real getattrlistbulk use (entry_count >= 0) - the rest of this function + * - fallback - handled above with dirp + * - closed fallback (dirp == NULL) - handled with this check + */ + if (handle->dirfd == -1) { + return false; + } + + if (handle->needs_dot) { + handle->needs_dot = false; + entry->d_name = "."; + entry->d_namlen = strlen("."); + entry->d_type = DT_DIR; + entry->stat_valid = false; + return true; + } else if (handle->needs_dotdot) { + handle->needs_dotdot = false; + entry->d_name = ".."; + entry->d_namlen = strlen(".."); + entry->d_type = DT_DIR; + entry->stat_valid = false; + return true; + } + + if (handle->cur_entry == handle->entry_count) { + if (handle->done) return false; /* Already done with the directory. */ + if (!advance_directory(handle)) return false; /* Reading the next buffer failed. */ + if (handle->done) return false; /* We're now done with the directory. */ + } + + bzero(entry, sizeof(*entry)); + + attrListAttributes *curattr_stat = NULL; + attrListAttributes_nostat *curattr_nostat = NULL; + if (!handle->nostat) { + curattr_stat = handle->curattr; + handle->cur_entry++; + handle->curattr = (attrListAttributes*)(((char*)curattr_stat) + curattr_stat->length); + + entry->d_name = ((char*)&curattr_stat->name) + curattr_stat->name.attr_dataoffset; + /* attr_length includes the null terminator, but readdir's d_namlen doesn't. */ + entry->d_namlen = curattr_stat->name.attr_length - 1; + } else { + curattr_nostat = handle->curattr_nostat; + handle->cur_entry++; + handle->curattr_nostat = (attrListAttributes_nostat*)(((char*)curattr_nostat) + curattr_nostat->length); + + entry->d_name = ((char*)&curattr_nostat->name) + curattr_nostat->name.attr_dataoffset; + /* attr_length includes the null terminator, but readdir's d_namlen doesn't. */ + entry->d_namlen = curattr_nostat->name.attr_length - 1; + } + + int stat_type = 0; + + switch (handle->nostat ? curattr_nostat->objtype : curattr_stat->objtype) { + case VREG: + entry->d_type = DT_REG; + stat_type = S_IFREG; + break; + case VDIR: + entry->d_type = DT_DIR; + /* Force a stat call so we don't have to guess on st_size, st_blocks, etc. */ + // stat_type = S_IFDIR; + break; + case VBLK: + entry->d_type = DT_BLK; + stat_type = S_IFBLK; + break; + case VCHR: + entry->d_type = DT_CHR; + stat_type = S_IFCHR; + break; + case VLNK: + entry->d_type = DT_LNK; + stat_type = S_IFLNK; + break; + case VSOCK: + entry->d_type = DT_SOCK; + stat_type = S_IFSOCK; + break; + case VFIFO: + entry->d_type = DT_FIFO; + stat_type = S_IFIFO; + break; + default: + entry->d_type = DT_UNKNOWN; + break; + } + + if (!handle->nostat && stat_type) { + entry->stat_valid = true; + + /* + * Make sure we got all the attributes we need to fill out a stat structure. + */ + + attrgroup_t requiredCommon = handle->requested_attrs.commonattr; + attrgroup_t requiredFile = handle->requested_attrs.fileattr; + + if ((entry->d_type != DT_BLK) && (entry->d_type != DT_CHR)) { + /* It's okay for ATTR_FILE_DEVTYPE to be missing if the entry isn't a block or character device. */ + curattr_stat->st_rdev = 0; + requiredFile &= ~ATTR_FILE_DEVTYPE; + } + + if ((curattr_stat->attrset.commonattr & requiredCommon) != requiredCommon || + (curattr_stat->attrset.fileattr & requiredFile) != requiredFile) { + /* Some of our required attributes are missing. */ + entry->stat_valid = false; + } + } else { + entry->stat_valid = false; + } + + if (entry->stat_valid) { + +#define COPY_FIELD(fld) entry->sb.fld = curattr_stat->fld + COPY_FIELD(st_dev); + /* COPY_FIELD(st_mode); Handled below. */ + COPY_FIELD(st_nlink); + COPY_FIELD(st_ino); + COPY_FIELD(st_uid); + COPY_FIELD(st_gid); + COPY_FIELD(st_rdev); + COPY_FIELD(st_atimespec); + COPY_FIELD(st_mtimespec); + COPY_FIELD(st_ctimespec); +#if __DARWIN_64_BIT_INO_T + COPY_FIELD(st_birthtimespec); +#endif /* __DARWIN_64_BIT_INO_T */ + COPY_FIELD(st_size); + /* COPY_FIELD(st_blocks); Handled below. */ + COPY_FIELD(st_blksize); + COPY_FIELD(st_flags); +#undef COPY_FIELD + + /* We have to handle some fields specially. */ + entry->sb.st_mode = (curattr_stat->accessmask & ~S_IFMT) | stat_type; + entry->sb.st_blocks = howmany(curattr_stat->allocsize, 512); /* Matches vn_stat implementation in xnu. */ + } + return true; +} + +static int +dir_fd(dir_handle *handle) +{ + return handle->dirp ? dirfd(handle->dirp) : handle->dirfd; +} + +static void +close_directory(dir_handle *handle) +{ + if (handle->dirp) { + closedir(handle->dirp); + handle->dirp = NULL; + } + if (handle->dirfd != -1) { + close(handle->dirfd); + handle->dirfd = -1; + } + free(handle->attrbuf); + handle->attrbuf = NULL; +} + /* * This is the tricky part -- do not casually change *anything* in here. The * idea is to build the linked list of entries that are used by fts_children @@ -645,18 +977,19 @@ fts_children(sp, instr) * types. This cuts the number of stat calls significantly. */ static FTSENT * -fts_build(sp, type) - register FTS *sp; - int type; +fts_build(FTS *sp, int type) { - register struct dirent *dp; - register FTSENT *p, *head; - register int nitems; + dir_entry de = { 0 }; + dir_entry *dp = &de; + FTSENT *p, *head; + int nitems; FTSENT *cur, *tail; - DIR *dirp; - void *adjaddr; - int cderrno, descend, len, level, maxlen, dostat, oflag, saved_errno; - char *cp = NULL; + dir_handle dirp; + void *oldaddr; + int len, maxlen; + int cderrno, descend, level, dostat, doadjust; + int saved_errno; + char *cp; /* Set current node pointer. */ cur = sp->fts_cur; @@ -665,15 +998,7 @@ fts_build(sp, type) * Open the directory for reading. If this fails, we're done. * If being called from fts_read, set the fts_info field. */ -#ifdef FTS_WHITEOUT - if (ISSET(FTS_WHITEOUT)) - oflag = DTF_NODUP|DTF_REWIND; - else - oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND; -#else -#define __opendir2(path, flag) opendir(path) -#endif - if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) { + if (!open_directory(sp, &dirp, cur->fts_accpath)) { if (type == BREAD) { cur->fts_info = FTS_DNR; cur->fts_errno = errno; @@ -683,6 +1008,8 @@ fts_build(sp, type) if (type == BNAMES) dostat = F_NOSTAT; + else if (ISSET(FTS_NOSTAT_TYPE)) + dostat = ISSET(FTS_PHYSICAL) ? F_D_TYPE : F_D_TYPESYM; else if (ISSET(FTS_NOSTAT)) dostat = ISSET(FTS_PHYSICAL) ? F_STATDIR : F_STATDIRSYM; else @@ -709,17 +1036,21 @@ fts_build(sp, type) * checking FTS_NS on the returned nodes. */ cderrno = 0; - if (dostat || type == BREAD) - if (FCHDIR(sp, dirfd(dirp))) { - if (dostat && type == BREAD) + if (dostat || type == BREAD) { + if (fts_safe_changedir(sp, cur, dir_fd(&dirp), NULL)) { + if (dostat && type == BREAD) { cur->fts_errno = errno; + } cur->fts_flags |= FTS_DONTCHDIR; descend = 0; cderrno = errno; - } else + close_directory(&dirp); + } else { descend = 1; - else + } + } else { descend = 0; + } /* * Figure out the max file name length that can be stored in the @@ -731,52 +1062,74 @@ fts_build(sp, type) * If not changing directories set a pointer so that can just append * each new name into the path. */ - maxlen = sp->fts_pathlen - cur->fts_pathlen - 1; len = NAPPEND(cur); if (ISSET(FTS_NOCHDIR)) { cp = sp->fts_path + len; *cp++ = '/'; } + len++; + maxlen = sp->fts_pathlen - len; - level = cur->fts_level + 1; + /* + * fts_level is signed so we must prevent it from wrapping + * around to FTS_ROOTLEVEL and FTS_ROOTPARENTLEVEL. + */ + level = cur->fts_level; + if (level < FTS_MAXLEVEL) + level++; /* Read the directory, attaching each entry to the `link' pointer. */ - adjaddr = NULL; - for (head = tail = NULL, nitems = 0; dp = readdir(dirp);) { + doadjust = 0; + for (head = tail = NULL, nitems = 0; read_dirent(&dirp, dp) ; ) { if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) continue; if ((p = fts_alloc(sp, dp->d_name, (int)dp->d_namlen)) == NULL) goto mem1; - if (dp->d_namlen > maxlen) { - if (fts_palloc(sp, (size_t)dp->d_namlen)) { + if (dp->d_namlen >= (size_t)maxlen) { /* include space for NUL */ + oldaddr = sp->fts_path; + if (fts_palloc(sp, dp->d_namlen +len + 1)) { /* * No more memory for path or structures. Save * errno, free up the current structure and the * structures already allocated. */ mem1: saved_errno = errno; - if (p) - free(p); + free(p); fts_lfree(head); - (void)closedir(dirp); - errno = saved_errno; + close_directory(&dirp); cur->fts_info = FTS_ERR; SET(FTS_STOP); + errno = saved_errno; return (NULL); } - adjaddr = sp->fts_path; - maxlen = sp->fts_pathlen - sp->fts_cur->fts_pathlen - 1; + /* Did realloc() change the pointer? */ + if (oldaddr != sp->fts_path) { + doadjust = 1; + if (ISSET(FTS_NOCHDIR)) + cp = sp->fts_path + len; + } + maxlen = sp->fts_pathlen - len; } - p->fts_pathlen = len + dp->d_namlen + 1; - p->fts_parent = sp->fts_cur; + if (len + dp->d_namlen >= USHRT_MAX) { + /* + * In an FTSENT, fts_pathlen is a u_short so it is + * possible to wraparound here. If we do, free up + * the current structure and the structures already + * allocated, then error out with ENAMETOOLONG. + */ + free(p); + fts_lfree(head); + close_directory(&dirp); + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + errno = ENAMETOOLONG; + return (NULL); + } p->fts_level = level; - -#ifdef FTS_WHITEOUT - if (dp->d_type == DT_WHT) - p->fts_flags |= FTS_ISW; -#endif + p->fts_parent = sp->fts_cur; + p->fts_pathlen = len + dp->d_namlen; if (cderrno) { if (dostat) { @@ -806,20 +1159,48 @@ mem1: saved_errno = errno; case (F_ALWAYSSTAT | DT_LNK): case (F_ALWAYSSTAT | DT_SOCK): case (F_ALWAYSSTAT | DT_WHT): + case (F_D_TYPE | DT_UNKNOWN): + case (F_D_TYPE | DT_DIR): + case (F_D_TYPESYM | DT_UNKNOWN): + case (F_D_TYPESYM | DT_DIR): + case (F_D_TYPESYM | DT_LNK): /* Build a file name for fts_stat to stat. */ if (ISSET(FTS_NOCHDIR)) { p->fts_accpath = p->fts_path; memmove(cp, p->fts_name, p->fts_namelen + 1); - } else + p->fts_info = fts_stat2(sp, p, 0, dir_fd(&dirp), dp->stat_valid ? &dp->sb : NULL); + } else { p->fts_accpath = p->fts_name; - /* Stat it. */ - p->fts_info = fts_stat(sp, p, 0); + p->fts_info = fts_stat2(sp, p, 0, -1, dp->stat_valid ? &dp->sb : NULL); + } break; + case (F_D_TYPE | DT_FIFO): + case (F_D_TYPE | DT_CHR): + case (F_D_TYPE | DT_BLK): + case (F_D_TYPE | DT_SOCK): + case (F_D_TYPESYM | DT_FIFO): + case (F_D_TYPESYM | DT_CHR): + case (F_D_TYPESYM | DT_BLK): + case (F_D_TYPESYM | DT_SOCK): + p->fts_info = FTS_DEFAULT; + goto common_no_stat; + case (F_D_TYPE | DT_REG): + case (F_D_TYPESYM | DT_REG): + p->fts_info = FTS_F; + goto common_no_stat; + case (F_D_TYPE | DT_LNK): + p->fts_info = FTS_SL; + goto common_no_stat; + case (F_D_TYPE | DT_WHT): + case (F_D_TYPESYM | DT_WHT): + p->fts_info = FTS_W; + goto common_no_stat; default: /* No stat necessary */ + p->fts_info = FTS_NSOK; +common_no_stat: p->fts_accpath = ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; - p->fts_info = FTS_NSOK; break; } } @@ -834,21 +1215,21 @@ mem1: saved_errno = errno; } ++nitems; } - (void)closedir(dirp); + close_directory(&dirp); /* - * If had to realloc the path, adjust the addresses for the rest - * of the tree. + * If realloc() changed the address of the path, adjust the + * addresses for the rest of the tree and the dir list. */ - if (adjaddr) - fts_padjust(sp, adjaddr); + if (doadjust) + fts_padjust(sp, head); /* * If not changing directories, reset the path back to original * state. */ if (ISSET(FTS_NOCHDIR)) { - if (cp - 1 > sp->fts_path) + if (len == sp->fts_pathlen || nitems == 0) --cp; *cp = '\0'; } @@ -861,8 +1242,8 @@ mem1: saved_errno = errno; * can't get back, we're done. */ if (descend && (type == BCHILD || !nitems) && - (cur->fts_level == FTS_ROOTLEVEL ? - FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) { + (cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) : + fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { cur->fts_info = FTS_ERR; SET(FTS_STOP); return (NULL); @@ -882,45 +1263,58 @@ mem1: saved_errno = errno; } static u_short -fts_stat(sp, p, follow) - FTS *sp; - register FTSENT *p; - int follow; +fts_stat(FTS *sp, FTSENT *p, int follow, int dfd) +{ + return fts_stat2(sp, p, follow, dfd, NULL); +} + +static u_short +fts_stat2(FTS *sp, FTSENT *p, int follow, int dfd, struct stat *insb) { - register FTSENT *t; - register dev_t dev; - register ino_t ino; + FTSENT *t; + dev_t dev; + ino_t ino; struct stat *sbp, sb; int saved_errno; + const char *path; + + if (dfd == -1) { + path = p->fts_accpath; + dfd = AT_FDCWD; + } else { + path = p->fts_name; + } /* If user needs stat info, stat buffer already allocated. */ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; -#ifdef FTS_WHITEOUT - /* check for whiteout */ - if (p->fts_flags & FTS_ISW) { - if (sbp != &sb) { - memset(sbp, '\0', sizeof (*sbp)); - sbp->st_mode = S_IFWHT; - } - return (FTS_W); - } -#endif - /* - * If doing a logical walk, or application requested FTS_FOLLOW, do - * a stat(2). If that fails, check for a non-existent symlink. If - * fail, set the errno from the stat call. + * getattrlistbulk always returns information about the link, not its + * destination, so if we are doing a logical walk we need to detect links + * and do a stat anyway. */ - if (ISSET(FTS_LOGICAL) || follow) { - if (stat(p->fts_accpath, sbp)) { + if (follow) { + insb = NULL; + } else if (insb && ISSET(FTS_LOGICAL) && ((insb->st_mode & S_IFLNK) == S_IFLNK)) { + insb = NULL; + } + + if (insb) { + memcpy(sbp, insb, sizeof(*insb)); + } else if (ISSET(FTS_LOGICAL) || follow) { + /* + * If doing a logical walk, or application requested FTS_FOLLOW, do + * a stat(2). If that fails, check for a non-existent symlink. If + * fail, set the errno from the stat call. + */ + if (fstatat(dfd, path, sbp, 0)) { saved_errno = errno; - if (!lstat(p->fts_accpath, sbp)) { + if (!fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { if (saved_errno == ELOOP) p->fts_errno = ELOOP; errno = 0; return (FTS_SLNONE); - } + } p->fts_errno = saved_errno; goto err; } @@ -929,12 +1323,12 @@ fts_stat(sp, p, follow) * a directory */ if (follow == -1 && !S_ISDIR(sbp->st_mode)) { - if (lstat(p->fts_accpath, sbp)) { + if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { p->fts_errno = errno; goto err; } } - } else if (lstat(p->fts_accpath, sbp)) { + } else if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { p->fts_errno = errno; err: memset(sbp, 0, sizeof(struct stat)); return (FTS_NS); @@ -977,12 +1371,9 @@ err: memset(sbp, 0, sizeof(struct stat)); } static FTSENT * -fts_sort(sp, head, nitems) - FTS *sp; - FTSENT *head; - register int nitems; +fts_sort(FTS *sp, FTSENT *head, int nitems) { - register FTSENT **ap, *p; + FTSENT **ap, *p; /* * Construct an array of pointers to the structures and call qsort(3). @@ -992,12 +1383,17 @@ fts_sort(sp, head, nitems) * 40 so don't realloc one entry at a time. */ if (nitems > sp->fts_nitems) { + struct _ftsent **a; + sp->fts_nitems = nitems + 40; - if ((sp->fts_array = realloc(sp->fts_array, - (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) { + if ((a = reallocarray(sp->fts_array, + sp->fts_nitems, sizeof(FTSENT *))) == NULL) { + free(sp->fts_array); + sp->fts_array = NULL; sp->fts_nitems = 0; return (head); } + sp->fts_array = a; } for (ap = sp->fts_array, p = head; p; p = p->fts_link) *ap++ = p; @@ -1014,12 +1410,9 @@ fts_sort(sp, head, nitems) } static FTSENT * -fts_alloc(sp, name, namelen) - FTS *sp; - char *name; - register int namelen; +fts_alloc(FTS *sp, char *name, int namelen) { - register FTSENT *p; + FTSENT *p; size_t len; /* @@ -1033,32 +1426,26 @@ fts_alloc(sp, name, namelen) len = sizeof(FTSENT) + namelen; if (!ISSET(FTS_NOSTAT)) len += sizeof(struct stat) + ALIGNBYTES; - if ((p = malloc(len)) == NULL) + if ((p = calloc(1, len)) == NULL) return (NULL); - /* Copy the name plus the trailing NULL. */ - memmove(p->fts_name, name, namelen + 1); - - if (!ISSET(FTS_NOSTAT)) - p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2); - p->fts_namelen = namelen; p->fts_path = sp->fts_path; - p->fts_errno = 0; - p->fts_flags = 0; + p->fts_namelen = namelen; p->fts_instr = FTS_NOINSTR; - p->fts_number = 0; - p->fts_pointer = NULL; + if (!ISSET(FTS_NOSTAT)) + p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2); + memcpy(p->fts_name, name, namelen); + return (p); } static void -fts_lfree(head) - register FTSENT *head; +fts_lfree(FTSENT *head) { - register FTSENT *p; + FTSENT *p; /* Free a linked list of structures. */ - while (p = head) { + while ((p = head)) { head = head->fts_link; free(p); } @@ -1066,18 +1453,35 @@ fts_lfree(head) /* * Allow essentially unlimited paths; find, rm, ls should all work on any tree. - * Most systems will allow creation of paths much longer than MAXPATHLEN, even + * Most systems will allow creation of paths much longer than PATH_MAX, even * though the kernel won't resolve them. Add the size (not just what's needed) - * plus 256 bytes so don't realloc the path 2 bytes at a time. + * plus 256 bytes so don't realloc the path 2 bytes at a time. */ static int -fts_palloc(sp, more) - FTS *sp; - size_t more; +fts_palloc(FTS *sp, size_t more) { + char *p; + sp->fts_pathlen += more + 256; - sp->fts_path = realloc(sp->fts_path, (size_t)sp->fts_pathlen); - return (sp->fts_path == NULL); + /* + * Check for possible wraparound. In an FTS, fts_pathlen is + * a signed int but in an FTSENT it is an unsigned short. + * We limit fts_pathlen to USHRT_MAX to be safe in both cases. + */ + if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) { + free(sp->fts_path); + sp->fts_path = NULL; + errno = ENAMETOOLONG; + return (1); + } + p = realloc(sp->fts_path, sp->fts_pathlen); + if (p == NULL) { + free(sp->fts_path); + sp->fts_path = NULL; + return (1); + } + sp->fts_path = p; + return (0); } /* @@ -1085,36 +1489,70 @@ fts_palloc(sp, more) * already returned. */ static void -fts_padjust(sp, addr) - FTS *sp; - void *addr; +fts_padjust(FTS *sp, FTSENT *head) { FTSENT *p; + char *addr = sp->fts_path; #define ADJUST(p) { \ - (p)->fts_accpath = \ - (char *)addr + ((p)->fts_accpath - (p)->fts_path); \ + if ((p)->fts_accpath != (p)->fts_name) { \ + (p)->fts_accpath = \ + (char *)addr + ((p)->fts_accpath - (p)->fts_path); \ + } \ (p)->fts_path = addr; \ } /* Adjust the current set of children. */ for (p = sp->fts_child; p; p = p->fts_link) ADJUST(p); - /* Adjust the rest of the tree. */ - for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { + /* Adjust the rest of the tree, including the current level. */ + for (p = head; p->fts_level >= FTS_ROOTLEVEL;) { ADJUST(p); p = p->fts_link ? p->fts_link : p->fts_parent; } } static size_t -fts_maxarglen(argv) - char * const *argv; +fts_maxarglen(char * const *argv) { size_t len, max; for (max = 0; *argv; ++argv) if ((len = strlen(*argv)) > max) max = len; - return (max); + return (max + 1); +} + +/* + * Change to dir specified by fd or p->fts_accpath without getting + * tricked by someone changing the world out from underneath us. + * Assumes p->fts_dev and p->fts_ino are filled in. + */ +static int +fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) +{ + int ret, oerrno, newfd; + struct stat sb; + + newfd = fd; + if (ISSET(FTS_NOCHDIR)) + return (0); + if (fd < 0 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0) + return (-1); + if (fstat(newfd, &sb)) { + ret = -1; + goto bail; + } + if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) { + errno = ENOENT; /* disinformation */ + ret = -1; + goto bail; + } + ret = fchdir(newfd); +bail: + oerrno = errno; + if (fd < 0) + (void)close(newfd); + errno = oerrno; + return (ret); } diff --git a/src/libc/gen/get_compat.c b/src/libc/gen/get_compat.c index bec0856f9..4a1f140f6 100644 --- a/src/libc/gen/get_compat.c +++ b/src/libc/gen/get_compat.c @@ -45,7 +45,7 @@ static pthread_once_t threadsafe = PTHREAD_ONCE_INIT; static void check_env_var(void) { char *mode = getenv("COMMAND_MODE"); - + if (mode) { if (!strcasecmp(mode, "legacy")) { unix2003_mode = false; @@ -108,7 +108,7 @@ compat_mode(const char *function, const char *mode) { char *op = NULL; - if (op = strpbrk(mode, "!^&|")) { + if ((op = strpbrk(mode, "!^&|"))) { if (*op == '!') { if (op != mode) goto syn_error; return !compat_mode(function, mode +1); @@ -117,7 +117,7 @@ compat_mode(const char *function, const char *mode) { /* XXX char tmp[] would be better for left_arg, but we are not sure what the max size should be... is alloca(3) frowned on? */ - int left_sz = 1 + (op - mode); + size_t left_sz = 1 + (op - mode); char *left_arg = malloc(left_sz); strlcpy(left_arg, mode, left_sz); bool left = compat_mode(function, left_arg); diff --git a/src/libc/gen/getttyent.3 b/src/libc/gen/getttyent.3 index 7bd9ae292..98eab3b77 100644 --- a/src/libc/gen/getttyent.3 +++ b/src/libc/gen/getttyent.3 @@ -83,8 +83,7 @@ The fields are as follows: .It Fa ty_name The name of the character-special file. .It Fa ty_getty -The name of the command invoked by -.Xr init 8 +The name of the command invoked to initialize tty line characteristics. .It Fa ty_type The name of the default terminal type connected to this tty line. @@ -94,11 +93,7 @@ tty line. The possible flags are as follows: .Bl -tag -width TTY_NETWORK .It Dv TTY_ON -Enables logins (i.e., -.Xr init 8 -will start the command referenced by -.Fa ty_getty -on this entry). +Enables logins .It Dv TTY_SECURE Allow users with a uid of 0 to login on this terminal. .It Dv TTY_DIALUP @@ -175,7 +170,6 @@ return 0 on failure and 1 on success. .Xr termcap 5 , .Xr ttys 5 , .Xr getty 8 , -.Xr init 8 .Sh HISTORY The .Fn getttyent , diff --git a/src/libc/gen/getttyent.c b/src/libc/gen/getttyent.c index def6fa393..d40361429 100644 --- a/src/libc/gen/getttyent.c +++ b/src/libc/gen/getttyent.c @@ -98,20 +98,20 @@ struct seq { char fmt[NAME_MAX + 17]; }; -static char brapat[] = "\\[(.*)]"; +static const char *brapat = "\\[(.*)]"; static regex_t brapreg; -static char decpat[] = "^([0-9]+)-([0-9]+)$"; +static const char *decpat = "^([0-9]+)-([0-9]+)$"; static regex_t decpreg; -static char hexpat[] = "^0x([0-9a-f]+)-0x([0-9a-f]+)$"; +static const char *hexpat = "^0x([0-9a-f]+)-0x([0-9a-f]+)$"; static regex_t hexpreg; static struct seq *seq = NULL; static int slot; struct ttyent * -getttyent() +getttyent(void) { static struct ttyent tty; - static struct ttyent nonexistent = { + static const struct ttyent nonexistent = { "\01", /* this shouldn't match anything */ NULL, NULL, @@ -145,7 +145,7 @@ restart: * entries until we catch up. */ slot++; - return &nonexistent; + return (struct ttyent *)&nonexistent; } if (seq->count > 0) { diff --git a/src/libc/gen/getusershell.c b/src/libc/gen/getusershell.c index 7dc16c57e..202a51b0a 100644 --- a/src/libc/gen/getusershell.c +++ b/src/libc/gen/getusershell.c @@ -69,7 +69,7 @@ * /etc/shells. */ -static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; +static const char * const okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; static char **curshell, **shells, *strings; static char **initshells(void); @@ -77,7 +77,7 @@ static char **initshells(void); * Get a list of shells from _PATH_SHELLS, if it exists. */ char * -getusershell() +getusershell(void) { char *ret; @@ -90,9 +90,8 @@ getusershell() } void -endusershell() +endusershell(void) { - if (shells != NULL) free(shells); shells = NULL; @@ -103,14 +102,13 @@ endusershell() } void -setusershell() +setusershell(void) { - curshell = initshells(); } static char ** -initshells() +initshells(void) { register char **sp, *cp; register FILE *fp; @@ -124,21 +122,21 @@ initshells() free(strings); strings = NULL; if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) - return (okshells); + return ((char **)okshells); if (fstat(fileno(fp), &statb) == -1) { (void)fclose(fp); - return (okshells); + return ((char **)okshells); } if ((strings = malloc((u_int)statb.st_size)) == NULL) { (void)fclose(fp); - return (okshells); + return ((char **)okshells); } shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); if (shells == NULL) { (void)fclose(fp); free(strings); strings = NULL; - return (okshells); + return ((char **)okshells); } sp = shells; cp = strings; diff --git a/src/libc/gen/isinf.c b/src/libc/gen/isinf.c deleted file mode 100644 index fecead0b8..000000000 --- a/src/libc/gen/isinf.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 1999, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -/* 3BSD compatibility function */ -#undef isinf -int -isinf(double d) -{ - return __inline_isinfd(d); -} diff --git a/src/libc/gen/isnan.c b/src/libc/gen/isnan.c deleted file mode 100644 index 43ce009b0..000000000 --- a/src/libc/gen/isnan.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 1999, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -/* 3BSD compatibility function */ -#undef isnan -int -isnan(double d) -{ - return __inline_isnand(d); -} diff --git a/src/libc/gen/magazine_malloc.c b/src/libc/gen/magazine_malloc.c deleted file mode 100644 index 6290df5be..000000000 --- a/src/libc/gen/magazine_malloc.c +++ /dev/null @@ -1,8199 +0,0 @@ -/* - * Copyright (c) 1999, 2006, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* Author: Bertrand Serlet, August 1999 */ - -/* - Multithread enhancements for "tiny" allocations introduced February 2008. - These are in the spirit of "Hoard". See: - Berger, E.D.; McKinley, K.S.; Blumofe, R.D.; Wilson, P.R. (2000). - "Hoard: a scalable memory allocator for multithreaded applications". - ACM SIGPLAN Notices 35 (11): 117-128. Berger2000. - - Retrieved on 2008-02-22. -*/ - -/* gcc -g -O3 magazine_malloc.c malloc.c -o libmagmalloc.dylib -I. \ - -I/System/Library/Frameworks/System.framework/PrivateHeaders/ -funit-at-a-time \ - -dynamiclib -Wall -arch x86_64 -arch i386 -arch ppc */ - -#include - -#include "scalable_malloc.h" -#include "malloc_printf.h" -#include "_simple.h" -#include "magmallocProvider.h" - -#include /* for pthread_lock_t SPI */ -#include /* for pthread API */ - -#include -#include -#include -#include -#include -#include -#include - -#if defined(__i386__) || defined(__x86_64__) -#define __APPLE_API_PRIVATE -#include -#define _COMM_PAGE_VERSION_REQD 9 -#undef __APPLE_API_PRIVATE -#else -#include -#endif - -#include -#include /* for NSVersionOfLinkTimeLibrary() */ -#include /* for _dyld_get_image_slide() */ -#include /* for _NSGetMachExecuteHeader() */ -#include -#include - -#include - -/********************* DEFINITIONS ************************/ - -#define DEBUG_MALLOC 0 // set to one to debug malloc itself - -#define DEBUG_CLIENT 0 // set to one to debug malloc client - -#define DEBUG_MADVISE 0 - -// -#define RELAXED_INVARIANT_CHECKS 1 - -#if DEBUG_MALLOC -#warning DEBUG_MALLOC ENABLED -# define INLINE -# define ALWAYSINLINE -# define CHECK_MAGAZINE_PTR_LOCKED(szone, mag_ptr, fun) \ -do { \ - if (__is_threaded && TRY_LOCK(mag_ptr->magazine_lock)) { \ - malloc_printf("*** magazine_lock was not set %p in %s\n", \ - mag_ptr->magazine_lock, fun); \ - } \ -} while (0) -#else -# define INLINE __inline__ -# define ALWAYSINLINE __attribute__((always_inline)) -# define CHECK_MAGAZINE_PTR_LOCKED(szone, mag_ptr, fun) {} -#endif - -# define NOINLINE __attribute__((noinline)) - -#if defined(__i386__) || defined(__x86_64__) -#define CACHE_ALIGN __attribute__ ((aligned (128) )) /* Future-proofing at 128B */ -#elif defined(__ppc__) || defined(__ppc64__) -#define CACHE_ALIGN __attribute__ ((aligned (128) )) -#else -#define CACHE_ALIGN -#endif - -#if !__LP64__ -#define ASLR_INTERNAL 1 -#endif - -/* - * Access to global variables is slow, so optimise our handling of vm_page_size - * and vm_page_shift. - */ -#define _vm_page_size vm_page_size /* to get to the originals */ -#define _vm_page_shift vm_page_shift -#define vm_page_size 4096 /* our normal working sizes */ -#define vm_page_shift 12 - -/* - * msize - a type to refer to the number of quanta of a tiny or small - * allocation. A tiny block with an msize of 3 would be 3 << SHIFT_TINY_QUANTUM - * bytes in size. - */ -typedef unsigned short msize_t; - -typedef union { - void *p; - uintptr_t u; -} ptr_union; - -typedef struct { - ptr_union previous; - ptr_union next; -} free_list_t; - -typedef unsigned int grain_t; // N.B. wide enough to index all free slots - -typedef int mag_index_t; - -#define CHECK_REGIONS (1 << 31) -#define DISABLE_ASLR (1 << 30) - -#define MAX_RECORDER_BUFFER 256 - -/********************* DEFINITIONS for tiny ************************/ - -/* - * Memory in the Tiny range is allocated from regions (heaps) pointed to by the - * szone's hashed_regions pointer. - * - * Each region is laid out as a heap, followed by a header block, all within - * a 1MB (2^20) block. This means there are 64520 16-byte blocks and the header - * is 16138 bytes, making the total 1048458 bytes, leaving 118 bytes unused. - * - * The header block is arranged as in struct tiny_region defined just below, and - * consists of two bitfields (or bit arrays) interleaved 32 bits by 32 bits. - * - * Each bitfield comprises NUM_TINY_BLOCKS bits, and refers to the corresponding - * TINY_QUANTUM block within the heap. - * - * The bitfields are used to encode the state of memory within the heap. The header bit indicates - * that the corresponding quantum is the first quantum in a block (either in use or free). The - * in-use bit is set for the header if the block has been handed out (allocated). If the header - * bit is not set, the in-use bit is invalid. - * - * The szone maintains an array of NUM_TINY_SLOTS freelists, each of which is used to hold - * free objects of the corresponding quantum size. - * - * A free block is laid out depending on its size, in order to fit all free - * blocks in 16 bytes, on both 32 and 64 bit platforms. One quantum blocks do - * not store their size in the block, instead relying on the header information - * to determine their size. Blocks of two or more quanta have room to store - * their size in the block, and store it both after the 'next' pointer, and in - * the last 2 bytes of the block. - * - * 1-quantum block - * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 : previous - * 0x4 0x08 : next - * end end - * - * >1-quantum block - * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 : previous - * 0x4 0x08 : next - * 0x8 0x10 : size (in quantum counts) - * end - 2 end - 2 : size (in quantum counts) - * end end - * - * All fields are pointer-sized, except for the size which is an unsigned short. - * - */ - -#define SHIFT_TINY_QUANTUM 4 // Required for AltiVec -#define TINY_QUANTUM (1 << SHIFT_TINY_QUANTUM) - -#define FOLLOWING_TINY_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM)) - -#ifdef __LP64__ -#define NUM_TINY_SLOTS 64 // number of slots for free-lists -#else -#define NUM_TINY_SLOTS 32 // number of slots for free-lists -#endif - -#define NUM_TINY_BLOCKS 64520 -#define SHIFT_TINY_CEIL_BLOCKS 16 // ceil(log2(NUM_TINY_BLOCKS)) -#define NUM_TINY_CEIL_BLOCKS (1 << SHIFT_TINY_CEIL_BLOCKS) -#define TINY_BLOCKS_ALIGN (SHIFT_TINY_CEIL_BLOCKS + SHIFT_TINY_QUANTUM) // 20 - -#define TINY_ENTROPY_BITS 15 -#define TINY_ENTROPY_MASK ((1 << TINY_ENTROPY_BITS) - 1) - -/* - * Avoid having so much entropy that the end of a valid tiny allocation - * might overrun the end of the tiny region. - */ -#if TINY_ENTROPY_MASK + NUM_TINY_SLOTS > NUM_TINY_BLOCKS -#error Too many entropy bits for tiny region requested -#endif - -/* - * Enough room for the data, followed by the bit arrays (2-bits per block) - * plus rounding to the nearest page. - */ -#define CEIL_NUM_TINY_BLOCKS_WORDS (((NUM_TINY_BLOCKS + 31) & ~31) >> 5) -#define TINY_METADATA_SIZE (sizeof(region_trailer_t) + sizeof(tiny_header_inuse_pair_t) * CEIL_NUM_TINY_BLOCKS_WORDS) -#define TINY_REGION_SIZE \ - ((NUM_TINY_BLOCKS * TINY_QUANTUM + TINY_METADATA_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1)) - -#define TINY_METADATA_START (NUM_TINY_BLOCKS * TINY_QUANTUM) - -/* - * Beginning and end pointers for a region's heap. - */ -#define TINY_REGION_ADDRESS(region) ((void *)(region)) -#define TINY_REGION_END(region) ((void *)(((uintptr_t)(region)) + (NUM_TINY_BLOCKS * TINY_QUANTUM))) - -/* - * Locate the heap base for a pointer known to be within a tiny region. - */ -#define TINY_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << TINY_BLOCKS_ALIGN) - 1))) - -/* - * Convert between byte and msize units. - */ -#define TINY_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_TINY_QUANTUM) -#define TINY_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_TINY_QUANTUM) - -#ifdef __LP64__ -# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[8]) -#else -# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[4]) -#endif -#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] - -/* - * Layout of a tiny region - */ -typedef uint32_t tiny_block_t[4]; // assert(TINY_QUANTUM == sizeof(tiny_block_t)) - -typedef struct tiny_header_inuse_pair -{ - uint32_t header; - uint32_t inuse; -} tiny_header_inuse_pair_t; - -typedef struct region_trailer -{ - struct region_trailer *prev; - struct region_trailer *next; - boolean_t recirc_suitable; - boolean_t failedREUSE; - volatile int pinned_to_depot; - unsigned bytes_used; - mag_index_t mag_index; -} region_trailer_t; - -typedef struct tiny_region -{ - tiny_block_t blocks[NUM_TINY_BLOCKS]; - - region_trailer_t trailer; - - // The interleaved bit arrays comprising the header and inuse bitfields. - // The unused bits of each component in the last pair will be initialized to sentinel values. - tiny_header_inuse_pair_t pairs[CEIL_NUM_TINY_BLOCKS_WORDS]; - - uint8_t pad[TINY_REGION_SIZE - (NUM_TINY_BLOCKS * sizeof(tiny_block_t)) - TINY_METADATA_SIZE]; -} *tiny_region_t; - -/* - * Per-region meta data for tiny allocator - */ -#define REGION_TRAILER_FOR_TINY_REGION(r) (&(((tiny_region_t)(r))->trailer)) -#define MAGAZINE_INDEX_FOR_TINY_REGION(r) (REGION_TRAILER_FOR_TINY_REGION(r)->mag_index) -#define BYTES_USED_FOR_TINY_REGION(r) (REGION_TRAILER_FOR_TINY_REGION(r)->bytes_used) - -/* - * Locate the block header for a pointer known to be within a tiny region. - */ -#define TINY_BLOCK_HEADER_FOR_PTR(_p) ((void *)&(((tiny_region_t)TINY_REGION_FOR_PTR(_p))->pairs)) - -/* - * Locate the inuse map for a given block header pointer. - */ -#define TINY_INUSE_FOR_HEADER(_h) ((void *)&(((tiny_header_inuse_pair_t *)(_h))->inuse)) - -/* - * Compute the bitmap index for a pointer known to be within a tiny region. - */ -#define TINY_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_CEIL_BLOCKS - 1)) - -#define TINY_CACHE 1 // This governs a last-free cache of 1 that bypasses the free-list - -#if ! TINY_CACHE -#warning TINY_CACHE turned off -#endif - -#define TINY_REGION_PAYLOAD_BYTES (NUM_TINY_BLOCKS * TINY_QUANTUM) - -/********************* DEFINITIONS for small ************************/ - -/* - * Memory in the Small range is allocated from regions (heaps) pointed to by the szone's hashed_regions - * pointer. - * - * Each region is laid out as a heap, followed by the metadata array, all within an 8MB (2^23) block. - * The array is arranged as an array of shorts, one for each SMALL_QUANTUM in the heap. - * This means there are 16320 512-blocks and the array is 16320*2 bytes, which totals 8388480, leaving - * 128 bytes unused. - * - * The MSB of each short is set for the first quantum in a free block. The low 15 bits encode the - * block size (in SMALL_QUANTUM units), or are zero if the quantum is not the first in a block. - * - * The szone maintains an array of 32 freelists, each of which is used to hold free objects - * of the corresponding quantum size. - * - * A free block is laid out as: - * - * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 : previous - * 0x4 0x08 : next - * 0x8 0x10 : size (in quantum counts) - * end - 2 end - 2 : size (in quantum counts) - * end end - * - * All fields are pointer-sized, except for the size which is an unsigned short. - * - */ - -#define SMALL_IS_FREE (1 << 15) - -#define SHIFT_SMALL_QUANTUM (SHIFT_TINY_QUANTUM + 5) // 9 -#define SMALL_QUANTUM (1 << SHIFT_SMALL_QUANTUM) // 512 bytes - -#define FOLLOWING_SMALL_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_SMALL_QUANTUM)) - -/* - * The number of slots in the free-list for small blocks. To avoid going to - * vm system as often on large memory machines, increase the number of free list - * spots above some amount of RAM installed in the system. - */ -#define NUM_SMALL_SLOTS 32 -#define NUM_SMALL_SLOTS_LARGEMEM 256 -#define SMALL_BITMAP_WORDS 8 - -/* - * We can only represent up to 1<<15 for msize; but we choose to stay even below that to avoid the - * convention msize=0 => msize = (1<<15) - */ -#define NUM_SMALL_BLOCKS 16320 -#define SHIFT_SMALL_CEIL_BLOCKS 14 // ceil(log2(NUM_SMALL_BLOCKs)) -#define NUM_SMALL_CEIL_BLOCKS (1 << SHIFT_SMALL_CEIL_BLOCKS) -#define SMALL_BLOCKS_ALIGN (SHIFT_SMALL_CEIL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23 - -#define SMALL_ENTROPY_BITS 13 -#define SMALL_ENTROPY_MASK ((1 << SMALL_ENTROPY_BITS) - 1) - -/* - * Avoid having so much entropy that the end of a valid small allocation - * might overrun the end of the small region. - */ -#if SMALL_ENTROPY_MASK + NUM_SMALL_SLOTS > NUM_SMALL_BLOCKS -#error Too many entropy bits for small region requested -#endif - -#define SMALL_METADATA_SIZE (sizeof(region_trailer_t) + NUM_SMALL_BLOCKS * sizeof(msize_t)) -#define SMALL_REGION_SIZE \ - ((NUM_SMALL_BLOCKS * SMALL_QUANTUM + SMALL_METADATA_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1)) - -#define SMALL_METADATA_START (NUM_SMALL_BLOCKS * SMALL_QUANTUM) - -/* - * Beginning and end pointers for a region's heap. - */ -#define SMALL_REGION_ADDRESS(region) ((unsigned char *)region) -#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region) + (NUM_SMALL_BLOCKS * SMALL_QUANTUM)) - -/* - * Locate the heap base for a pointer known to be within a small region. - */ -#define SMALL_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << SMALL_BLOCKS_ALIGN) - 1))) - -/* - * Convert between byte and msize units. - */ -#define SMALL_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_SMALL_QUANTUM) -#define SMALL_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_SMALL_QUANTUM) - -#define SMALL_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] - -/* - * Layout of a small region - */ -typedef uint32_t small_block_t[SMALL_QUANTUM/sizeof(uint32_t)]; - -typedef struct small_region -{ - small_block_t blocks[NUM_SMALL_BLOCKS]; - - region_trailer_t trailer; - - msize_t small_meta_words[NUM_SMALL_BLOCKS]; - - uint8_t pad[SMALL_REGION_SIZE - (NUM_SMALL_BLOCKS * sizeof(small_block_t)) - SMALL_METADATA_SIZE]; -} *small_region_t; - -/* - * Per-region meta data for small allocator - */ -#define REGION_TRAILER_FOR_SMALL_REGION(r) (&(((small_region_t)(r))->trailer)) -#define MAGAZINE_INDEX_FOR_SMALL_REGION(r) (REGION_TRAILER_FOR_SMALL_REGION(r)->mag_index) -#define BYTES_USED_FOR_SMALL_REGION(r) (REGION_TRAILER_FOR_SMALL_REGION(r)->bytes_used) - -/* - * Locate the metadata base for a pointer known to be within a small region. - */ -#define SMALL_META_HEADER_FOR_PTR(_p) (((small_region_t)SMALL_REGION_FOR_PTR(_p))->small_meta_words) - -/* - * Compute the metadata index for a pointer known to be within a small region. - */ -#define SMALL_META_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_CEIL_BLOCKS - 1)) - -/* - * Find the metadata word for a pointer known to be within a small region. - */ -#define SMALL_METADATA_FOR_PTR(_p) (SMALL_META_HEADER_FOR_PTR(_p) + SMALL_META_INDEX_FOR_PTR(_p)) - -/* - * Determine whether a pointer known to be within a small region points to memory which is free. - */ -#define SMALL_PTR_IS_FREE(_p) (*SMALL_METADATA_FOR_PTR(_p) & SMALL_IS_FREE) - -/* - * Extract the msize value for a pointer known to be within a small region. - */ -#define SMALL_PTR_SIZE(_p) (*SMALL_METADATA_FOR_PTR(_p) & ~SMALL_IS_FREE) - -#define SMALL_CACHE 1 -#if !SMALL_CACHE -#warning SMALL_CACHE turned off -#endif - -#define SMALL_REGION_PAYLOAD_BYTES (NUM_SMALL_BLOCKS * SMALL_QUANTUM) - -/************************* DEFINITIONS for large ****************************/ - -#define LARGE_THRESHOLD (15 * 1024) // strictly above this use "large" -#define LARGE_THRESHOLD_LARGEMEM (127 * 1024) - -#if (LARGE_THRESHOLD > NUM_SMALL_SLOTS * SMALL_QUANTUM) -#error LARGE_THRESHOLD should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM -#endif - -#if (LARGE_THRESHOLD_LARGEMEM > NUM_SMALL_SLOTS_LARGEMEM * SMALL_QUANTUM) -#error LARGE_THRESHOLD_LARGEMEM should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM -#endif - -/* - * When all memory is touched after a copy, vm_copy() is always a lose - * But if the memory is only read, vm_copy() wins over memmove() at 3 or 4 pages - * (on a G3/300MHz) - * - * This must be larger than LARGE_THRESHOLD - */ -#define VM_COPY_THRESHOLD (40 * 1024) -#define VM_COPY_THRESHOLD_LARGEMEM (128 * 1024) - -typedef struct { - vm_address_t address; - vm_size_t size; - boolean_t did_madvise_reusable; -} large_entry_t; - -#if !TARGET_OS_EMBEDDED -#define LARGE_CACHE 1 -#else -#define LARGE_CACHE 0 -#endif -#if !LARGE_CACHE -#warning LARGE_CACHE turned off -#endif -#if defined(__LP64__) -#define LARGE_ENTRY_CACHE_SIZE 16 -#define LARGE_CACHE_SIZE_LIMIT ((vm_size_t)0x80000000) /* 2Gb */ -#else -#define LARGE_ENTRY_CACHE_SIZE 8 -#define LARGE_CACHE_SIZE_LIMIT ((vm_size_t)0x02000000) /* 32Mb */ -#endif -#define LARGE_CACHE_SIZE_ENTRY_LIMIT (LARGE_CACHE_SIZE_LIMIT/LARGE_ENTRY_CACHE_SIZE) - -#define SZONE_FLOTSAM_THRESHOLD_LOW (1024 * 512) -#define SZONE_FLOTSAM_THRESHOLD_HIGH (1024 * 1024) - -/******************************************************************************* - * Definitions for region hash - ******************************************************************************/ - -typedef void * region_t; -typedef region_t * rgnhdl_t; /* A pointer into hashed_regions array. */ - -#define INITIAL_NUM_REGIONS_SHIFT 6 // log2(INITIAL_NUM_REGIONS) -#define INITIAL_NUM_REGIONS (1 << INITIAL_NUM_REGIONS_SHIFT) // Must be a power of 2! -#define HASHRING_OPEN_ENTRY ((region_t) 0) // Initial value and sentinel marking end of collision chain -#define HASHRING_REGION_DEALLOCATED ((region_t)-1) // Region at this slot reclaimed by OS -#define HASH_BLOCKS_ALIGN TINY_BLOCKS_ALIGN // MIN( TINY_BLOCKS_ALIGN, SMALL_BLOCKS_ALIGN, ... ) - -typedef struct region_hash_generation { - size_t num_regions_allocated; - size_t num_regions_allocated_shift; // log2(num_regions_allocated) - region_t *hashed_regions; // hashed by location - struct region_hash_generation *nextgen; -} region_hash_generation_t; - -/******************************************************************************* - * Per-processor magazine for tiny and small allocators - ******************************************************************************/ - -typedef struct { // vm_allocate()'d, so the array of magazines is page-aligned to begin with. - // Take magazine_lock first, Depot lock when needed for recirc, then szone->{tiny,small}_regions_lock when needed for alloc - pthread_lock_t magazine_lock CACHE_ALIGN; - // Protection for the crtical section that does allocate_pages outside the magazine_lock - volatile boolean_t alloc_underway; - - // One element deep "death row", optimizes malloc/free/malloc for identical size. - void *mag_last_free; // low SHIFT_{TINY,SMALL}_QUANTUM bits indicate the msize - region_t mag_last_free_rgn; // holds the region for mag_last_free - - free_list_t *mag_free_list[256]; // assert( 256 >= MAX( NUM_TINY_SLOTS, NUM_SMALL_SLOTS_LARGEMEM )) - unsigned mag_bitmap[8]; // assert( sizeof(mag_bitmap) << 3 >= sizeof(mag_free_list)/sizeof(free_list_t) ) - - // the first and last free region in the last block are treated as big blocks in use that are not accounted for - size_t mag_bytes_free_at_end; - size_t mag_bytes_free_at_start; - region_t mag_last_region; // Valid iff mag_bytes_free_at_end || mag_bytes_free_at_start > 0 - - // bean counting ... - unsigned mag_num_objects; - size_t mag_num_bytes_in_objects; - size_t num_bytes_in_magazine; - - // recirculation list -- invariant: all regions owned by this magazine that meet the emptiness criteria - // are located nearer to the head of the list than any region that doesn't satisfy that criteria. - // Doubly linked list for efficient extraction. - unsigned recirculation_entries; - region_trailer_t *firstNode; - region_trailer_t *lastNode; - -#if __LP64__ - uint64_t pad[48]; // So sizeof(magazine_t) is 2560 bytes. FIXME: assert this at compile time -#else - uint32_t pad[12]; // So sizeof(magazine_t) is 1280 bytes. FIXME: assert this at compile time -#endif -} magazine_t; - -#define TINY_MAX_MAGAZINES 32 /* MUST BE A POWER OF 2! */ -#define TINY_MAGAZINE_PAGED_SIZE \ - (((sizeof(magazine_t) * (TINY_MAX_MAGAZINES + 1)) + vm_page_size - 1) &\ - ~ (vm_page_size - 1)) /* + 1 for the Depot */ - -#define SMALL_MAX_MAGAZINES 32 /* MUST BE A POWER OF 2! */ -#define SMALL_MAGAZINE_PAGED_SIZE \ - (((sizeof(magazine_t) * (SMALL_MAX_MAGAZINES + 1)) + vm_page_size - 1) &\ - ~ (vm_page_size - 1)) /* + 1 for the Depot */ - -#define DEPOT_MAGAZINE_INDEX -1 - -/****************************** zone itself ***********************************/ - -/* - * Note that objects whose adddress are held in pointers here must be pursued - * individually in the {tiny,small}_in_use_enumeration() routines. See for - * example the treatment of region_hash_generation and tiny_magazines below. - */ - -typedef struct szone_s { // vm_allocate()'d, so page-aligned to begin with. - malloc_zone_t basic_zone; // first page will be given read-only protection - uint8_t pad[vm_page_size - sizeof(malloc_zone_t)]; - - pthread_key_t cpu_id_key; // remainder of structure is R/W (contains no function pointers) - unsigned debug_flags; - void *log_address; - - /* Regions for tiny objects */ - pthread_lock_t tiny_regions_lock CACHE_ALIGN; - size_t num_tiny_regions; - size_t num_tiny_regions_dealloc; - region_hash_generation_t *tiny_region_generation; - region_hash_generation_t trg[2]; - - int num_tiny_magazines; - unsigned num_tiny_magazines_mask; - int num_tiny_magazines_mask_shift; - magazine_t *tiny_magazines; // array of per-processor magazines - -#if TARGET_OS_EMBEDDED - uintptr_t last_tiny_advise; -#endif - - /* Regions for small objects */ - pthread_lock_t small_regions_lock CACHE_ALIGN; - size_t num_small_regions; - size_t num_small_regions_dealloc; - region_hash_generation_t *small_region_generation; - region_hash_generation_t srg[2]; - - unsigned num_small_slots; // determined by physmem size - - int num_small_magazines; - unsigned num_small_magazines_mask; - int num_small_magazines_mask_shift; - magazine_t *small_magazines; // array of per-processor magazines - -#if TARGET_OS_EMBEDDED - uintptr_t last_small_advise; -#endif - - /* large objects: all the rest */ - pthread_lock_t large_szone_lock CACHE_ALIGN; // One customer at a time for large - unsigned num_large_objects_in_use; - unsigned num_large_entries; - large_entry_t *large_entries; // hashed by location; null entries don't count - size_t num_bytes_in_large_objects; - -#if LARGE_CACHE - int large_entry_cache_oldest; - int large_entry_cache_newest; - large_entry_t large_entry_cache[LARGE_ENTRY_CACHE_SIZE]; // "death row" for large malloc/free - boolean_t large_legacy_reset_mprotect; - size_t large_entry_cache_reserve_bytes; - size_t large_entry_cache_reserve_limit; - size_t large_entry_cache_bytes; // total size of death row, bytes -#endif - - /* flag and limits pertaining to altered malloc behavior for systems with - large amounts of physical memory */ - unsigned is_largemem; - unsigned large_threshold; - unsigned vm_copy_threshold; - - /* security cookie */ - uintptr_t cookie; - - /* Initial region list */ - region_t initial_tiny_regions[INITIAL_NUM_REGIONS]; - region_t initial_small_regions[INITIAL_NUM_REGIONS]; - - /* The purgeable zone constructed by create_purgeable_zone() would like to hand off tiny and small - * allocations to the default scalable zone. Record the latter as the "helper" zone here. */ - struct szone_s *helper_zone; - - boolean_t flotsam_enabled; -} szone_t; - -#define SZONE_PAGED_SIZE ((sizeof(szone_t) + vm_page_size - 1) & ~ (vm_page_size - 1)) - -#if DEBUG_MALLOC || DEBUG_CLIENT -static void szone_sleep(void); -#endif -__private_extern__ void malloc_error_break(void); - -// msg prints after fmt, ... -static NOINLINE void szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...) - __printflike(5, 6); - -static void protect(void *address, size_t size, unsigned protection, unsigned debug_flags); -static void *allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, - int vm_page_label); -static void *allocate_pages_securely(szone_t *szone, size_t size, unsigned char align, - int vm_page_label); -static void deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags); -#if TARGET_OS_EMBEDDED -static int madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi, uintptr_t *last); -#else -static int madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi); -#endif -static kern_return_t _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr); - -static INLINE mag_index_t mag_get_thread_index(szone_t *szone) ALWAYSINLINE; -static magazine_t *mag_lock_zine_for_region_trailer(szone_t *szone, magazine_t *magazines, region_trailer_t *trailer, - mag_index_t mag_index); - -static INLINE rgnhdl_t hash_lookup_region_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) - ALWAYSINLINE; -static void hash_region_insert_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r); -static region_t *hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries); -static region_t *hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, - size_t *mutable_shift, size_t *new_size); - -static INLINE uintptr_t free_list_gen_checksum(uintptr_t ptr) ALWAYSINLINE; -static INLINE uintptr_t free_list_checksum_ptr(szone_t *szone, void *p) ALWAYSINLINE; -static INLINE void *free_list_unchecksum_ptr(szone_t *szone, ptr_union *ptr) ALWAYSINLINE; -static unsigned free_list_count(szone_t *szone, free_list_t *ptr); - -static INLINE void recirc_list_extract(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) ALWAYSINLINE; -static INLINE void recirc_list_splice_last(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) ALWAYSINLINE; -static INLINE void recirc_list_splice_first(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) ALWAYSINLINE; - -static INLINE void BITARRAY_SET(uint32_t *bits, msize_t index) ALWAYSINLINE; -static INLINE void BITARRAY_CLR(uint32_t *bits, msize_t index) ALWAYSINLINE; -static INLINE boolean_t BITARRAY_BIT(uint32_t *bits, msize_t index) ALWAYSINLINE; - -static msize_t get_tiny_free_size(const void *ptr); -static msize_t get_tiny_previous_free_msize(const void *ptr); -static INLINE msize_t get_tiny_meta_header(const void *ptr, boolean_t *is_free) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_in_use(const void *ptr, msize_t msize) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_in_use_1(const void *ptr) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_middle(const void *ptr) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_free(const void *ptr, msize_t msize) ALWAYSINLINE; -static INLINE boolean_t tiny_meta_header_is_free(const void *ptr) ALWAYSINLINE; -static INLINE void *tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) ALWAYSINLINE; - -static void tiny_free_list_add_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize); -static void tiny_free_list_remove_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize); -static INLINE region_t tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; - -static void tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr); -static int tiny_free_detach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r); -static size_t tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r); -static void tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r); -static region_t tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node); -static boolean_t tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index); -static region_t tiny_find_msize_region(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize); -static boolean_t tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize); - -static INLINE boolean_t tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, - void *ptr, msize_t msize) ALWAYSINLINE; -static void *tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, - msize_t msize, void *fresh_region); -static boolean_t tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size); -static boolean_t tiny_check_region(szone_t *szone, region_t region); -static kern_return_t tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, - memory_reader_t reader, vm_range_recorder_t recorder); -static void *tiny_malloc_from_free_list(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, - msize_t msize); -static INLINE void *tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE; -static INLINE void free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size) ALWAYSINLINE; -static void print_tiny_free_list(szone_t *szone); -static void print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end); -static boolean_t tiny_free_list_check(szone_t *szone, grain_t slot); - -static INLINE void small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize) ALWAYSINLINE; -static INLINE void small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) ALWAYSINLINE; -static INLINE void small_meta_header_set_middle(msize_t *meta_headers, msize_t index) ALWAYSINLINE; -static void small_free_list_add_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize); -static void small_free_list_remove_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize); -static INLINE region_t small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; - -static void small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr); -static int small_free_detach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r); -static size_t small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r); -static void small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r); -static region_t small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node); -static boolean_t small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index); -static region_t small_find_msize_region(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize); -static boolean_t small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize); -static INLINE boolean_t small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region, - void *ptr, msize_t msize) ALWAYSINLINE; -static void *small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, - msize_t msize, void *fresh_region); -static boolean_t small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size); -static boolean_t small_check_region(szone_t *szone, region_t region); -static kern_return_t small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, - memory_reader_t reader, vm_range_recorder_t recorder); -static void *small_malloc_from_free_list(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, - msize_t msize); -static INLINE void *small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE; -static INLINE void free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size) ALWAYSINLINE; -static void print_small_free_list(szone_t *szone); -static void print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end); -static boolean_t small_free_list_check(szone_t *szone, grain_t grain); - -#if DEBUG_MALLOC -static void large_debug_print(szone_t *szone); -#endif -static large_entry_t *large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr); -static void large_entry_insert_no_lock(szone_t *szone, large_entry_t range); -static INLINE void large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) ALWAYSINLINE; -static INLINE large_entry_t *large_entries_alloc_no_lock(szone_t *szone, unsigned num) ALWAYSINLINE; -static void large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, - vm_range_t *range_to_deallocate); -static large_entry_t *large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate); -static vm_range_t large_entry_free_no_lock(szone_t *szone, large_entry_t *entry); -static NOINLINE kern_return_t large_in_use_enumerator(task_t task, void *context, - unsigned type_mask, vm_address_t large_entries_address, - unsigned num_entries, memory_reader_t reader, - vm_range_recorder_t recorder); -static void *large_malloc(szone_t *szone, size_t num_pages, unsigned char alignment, boolean_t cleared_requested); -static NOINLINE void free_large(szone_t *szone, void *ptr); -static INLINE int large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE; - -/* - * Mark these NOINLINE to avoid bloating the purgeable zone call backs - */ -static NOINLINE void szone_free(szone_t *szone, void *ptr); -static NOINLINE void *szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested); -static NOINLINE void *szone_malloc(szone_t *szone, size_t size); -static NOINLINE void *szone_calloc(szone_t *szone, size_t num_items, size_t size); -static NOINLINE void *szone_valloc(szone_t *szone, size_t size); -static NOINLINE size_t szone_size_try_large(szone_t *szone, const void *ptr); -static NOINLINE size_t szone_size(szone_t *szone, const void *ptr); -static NOINLINE void *szone_realloc(szone_t *szone, void *ptr, size_t new_size); -static NOINLINE void *szone_memalign(szone_t *szone, size_t alignment, size_t size); -static NOINLINE void szone_free_definite_size(szone_t *szone, void *ptr, size_t size); -static NOINLINE unsigned szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count); -static NOINLINE void szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count); -static void szone_destroy(szone_t *szone); -static NOINLINE size_t szone_good_size(szone_t *szone, size_t size); - -static NOINLINE boolean_t szone_check_all(szone_t *szone, const char *function); -static boolean_t szone_check(szone_t *szone); -static kern_return_t szone_ptr_in_use_enumerator(task_t task, void *context, - unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, vm_range_recorder_t recorder); -static NOINLINE void szone_print(szone_t *szone, boolean_t verbose); -static void szone_log(malloc_zone_t *zone, void *log_address); -static void szone_force_lock(szone_t *szone); -static void szone_force_unlock(szone_t *szone); -static boolean_t szone_locked(szone_t *szone); - -static void szone_statistics(szone_t *szone, malloc_statistics_t *stats); - -static void purgeable_free(szone_t *szone, void *ptr); -static void *purgeable_malloc(szone_t *szone, size_t size); -static void *purgeable_calloc(szone_t *szone, size_t num_items, size_t size); -static void *purgeable_valloc(szone_t *szone, size_t size); -static size_t purgeable_size(szone_t *szone, const void *ptr); -static void *purgeable_realloc(szone_t *szone, void *ptr, size_t new_size); -static void *purgeable_memalign(szone_t *szone, size_t alignment, size_t size); -static void purgeable_free_definite_size(szone_t *szone, void *ptr, size_t size); -static unsigned purgeable_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count); -static void purgeable_batch_free(szone_t *szone, void **to_be_freed, unsigned count); -static void purgeable_destroy(szone_t *szone); -static size_t purgeable_good_size(szone_t *szone, size_t size); - -static boolean_t purgeable_check(szone_t *szone); -static kern_return_t purgeable_ptr_in_use_enumerator(task_t task, void *context, - unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, vm_range_recorder_t recorder); -static void purgeable_print(szone_t *szone, boolean_t verbose); -static void purgeable_log(malloc_zone_t *zone, void *log_address); -static void purgeable_force_lock(szone_t *szone); -static void purgeable_force_unlock(szone_t *szone); -static boolean_t purgeable_locked(szone_t *szone); - -static void purgeable_statistics(szone_t *szone, malloc_statistics_t *stats); - -static void *frozen_malloc(szone_t *zone, size_t new_size); -static void *frozen_calloc(szone_t *zone, size_t num_items, size_t size); -static void *frozen_valloc(szone_t *zone, size_t new_size); -static void *frozen_realloc(szone_t *zone, void *ptr, size_t new_size); -static void frozen_free(szone_t *zone, void *ptr); -static void frozen_destroy(szone_t *zone); - -static volatile uintptr_t entropic_address = 0; -static volatile uintptr_t entropic_limit = 0; -#define ENTROPIC_KABILLION 0x10000000 /* 256Mb */ - -__private_extern__ uint64_t malloc_entropy[2]; - -#define SZONE_LOCK(szone) \ - do { \ - LOCK(szone->large_szone_lock); \ - } while (0) - -#define SZONE_UNLOCK(szone) \ - do { \ - UNLOCK(szone->large_szone_lock); \ - } while (0) - -#define SZONE_TRY_LOCK(szone) \ - TRY_LOCK(szone->large_szone_lock); - -#define SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr) \ - do { \ - LOCK(mag_ptr->magazine_lock); \ - } while(0) - -#define SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr) \ - do { \ - UNLOCK(mag_ptr->magazine_lock); \ - } while(0) - -#define SZONE_MAGAZINE_PTR_TRY_LOCK(szone, mag_ptr) \ - TRY_LOCK(mag_ptr->magazine_lock); - -#if DEBUG_MALLOC -# define LOG(szone,ptr) \ - (szone->log_address && (((uintptr_t)szone->log_address == -1) || \ - (szone->log_address == (void *)(ptr)))) -#else -# define LOG(szone,ptr) 0 -#endif - -#if DEBUG_MALLOC || DEBUG_CLIENT -# define CHECK(szone,fun) \ - if ((szone)->debug_flags & CHECK_REGIONS) \ - szone_check_all(szone, fun) -#else -# define CHECK(szone,fun) \ - do {} while (0) -#endif - -/********************* VERY LOW LEVEL UTILITIES ************************/ - -static void -szone_sleep(void) -{ - if (getenv("MallocErrorStop")) { - _malloc_printf(ASL_LEVEL_NOTICE, "*** sending SIGSTOP to help debug\n"); - kill(getpid(), SIGSTOP); - } else if (getenv("MallocErrorSleep")) { - _malloc_printf(ASL_LEVEL_NOTICE, "*** sleeping to help debug\n"); - sleep(3600); // to help debug - } -} - -// msg prints after fmt, ... -static NOINLINE void -szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...) -{ - va_list ap; - _SIMPLE_STRING b = _simple_salloc(); - - if (szone) SZONE_UNLOCK(szone); // FIXME: unlock magazine and region locks? - if (b) { - if (fmt) { - va_start(ap, fmt); - _simple_vsprintf(b, fmt, ap); - va_end(ap); - } - if (ptr) { - _simple_sprintf(b, "*** error for object %p: %s\n", ptr, msg); - } else { - _simple_sprintf(b, "*** error: %s\n", msg); - } - malloc_printf("%s*** set a breakpoint in malloc_error_break to debug\n", _simple_string(b)); - } else { - /* - * Should only get here if vm_allocate() can't get a single page of - * memory, implying _simple_asl_log() would also fail. So we just - * print to the file descriptor. - */ - if (fmt) { - va_start(ap, fmt); - _malloc_vprintf(MALLOC_PRINTF_NOLOG, fmt, ap); - va_end(ap); - } - if (ptr) { - _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error for object %p: %s\n", ptr, msg); - } else { - _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error: %s\n", msg); - } - _malloc_printf(MALLOC_PRINTF_NOLOG, "*** set a breakpoint in malloc_error_break to debug\n"); - } - malloc_error_break(); -#if DEBUG_MALLOC - szone_print(szone, 1); -#endif - szone_sleep(); - // Call abort() if this is a memory corruption error and the abort on - // corruption flag is set, or if any error should abort. - if ((is_corruption && (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_CORRUPTION)) || - (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_ERROR)) { - CRSetCrashLogMessage(b ? _simple_string(b) : msg); - abort(); - } else if (b) { - _simple_sfree(b); - } -} - -static void -protect(void *address, size_t size, unsigned protection, unsigned debug_flags) -{ - kern_return_t err; - - if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_PRELUDE)) { - err = mprotect((void *)((uintptr_t)address - vm_page_size), vm_page_size, protection); - if (err) { - malloc_printf("*** can't protect(%p) region for prelude guard page at %p\n", - protection,(uintptr_t)address - (1 << vm_page_shift)); - } - } - if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE)) { - err = mprotect((void *)((uintptr_t)address + size), vm_page_size, protection); - if (err) { - malloc_printf("*** can't protect(%p) region for postlude guard page at %p\n", - protection, (uintptr_t)address + size); - } - } -} - -static void * -allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label) -{ - // align specifies a desired alignment (as a log) or 0 if no alignment requested - void *vm_addr; - uintptr_t addr = 0, aligned_address; - boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; - boolean_t purgeable = debug_flags & SCALABLE_MALLOC_PURGEABLE; - size_t allocation_size = round_page(size); - size_t delta; - int alloc_flags = VM_MAKE_TAG(vm_page_label); - - if (align) add_guard_pages = 0; // too cumbersome to deal with that - if (!allocation_size) allocation_size = 1 << vm_page_shift; - if (add_guard_pages) allocation_size += 2 * (1 << vm_page_shift); - if (align) allocation_size += (size_t)1 << align; - if (purgeable) alloc_flags |= VM_FLAGS_PURGABLE; - - if (allocation_size < size) // size_t arithmetic wrapped! - return NULL; - - vm_addr = mmap(0 /* addr */, - allocation_size /* size */, - PROT_READ | PROT_WRITE /* prot */, - MAP_ANON | MAP_PRIVATE /* flags */, - alloc_flags /* fd being used to pass "purgeable" and "vm_page_label" */, - 0 /* offset */); - if ((uintptr_t)vm_addr == -1) { - szone_error(szone, 0, "can't allocate region", NULL, "*** mmap(size=%lu) failed (error code=%d)\n", - allocation_size, errno); - return NULL; - } - addr = (uintptr_t)vm_addr; - - if (align) { - aligned_address = (addr + ((uintptr_t)1 << align) - 1) & ~ (((uintptr_t)1 << align) - 1); - if (aligned_address != addr) { - delta = aligned_address - addr; - if (munmap((void *)addr, delta) == -1) - malloc_printf("*** munmap unaligned header failed with %d\n", errno); - addr = aligned_address; - allocation_size -= delta; - } - if (allocation_size > size) { - if (munmap((void *)(addr + size), allocation_size - size) == -1) - malloc_printf("*** munmap unaligned footer failed with %d\n", errno); - } - } - if (add_guard_pages) { - addr += (uintptr_t)1 << vm_page_shift; - protect((void *)addr, size, PROT_NONE, debug_flags); - } - return (void *)addr; -} - -static void * -allocate_pages_securely(szone_t *szone, size_t size, unsigned char align, int vm_page_label) -{ - // align specifies a desired alignment (as a log) or 0 if no alignment requested - void *vm_addr; - uintptr_t addr, aligned_address; - size_t delta, allocation_size = MAX(round_page(size), vm_page_size); - int alloc_flags = VM_MAKE_TAG(vm_page_label); - - if (szone->debug_flags & DISABLE_ASLR) - return allocate_pages(szone, size, align, 0, vm_page_label); - - if (align) - allocation_size += (size_t)1 << align; - - if (allocation_size < size) // size_t arithmetic wrapped! - return NULL; - -retry: - vm_addr = mmap((void *)entropic_address /* kernel finds next available range at or above this address */, - allocation_size /* size */, - PROT_READ | PROT_WRITE /* prot */, - MAP_ANON | MAP_PRIVATE /* flags */, - alloc_flags /* fd being used to pass "vm_page_label" */, - 0 /* offset */); - if (MAP_FAILED == vm_addr) { - szone_error(szone, 0, "can't allocate region securely", NULL, "*** mmap(size=%lu) failed (error code=%d)\n", - size, errno); - return NULL; - } - addr = (uintptr_t)vm_addr; - - // Don't allow allocation to rise above entropic_limit (for tidiness). - if (addr + allocation_size > entropic_limit) { // Exhausted current range? - uintptr_t t = entropic_address; - uintptr_t u = t - ENTROPIC_KABILLION; - - if (u < t) { // provided we don't wrap, unmap and retry, in the expanded entropic range - munmap((void *)addr, allocation_size); - (void)__sync_bool_compare_and_swap(&entropic_address, t, u); // Just one reduction please - goto retry; - } - // fall through to use what we got - } - - if (addr < entropic_address) { // mmap wrapped to find this allocation, expand the entropic range - uintptr_t t = entropic_address; - uintptr_t u = t - ENTROPIC_KABILLION; - if (u < t) - (void)__sync_bool_compare_and_swap(&entropic_address, t, u); // Just one reduction please - // fall through to use what we got - } - - // unmap any excess address range used for alignment padding - if (align) { - aligned_address = (addr + ((uintptr_t)1 << align) - 1) & ~ (((uintptr_t)1 << align) - 1); - if (aligned_address != addr) { - delta = aligned_address - addr; - if (munmap((void *)addr, delta) == -1) - malloc_printf("*** munmap unaligned header failed with %d\n", errno); - addr = aligned_address; - allocation_size -= delta; - } - if (allocation_size > size) { - if (munmap((void *)(addr + size), allocation_size - size) == -1) - malloc_printf("*** munmap unaligned footer failed with %d\n", errno); - } - } - return (void *)addr; -} - -static void -deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags) -{ - int err; - boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; - - if (add_guard_pages) { - addr = (void *)((uintptr_t)addr - (1 << vm_page_shift)); - size += 2 * (1 << vm_page_shift); - } - err = munmap(addr, size); - if ((err == -1) && szone) - szone_error(szone, 0, "Can't deallocate_pages region", addr, NULL); -} - -static int -#if TARGET_OS_EMBEDDED -madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi, uintptr_t *last) -#else -madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi) -#endif -{ - if (pgHi > pgLo) { - size_t len = pgHi - pgLo; - -#if DEBUG_MALLOC - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) - memset((void *)pgLo, 0xed, len); // Scribble on MADV_FREEd memory -#endif - -#if TARGET_OS_EMBEDDED - if (last) { - if (*last == pgLo) - return 0; - - *last = pgLo; - } -#endif - - MAGMALLOC_MADVFREEREGION((void *)szone, (void *)r, (void *)pgLo, len); // DTrace USDT Probe -#if TARGET_OS_EMBEDDED - if (-1 == madvise((void *)pgLo, len, MADV_FREE)) { -#else - if (-1 == madvise((void *)pgLo, len, MADV_FREE_REUSABLE)) { -#endif - /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ -#if DEBUG_MADVISE - szone_error(szone, 0, "madvise_free_range madvise(..., MADV_FREE_REUSABLE) failed", - (void *)pgLo, "length=%d\n", len); -#endif - } - } - return 0; -} - -static kern_return_t -_szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) -{ - *ptr = (void *)address; - return 0; -} - -// Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...] -// pthread_t's are page aligned, (sometimes even in ascending sequence). These hash well. -// See Knuth TAOCP, Vol. 3. -#if __LP64__ -#define HASH_SELF() \ - ((((uintptr_t)pthread_self()) >> vm_page_shift) * 11400714819323198549ULL) >> (64 - szone->num_tiny_magazines_mask_shift) -#else -#define HASH_SELF() \ - ((((uintptr_t)pthread_self()) >> vm_page_shift) * 2654435761UL) >> (32 - szone->num_tiny_magazines_mask_shift) -#endif - -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) -/* - * These commpage routines provide fast access to the logical cpu number - * of the calling processor assuming no pre-emption occurs. - */ - -static INLINE mag_index_t -mag_get_thread_index(szone_t *szone) -{ - if (!__is_threaded) - return 0; - else - return cpu_number() & (TINY_MAX_MAGAZINES - 1); -} - -#else -#warning deriving magazine index from pthread_self() [want processor number] - -static INLINE mag_index_t -mag_get_thread_index(szone_t *szone) -{ - if (!__is_threaded) - return 0; - else if ((pthread_key_t) -1 == szone->cpu_id_key) { // In case pthread_key_create() failed. - return HASH_SELF(); - } else { - mag_index_t idx = (mag_index_t)(intptr_t)pthread_getspecific(szone->cpu_id_key); - - // Has this thread been hinted with a non-zero value [i.e. 1 + cpuid()] ? - // If so, bump down the hint to a zero-based magazine index and return it. - if (idx) { - return idx - 1; - } else { - // No hint available. Contruct a magazine index for this thread ... - idx = HASH_SELF(); - - // bump up the hint to exclude zero and try to memorize it ... - pthread_setspecific(szone->cpu_id_key, (const void *)((uintptr_t)idx + 1)); - - // and return the (zero-based) magazine index. - return idx; - } - } -} -#endif - -static magazine_t * -mag_lock_zine_for_region_trailer(szone_t *szone, magazine_t *magazines, region_trailer_t *trailer, mag_index_t mag_index) -{ - mag_index_t refreshed_index; - magazine_t *mag_ptr = &(magazines[mag_index]); - - // Take the lock on entry. - SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr); - - // Now in the time it took to acquire the lock, the region may have migrated - // from one magazine to another. In which case the magazine lock we obtained - // (namely magazines[mag_index].mag_lock) is stale. If so, keep on tryin' ... - while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment - - SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); - - mag_index = refreshed_index; - mag_ptr = &(magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr); - } - - return mag_ptr; -} - -/******************************************************************************* - * Region hash implementation - * - * This is essentially a duplicate of the existing Large allocator hash, minus - * the ability to remove entries. The two should be combined eventually. - ******************************************************************************/ -#pragma mark region hash - -/* - * hash_lookup_region_no_lock - Scan a hash ring looking for an entry for a - * given region. - * - * FIXME: If consecutive queries of the same region are likely, a one-entry - * cache would likely be a significant performance win here. - */ -static INLINE rgnhdl_t -hash_lookup_region_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) { - size_t index, hash_index; - rgnhdl_t entry; - - if (!num_entries) - return 0; - - // Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...] - // Since the values of (((uintptr_t)r >> HASH_BLOCKS_ALIGN) are (roughly) an ascending sequence of integers, - // this hash works really well. See Knuth TAOCP, Vol. 3. -#if __LP64__ - index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 11400714819323198549ULL) >> (64 - shift); -#else - index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 2654435761UL) >> (32 - shift); -#endif - do { - entry = regions + index; - if (*entry == 0) - return 0; - if (*entry == r) - return entry; - if (++index == num_entries) - index = 0; - } while (index != hash_index); - return 0; -} - -/* - * hash_region_insert_no_lock - Insert a region into the hash ring. - */ -static void -hash_region_insert_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) { - size_t index, hash_index; - rgnhdl_t entry; - - // Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...] - // Since the values of (((uintptr_t)r >> HASH_BLOCKS_ALIGN) are (roughly) an ascending sequence of integers, - // this hash works really well. See Knuth TAOCP, Vol. 3. -#if __LP64__ - index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 11400714819323198549ULL) >> (64 - shift); -#else - index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 2654435761UL) >> (32 - shift); -#endif - do { - entry = regions + index; - if (*entry == HASHRING_OPEN_ENTRY || *entry == HASHRING_REGION_DEALLOCATED) { - *entry = r; - return; - } - if (++index == num_entries) - index = 0; - } while (index != hash_index); -} - -/* - * hash_regions_alloc_no_lock - Allocate space for a number of entries. This - * must be a VM allocation as to avoid recursing between allocating a new small - * region, and asking the small region to allocate space for the new list of - * regions. - */ -static region_t * -hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries) -{ - size_t size = num_entries * sizeof(region_t); - - return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC); -} - -/* - * hash_regions_grow_no_lock - Grow the hash ring, and rehash the entries. - * Return the new region and new size to update the szone. Do not deallocate - * the old entries since someone may still be allocating them. - */ -static region_t * -hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, size_t *mutable_shift, - size_t *new_size) -{ - // double in size and allocate memory for the regions - *new_size = old_size + old_size; - *mutable_shift = *mutable_shift + 1; - region_t *new_regions = hash_regions_alloc_no_lock(szone, *new_size); - - // rehash the entries into the new list - size_t index; - for (index = 0; index < old_size; ++index) { - region_t r = regions[index]; - if (r != HASHRING_OPEN_ENTRY && r != HASHRING_REGION_DEALLOCATED) - hash_region_insert_no_lock(new_regions, *new_size, *mutable_shift, r); - } - return new_regions; -} - -/********************* FREE LIST UTILITIES ************************/ - -// A free list entry is comprised of a pair of pointers, previous and next. -// These are used to implement a doubly-linked list, which permits efficient -// extraction. -// -// Because the free list entries are previously freed objects, a misbehaved -// program may write to a pointer after it has called free() on that pointer, -// either by dereference or buffer overflow from an adjacent pointer. This write -// would then corrupt the free list's previous and next pointers, leading to a -// crash. In order to detect this case, we take advantage of the fact that -// malloc'd pointers are known to be at least 16 byte aligned, and thus have -// at least 4 trailing zero bits. -// -// When an entry is added to the free list, a checksum of the previous and next -// pointers is calculated and written to the high four bits of the respective -// pointers. Upon detection of an invalid checksum, an error is logged and NULL -// is returned. Since all code which un-checksums pointers checks for a NULL -// return, a potentially crashing or malicious dereference is avoided at the -// cost of leaking the corrupted block, and any subsequent blocks on the free -// list of that size. - -static NOINLINE void -free_list_checksum_botch(szone_t *szone, free_list_t *ptr) -{ - szone_error(szone, 1, "incorrect checksum for freed object " - "- object was probably modified after being freed.", ptr, NULL); -} - -static INLINE uintptr_t free_list_gen_checksum(uintptr_t ptr) -{ - uint8_t chk; - - chk = (unsigned char)(ptr >> 0); - chk += (unsigned char)(ptr >> 8); - chk += (unsigned char)(ptr >> 16); - chk += (unsigned char)(ptr >> 24); -#if __LP64__ - chk += (unsigned char)(ptr >> 32); - chk += (unsigned char)(ptr >> 40); - chk += (unsigned char)(ptr >> 48); - chk += (unsigned char)(ptr >> 56); -#endif - - return chk & (uintptr_t)0xF; -} - -#define NYBBLE 4 -#if __LP64__ -#define ANTI_NYBBLE (64 - NYBBLE) -#else -#define ANTI_NYBBLE (32 - NYBBLE) -#endif - -static INLINE uintptr_t -free_list_checksum_ptr(szone_t *szone, void *ptr) -{ - uintptr_t p = (uintptr_t)ptr; - return (p >> NYBBLE) | (free_list_gen_checksum(p ^ szone->cookie) << ANTI_NYBBLE); // compiles to rotate instruction -} - -static INLINE void * -free_list_unchecksum_ptr(szone_t *szone, ptr_union *ptr) -{ - ptr_union p; - uintptr_t t = ptr->u; - - t = (t << NYBBLE) | (t >> ANTI_NYBBLE); // compiles to rotate instruction - p.u = t & ~(uintptr_t)0xF; - - if ((t & (uintptr_t)0xF) != free_list_gen_checksum(p.u ^ szone->cookie)) - { - free_list_checksum_botch(szone, (free_list_t *)ptr); - return NULL; - } - return p.p; -} - -#undef ANTI_NYBBLE -#undef NYBBLE - -static unsigned -free_list_count(szone_t *szone, free_list_t *ptr) -{ - unsigned count = 0; - - while (ptr) { - count++; - ptr = free_list_unchecksum_ptr(szone, &ptr->next); - } - return count; -} - -static INLINE void -recirc_list_extract(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) -{ - // excise node from list - if (NULL == node->prev) - mag_ptr->firstNode = node->next; - else - node->prev->next = node->next; - - if (NULL == node->next) - mag_ptr->lastNode = node->prev; - else - node->next->prev = node->prev; - - mag_ptr->recirculation_entries--; -} - -static INLINE void -recirc_list_splice_last(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) -{ - if (NULL == mag_ptr->lastNode) { - mag_ptr->firstNode = node; - node->prev = NULL; - } else { - node->prev = mag_ptr->lastNode; - mag_ptr->lastNode->next = node; - } - mag_ptr->lastNode = node; - node->next = NULL; - node->recirc_suitable = FALSE; - mag_ptr->recirculation_entries++; -} - -static INLINE void -recirc_list_splice_first(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) -{ - if (NULL == mag_ptr->firstNode) { - mag_ptr->lastNode = node; - node->next = NULL; - } else { - node->next = mag_ptr->firstNode; - mag_ptr->firstNode->prev = node; - } - mag_ptr->firstNode = node; - node->prev = NULL; - node->recirc_suitable = FALSE; - mag_ptr->recirculation_entries++; -} - -/* Macros used to manipulate the uint32_t quantity mag_bitmap. */ - -/* BITMAPV variants are used by tiny. */ -#if defined(__LP64__) -// assert(NUM_SLOTS == 64) in which case (slot >> 5) is either 0 or 1 -#define BITMAPV_SET(bitmap,slot) (bitmap[(slot) >> 5] |= 1 << ((slot) & 31)) -#define BITMAPV_CLR(bitmap,slot) (bitmap[(slot) >> 5] &= ~ (1 << ((slot) & 31))) -#define BITMAPV_BIT(bitmap,slot) ((bitmap[(slot) >> 5] >> ((slot) & 31)) & 1) -#define BITMAPV_CTZ(bitmap) (__builtin_ctzl(bitmap)) -#else -// assert(NUM_SLOTS == 32) in which case (slot >> 5) is always 0, so code it that way -#define BITMAPV_SET(bitmap,slot) (bitmap[0] |= 1 << (slot)) -#define BITMAPV_CLR(bitmap,slot) (bitmap[0] &= ~ (1 << (slot))) -#define BITMAPV_BIT(bitmap,slot) ((bitmap[0] >> (slot)) & 1) -#define BITMAPV_CTZ(bitmap) (__builtin_ctz(bitmap)) -#endif - -/* BITMAPN is used by small. (slot >> 5) takes on values from 0 to 7. */ -#define BITMAPN_SET(bitmap,slot) (bitmap[(slot) >> 5] |= 1 << ((slot) & 31)) -#define BITMAPN_CLR(bitmap,slot) (bitmap[(slot) >> 5] &= ~ (1 << ((slot) & 31))) -#define BITMAPN_BIT(bitmap,slot) ((bitmap[(slot) >> 5] >> ((slot) & 31)) & 1) - -/* returns bit # of least-significant one bit, starting at 0 (undefined if !bitmap) */ -#define BITMAP32_CTZ(bitmap) (__builtin_ctz(bitmap[0])) - -/********************* TINY FREE LIST UTILITIES ************************/ - -// We encode the meta-headers as follows: -// Each quantum has an associated set of 2 bits: -// block_header when 1 says this block is the beginning of a block -// in_use when 1 says this block is in use -// so a block in use of size 3 is 1-1 0-X 0-X -// for a free block TINY_FREE_SIZE(ptr) carries the size and the bits are 1-0 X-X X-X -// for a block middle the bits are 0-0 - -// We store the meta-header bit arrays by interleaving them 32 bits at a time. -// Initial 32 bits of block_header, followed by initial 32 bits of in_use, followed -// by next 32 bits of block_header, followed by next 32 bits of in_use, etc. -// This localizes memory references thereby reducing cache and TLB pressures. - -static INLINE void -BITARRAY_SET(uint32_t *bits, msize_t index) -{ - // index >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array - // (index >> 5) << 1 identifies the uint32_t allowing for the actual interleaving - bits[(index >> 5) << 1] |= (1 << (index & 31)); -} - -static INLINE void -BITARRAY_CLR(uint32_t *bits, msize_t index) -{ - bits[(index >> 5) << 1] &= ~(1 << (index & 31)); -} - -static INLINE boolean_t -BITARRAY_BIT(uint32_t *bits, msize_t index) -{ - return ((bits[(index >> 5) << 1]) >> (index & 31)) & 1; -} - -#if 0 -static INLINE void bitarray_mclr(uint32_t *bits, unsigned start, unsigned end) ALWAYSINLINE; - -static INLINE void -bitarray_mclr(uint32_t *bits, unsigned start, unsigned end) -{ - // start >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array - // (start >> 5) << 1 identifies the uint32_t allowing for the actual interleaving - uint32_t *addr = bits + ((start >> 5) << 1); - - uint32_t span = end - start; - start = start & 31; - end = start + span; - - if (end > 31) { - addr[0] &= (0xFFFFFFFFU >> (31 - start)) >> 1; - addr[2] &= (0xFFFFFFFFU << (end - 32)); - } else { - unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1; - mask |= (0xFFFFFFFFU << end); - addr[0] &= mask; - } -} -#endif - -/* - * Obtain the size of a free tiny block (in msize_t units). - */ -static msize_t -get_tiny_free_size(const void *ptr) -{ - void *next_block = (void *)((uintptr_t)ptr + TINY_QUANTUM); - void *region_end = TINY_REGION_END(TINY_REGION_FOR_PTR(ptr)); - - // check whether the next block is outside the tiny region or a block header - // if so, then the size of this block is one, and there is no stored size. - if (next_block < region_end) - { - uint32_t *next_header = TINY_BLOCK_HEADER_FOR_PTR(next_block); - msize_t next_index = TINY_INDEX_FOR_PTR(next_block); - - if (!BITARRAY_BIT(next_header, next_index)) - return TINY_FREE_SIZE(ptr); - } - return 1; -} - -/* - * Get the size of the previous free block, which is stored in the last two - * bytes of the block. If the previous block is not free, then the result is - * undefined. - */ -static msize_t -get_tiny_previous_free_msize(const void *ptr) -{ - // check whether the previous block is in the tiny region and a block header - // if so, then the size of the previous block is one, and there is no stored - // size. - if (ptr != TINY_REGION_FOR_PTR(ptr)) - { - void *prev_block = (void *)((uintptr_t)ptr - TINY_QUANTUM); - uint32_t *prev_header = TINY_BLOCK_HEADER_FOR_PTR(prev_block); - msize_t prev_index = TINY_INDEX_FOR_PTR(prev_block); - if (BITARRAY_BIT(prev_header, prev_index)) - return 1; - return TINY_PREVIOUS_MSIZE(ptr); - } - // don't read possibly unmapped memory before the beginning of the region - return 0; -} - -static INLINE msize_t -get_tiny_meta_header(const void *ptr, boolean_t *is_free) -{ - // returns msize and is_free - // may return 0 for the msize component (meaning 65536) - uint32_t *block_header; - msize_t index; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - index = TINY_INDEX_FOR_PTR(ptr); - - msize_t midx = (index >> 5) << 1; - uint32_t mask = 1 << (index & 31); - *is_free = 0; - if (0 == (block_header[midx] & mask)) // if (!BITARRAY_BIT(block_header, index)) - return 0; - if (0 == (block_header[midx + 1] & mask)) { // if (!BITARRAY_BIT(in_use, index)) - *is_free = 1; - return get_tiny_free_size(ptr); - } - - // index >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array - // (index >> 5) << 1 identifies the uint32_t allowing for the actual interleaving -#if defined(__LP64__) - // The return value, msize, is computed as the distance to the next 1 bit in block_header. - // That's guaranteed to be somewhwere in the next 64 bits. And those bits could span three - // uint32_t block_header elements. Collect the bits into a single uint64_t and measure up with ffsl. - uint32_t *addr = ((uint32_t *)block_header) + ((index >> 5) << 1); - uint32_t bitidx = index & 31; - uint64_t word_lo = addr[0]; - uint64_t word_mid = addr[2]; - uint64_t word_hi = addr[4]; - uint64_t word_lomid = (word_lo >> bitidx) | (word_mid << (32 - bitidx)); - uint64_t word = bitidx ? word_lomid | (word_hi << (64 - bitidx)) : word_lomid; - uint32_t result = __builtin_ffsl(word >> 1); -#else - // The return value, msize, is computed as the distance to the next 1 bit in block_header. - // That's guaranteed to be somwhwere in the next 32 bits. And those bits could span two - // uint32_t block_header elements. Collect the bits into a single uint32_t and measure up with ffs. - uint32_t *addr = ((uint32_t *)block_header) + ((index >> 5) << 1); - uint32_t bitidx = index & 31; - uint32_t word = bitidx ? (addr[0] >> bitidx) | (addr[2] << (32 - bitidx)) : addr[0]; - uint32_t result = __builtin_ffs(word >> 1); -#endif - return result; -} - -static INLINE void -set_tiny_meta_header_in_use(const void *ptr, msize_t msize) -{ - uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - msize_t index = TINY_INDEX_FOR_PTR(ptr); - msize_t clr_msize = msize - 1; - msize_t midx = (index >> 5) << 1; - uint32_t val = (1 << (index & 31)); - -#if DEBUG_MALLOC - if (msize >= NUM_TINY_SLOTS) - malloc_printf("set_tiny_meta_header_in_use() invariant broken %p %d\n", ptr, msize); - if ((unsigned)index + (unsigned)msize > 0x10000) - malloc_printf("set_tiny_meta_header_in_use() invariant broken (2) %p %d\n", ptr, msize); -#endif - - block_header[midx] |= val; // BITARRAY_SET(block_header, index); - block_header[midx + 1] |= val; // BITARRAY_SET(in_use, index); - - // bitarray_mclr(block_header, index, end_bit); - // bitarray_mclr(in_use, index, end_bit); - - index++; - midx = (index >> 5) << 1; - - unsigned start = index & 31; - unsigned end = start + clr_msize; - -#if defined(__LP64__) - if (end > 63) { - unsigned mask0 = (0xFFFFFFFFU >> (31 - start)) >> 1; - unsigned mask1 = (0xFFFFFFFFU << (end - 64)); - block_header[midx + 0] &= mask0; // clear header - block_header[midx + 1] &= mask0; // clear in_use - block_header[midx + 2] = 0; // clear header - block_header[midx + 3] = 0; // clear in_use - block_header[midx + 4] &= mask1; // clear header - block_header[midx + 5] &= mask1; // clear in_use - } else -#endif - if (end > 31) { - unsigned mask0 = (0xFFFFFFFFU >> (31 - start)) >> 1; - unsigned mask1 = (0xFFFFFFFFU << (end - 32)); - block_header[midx + 0] &= mask0; - block_header[midx + 1] &= mask0; - block_header[midx + 2] &= mask1; - block_header[midx + 3] &= mask1; - } else { - unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1; - mask |= (0xFFFFFFFFU << end); - block_header[midx + 0] &= mask; - block_header[midx + 1] &= mask; - } - - // we set the block_header bit for the following block to reaffirm next block is a block - index += clr_msize; - midx = (index >> 5) << 1; - val = (1 << (index & 31)); - block_header[midx] |= val; // BITARRAY_SET(block_header, (index+clr_msize)); -#if DEBUG_MALLOC - { - boolean_t ff; - msize_t mf; - - mf = get_tiny_meta_header(ptr, &ff); - if (msize != mf) { - malloc_printf("setting header for tiny in_use %p : %d\n", ptr, msize); - malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff); - } - } -#endif -} - -static INLINE void -set_tiny_meta_header_in_use_1(const void *ptr) // As above with msize == 1 -{ - uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - msize_t index = TINY_INDEX_FOR_PTR(ptr); - msize_t midx = (index >> 5) << 1; - uint32_t val = (1 << (index & 31)); - - block_header[midx] |= val; // BITARRAY_SET(block_header, index); - block_header[midx + 1] |= val; // BITARRAY_SET(in_use, index); - - index++; - midx = (index >> 5) << 1; - val = (1 << (index & 31)); - - block_header[midx] |= val; // BITARRAY_SET(block_header, (index+clr_msize)) -} - -static INLINE void -set_tiny_meta_header_middle(const void *ptr) -{ - // indicates this block is in the middle of an in use block - uint32_t *block_header; - uint32_t *in_use; - msize_t index; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); - - BITARRAY_CLR(block_header, index); - BITARRAY_CLR(in_use, index); -} - -static INLINE void -set_tiny_meta_header_free(const void *ptr, msize_t msize) -{ - // !msize is acceptable and means 65536 - uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - msize_t index = TINY_INDEX_FOR_PTR(ptr); - msize_t midx = (index >> 5) << 1; - uint32_t val = (1 << (index & 31)); - -#if DEBUG_MALLOC - if ((unsigned)index + (unsigned)msize > 0x10000) { - malloc_printf("setting header for tiny free %p msize too large: %d\n", ptr, msize); - } -#endif - - block_header[midx] |= val; // BITARRAY_SET(block_header, index); - block_header[midx + 1] &= ~val; // BITARRAY_CLR(in_use, index); - - // mark the end of this block if msize is > 1. For msize == 0, the whole - // region is free, so there is no following block. For msize == 1, there is - // no space to write the size on 64 bit systems. The size for 1 quantum - // blocks is computed from the metadata bitmaps. - if (msize > 1) { - void *follower = FOLLOWING_TINY_PTR(ptr, msize); - TINY_PREVIOUS_MSIZE(follower) = msize; - TINY_FREE_SIZE(ptr) = msize; - } - if (msize == 0) { - TINY_FREE_SIZE(ptr) = msize; - } -#if DEBUG_MALLOC - boolean_t ff; - msize_t mf = get_tiny_meta_header(ptr, &ff); - if ((msize != mf) || !ff) { - malloc_printf("setting header for tiny free %p : %u\n", ptr, msize); - malloc_printf("reading header for tiny %p : %u %u\n", ptr, mf, ff); - } -#endif -} - -static INLINE boolean_t -tiny_meta_header_is_free(const void *ptr) -{ - uint32_t *block_header; - uint32_t *in_use; - msize_t index; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); - if (!BITARRAY_BIT(block_header, index)) - return 0; - return !BITARRAY_BIT(in_use, index); -} - -static INLINE void * -tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) -{ - // returns the previous block, assuming and verifying it's free - uint32_t *block_header; - uint32_t *in_use; - msize_t index; - msize_t previous_msize; - msize_t previous_index; - void *previous_ptr; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); - - if (!index) - return NULL; - if ((previous_msize = get_tiny_previous_free_msize(ptr)) > index) - return NULL; - - previous_index = index - previous_msize; - previous_ptr = (void *)((uintptr_t)TINY_REGION_FOR_PTR(ptr) + TINY_BYTES_FOR_MSIZE(previous_index)); - if (!BITARRAY_BIT(block_header, previous_index)) - return NULL; - if (BITARRAY_BIT(in_use, previous_index)) - return NULL; - if (get_tiny_free_size(previous_ptr) != previous_msize) - return NULL; - - // conservative check did match true check - *prev_msize = previous_msize; - return previous_ptr; -} - -/* - * Adds an item to the proper free list, and also marks the meta-header of the - * block properly. - * Assumes szone has been locked - */ -static void -tiny_free_list_add_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize) -{ - grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; - free_list_t *free_ptr = ptr; - free_list_t *free_head = tiny_mag_ptr->mag_free_list[slot]; - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } - if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { - szone_error(szone, 1, "tiny_free_list_add_ptr: Unaligned ptr", ptr, NULL); - } -#endif - set_tiny_meta_header_free(ptr, msize); - if (free_head) { -#if DEBUG_MALLOC - if (free_list_unchecksum_ptr(szone, &free_head->previous)) { - szone_error(szone, 1, "tiny_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr, - "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, (void *)free_head, free_head->previous.p); - } - if (! tiny_meta_header_is_free(free_head)) { - szone_error(szone, 1, "tiny_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, - "ptr=%p slot=%d free_head=%p\n", ptr, slot, (void *)free_head); - } -#endif - free_head->previous.u = free_list_checksum_ptr(szone, free_ptr); - } else { - BITMAPV_SET(tiny_mag_ptr->mag_bitmap, slot); - } - free_ptr->previous.u = free_list_checksum_ptr(szone, NULL); - free_ptr->next.u = free_list_checksum_ptr(szone, free_head); - - tiny_mag_ptr->mag_free_list[slot] = free_ptr; -} - -/* - * Removes the item pointed to by ptr in the proper free list. - * Assumes szone has been locked - */ -static void -tiny_free_list_remove_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize) -{ - grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; - free_list_t *free_ptr = ptr, *next, *previous; - - next = free_list_unchecksum_ptr(szone, &free_ptr->next); - previous = free_list_unchecksum_ptr(szone, &free_ptr->previous); - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } -#endif - if (!previous) { - // The block to remove is the head of the free list -#if DEBUG_MALLOC - if (tiny_mag_ptr->mag_free_list[slot] != ptr) { - szone_error(szone, 1, "tiny_free_list_remove_ptr: Internal invariant broken (tiny_mag_ptr->mag_free_list[slot])", ptr, - "ptr=%p slot=%d msize=%d tiny_mag_ptr->mag_free_list[slot]=%p\n", - ptr, slot, msize, (void *)tiny_mag_ptr->mag_free_list[slot]); - return; - } -#endif - tiny_mag_ptr->mag_free_list[slot] = next; - if (!next) BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot); - } else { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - previous->next = free_ptr->next; - } - if (next) { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - next->previous = free_ptr->previous; - } -} - -/* - * tiny_region_for_ptr_no_lock - Returns the tiny region containing the pointer, - * or NULL if not found. - */ -static INLINE region_t -tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) -{ - rgnhdl_t r = hash_lookup_region_no_lock(szone->tiny_region_generation->hashed_regions, - szone->tiny_region_generation->num_regions_allocated, - szone->tiny_region_generation->num_regions_allocated_shift, - TINY_REGION_FOR_PTR(ptr)); - return r ? *r : r; -} - -static void -tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr) { - void *last_block, *previous_block; - uint32_t *last_header; - msize_t last_msize, previous_msize, last_index; - - // It is possible that the block prior to the last block in the region has - // been free'd, but was not coalesced with the free bytes at the end of the - // block, since we treat the bytes at the end of the region as "in use" in - // the meta headers. Attempt to coalesce the last block with the previous - // block, so we don't violate the "no consecutive free blocks" invariant. - // - // FIXME: Need to investigate how much work would be required to increase - // 'mag_bytes_free_at_end' when freeing the preceding block, rather - // than performing this workaround. - // - - if (tiny_mag_ptr->mag_bytes_free_at_end) { - last_block = (void *) - ((uintptr_t)TINY_REGION_END(tiny_mag_ptr->mag_last_region) - tiny_mag_ptr->mag_bytes_free_at_end); - last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end); - last_header = TINY_BLOCK_HEADER_FOR_PTR(last_block); - last_index = TINY_INDEX_FOR_PTR(last_block); - - // Before anything we transform any remaining mag_bytes_free_at_end into a - // regular free block. We take special care here to update the bitfield - // information, since we are bypassing the normal free codepath. If there - // is more than one quanta worth of memory in mag_bytes_free_at_end, then - // there will be two block headers: - // 1) header for the free space at end, msize = 1 - // 2) header inserted by set_tiny_meta_header_in_use after block - // We must clear the second one so that when the free block's size is - // queried, we do not think the block is only 1 quantum in size because - // of the second set header bit. - if (last_index != (NUM_TINY_BLOCKS - 1)) - BITARRAY_CLR(last_header, (last_index + 1)); - - previous_block = tiny_previous_preceding_free(last_block, &previous_msize); - if (previous_block) { - set_tiny_meta_header_middle(last_block); - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, previous_block, previous_msize); - last_block = previous_block; - last_msize += previous_msize; - } - - // splice last_block into the free list - tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize); - tiny_mag_ptr->mag_bytes_free_at_end = 0; - } - -#if ASLR_INTERNAL - // Coalesce the big free block at start with any following free blocks - if (tiny_mag_ptr->mag_bytes_free_at_start) { - last_block = TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region); - last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start); - - void *next_block = (void *) ((uintptr_t)last_block + tiny_mag_ptr->mag_bytes_free_at_start); - - // clear the in use bit we were using to mark the end of the big start block - set_tiny_meta_header_middle((uintptr_t)next_block - TINY_QUANTUM); - - // Coalesce the big start block with any following free blocks - if (tiny_meta_header_is_free(next_block)) { - msize_t next_msize = get_tiny_free_size(next_block); - set_tiny_meta_header_middle(next_block); - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); - last_msize += next_msize; - } - - // splice last_block into the free list - tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize); - tiny_mag_ptr->mag_bytes_free_at_start = 0; - } -#endif - - tiny_mag_ptr->mag_last_region = NULL; -} - -static int -tiny_free_detach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r) { - uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)TINY_REGION_END(r); - boolean_t is_free; - msize_t msize; - int total_alloc = 0; - - while (current < limit) { - msize = get_tiny_meta_header((void *)current, &is_free); - if (is_free && !msize && (current == start)) { - // first block is all free - break; - } - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_detach_region error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, (void *)current, msize); - } else { - total_alloc++; - } - current += TINY_BYTES_FOR_MSIZE(msize); - } - return total_alloc; -} - -static size_t -tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r) { - uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)TINY_REGION_END(r); - boolean_t is_free; - msize_t msize; - size_t total_alloc = 0; - - while (current < limit) { - msize = get_tiny_meta_header((void *)current, &is_free); - if (is_free && !msize && (current == start)) { - // first block is all free - break; - } - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_reattach_region error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - tiny_free_list_add_ptr(szone, tiny_mag_ptr, (void *)current, msize); - } else { - total_alloc += TINY_BYTES_FOR_MSIZE(msize); - } - current += TINY_BYTES_FOR_MSIZE(msize); - } - return total_alloc; -} - -typedef struct { - uint8_t pnum, size; -} tiny_pg_pair_t; - -static void NOINLINE /* want private stack frame for automatic array */ -tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) { - uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)TINY_REGION_END(r); - boolean_t is_free; - msize_t msize; - tiny_pg_pair_t advisory[((TINY_REGION_PAYLOAD_BYTES + vm_page_size - 1) >> vm_page_shift) >> 1]; // 256bytes stack allocated - int advisories = 0; - - // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list - // management data. - while (current < limit) { - msize = get_tiny_meta_header((void *)current, &is_free); - if (is_free && !msize && (current == start)) { - // first block is all free -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_scan_madvise_free first block is all free! %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - uintptr_t pgLo = round_page(start + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page(start + TINY_REGION_SIZE - sizeof(msize_t)); - - if (pgLo < pgHi) { - advisory[advisories].pnum = (pgLo - start) >> vm_page_shift; - advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift; - advisories++; - } - break; - } - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_scan_madvise_free error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - uintptr_t pgLo = round_page(current + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); - - if (pgLo < pgHi) { - advisory[advisories].pnum = (pgLo - start) >> vm_page_shift; - advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift; - advisories++; - } - } - current += TINY_BYTES_FOR_MSIZE(msize); - } - - if (advisories > 0) { - int i; - - // So long as the following hold for this region: - // (1) No malloc()'s are ever performed from the depot (hence free pages remain free,) - // (2) The region is not handed over to a per-CPU magazine (where malloc()'s could be performed), - // (3) The entire region is not mumap()'d (so the madvise's are applied to the intended addresses), - // then the madvise opportunities collected just above can be applied outside all locks. - // (1) is ensured by design, (2) and (3) are ensured by bumping the globally visible counter node->pinned_to_depot. - - OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot)); - SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); - for (i = 0; i < advisories; ++i) { - uintptr_t addr = (advisory[i].pnum << vm_page_shift) + start; - size_t size = advisory[i].size << vm_page_shift; - -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, r, addr, addr + size, NULL); -#else - madvise_free_range(szone, r, addr, addr + size); -#endif - } - SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); - OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot)); - } -} - -static region_t -tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node) -{ - if (0 < node->bytes_used || - 0 < node->pinned_to_depot || - depot_ptr->recirculation_entries < (szone->num_tiny_magazines * 2)) { - return NULL; - } - - // disconnect node from Depot - recirc_list_extract(szone, depot_ptr, node); - - // Iterate the region pulling its free entries off the (locked) Depot's free list - region_t sparse_region = TINY_REGION_FOR_PTR(node); - int objects_in_use = tiny_free_detach_region(szone, depot_ptr, sparse_region); - - if (0 == objects_in_use) { - // Invalidate the hash table entry for this region with HASHRING_REGION_DEALLOCATED. - // Using HASHRING_REGION_DEALLOCATED preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not. - rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->tiny_region_generation->hashed_regions, - szone->tiny_region_generation->num_regions_allocated, - szone->tiny_region_generation->num_regions_allocated_shift, sparse_region); - if (NULL == pSlot) { - szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region); - return NULL; - } - *pSlot = HASHRING_REGION_DEALLOCATED; - depot_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; - __sync_fetch_and_add( &(szone->num_tiny_regions_dealloc), 1); // Atomically increment num_tiny_regions_dealloc - - // Caller will transfer ownership of the region back to the OS with no locks held - MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, TINY_REGION_SIZE); // DTrace USDT Probe - return sparse_region; - } else { - szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use); - return NULL; - } -} - -static boolean_t -tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index) -{ - // The entire magazine crossed the "emptiness threshold". Transfer a region - // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e - // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. - region_trailer_t *node = tiny_mag_ptr->firstNode; - - while (node && !node->recirc_suitable) { - node = node->next; - } - - if (NULL == node) { -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_do_recirc_to_depot end of list\n"); -#endif - return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - } - - region_t sparse_region = TINY_REGION_FOR_PTR(node); - - // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start - if (sparse_region == tiny_mag_ptr->mag_last_region && (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start)) { - tiny_finalize_region(szone, tiny_mag_ptr); - } - - // disconnect "suitable" node from magazine - recirc_list_extract(szone, tiny_mag_ptr, node); - - // Iterate the region pulling its free entries off its (locked) magazine's free list - int objects_in_use = tiny_free_detach_region(szone, tiny_mag_ptr, sparse_region); - magazine_t *depot_ptr = &(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); - - // hand over the region to the (locked) Depot - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - // this will cause tiny_free_list_add_ptr called by tiny_free_reattach_region to use - // the depot as its target magazine, rather than magazine formerly associated with sparse_region - MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX; - node->pinned_to_depot = 0; - - // Iterate the region putting its free entries on Depot's free list - size_t bytes_inplay = tiny_free_reattach_region(szone, depot_ptr, sparse_region); - - tiny_mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; - tiny_mag_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; - tiny_mag_ptr->mag_num_objects -= objects_in_use; - - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); // Unlock the originating magazine - - depot_ptr->mag_num_bytes_in_objects += bytes_inplay; - depot_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; - depot_ptr->mag_num_objects += objects_in_use; - - // connect to Depot as last node - recirc_list_splice_last(szone, depot_ptr, node); - - MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE, - (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe - - // Mark free'd dirty pages with MADV_FREE to reduce memory pressure - tiny_free_scan_madvise_free(szone, depot_ptr, sparse_region); - - // If the region is entirely empty vm_deallocate() it outside the depot lock - region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, depot_ptr, node); - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - if (r_dealloc) - deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0); - return FALSE; // Caller need not unlock the originating magazine -} - -static region_t -tiny_find_msize_region(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - free_list_t *ptr; - grain_t slot = msize - 1; - free_list_t **free_list = tiny_mag_ptr->mag_free_list; - free_list_t **the_slot = free_list + slot; - free_list_t **limit; -#if defined(__LP64__) - uint64_t bitmap; -#else - uint32_t bitmap; -#endif - // Assumes we've locked the magazine - CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__); - - // Look for an exact match by checking the freelist for this msize. - ptr = *the_slot; - if (ptr) - return TINY_REGION_FOR_PTR(ptr); - - // Mask off the bits representing slots holding free blocks smaller than the - // size we need. If there are no larger free blocks, try allocating from - // the free space at the end of the tiny region. -#if defined(__LP64__) - bitmap = ((uint64_t *)(tiny_mag_ptr->mag_bitmap))[0] & ~ ((1ULL << slot) - 1); -#else - bitmap = tiny_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1); -#endif - if (!bitmap) - return NULL; - - slot = BITMAPV_CTZ(bitmap); - limit = free_list + NUM_TINY_SLOTS - 1; - free_list += slot; - - if (free_list < limit) { - ptr = *free_list; - if (ptr) - return TINY_REGION_FOR_PTR(ptr); - else { - /* Shouldn't happen. Fall through to look at last slot. */ -#if DEBUG_MALLOC - malloc_printf("in tiny_find_msize_region(), mag_bitmap out of sync, slot=%d\n",slot); -#endif - } - } - - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than (NUM_TINY_SLOTS - 1) * tiny quantum size. - ptr = *limit; - if (ptr) - return TINY_REGION_FOR_PTR(ptr); - - return NULL; -} - -static boolean_t -tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - magazine_t *depot_ptr = &(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); - - /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ - if (szone->num_tiny_magazines == 1) // Uniprocessor, single magazine, so no recirculation necessary - return 0; - -#if DEBUG_MALLOC - if (DEPOT_MAGAZINE_INDEX == mag_index) { - szone_error(szone, 1, "tiny_get_region_from_depot called for magazine index -1", NULL, NULL); - return 0; - } -#endif - - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - - // Appropriate a Depot'd region that can satisfy requested msize. - region_trailer_t *node; - region_t sparse_region; - - while (1) { - sparse_region = tiny_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); - if (NULL == sparse_region) { // Depot empty? - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - return 0; - } - - node = REGION_TRAILER_FOR_TINY_REGION(sparse_region); - if (0 >= node->pinned_to_depot) - break; - - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - pthread_yield_np(); - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - } - - // disconnect node from Depot - recirc_list_extract(szone, depot_ptr, node); - - // Iterate the region pulling its free entries off the (locked) Depot's free list - int objects_in_use = tiny_free_detach_region(szone, depot_ptr, sparse_region); - - // Transfer ownership of the region - MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = mag_index; - node->pinned_to_depot = 0; - - // Iterate the region putting its free entries on its new (locked) magazine's free list - size_t bytes_inplay = tiny_free_reattach_region(szone, tiny_mag_ptr, sparse_region); - - depot_ptr->mag_num_bytes_in_objects -= bytes_inplay; - depot_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; - depot_ptr->mag_num_objects -= objects_in_use; - - tiny_mag_ptr->mag_num_bytes_in_objects += bytes_inplay; - tiny_mag_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; - tiny_mag_ptr->mag_num_objects += objects_in_use; - - // connect to magazine as first node - recirc_list_splice_first(szone, tiny_mag_ptr, node); - - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - - // madvise() outside the Depot lock -#if TARGET_OS_EMBEDDED - if (node->failedREUSE) { -#else - if (node->failedREUSE || - -1 == madvise((void *)sparse_region, TINY_REGION_PAYLOAD_BYTES, MADV_FREE_REUSE)) { -#endif - /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ -#if DEBUG_MADVISE - szone_error(szone, 0, "tiny_get_region_from_depot madvise(..., MADV_FREE_REUSE) failed", - sparse_region, "length=%d\n", TINY_REGION_PAYLOAD_BYTES); -#endif - node->failedREUSE = TRUE; - } - - MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE, - (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe - - return 1; -} - -#define K 1.5 // headroom measured in number of 1Mb regions -#define DENSITY_THRESHOLD(a) \ - ((a) - ((a) >> 2)) // "Emptiness" f = 0.25, so "Density" is (1 - f)*a. Generally: ((a) - ((a) >> -log2(f))) - -static INLINE boolean_t -tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, - msize_t msize) -{ - void *original_ptr = ptr; - size_t original_size = TINY_BYTES_FOR_MSIZE(msize); - void *next_block = ((unsigned char *)ptr + original_size); - msize_t previous_msize, next_msize; - void *previous; - free_list_t *big_free_block; - free_list_t *after_next_block; - free_list_t *before_next_block; - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } - if (!msize) { - szone_error(szone, 1, "trying to free tiny block that is too small", ptr, - "in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } -#endif - - // We try to coalesce this block with the preceeding one - previous = tiny_previous_preceding_free(ptr, &previous_msize); - if (previous) { -#if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone,previous)) { - malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); - } -#endif - - // clear the meta_header since this is no longer the start of a block - set_tiny_meta_header_middle(ptr); - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, previous, previous_msize); - ptr = previous; - msize += previous_msize; - } - // We try to coalesce with the next block - if ((next_block < TINY_REGION_END(region)) && tiny_meta_header_is_free(next_block)) { - next_msize = get_tiny_free_size(next_block); -#if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone, next_block)) { - malloc_printf("in tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n", - ptr, msize, next_block, next_msize); - } -#endif - // If we are coalescing with the next block, and the next block is in - // the last slot of the free list, then we optimize this case here to - // avoid removing next_block from the slot (NUM_TINY_SLOTS - 1) and then adding ptr back - // to slot (NUM_TINY_SLOTS - 1). - if (next_msize >= NUM_TINY_SLOTS) { - msize += next_msize; - - big_free_block = (free_list_t *)next_block; - after_next_block = free_list_unchecksum_ptr(szone, &big_free_block->next); - before_next_block = free_list_unchecksum_ptr(szone, &big_free_block->previous); - - if (!before_next_block) { - tiny_mag_ptr->mag_free_list[NUM_TINY_SLOTS-1] = ptr; - } else { - before_next_block->next.u = free_list_checksum_ptr(szone, ptr); - } - - if (after_next_block) { - after_next_block->previous.u = free_list_checksum_ptr(szone, ptr); - } - - // we don't need to checksum these since they are already checksummed - ((free_list_t *)ptr)->previous = big_free_block->previous; - ((free_list_t *)ptr)->next = big_free_block->next; - - // clear the meta_header to enable coalescing backwards - set_tiny_meta_header_middle(big_free_block); - set_tiny_meta_header_free(ptr, msize); - - goto tiny_free_ending; - } - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); - set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards - msize += next_msize; - } - - // The tiny cache already scribbles free blocks as they go through the - // cache whenever msize < TINY_QUANTUM , so we do not need to do it here. - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize && (msize >= TINY_QUANTUM)) - memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize)); - - tiny_free_list_add_ptr(szone, tiny_mag_ptr, ptr, msize); - - tiny_free_ending: - - tiny_mag_ptr->mag_num_objects--; - // we use original_size and not msize to avoid double counting the coalesced blocks - tiny_mag_ptr->mag_num_bytes_in_objects -= original_size; - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(region); - size_t bytes_used = node->bytes_used - original_size; - node->bytes_used = bytes_used; - -#if !TARGET_OS_EMBEDDED // Always madvise for embedded platforms - /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ - if (szone->num_tiny_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary - /* NOTHING */ - } else if (DEPOT_MAGAZINE_INDEX != mag_index) { - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) { - /* Region has crossed threshold from density to sparsity. Mark it "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = TRUE; - } else { - /* After this free, we've found the region is still dense, so it must have been even more so before - the free. That implies the region is already correctly marked. Do nothing. */ - } - - // Has the entire magazine crossed the "emptiness threshold"? If so, transfer a region - // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e - // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. - size_t a = tiny_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine - size_t u = tiny_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine - - if (a - u > ((3 * TINY_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) { - return tiny_free_do_recirc_to_depot(szone, tiny_mag_ptr, mag_index); - } - - } else { -#endif - // Freed to Depot. N.B. Lock on tiny_magazines[DEPOT_MAGAZINE_INDEX] is already held - // Calcuate the first page in the coalesced block that would be safe to mark MADV_FREE - uintptr_t safe_ptr = (uintptr_t)ptr + sizeof(free_list_t) + sizeof(msize_t); - uintptr_t round_safe = round_page(safe_ptr); - - // Calcuate the last page in the coalesced block that would be safe to mark MADV_FREE - uintptr_t safe_extent = (uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t); - uintptr_t trunc_extent = trunc_page(safe_extent); - - // The newly freed block may complete a span of bytes that cover a page. Mark it with MADV_FREE. - if (round_safe < trunc_extent) { // Safe area covers a page (perhaps many) - uintptr_t lo = trunc_page((uintptr_t)original_ptr); - uintptr_t hi = round_page((uintptr_t)original_ptr + original_size); - - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, ptr, msize); - set_tiny_meta_header_in_use(ptr, msize); - - OSAtomicIncrement32Barrier(&(node->pinned_to_depot)); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi), &szone->last_tiny_advise); -#else - madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi)); -#endif - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - OSAtomicDecrement32Barrier(&(node->pinned_to_depot)); - - set_tiny_meta_header_free(ptr, msize); - tiny_free_list_add_ptr(szone, tiny_mag_ptr, ptr, msize); - } - -#if !TARGET_OS_EMBEDDED - if (0 < bytes_used || 0 < node->pinned_to_depot) { - /* Depot'd region is still live. Leave it in place on the Depot's recirculation list - so as to avoid thrashing between the Depot's free list and a magazines's free list - with detach_region/reattach_region */ - } else { - /* Depot'd region is just now empty. Consider return to OS. */ - region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, tiny_mag_ptr, node); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - if (r_dealloc) - deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0); - return FALSE; // Caller need not unlock - } - } -#endif - - return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr) -} - -// Allocates from the last region or a freshly allocated region -static void * -tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, - msize_t msize, void * aligned_address) -{ - void *ptr; - - // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start - if (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start) - tiny_finalize_region(szone, tiny_mag_ptr); - - // We set the unused bits of the header in the last pair to be all ones, and those of the inuse to zeroes. - ((tiny_region_t)aligned_address)->pairs[CEIL_NUM_TINY_BLOCKS_WORDS-1].header = - (NUM_TINY_BLOCKS & 31) ? (0xFFFFFFFFU << (NUM_TINY_BLOCKS & 31)) : 0; - ((tiny_region_t)aligned_address)->pairs[CEIL_NUM_TINY_BLOCKS_WORDS-1].inuse = 0; - - // Here find the only place in tinyland that (infrequently) takes the tiny_regions_lock. - // Only one thread at a time should be permitted to assess the density of the hash - // ring and adjust if needed. - // Only one thread at a time should be permitted to insert its new region on - // the hash ring. - // It is safe for all other threads to read the hash ring (hashed_regions) and - // the associated sizes (num_regions_allocated and num_tiny_regions). - - LOCK(szone->tiny_regions_lock); - - // Check to see if the hash ring of tiny regions needs to grow. Try to - // avoid the hash ring becoming too dense. - if (szone->tiny_region_generation->num_regions_allocated < (2 * szone->num_tiny_regions)) { - region_t *new_regions; - size_t new_size; - size_t new_shift = szone->tiny_region_generation->num_regions_allocated_shift; // In/Out parameter - new_regions = hash_regions_grow_no_lock(szone, szone->tiny_region_generation->hashed_regions, - szone->tiny_region_generation->num_regions_allocated, - &new_shift, - &new_size); - // Do not deallocate the current hashed_regions allocation since someone may - // be iterating it. Instead, just leak it. - - // Prepare to advance to the "next generation" of the hash ring. - szone->tiny_region_generation->nextgen->hashed_regions = new_regions; - szone->tiny_region_generation->nextgen->num_regions_allocated = new_size; - szone->tiny_region_generation->nextgen->num_regions_allocated_shift = new_shift; - - // Throw the switch to atomically advance to the next generation. - szone->tiny_region_generation = szone->tiny_region_generation->nextgen; - // Ensure everyone sees the advance. - OSMemoryBarrier(); - } - // Tag the region at "aligned_address" as belonging to us, - // and so put it under the protection of the magazine lock we are holding. - // Do this before advertising "aligned_address" on the hash ring(!) - MAGAZINE_INDEX_FOR_TINY_REGION(aligned_address) = mag_index; - - // Insert the new region into the hash ring, and update malloc statistics - hash_region_insert_no_lock(szone->tiny_region_generation->hashed_regions, - szone->tiny_region_generation->num_regions_allocated, - szone->tiny_region_generation->num_regions_allocated_shift, - aligned_address); - - szone->num_tiny_regions++; - UNLOCK(szone->tiny_regions_lock); - - tiny_mag_ptr->mag_last_region = aligned_address; - BYTES_USED_FOR_TINY_REGION(aligned_address) = TINY_BYTES_FOR_MSIZE(msize); -#if ASLR_INTERNAL - int offset_msize = malloc_entropy[0] & TINY_ENTROPY_MASK; -#if DEBUG_MALLOC - if (getenv("MallocASLRForce")) offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & TINY_ENTROPY_MASK; - if (getenv("MallocASLRPrint")) malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize); -#endif -#else - int offset_msize = 0; -#endif - ptr = (void *)((uintptr_t) aligned_address + TINY_BYTES_FOR_MSIZE(offset_msize)); - set_tiny_meta_header_in_use(ptr, msize); - tiny_mag_ptr->mag_num_objects++; - tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(msize); - tiny_mag_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; - - // We put a header on the last block so that it appears in use (for coalescing, etc...) - set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize))); - tiny_mag_ptr->mag_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize - offset_msize); - -#if ASLR_INTERNAL - // Put a header on the previous block for same reason - tiny_mag_ptr->mag_bytes_free_at_start = TINY_BYTES_FOR_MSIZE(offset_msize); - if (offset_msize) { - set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr - TINY_QUANTUM)); - } -#else - tiny_mag_ptr->mag_bytes_free_at_start = 0; -#endif - - // connect to magazine as last node - recirc_list_splice_last(szone, tiny_mag_ptr, REGION_TRAILER_FOR_TINY_REGION(aligned_address)); - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_region_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } -#endif - return ptr; -} - -static INLINE void * -tiny_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) -{ - msize_t new_msize = TINY_MSIZE_FOR_BYTES(new_good_size); - msize_t mshrinkage = TINY_MSIZE_FOR_BYTES(old_size) - new_msize; - - if (mshrinkage) { - void *q = (void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(new_msize)); - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)), - MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr))); - - // Mark q as block header and in-use, thus creating two blocks. - set_tiny_meta_header_in_use(q, mshrinkage); - tiny_mag_ptr->mag_num_objects++; - - SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr); - szone_free(szone, q); // avoid inlining free_tiny(szone, q, ...); - } - return ptr; -} - -static INLINE boolean_t -tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) -{ - // returns 1 on success - msize_t index; - msize_t old_msize; - unsigned next_index; - void *next_block; - boolean_t is_free; - msize_t next_msize, coalesced_msize, leftover_msize; - void *leftover; - - index = TINY_INDEX_FOR_PTR(ptr); - old_msize = TINY_MSIZE_FOR_BYTES(old_size); - next_index = index + old_msize; - - if (next_index >= NUM_TINY_BLOCKS) { - return 0; - } - next_block = (char *)ptr + old_size; - - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)), - MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr))); - - /* - * Look for a free block immediately afterwards. If it's large enough, we can consume (part of) - * it. - */ - is_free = tiny_meta_header_is_free(next_block); - if (!is_free) { - SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr); - return 0; // next_block is in use; - } - next_msize = get_tiny_free_size(next_block); - if (old_size + TINY_BYTES_FOR_MSIZE(next_msize) < new_size) { - SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr); - return 0; // even with next block, not enough - } - /* - * The following block is big enough; pull it from its freelist and chop off enough to satisfy - * our needs. - */ - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); - set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards - coalesced_msize = TINY_MSIZE_FOR_BYTES(new_size - old_size + TINY_QUANTUM - 1); - leftover_msize = next_msize - coalesced_msize; - if (leftover_msize) { - /* there's some left, so put the remainder back */ - leftover = (void *)((uintptr_t)next_block + TINY_BYTES_FOR_MSIZE(coalesced_msize)); - - tiny_free_list_add_ptr(szone, tiny_mag_ptr, leftover, leftover_msize); - } - set_tiny_meta_header_in_use(ptr, old_msize + coalesced_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_try_realloc_in_place(), ptr=%p, msize=%d\n", ptr, old_msize + coalesced_msize); - } -#endif - tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(coalesced_msize); - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); - size_t bytes_used = node->bytes_used + TINY_BYTES_FOR_MSIZE(coalesced_msize); - node->bytes_used = bytes_used; - - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) { - /* After this reallocation the region is still sparse, so it must have been even more so before - the reallocation. That implies the region is already correctly marked. Do nothing. */ - } else { - /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = FALSE; - } - - SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return 1; -} - -static boolean_t -tiny_check_region(szone_t *szone, region_t region) -{ - uintptr_t start, ptr, region_end; - boolean_t prev_free = 0; - boolean_t is_free; - msize_t msize; - free_list_t *free_head; - void *follower, *previous, *next; - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(region); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - // Assumes locked - CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__); - - /* establish region limits */ - start = (uintptr_t)TINY_REGION_ADDRESS(region); - ptr = start; - if (region == tiny_mag_ptr->mag_last_region) { - ptr += tiny_mag_ptr->mag_bytes_free_at_start; - - /* - * Check the leading block's integrity here also. - */ - if (tiny_mag_ptr->mag_bytes_free_at_start) { - msize = get_tiny_meta_header((void *)(ptr - TINY_QUANTUM), &is_free); - if (is_free || (msize != 1)) { - malloc_printf("*** invariant broken for leader block %p - %d %d\n", ptr - TINY_QUANTUM, msize, is_free); - } - } - } - region_end = (uintptr_t)TINY_REGION_END(region); - - /* - * The last region may have a trailing chunk which has not been converted into inuse/freelist - * blocks yet. - */ - if (region == tiny_mag_ptr->mag_last_region) - region_end -= tiny_mag_ptr->mag_bytes_free_at_end; - - /* - * Scan blocks within the region. - */ - while (ptr < region_end) { - /* - * If the first block is free, and its size is 65536 (msize = 0) then the entire region is - * free. - */ - msize = get_tiny_meta_header((void *)ptr, &is_free); - if (is_free && !msize && (ptr == start)) { - return 1; - } - - /* - * If the block's size is 65536 (msize = 0) then since we're not the first entry the size is - * corrupt. - */ - if (!msize) { - malloc_printf("*** invariant broken for tiny block %p this msize=%d - size is too small\n", - ptr, msize); - return 0; - } - - if (!is_free) { - /* - * In use blocks cannot be more than (NUM_TINY_SLOTS - 1) quanta large. - */ - prev_free = 0; - if (msize > (NUM_TINY_SLOTS - 1)) { - malloc_printf("*** invariant broken for %p this tiny msize=%d - size is too large\n", - ptr, msize); - return 0; - } - /* move to next block */ - ptr += TINY_BYTES_FOR_MSIZE(msize); - } else { -#if !RELAXED_INVARIANT_CHECKS - /* - * Free blocks must have been coalesced, we cannot have a free block following another - * free block. - */ - if (prev_free) { - malloc_printf("*** invariant broken for free block %p this tiny msize=%d: two free blocks in a row\n", - ptr, msize); - return 0; - } -#endif // RELAXED_INVARIANT_CHECKS - prev_free = 1; - /* - * Check the integrity of this block's entry in its freelist. - */ - free_head = (free_list_t *)ptr; - previous = free_list_unchecksum_ptr(szone, &free_head->previous); - next = free_list_unchecksum_ptr(szone, &free_head->next); - if (previous && !tiny_meta_header_is_free(previous)) { - malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", - ptr, previous); - return 0; - } - if (next && !tiny_meta_header_is_free(next)) { - malloc_printf("*** invariant broken for %p (next in free list %p is not a free pointer)\n", - ptr, next); - return 0; - } - /* - * Check the free block's trailing size value. - */ - follower = FOLLOWING_TINY_PTR(ptr, msize); - if (((uintptr_t)follower != region_end) && (get_tiny_previous_free_msize(follower) != msize)) { - malloc_printf("*** invariant broken for tiny free %p followed by %p in region [%p-%p] " - "(end marker incorrect) should be %d; in fact %d\n", - ptr, follower, TINY_REGION_ADDRESS(region), region_end, msize, get_tiny_previous_free_msize(follower)); - return 0; - } - /* move to next block */ - ptr = (uintptr_t)follower; - } - } - /* - * Ensure that we scanned the entire region - */ - if (ptr != region_end) { - malloc_printf("*** invariant broken for region end %p - %p\n", ptr, region_end); - return 0; - } - /* - * Check the trailing block's integrity. - */ - if (region == tiny_mag_ptr->mag_last_region) { - if (tiny_mag_ptr->mag_bytes_free_at_end) { - msize = get_tiny_meta_header((void *)ptr, &is_free); - if (is_free || (msize != 1)) { - malloc_printf("*** invariant broken for blocker block %p - %d %d\n", ptr, msize, is_free); - } - } - } - return 1; -} - -static kern_return_t -tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, - memory_reader_t reader, vm_range_recorder_t recorder) -{ - size_t num_regions; - size_t index; - region_t *regions; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - kern_return_t err; - region_t region; - vm_range_t range; - vm_range_t admin_range; - vm_range_t ptr_range; - unsigned char *mapped_region; - uint32_t *block_header; - uint32_t *in_use; - unsigned block_index; - unsigned block_limit; - boolean_t is_free; - msize_t msize; - void *mapped_ptr; - unsigned bit; - magazine_t *tiny_mag_base = NULL; - - region_hash_generation_t *trg_ptr; - err = reader(task, (vm_address_t)szone->tiny_region_generation, sizeof(region_hash_generation_t), (void **)&trg_ptr); - if (err) return err; - - num_regions = trg_ptr->num_regions_allocated; - err = reader(task, (vm_address_t)trg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions); - if (err) return err; - - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - // Map in all active magazines. Do this outside the iteration over regions. - err = reader(task, (vm_address_t)(szone->tiny_magazines), - szone->num_tiny_magazines*sizeof(magazine_t),(void **)&tiny_mag_base); - if (err) return err; - } - - for (index = 0; index < num_regions; ++index) { - region = regions[index]; - if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { - range.address = (vm_address_t)TINY_REGION_ADDRESS(region); - range.size = (vm_size_t)TINY_REGION_SIZE; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - admin_range.address = range.address + TINY_METADATA_START; - admin_range.size = TINY_METADATA_SIZE; - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); - } - if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { - ptr_range.address = range.address; - ptr_range.size = NUM_TINY_BLOCKS * TINY_QUANTUM; - recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); - } - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - void *mag_last_free; - vm_address_t mag_last_free_ptr = 0; - msize_t mag_last_free_msize = 0; - - err = reader(task, range.address, range.size, (void **)&mapped_region); - if (err) - return err; - - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(mapped_region); - magazine_t *tiny_mag_ptr = tiny_mag_base + mag_index; - - if (DEPOT_MAGAZINE_INDEX != mag_index) { - mag_last_free = tiny_mag_ptr->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(TINY_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (TINY_QUANTUM - 1); - } - } else { - for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { - if ((void *)range.address == (tiny_mag_base + mag_index)->mag_last_free_rgn) { - mag_last_free = (tiny_mag_base + mag_index)->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(TINY_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (TINY_QUANTUM - 1); - } - } - } - } - - block_header = (uint32_t *)(mapped_region + TINY_METADATA_START + sizeof(region_trailer_t)); - in_use = TINY_INUSE_FOR_HEADER(block_header); - block_index = 0; - block_limit = NUM_TINY_BLOCKS; - if (region == tiny_mag_ptr->mag_last_region) { - block_index += TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start); - block_limit -= TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end); - } - - while (block_index < block_limit) { - vm_size_t block_offset = TINY_BYTES_FOR_MSIZE(block_index); - is_free = !BITARRAY_BIT(in_use, block_index); - if (is_free) { - mapped_ptr = mapped_region + block_offset; - - // mapped_region, the address at which 'range' in 'task' has been - // mapped into our process, is not necessarily aligned to - // TINY_BLOCKS_ALIGN. - // - // Since the code in get_tiny_free_size() assumes the pointer came - // from a properly aligned tiny region, and mapped_region is not - // necessarily aligned, then do the size calculation directly. - // If the next bit is set in the header bitmap, then the size is one - // quantum. Otherwise, read the size field. - if (!BITARRAY_BIT(block_header, (block_index+1))) - msize = TINY_FREE_SIZE(mapped_ptr); - else - msize = 1; - - } else if (range.address + block_offset != mag_last_free_ptr) { - msize = 1; - bit = block_index + 1; - while (! BITARRAY_BIT(block_header, bit)) { - bit++; - msize ++; - } - buffer[count].address = range.address + block_offset; - buffer[count].size = TINY_BYTES_FOR_MSIZE(msize); - count++; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } else { - // Block is not free but it matches mag_last_free_ptr so even - // though it is not marked free in the bitmap, we treat it as if - // it is and move on - msize = mag_last_free_msize; - } - - if (!msize) - return KERN_FAILURE; // Somethings amiss. Avoid looping at this block_index. - - block_index += msize; - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } - } - } - return 0; -} - -static void * -tiny_malloc_from_free_list(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - free_list_t *ptr; - msize_t this_msize; - grain_t slot = msize - 1; - free_list_t **free_list = tiny_mag_ptr->mag_free_list; - free_list_t **the_slot = free_list + slot; - free_list_t *next; - free_list_t **limit; -#if defined(__LP64__) - uint64_t bitmap; -#else - uint32_t bitmap; -#endif - msize_t leftover_msize; - free_list_t *leftover_ptr; - - // Assumes we've locked the region - CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__); - - // Look for an exact match by checking the freelist for this msize. - // - ptr = *the_slot; - if (ptr) { - next = free_list_unchecksum_ptr(szone, &ptr->next); - if (next) { - next->previous = ptr->previous; - } else { - BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot); - } - *the_slot = next; - this_msize = msize; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize); - } -#endif - goto return_tiny_alloc; - } - - // Mask off the bits representing slots holding free blocks smaller than the - // size we need. If there are no larger free blocks, try allocating from - // the free space at the end of the tiny region. -#if defined(__LP64__) - bitmap = ((uint64_t *)(tiny_mag_ptr->mag_bitmap))[0] & ~ ((1ULL << slot) - 1); -#else - bitmap = tiny_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1); -#endif - if (!bitmap) - goto try_tiny_malloc_from_end; - - slot = BITMAPV_CTZ(bitmap); - limit = free_list + NUM_TINY_SLOTS - 1; - free_list += slot; - - if (free_list < limit) { - ptr = *free_list; - if (ptr) { - next = free_list_unchecksum_ptr(szone, &ptr->next); - *free_list = next; - if (next) { - next->previous = ptr->previous; - } else { - BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot); - } - this_msize = get_tiny_free_size(ptr); - goto add_leftover_and_proceed; - } -#if DEBUG_MALLOC - malloc_printf("in tiny_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n",slot); -#endif - } - - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than (NUM_TINY_SLOTS - 1) * tiny quantum size. - // If the last freelist is not empty, and the head contains a block that is - // larger than our request, then the remainder is put back on the free list. - ptr = *limit; - if (ptr) { - this_msize = get_tiny_free_size(ptr); - next = free_list_unchecksum_ptr(szone, &ptr->next); - if (this_msize - msize >= NUM_TINY_SLOTS) { - // the leftover will go back to the free list, so we optimize by - // modifying the free list rather than a pop and push of the head - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); - *limit = leftover_ptr; - if (next) { - next->previous.u = free_list_checksum_ptr(szone, leftover_ptr); - } - leftover_ptr->previous = ptr->previous; - leftover_ptr->next = ptr->next; - set_tiny_meta_header_free(leftover_ptr, leftover_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", - ptr, msize, this_msize); - } -#endif - this_msize = msize; - goto return_tiny_alloc; - } - if (next) { - next->previous = ptr->previous; - } - *limit = next; - goto add_leftover_and_proceed; - /* NOTREACHED */ - } - -try_tiny_malloc_from_end: - // Let's see if we can use tiny_mag_ptr->mag_bytes_free_at_end - if (tiny_mag_ptr->mag_bytes_free_at_end >= TINY_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)((uintptr_t)TINY_REGION_END(tiny_mag_ptr->mag_last_region) - - tiny_mag_ptr->mag_bytes_free_at_end); - tiny_mag_ptr->mag_bytes_free_at_end -= TINY_BYTES_FOR_MSIZE(msize); - if (tiny_mag_ptr->mag_bytes_free_at_end) { - // let's add an in use block after ptr to serve as boundary - set_tiny_meta_header_in_use_1((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); - } - this_msize = msize; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize); - } -#endif - goto return_tiny_alloc; - } -#if ASLR_INTERNAL - // Try from start if nothing left at end - if (tiny_mag_ptr->mag_bytes_free_at_start >= TINY_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)(TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region) + - tiny_mag_ptr->mag_bytes_free_at_start - TINY_BYTES_FOR_MSIZE(msize)); - tiny_mag_ptr->mag_bytes_free_at_start -= TINY_BYTES_FOR_MSIZE(msize); - if (tiny_mag_ptr->mag_bytes_free_at_start) { - // let's add an in use block before ptr to serve as boundary - set_tiny_meta_header_in_use_1((unsigned char *)ptr - TINY_QUANTUM); - } - this_msize = msize; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), from start ptr=%p, msize=%d\n", ptr, msize); - } -#endif - goto return_tiny_alloc; - } -#endif - return NULL; - -add_leftover_and_proceed: - if (!this_msize || (this_msize > msize)) { - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); - } -#endif - tiny_free_list_add_ptr(szone, tiny_mag_ptr, leftover_ptr, leftover_msize); - this_msize = msize; - } - -return_tiny_alloc: - tiny_mag_ptr->mag_num_objects++; - tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(this_msize); - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); - size_t bytes_used = node->bytes_used + TINY_BYTES_FOR_MSIZE(this_msize); - node->bytes_used = bytes_used; - - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) { - /* After this allocation the region is still sparse, so it must have been even more so before - the allocation. That implies the region is already correctly marked. Do nothing. */ - } else { - /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = FALSE; - } -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); - } -#endif - if (this_msize > 1) - set_tiny_meta_header_in_use(ptr, this_msize); - else - set_tiny_meta_header_in_use_1(ptr); - return ptr; -} -#undef DENSITY_THRESHOLD -#undef K - -static INLINE void * -tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) -{ - void *ptr; - mag_index_t mag_index = mag_get_thread_index(szone); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - -#if DEBUG_MALLOC - if (DEPOT_MAGAZINE_INDEX == mag_index) { - szone_error(szone, 1, "malloc called for magazine index -1", NULL, NULL); - return(NULL); - } - - if (!msize) { - szone_error(szone, 1, "invariant broken (!msize) in allocation (region)", NULL, NULL); - return(NULL); - } -#endif - - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - -#if TINY_CACHE - ptr = tiny_mag_ptr->mag_last_free; - - if ((((uintptr_t)ptr) & (TINY_QUANTUM - 1)) == msize) { - // we have a winner - tiny_mag_ptr->mag_last_free = NULL; - tiny_mag_ptr->mag_last_free_rgn = NULL; - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - ptr = (void *)((uintptr_t)ptr & ~ (TINY_QUANTUM - 1)); - if (cleared_requested) { - memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); - } -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_should_clear(), tiny cache ptr=%p, msize=%d\n", ptr, msize); - } -#endif - return ptr; - } -#endif /* TINY_CACHE */ - - while (1) { - ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - - if (tiny_get_region_from_depot(szone, tiny_mag_ptr, mag_index, msize)) { - ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - } - - // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc(). - // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first - // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section. - // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the - // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation, - // and retry-ing threads succeed in the code just above. - if (!tiny_mag_ptr->alloc_underway) { - void *fresh_region; - - // time to create a new region (do this outside the magazine lock) - tiny_mag_ptr->alloc_underway = TRUE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - fresh_region = allocate_pages_securely(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, VM_MEMORY_MALLOC_TINY); - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - - MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, TINY_REGION_SIZE); // DTrace USDT Probe - - if (!fresh_region) { // out of memory! - tiny_mag_ptr->alloc_underway = FALSE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return NULL; - } - - ptr = tiny_malloc_from_region_no_lock(szone, tiny_mag_ptr, mag_index, msize, fresh_region); - - // we don't clear because this freshly allocated space is pristine - tiny_mag_ptr->alloc_underway = FALSE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return ptr; - } else { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - pthread_yield_np(); - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - } - } - /* NOTREACHED */ -} - -static NOINLINE void -free_tiny_botch(szone_t *szone, free_list_t *ptr) -{ - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - szone_error(szone, 1, "double free", ptr, NULL); -} - -static INLINE void -free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size) -{ - msize_t msize; - boolean_t is_free; - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - // ptr is known to be in tiny_region - if (known_size) { - msize = TINY_MSIZE_FOR_BYTES(known_size + TINY_QUANTUM - 1); - } else { - msize = get_tiny_meta_header(ptr, &is_free); - if (is_free) { - free_tiny_botch(szone, ptr); - return; - } - } -#if DEBUG_MALLOC - if (!msize) { - malloc_printf("*** free_tiny() block in use is too large: %p\n", ptr); - return; - } -#endif - - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - -#if TINY_CACHE - // Depot does not participate in TINY_CACHE since it can't be directly malloc()'d - if (DEPOT_MAGAZINE_INDEX != mag_index) { - if (msize < TINY_QUANTUM) { // to see if the bits fit in the last 4 bits - void *ptr2 = tiny_mag_ptr->mag_last_free; // Might be NULL - region_t rgn2 = tiny_mag_ptr->mag_last_free_rgn; - - /* check that we don't already have this pointer in the cache */ - if (ptr == (void *)((uintptr_t)ptr2 & ~ (TINY_QUANTUM - 1))) { - free_tiny_botch(szone, ptr); - return; - } - - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) - memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize)); - - tiny_mag_ptr->mag_last_free = (void *)(((uintptr_t)ptr) | msize); - tiny_mag_ptr->mag_last_free_rgn = tiny_region; - - if (!ptr2) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return; - } - - msize = (uintptr_t)ptr2 & (TINY_QUANTUM - 1); - ptr = (void *)(((uintptr_t)ptr2) & ~(TINY_QUANTUM - 1)); - tiny_region = rgn2; - } - } -#endif /* TINY_CACHE */ - - // Now in the time it took to acquire the lock, the region may have migrated - // from one magazine to another. I.e. trailer->mag_index is volatile. - // In which case the magazine lock we obtained (namely magazines[mag_index].mag_lock) - // is stale. If so, keep on tryin' ... - region_trailer_t *trailer = REGION_TRAILER_FOR_TINY_REGION(tiny_region); - mag_index_t refreshed_index; - - while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment - - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - - mag_index = refreshed_index; - tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - } - - if (tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize)) - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - - CHECK(szone, __PRETTY_FUNCTION__); -} - -static void -print_tiny_free_list(szone_t *szone) -{ - free_list_t *ptr; - _SIMPLE_STRING b = _simple_salloc(); - mag_index_t mag_index; - - if (b) { - _simple_sappend(b, "tiny free sizes:\n"); - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - grain_t slot = 0; - _simple_sprintf(b,"\tMagazine %d: ", mag_index); - while (slot < NUM_TINY_SLOTS) { - ptr = szone->tiny_magazines[mag_index].mag_free_list[slot]; - if (ptr) { - _simple_sprintf(b, "%s%y[%d]; ", (slot == NUM_TINY_SLOTS-1) ? ">=" : "", - (slot+1)*TINY_QUANTUM, free_list_count(szone, ptr)); - } - slot++; - } - _simple_sappend(b,"\n"); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static void -print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end) -{ - unsigned counts[1024]; - unsigned in_use = 0; - uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(region); - uintptr_t current = start + bytes_at_end; - uintptr_t limit = (uintptr_t)TINY_REGION_END(region) - bytes_at_end; - boolean_t is_free; - msize_t msize; - unsigned ci; - _SIMPLE_STRING b; - uintptr_t pgTot = 0; - - if (region == HASHRING_REGION_DEALLOCATED) { - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Tiny region [unknown address] was returned to the OS\n"); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } - return; - } - - memset(counts, 0, sizeof(counts)); - while (current < limit) { - msize = get_tiny_meta_header((void *)current, &is_free); - if (is_free & !msize && (current == start)) { - // first block is all free - uintptr_t pgLo = round_page(start + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page(start + TINY_REGION_SIZE - sizeof(msize_t)); - - if (pgLo < pgHi) { - pgTot += (pgHi - pgLo); - } - break; - } - if (!msize) { - malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize); - break; - } - if (!is_free) { - // block in use - if (msize > NUM_TINY_SLOTS) - malloc_printf("*** error at %p msize for in_use is %d\n", (void *)current, msize); - if (msize < 1024) - counts[msize]++; - in_use++; - } else { - uintptr_t pgLo = round_page(current + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); - - if (pgLo < pgHi) { - pgTot += (pgHi - pgLo); - } - } - current += TINY_BYTES_FOR_MSIZE(msize); - } - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Tiny region [%p-%p, %y] \t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE); - _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_TINY_REGION(region)); - _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_TINY_REGION(region)); - if (bytes_at_end || bytes_at_start) - _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start); - if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_TINY_REGION(region)) { - _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot); - } else { - _simple_sprintf(b, "Fragments subject to reclamation=%ly", pgTot); - } - if (verbose && in_use) { - _simple_sappend(b, "\n\tSizes in use: "); - for (ci = 0; ci < 1024; ci++) - if (counts[ci]) - _simple_sprintf(b, "%d[%d] ", TINY_BYTES_FOR_MSIZE(ci), counts[ci]); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static boolean_t -tiny_free_list_check(szone_t *szone, grain_t slot) -{ - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - - unsigned count = 0; - free_list_t *ptr = szone->tiny_magazines[mag_index].mag_free_list[slot]; - boolean_t is_free; - free_list_t *previous = NULL; - - while (ptr) { - is_free = tiny_meta_header_is_free(ptr); - if (! is_free) { - malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return 0; - } - if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { - malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return 0; - } - if (!tiny_region_for_ptr_no_lock(szone, ptr)) { - malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return 0; - } - if (free_list_unchecksum_ptr(szone, &ptr->previous) != previous) { - malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return 0; - } - previous = ptr; - ptr = free_list_unchecksum_ptr(szone, &ptr->next); - count++; - } - - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - } - return 1; -} - -/********************* SMALL FREE LIST UTILITIES ************************/ - -/* - * Mark a block as free. Only the first quantum of a block is marked thusly, - * the remainder are marked "middle". - */ -static INLINE void -small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize) -{ - meta_headers[index] = msize | SMALL_IS_FREE; -} - -/* - * Mark a block as in use. Only the first quantum of a block is marked thusly, - * the remainder are marked "middle". - */ -static INLINE void -small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) -{ - meta_headers[index] = msize; -} - -/* - * Mark a quantum as being the second or later in a block. - */ -static INLINE void -small_meta_header_set_middle(msize_t *meta_headers, msize_t index) -{ - meta_headers[index] = 0; -} - -/* - * Adds an item to the proper free list, and also marks the meta-header of the - * block properly. - * Assumes szone has been locked - */ -static void -small_free_list_add_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize) -{ - grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; - free_list_t *free_ptr = ptr; - free_list_t *free_head = small_mag_ptr->mag_free_list[slot]; - void *follower; - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } - if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { - szone_error(szone, 1, "small_free_list_add_ptr: Unaligned ptr", ptr, NULL); - } -#endif - small_meta_header_set_is_free(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), msize); - - if (free_head) { -#if DEBUG_MALLOC - if (free_list_unchecksum_ptr(szone, &free_head->previous)) { - szone_error(szone, 1, "small_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr, - "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, (void *)free_head, free_head->previous.p); - } - if (!SMALL_PTR_IS_FREE(free_head)) { - szone_error(szone, 1, "small_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, - "ptr=%p slot=%d free_head=%p\n", ptr, slot, (void *)free_head); - } -#endif - free_head->previous.u = free_list_checksum_ptr(szone, free_ptr); - } else { - BITMAPN_SET(small_mag_ptr->mag_bitmap, slot); - } - free_ptr->previous.u = free_list_checksum_ptr(szone, NULL); - free_ptr->next.u = free_list_checksum_ptr(szone, free_head); - - small_mag_ptr->mag_free_list[slot] = free_ptr; - - // Store msize at the end of the block denoted by "ptr" (i.e. at a negative offset from "follower") - follower = (void *)((uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(msize)); - SMALL_PREVIOUS_MSIZE(follower) = msize; -} - -/* - * Removes the item pointed to by ptr in the proper free list. - * Assumes szone has been locked - */ -static void -small_free_list_remove_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize) -{ - grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; - free_list_t *free_ptr = ptr, *next, *previous; - - next = free_list_unchecksum_ptr(szone, &free_ptr->next); - previous = free_list_unchecksum_ptr(szone, &free_ptr->previous); - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } -#endif - - if (!previous) { - // The block to remove is the head of the free list -#if DEBUG_MALLOC - if (small_mag_ptr->mag_free_list[slot] != ptr) { - szone_error(szone, 1, "small_free_list_remove_ptr: Internal invariant broken (small_mag_ptr->mag_free_list[slot])", ptr, - "ptr=%p slot=%d msize=%d small_mag_ptr->mag_free_list[slot]=%p\n", - ptr, slot, msize, (void *)small_mag_ptr->mag_free_list[slot]); - return; - } -#endif - small_mag_ptr->mag_free_list[slot] = next; - if (!next) BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot); - } else { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - previous->next = free_ptr->next; - } - if (next) { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - next->previous = free_ptr->previous; - } -} - -/* - * small_region_for_ptr_no_lock - Returns the small region containing the pointer, - * or NULL if not found. - */ -static INLINE region_t -small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) -{ - rgnhdl_t r = hash_lookup_region_no_lock(szone->small_region_generation->hashed_regions, - szone->small_region_generation->num_regions_allocated, - szone->small_region_generation->num_regions_allocated_shift, - SMALL_REGION_FOR_PTR(ptr)); - return r ? *r : r; -} - -static void -small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr) { - void *last_block, *previous_block; - msize_t last_msize, previous_msize, last_index; - - // It is possible that the block prior to the last block in the region has - // been free'd, but was not coalesced with the free bytes at the end of the - // block, since we treat the bytes at the end of the region as "in use" in - // the meta headers. Attempt to coalesce the last block with the previous - // block, so we don't violate the "no consecutive free blocks" invariant. - // - // FIXME: If we could calculate the previous small free size in the same - // manner as tiny_previous_preceding_free, it would eliminate the - // index & previous msize checks, which are a guard against reading - // bogus data out of in-use or written-on-freed memory. - // - // FIXME: Need to investigate how much work would be required to increase - // 'mag_bytes_free_at_end' when freeing the preceding block, rather - // than performing this workaround. - // - if (small_mag_ptr->mag_bytes_free_at_end) { - last_block = SMALL_REGION_END(small_mag_ptr->mag_last_region) - small_mag_ptr->mag_bytes_free_at_end; - last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end); - - last_index = SMALL_META_INDEX_FOR_PTR(last_block); - previous_msize = SMALL_PREVIOUS_MSIZE(last_block); - - if (last_index && (previous_msize <= last_index)) { - previous_block = (void *)((uintptr_t)last_block - SMALL_BYTES_FOR_MSIZE(previous_msize)); - if (*SMALL_METADATA_FOR_PTR(previous_block) == (previous_msize | SMALL_IS_FREE)) { - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(last_block); - - small_meta_header_set_middle(meta_headers, last_index); - small_free_list_remove_ptr(szone, small_mag_ptr, previous_block, previous_msize); - last_block = (void *)((uintptr_t)last_block - SMALL_BYTES_FOR_MSIZE(previous_msize)); - last_msize += previous_msize; - } - } - - // splice last_block into the free list - small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize); - small_mag_ptr->mag_bytes_free_at_end = 0; - } - -#if ASLR_INTERNAL - if (small_mag_ptr->mag_bytes_free_at_start) { - last_block = SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region); - last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start); - - void *next_block = (void *) ((uintptr_t)last_block + small_mag_ptr->mag_bytes_free_at_start); - if (SMALL_PTR_IS_FREE(next_block)) { - msize_t next_msize = SMALL_PTR_SIZE(next_block); - - small_meta_header_set_middle(SMALL_META_HEADER_FOR_PTR(next_block), SMALL_META_INDEX_FOR_PTR(next_block)); - small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize); - last_msize += next_msize; - } - - // splice last_block into the free list - small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize); - small_mag_ptr->mag_bytes_free_at_start = 0; - } -#endif - - // TODO: Will we ever need to coalesce the blocks at the beginning and end when we finalize? - - small_mag_ptr->mag_last_region = NULL; -} - -static int -small_free_detach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r) { - unsigned char *ptr = SMALL_REGION_ADDRESS(r); - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); - int total_alloc = 0; - - while (current < limit) { - unsigned index = SMALL_META_INDEX_FOR_PTR(current); - msize_t msize_and_free = meta_headers[index]; - boolean_t is_free = msize_and_free & SMALL_IS_FREE; - msize_t msize = msize_and_free & ~ SMALL_IS_FREE; - - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** small_free_detach_region error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - small_free_list_remove_ptr(szone, small_mag_ptr, (void *)current, msize); - } else { - total_alloc++; - } - current += SMALL_BYTES_FOR_MSIZE(msize); - } - return total_alloc; -} - -static size_t -small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r) { - unsigned char *ptr = SMALL_REGION_ADDRESS(r); - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); - size_t total_alloc = 0; - - while (current < limit) { - unsigned index = SMALL_META_INDEX_FOR_PTR(current); - msize_t msize_and_free = meta_headers[index]; - boolean_t is_free = msize_and_free & SMALL_IS_FREE; - msize_t msize = msize_and_free & ~ SMALL_IS_FREE; - - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** small_free_reattach_region error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - small_free_list_add_ptr(szone, small_mag_ptr, (void *)current, msize); - } else { - total_alloc += SMALL_BYTES_FOR_MSIZE(msize); - } - current += SMALL_BYTES_FOR_MSIZE(msize); - } - return total_alloc; -} - -typedef struct { - uint16_t pnum, size; -} small_pg_pair_t; - -static void NOINLINE /* want private stack frame for automatic array */ -small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) { - uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(start); - small_pg_pair_t advisory[((SMALL_REGION_PAYLOAD_BYTES + vm_page_size - 1) >> vm_page_shift) >> 1]; // 4096bytes stack allocated - int advisories = 0; - - // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list - // management data. - while (current < limit) { - unsigned index = SMALL_META_INDEX_FOR_PTR(current); - msize_t msize_and_free = meta_headers[index]; - boolean_t is_free = msize_and_free & SMALL_IS_FREE; - msize_t msize = msize_and_free & ~ SMALL_IS_FREE; - - if (is_free && !msize && (current == start)) { -#if DEBUG_MALLOC - // first block is all free - malloc_printf("*** small_free_scan_madvise_free first block is all free! %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - uintptr_t pgLo = round_page(start + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page(start + SMALL_REGION_SIZE - sizeof(msize_t)); - - if (pgLo < pgHi) { - advisory[advisories].pnum = (pgLo - start) >> vm_page_shift; - advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift; - advisories++; - } - break; - } - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** small_free_scan_madvise_free error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - uintptr_t pgLo = round_page(current + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); - - if (pgLo < pgHi) { - advisory[advisories].pnum = (pgLo - start) >> vm_page_shift; - advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift; - advisories++; - } - } - current += SMALL_BYTES_FOR_MSIZE(msize); - } - - if (advisories > 0) { - int i; - - OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot)); - SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); - for (i = 0; i < advisories; ++i) { - uintptr_t addr = (advisory[i].pnum << vm_page_shift) + start; - size_t size = advisory[i].size << vm_page_shift; - -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, r, addr, addr + size, NULL); -#else - madvise_free_range(szone, r, addr, addr + size); -#endif - } - SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); - OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot)); - } -} - -static region_t -small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node) -{ - if (0 < node->bytes_used || - 0 < node->pinned_to_depot || - depot_ptr->recirculation_entries < (szone->num_small_magazines * 2)) { - return NULL; - } - - // disconnect first node from Depot - recirc_list_extract(szone, depot_ptr, node); - - // Iterate the region pulling its free entries off the (locked) Depot's free list - region_t sparse_region = SMALL_REGION_FOR_PTR(node); - int objects_in_use = small_free_detach_region(szone, depot_ptr, sparse_region); - - if (0 == objects_in_use) { - // Invalidate the hash table entry for this region with HASHRING_REGION_DEALLOCATED. - // Using HASHRING_REGION_DEALLOCATED preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not. - rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->small_region_generation->hashed_regions, - szone->small_region_generation->num_regions_allocated, - szone->small_region_generation->num_regions_allocated_shift, sparse_region); - if (NULL == pSlot) { - szone_error(szone, 1, "small_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region); - return NULL; - } - *pSlot = HASHRING_REGION_DEALLOCATED; - depot_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; - __sync_fetch_and_add( &(szone->num_small_regions_dealloc), 1); // Atomically increment num_small_regions_dealloc - - // Caller will transfer ownership of the region back to the OS with no locks held - MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, SMALL_REGION_SIZE); // DTrace USDT Probe - return sparse_region; - - } else { - szone_error(szone, 1, "small_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use); - return NULL; - } -} - -static boolean_t -small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index) -{ - // The entire magazine crossed the "emptiness threshold". Transfer a region - // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e - // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. - region_trailer_t *node = small_mag_ptr->firstNode; - - while (node && !node->recirc_suitable) { - node = node->next; - } - - if (NULL == node) { -#if DEBUG_MALLOC - malloc_printf("*** small_free_do_recirc_to_depot end of list\n"); -#endif - return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - } - - region_t sparse_region = SMALL_REGION_FOR_PTR(node); - - // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at start - if (sparse_region == small_mag_ptr->mag_last_region && (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start)) { - small_finalize_region(szone, small_mag_ptr); - } - - // disconnect "suitable" node from magazine - recirc_list_extract(szone, small_mag_ptr, node); - - // Iterate the region pulling its free entries off its (locked) magazine's free list - int objects_in_use = small_free_detach_region(szone, small_mag_ptr, sparse_region); - magazine_t *depot_ptr = &(szone->small_magazines[DEPOT_MAGAZINE_INDEX]); - - // hand over the region to the (locked) Depot - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - // this will cause small_free_list_add_ptr called by small_free_reattach_region to use - // the depot as its target magazine, rather than magazine formerly associated with sparse_region - MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX; - node->pinned_to_depot = 0; - - // Iterate the region putting its free entries on Depot's free list - size_t bytes_inplay = small_free_reattach_region(szone, depot_ptr, sparse_region); - - small_mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; - small_mag_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; - small_mag_ptr->mag_num_objects -= objects_in_use; - - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); // Unlock the originating magazine - - depot_ptr->mag_num_bytes_in_objects += bytes_inplay; - depot_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; - depot_ptr->mag_num_objects += objects_in_use; - - // connect to Depot as last node - recirc_list_splice_last(szone, depot_ptr, node); - - MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE, - (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe - - // Mark free'd dirty pages with MADV_FREE to reduce memory pressure - small_free_scan_madvise_free(szone, depot_ptr, sparse_region); - - // If the region is entirely empty vm_deallocate() it outside the depot lock - region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, depot_ptr, node); - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - if (r_dealloc) - deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0); - return FALSE; // Caller need not unlock the originating magazine -} - -static region_t -small_find_msize_region(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - free_list_t *ptr; - grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; - free_list_t **free_list = small_mag_ptr->mag_free_list; - free_list_t **the_slot = free_list + slot; - free_list_t **limit; - unsigned bitmap; - - // Assumes we've locked the magazine - CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); - - // Look for an exact match by checking the freelist for this msize. - ptr = *the_slot; - if (ptr) - return SMALL_REGION_FOR_PTR(ptr); - - // Mask off the bits representing slots holding free blocks smaller than - // the size we need. - if (szone->is_largemem) { - // BITMAPN_CTZ implementation - unsigned idx = slot >> 5; - bitmap = 0; - unsigned mask = ~ ((1 << (slot & 31)) - 1); - for ( ; idx < SMALL_BITMAP_WORDS; ++idx ) { - bitmap = small_mag_ptr->mag_bitmap[idx] & mask; - if (bitmap != 0) - break; - mask = ~0U; - } - // Check for fallthrough: No bits set in bitmap - if ((bitmap == 0) && (idx == SMALL_BITMAP_WORDS)) - return NULL; - - // Start looking at the first set bit, plus 32 bits for every word of - // zeroes or entries that were too small. - slot = BITMAP32_CTZ((&bitmap)) + (idx * 32); - } else { - bitmap = small_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1); - if (!bitmap) - return NULL; - - slot = BITMAP32_CTZ((&bitmap)); - } - limit = free_list + szone->num_small_slots - 1; - free_list += slot; - - if (free_list < limit) { - ptr = *free_list; - if (ptr) - return SMALL_REGION_FOR_PTR(ptr); - else { - /* Shouldn't happen. Fall through to look at last slot. */ -#if DEBUG_MALLOC - malloc_printf("in small_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n",slot); -#endif - } - } - - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than (num_small_slots - 1) * (small quantum size). - ptr = *limit; - if (ptr) - return SMALL_REGION_FOR_PTR(ptr); - - return NULL; -} - -static boolean_t -small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - magazine_t *depot_ptr = &(szone->small_magazines[DEPOT_MAGAZINE_INDEX]); - - /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ - if (szone->num_small_magazines == 1) // Uniprocessor, single magazine, so no recirculation necessary - return 0; - -#if DEBUG_MALLOC - if (DEPOT_MAGAZINE_INDEX == mag_index) { - szone_error(szone, 1, "small_get_region_from_depot called for magazine index -1", NULL, NULL); - return 0; - } -#endif - - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - - // Appropriate a Depot'd region that can satisfy requested msize. - region_trailer_t *node; - region_t sparse_region; - - while (1) { - sparse_region = small_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); - if (NULL == sparse_region) { // Depot empty? - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - return 0; - } - - node = REGION_TRAILER_FOR_SMALL_REGION(sparse_region); - if (0 >= node->pinned_to_depot) - break; - - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - pthread_yield_np(); - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - } - - // disconnect node from Depot - recirc_list_extract(szone, depot_ptr, node); - - // Iterate the region pulling its free entries off the (locked) Depot's free list - int objects_in_use = small_free_detach_region(szone, depot_ptr, sparse_region); - - // Transfer ownership of the region - MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = mag_index; - node->pinned_to_depot = 0; - - // Iterate the region putting its free entries on its new (locked) magazine's free list - size_t bytes_inplay = small_free_reattach_region(szone, small_mag_ptr, sparse_region); - - depot_ptr->mag_num_bytes_in_objects -= bytes_inplay; - depot_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; - depot_ptr->mag_num_objects -= objects_in_use; - - small_mag_ptr->mag_num_bytes_in_objects += bytes_inplay; - small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; - small_mag_ptr->mag_num_objects += objects_in_use; - - // connect to magazine as first node - recirc_list_splice_first(szone, small_mag_ptr, node); - - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - - // madvise() outside the Depot lock -#if TARGET_OS_EMBEDDED - if (node->failedREUSE) { -#else - if (node->failedREUSE || - -1 == madvise((void *)sparse_region, SMALL_REGION_PAYLOAD_BYTES, MADV_FREE_REUSE)) { -#endif - /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ -#if DEBUG_MADVISE - szone_error(szone, 0, "small_get_region_from_depot madvise(..., MADV_FREE_REUSE) failed", - sparse_region, "length=%d\n", SMALL_REGION_PAYLOAD_BYTES); -#endif - node->failedREUSE = TRUE; - } - - MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE, - (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe - - return 1; -} - -#define K 1.5 // headroom measured in number of 8Mb regions -#define DENSITY_THRESHOLD(a) \ - ((a) - ((a) >> 2)) // "Emptiness" f = 0.25, so "Density" is (1 - f)*a. Generally: ((a) - ((a) >> -log2(f))) - -static INLINE boolean_t -small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize) -{ - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned index = SMALL_META_INDEX_FOR_PTR(ptr); - void *original_ptr = ptr; - size_t original_size = SMALL_BYTES_FOR_MSIZE(msize); - unsigned char *next_block = ((unsigned char *)ptr + original_size); - msize_t next_index = index + msize; - msize_t previous_msize, next_msize; - void *previous; - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } - if (!msize) { - szone_error(szone, 1, "trying to free small block that is too small", ptr, - "in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } -#endif - - // We try to coalesce this block with the preceeding one - if (index && (SMALL_PREVIOUS_MSIZE(ptr) <= index)) { - previous_msize = SMALL_PREVIOUS_MSIZE(ptr); - if (meta_headers[index - previous_msize] == (previous_msize | SMALL_IS_FREE)) { - previous = (void *)((uintptr_t)ptr - SMALL_BYTES_FOR_MSIZE(previous_msize)); - // previous is really to be coalesced -#if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone,previous)) { - malloc_printf("in small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); - } -#endif - small_free_list_remove_ptr(szone, small_mag_ptr, previous, previous_msize); - small_meta_header_set_middle(meta_headers, index); - ptr = previous; - msize += previous_msize; - index -= previous_msize; - } - } - // We try to coalesce with the next block - if ((next_block < SMALL_REGION_END(region)) && (meta_headers[next_index] & SMALL_IS_FREE)) { - // next block is free, we coalesce - next_msize = meta_headers[next_index] & ~ SMALL_IS_FREE; -#if DEBUG_MALLOC - if (LOG(szone,ptr)) - malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n", - ptr, msize, next_block, next_msize); -#endif - small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize); - small_meta_header_set_middle(meta_headers, next_index); - msize += next_msize; - } - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) { - if (!msize) { - szone_error(szone, 1, "incorrect size information - block header was damaged", ptr, NULL); - } else { - memset(ptr, 0x55, SMALL_BYTES_FOR_MSIZE(msize)); - } - } - small_free_list_add_ptr(szone, small_mag_ptr, ptr, msize); - small_mag_ptr->mag_num_objects--; - // we use original_size and not msize to avoid double counting the coalesced blocks - small_mag_ptr->mag_num_bytes_in_objects -= original_size; - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(region); - size_t bytes_used = node->bytes_used - original_size; - node->bytes_used = bytes_used; - -#if !TARGET_OS_EMBEDDED // Always madvise for embedded platforms - /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ - if (szone->num_small_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary - /* NOTHING */ - } else if (DEPOT_MAGAZINE_INDEX != mag_index) { - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) { - /* Region has crossed threshold from density to sparsity. Mark it "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = TRUE; - } else { - /* After this free, we've found the region is still dense, so it must have been even more so before - the free. That implies the region is already correctly marked. Do nothing. */ - } - - // Has the entire magazine crossed the "emptiness threshold"? If so, transfer a region - // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e - // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. - - size_t a = small_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine - size_t u = small_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine - - if (a - u > ((3 * SMALL_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) { - return small_free_do_recirc_to_depot(szone, small_mag_ptr, mag_index); - } - - } else { -#endif - // Freed to Depot. N.B. Lock on small_magazines[DEPOT_MAGAZINE_INDEX] is already held - // Calcuate the first page in the coalesced block that would be safe to mark MADV_FREE - uintptr_t safe_ptr = (uintptr_t)ptr + sizeof(free_list_t) + sizeof(msize_t); - uintptr_t round_safe = round_page(safe_ptr); - - // Calcuate the last page in the coalesced block that would be safe to mark MADV_FREE - uintptr_t safe_extent = (uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t); - uintptr_t trunc_extent = trunc_page(safe_extent); - - // The newly freed block may complete a span of bytes that cover one or more pages. Mark the span with MADV_FREE. - if (round_safe < trunc_extent) { // Safe area covers a page (perhaps many) - uintptr_t lo = trunc_page((uintptr_t)original_ptr); - uintptr_t hi = round_page((uintptr_t)original_ptr + original_size); - - small_free_list_remove_ptr(szone, small_mag_ptr, ptr, msize); - small_meta_header_set_in_use(meta_headers, index, msize); - - OSAtomicIncrement32Barrier(&(node->pinned_to_depot)); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); -#if TARGET_OS_EMBEDDED - madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi), &szone->last_small_advise); -#else - madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi)); -#endif - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - OSAtomicDecrement32Barrier(&(node->pinned_to_depot)); - - small_meta_header_set_is_free(meta_headers, index, msize); - small_free_list_add_ptr(szone, small_mag_ptr, ptr, msize); - } - -#if !TARGET_OS_EMBEDDED - if (0 < bytes_used || 0 < node->pinned_to_depot) { - /* Depot'd region is still live. Leave it in place on the Depot's recirculation list - so as to avoid thrashing between the Depot's free list and a magazines's free list - with detach_region/reattach_region */ - } else { - /* Depot'd region is just now empty. Consider return to OS. */ - region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, small_mag_ptr, node); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - if (r_dealloc) - deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0); - return FALSE; // Caller need not unlock - } - } -#endif - - return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr) -} - -// Allocates from the last region or a freshly allocated region -static void * -small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, - msize_t msize, void *aligned_address) -{ - void *ptr; - - // Before anything we transform the mag_bytes_free_at_end or mag_bytes_free_at_start - if any - to a regular free block - /* FIXME: last_block needs to be coalesced with previous entry if free, */ - if (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start) - small_finalize_region(szone, small_mag_ptr); - - // Here find the only place in smallville that (infrequently) takes the small_regions_lock. - // Only one thread at a time should be permitted to assess the density of the hash - // ring and adjust if needed. - // Only one thread at a time should be permitted to insert its new region on - // the hash ring. - // It is safe for all other threads to read the hash ring (hashed_regions) and - // the associated sizes (num_regions_allocated and num_small_regions). - - LOCK(szone->small_regions_lock); - // Check to see if the hash ring of small regions needs to grow. Try to - // avoid the hash ring becoming too dense. - if (szone->small_region_generation->num_regions_allocated < (2 * szone->num_small_regions)) { - region_t *new_regions; - size_t new_size; - size_t new_shift = szone->small_region_generation->num_regions_allocated_shift; // In/Out parameter - new_regions = hash_regions_grow_no_lock(szone, szone->small_region_generation->hashed_regions, - szone->small_region_generation->num_regions_allocated, - &new_shift, - &new_size); - // Do not deallocate the current hashed_regions allocation since someone - // may be iterating it. Instead, just leak it. - - // Prepare to advance to the "next generation" of the hash ring. - szone->small_region_generation->nextgen->hashed_regions = new_regions; - szone->small_region_generation->nextgen->num_regions_allocated = new_size; - szone->small_region_generation->nextgen->num_regions_allocated_shift = new_shift; - - // Throw the switch to atomically advance to the next generation. - szone->small_region_generation = szone->small_region_generation->nextgen; - // Ensure everyone sees the advance. - OSMemoryBarrier(); - } - // Tag the region at "aligned_address" as belonging to us, - // and so put it under the protection of the magazine lock we are holding. - // Do this before advertising "aligned_address" on the hash ring(!) - MAGAZINE_INDEX_FOR_SMALL_REGION(aligned_address) = mag_index; - - // Insert the new region into the hash ring, and update malloc statistics - hash_region_insert_no_lock(szone->small_region_generation->hashed_regions, - szone->small_region_generation->num_regions_allocated, - szone->small_region_generation->num_regions_allocated_shift, - aligned_address); - - szone->num_small_regions++; - - UNLOCK(szone->small_regions_lock); - - small_mag_ptr->mag_last_region = aligned_address; - BYTES_USED_FOR_SMALL_REGION(aligned_address) = SMALL_BYTES_FOR_MSIZE(msize); -#if ASLR_INTERNAL - int offset_msize = malloc_entropy[1] & SMALL_ENTROPY_MASK; -#if DEBUG_MALLOC - if (getenv("MallocASLRForce")) offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & SMALL_ENTROPY_MASK; - if (getenv("MallocASLRPrint")) malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize); -#endif -#else - int offset_msize = 0; -#endif - ptr = (void *)((uintptr_t) aligned_address + SMALL_BYTES_FOR_MSIZE(offset_msize)); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize, msize); - small_mag_ptr->mag_num_objects++; - small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(msize); - small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; - - // add a big free block at the end - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize + msize, NUM_SMALL_BLOCKS - msize - offset_msize); - small_mag_ptr->mag_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(NUM_SMALL_BLOCKS - msize - offset_msize); - -#if ASLR_INTERNAL - // add a big free block at the start - small_mag_ptr->mag_bytes_free_at_start = SMALL_BYTES_FOR_MSIZE(offset_msize); - if (offset_msize) { - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, offset_msize); - } -#else - small_mag_ptr->mag_bytes_free_at_start = 0; -#endif - - // connect to magazine as last node - recirc_list_splice_last(szone, small_mag_ptr, REGION_TRAILER_FOR_SMALL_REGION(aligned_address)); - - return ptr; -} - -static INLINE void * -small_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) -{ - msize_t new_msize = SMALL_MSIZE_FOR_BYTES(new_good_size); - msize_t mshrinkage = SMALL_MSIZE_FOR_BYTES(old_size) - new_msize; - - if (mshrinkage) { - void *q = (void *)((uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(new_msize)); - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)), - MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr))); - - // Mark q as block header and in-use, thus creating two blocks. - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), new_msize); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), mshrinkage); - small_mag_ptr->mag_num_objects++; - - SZONE_MAGAZINE_PTR_UNLOCK(szone,small_mag_ptr); - szone_free(szone, q); // avoid inlining free_small(szone, q, ...); - } - - return ptr; -} - -static INLINE boolean_t -small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) -{ - // returns 1 on success - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned index; - msize_t old_msize, new_msize; - unsigned next_index; - void *next_block; - msize_t next_msize_and_free; - boolean_t is_free; - msize_t next_msize, leftover_msize; - void *leftover; - - index = SMALL_META_INDEX_FOR_PTR(ptr); - old_msize = SMALL_MSIZE_FOR_BYTES(old_size); - new_msize = SMALL_MSIZE_FOR_BYTES(new_size + SMALL_QUANTUM - 1); - next_index = index + old_msize; - - if (next_index >= NUM_SMALL_BLOCKS) { - return 0; - } - next_block = (char *)ptr + old_size; - -#if DEBUG_MALLOC - if ((uintptr_t)next_block & (SMALL_QUANTUM - 1)) { - szone_error(szone, 1, "internal invariant broken in realloc(next_block)", next_block, NULL); - } - if (meta_headers[index] != old_msize) - malloc_printf("*** small_try_realloc_in_place incorrect old %d %d\n", - meta_headers[index], old_msize); -#endif - - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)), - MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr))); - - /* - * Look for a free block immediately afterwards. If it's large enough, we can consume (part of) - * it. - */ - next_msize_and_free = meta_headers[next_index]; - is_free = next_msize_and_free & SMALL_IS_FREE; - if (!is_free) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; // next_block is in use; - } - next_msize = next_msize_and_free & ~ SMALL_IS_FREE; - if (old_msize + next_msize < new_msize) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; // even with next block, not enough - } - /* - * The following block is big enough; pull it from its freelist and chop off enough to satisfy - * our needs. - */ - small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize); - small_meta_header_set_middle(meta_headers, next_index); - leftover_msize = old_msize + next_msize - new_msize; - if (leftover_msize) { - /* there's some left, so put the remainder back */ - leftover = (unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(new_msize); - - small_free_list_add_ptr(szone, small_mag_ptr, leftover, leftover_msize); - } -#if DEBUG_MALLOC - if (SMALL_BYTES_FOR_MSIZE(new_msize) > szone->large_threshold) { - malloc_printf("*** realloc in place for %p exceeded msize=%d\n", new_msize); - } -#endif - small_meta_header_set_in_use(meta_headers, index, new_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_try_realloc_in_place(), ptr=%p, msize=%d\n", ptr, *SMALL_METADATA_FOR_PTR(ptr)); - } -#endif - small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(new_msize - old_msize); - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - size_t bytes_used = node->bytes_used + SMALL_BYTES_FOR_MSIZE(new_msize - old_msize); - node->bytes_used = bytes_used; - - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) { - /* After this reallocation the region is still sparse, so it must have been even more so before - the reallocation. That implies the region is already correctly marked. Do nothing. */ - } else { - /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = FALSE; - } - - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return 1; -} - -static boolean_t -small_check_region(szone_t *szone, region_t region) -{ - unsigned char *ptr = SMALL_REGION_ADDRESS(region); - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned char *region_end = SMALL_REGION_END(region); - msize_t prev_free = 0; - unsigned index; - msize_t msize_and_free; - msize_t msize; - free_list_t *free_head; - void *previous, *next; - msize_t *follower; - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - // Assumes locked - CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); - - if (region == small_mag_ptr->mag_last_region) { - ptr += small_mag_ptr->mag_bytes_free_at_start; - region_end -= small_mag_ptr->mag_bytes_free_at_end; - } - - while (ptr < region_end) { - index = SMALL_META_INDEX_FOR_PTR(ptr); - msize_and_free = meta_headers[index]; - if (!(msize_and_free & SMALL_IS_FREE)) { - // block is in use - msize = msize_and_free; - if (!msize) { - malloc_printf("*** invariant broken: null msize ptr=%p num_small_regions=%d end=%p\n", - ptr, szone->num_small_regions, region_end); - return 0; - } -#if !RELAXED_INVARIANT_CHECKS - if (SMALL_BYTES_FOR_MSIZE(msize) > szone->large_threshold) { - malloc_printf("*** invariant broken for %p this small msize=%d - size is too large\n", - ptr, msize_and_free); - return 0; - } -#endif // RELAXED_INVARIANT_CHECKS - ptr += SMALL_BYTES_FOR_MSIZE(msize); - prev_free = 0; - } else { - // free pointer - msize = msize_and_free & ~ SMALL_IS_FREE; - free_head = (free_list_t *)ptr; - follower = (msize_t *)FOLLOWING_SMALL_PTR(ptr, msize); - if (!msize) { - malloc_printf("*** invariant broken for free block %p this msize=%d\n", ptr, msize); - return 0; - } -#if !RELAXED_INVARIANT_CHECKS - if (prev_free) { - malloc_printf("*** invariant broken for %p (2 free in a row)\n", ptr); - return 0; - } -#endif - previous = free_list_unchecksum_ptr(szone, &free_head->previous); - next = free_list_unchecksum_ptr(szone, &free_head->next); - if (previous && !SMALL_PTR_IS_FREE(previous)) { - malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", - ptr, free_head->previous); - return 0; - } - if (next && !SMALL_PTR_IS_FREE(next)) { - malloc_printf("*** invariant broken for %p (next is not a free pointer)\n", ptr); - return 0; - } - if (SMALL_PREVIOUS_MSIZE(follower) != msize) { - malloc_printf("*** invariant broken for small free %p followed by %p in region [%p-%p] " - "(end marker incorrect) should be %d; in fact %d\n", - ptr, follower, SMALL_REGION_ADDRESS(region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower)); - return 0; - } - ptr = (unsigned char *)follower; - prev_free = SMALL_IS_FREE; - } - } - return 1; -} - -static kern_return_t -small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, - memory_reader_t reader, vm_range_recorder_t recorder) -{ - size_t num_regions; - size_t index; - region_t *regions; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - kern_return_t err; - region_t region; - vm_range_t range; - vm_range_t admin_range; - vm_range_t ptr_range; - unsigned char *mapped_region; - msize_t *block_header; - unsigned block_index; - unsigned block_limit; - msize_t msize_and_free; - msize_t msize; - magazine_t *small_mag_base = NULL; - - region_hash_generation_t *srg_ptr; - err = reader(task, (vm_address_t)szone->small_region_generation, sizeof(region_hash_generation_t), (void **)&srg_ptr); - if (err) return err; - - num_regions = srg_ptr->num_regions_allocated; - err = reader(task, (vm_address_t)srg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions); - if (err) return err; - - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - // Map in all active magazines. Do this outside the iteration over regions. - err = reader(task, (vm_address_t)(szone->small_magazines), - szone->num_small_magazines*sizeof(magazine_t),(void **)&small_mag_base); - if (err) return err; - } - - for (index = 0; index < num_regions; ++index) { - region = regions[index]; - if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { - range.address = (vm_address_t)SMALL_REGION_ADDRESS(region); - range.size = SMALL_REGION_SIZE; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - admin_range.address = range.address + SMALL_METADATA_START; - admin_range.size = SMALL_METADATA_SIZE; - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); - } - if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { - ptr_range.address = range.address; - ptr_range.size = NUM_SMALL_BLOCKS * SMALL_QUANTUM; - recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); - } - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - void *mag_last_free; - vm_address_t mag_last_free_ptr = 0; - msize_t mag_last_free_msize = 0; - - err = reader(task, range.address, range.size, (void **)&mapped_region); - if (err) - return err; - - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(mapped_region); - magazine_t *small_mag_ptr = small_mag_base + mag_index; - - if (DEPOT_MAGAZINE_INDEX != mag_index) { - mag_last_free = small_mag_ptr->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(SMALL_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (SMALL_QUANTUM - 1); - } - } else { - for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { - if ((void *)range.address == (small_mag_base + mag_index)->mag_last_free_rgn) { - mag_last_free = (small_mag_base + mag_index)->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(SMALL_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (SMALL_QUANTUM - 1); - } - } - } - } - - block_header = (msize_t *)(mapped_region + SMALL_METADATA_START + sizeof(region_trailer_t)); - block_index = 0; - block_limit = NUM_SMALL_BLOCKS; - if (region == small_mag_ptr->mag_last_region) { - block_index += SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start); - block_limit -= SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end); - } - while (block_index < block_limit) { - msize_and_free = block_header[block_index]; - msize = msize_and_free & ~ SMALL_IS_FREE; - if (! (msize_and_free & SMALL_IS_FREE) && - range.address + SMALL_BYTES_FOR_MSIZE(block_index) != mag_last_free_ptr) { - // Block in use - buffer[count].address = range.address + SMALL_BYTES_FOR_MSIZE(block_index); - buffer[count].size = SMALL_BYTES_FOR_MSIZE(msize); - count++; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } - - if (!msize) - return KERN_FAILURE; // Somethings amiss. Avoid looping at this block_index. - - block_index += msize; - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } - } - } - return 0; -} - -static void * -small_malloc_from_free_list(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - free_list_t *ptr; - msize_t this_msize; - grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; - free_list_t **free_list = small_mag_ptr->mag_free_list; - free_list_t **the_slot = free_list + slot; - free_list_t *next; - free_list_t **limit; - unsigned bitmap; - msize_t leftover_msize; - free_list_t *leftover_ptr; - - // Assumes we've locked the region - CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); - - // Look for an exact match by checking the freelist for this msize. - // - ptr = *the_slot; - if (ptr) { - next = free_list_unchecksum_ptr(szone, &ptr->next); - if (next) { - next->previous = ptr->previous; - } else { - BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot); - } - *the_slot = next; - this_msize = msize; - goto return_small_alloc; - } - - // Mask off the bits representing slots holding free blocks smaller than - // the size we need. If there are no larger free blocks, try allocating - // from the free space at the end of the small region. - if (szone->is_largemem) { - // BITMAPN_CTZ implementation - unsigned idx = slot >> 5; - bitmap = 0; - unsigned mask = ~ ((1 << (slot & 31)) - 1); - for ( ; idx < SMALL_BITMAP_WORDS; ++idx ) { - bitmap = small_mag_ptr->mag_bitmap[idx] & mask; - if (bitmap != 0) - break; - mask = ~0U; - } - // Check for fallthrough: No bits set in bitmap - if ((bitmap == 0) && (idx == SMALL_BITMAP_WORDS)) - goto try_small_from_end; - - // Start looking at the first set bit, plus 32 bits for every word of - // zeroes or entries that were too small. - slot = BITMAP32_CTZ((&bitmap)) + (idx * 32); - } else { - bitmap = small_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1); - if (!bitmap) - goto try_small_from_end; - - slot = BITMAP32_CTZ((&bitmap)); - } - // FIXME: Explain use of - 1 here, last slot has special meaning - limit = free_list + szone->num_small_slots - 1; - free_list += slot; - - if (free_list < limit) { - ptr = *free_list; - if (ptr) { - - next = free_list_unchecksum_ptr(szone, &ptr->next); - *free_list = next; - if (next) { - next->previous = ptr->previous; - } else { - BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot); - } - this_msize = SMALL_PTR_SIZE(ptr); - goto add_leftover_and_proceed; - } -#if DEBUG_MALLOC - malloc_printf("in small_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n",slot); -#endif - } - - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than (num_small_slots - 1) * (small quantum size). - // If the last freelist is not empty, and the head contains a block that is - // larger than our request, then the remainder is put back on the free list. - // - ptr = *limit; - if (ptr) { - this_msize = SMALL_PTR_SIZE(ptr); - next = free_list_unchecksum_ptr(szone, &ptr->next); - if (this_msize - msize >= szone->num_small_slots) { - // the leftover will go back to the free list, so we optimize by - // modifying the free list rather than a pop and push of the head - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)); - *limit = leftover_ptr; - if (next) { - next->previous.u = free_list_checksum_ptr(szone, leftover_ptr); - } - leftover_ptr->previous = ptr->previous; - leftover_ptr->next = ptr->next; - small_meta_header_set_is_free(SMALL_META_HEADER_FOR_PTR(leftover_ptr), - SMALL_META_INDEX_FOR_PTR(leftover_ptr), leftover_msize); - // Store msize at the end of the block denoted by "leftover_ptr" (i.e. at a negative offset from follower) - SMALL_PREVIOUS_MSIZE(FOLLOWING_SMALL_PTR(leftover_ptr, leftover_msize)) = leftover_msize; // Access is safe -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize); - } -#endif - this_msize = msize; - goto return_small_alloc; - } - if (next) { - next->previous = ptr->previous; - } - *limit = next; - goto add_leftover_and_proceed; - } - -try_small_from_end: - // Let's see if we can use small_mag_ptr->mag_bytes_free_at_end - if (small_mag_ptr->mag_bytes_free_at_end >= SMALL_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)(SMALL_REGION_END(small_mag_ptr->mag_last_region) - - small_mag_ptr->mag_bytes_free_at_end); - small_mag_ptr->mag_bytes_free_at_end -= SMALL_BYTES_FOR_MSIZE(msize); - if (small_mag_ptr->mag_bytes_free_at_end) { - // let's mark this block as in use to serve as boundary - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), - SMALL_META_INDEX_FOR_PTR((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)), - SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end)); - } - this_msize = msize; - goto return_small_alloc; - } -#if ASLR_INTERNAL - // Try from start if nothing left at end - if (small_mag_ptr->mag_bytes_free_at_start >= SMALL_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)(SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region) + - small_mag_ptr->mag_bytes_free_at_start - SMALL_BYTES_FOR_MSIZE(msize)); - small_mag_ptr->mag_bytes_free_at_start -= SMALL_BYTES_FOR_MSIZE(msize); - if (small_mag_ptr->mag_bytes_free_at_start) { - // let's mark this block as in use to serve as boundary - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start)); - } - this_msize = msize; - goto return_small_alloc; - } -#endif - return NULL; - -add_leftover_and_proceed: - if (this_msize > msize) { - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); - } -#endif - small_free_list_add_ptr(szone, small_mag_ptr, leftover_ptr, leftover_msize); - this_msize = msize; - } - -return_small_alloc: - small_mag_ptr->mag_num_objects++; - small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(this_msize); - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - size_t bytes_used = node->bytes_used + SMALL_BYTES_FOR_MSIZE(this_msize); - node->bytes_used = bytes_used; - - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) { - /* After this allocation the region is still sparse, so it must have been even more so before - the allocation. That implies the region is already correctly marked. Do nothing. */ - } else { - /* Region has crossed threshold from sparsity to density. Mark in not "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = FALSE; - } -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); - } -#endif - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), this_msize); - return ptr; -} -#undef DENSITY_THRESHOLD -#undef K - -static INLINE void * -small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) -{ - void *ptr; - mag_index_t mag_index = mag_get_thread_index(szone); - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - -#if SMALL_CACHE - ptr = (void *)small_mag_ptr->mag_last_free; - - if ((((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) == msize) { - // we have a winner - small_mag_ptr->mag_last_free = NULL; - small_mag_ptr->mag_last_free_rgn = NULL; - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - ptr = (void *)((uintptr_t)ptr & ~ (SMALL_QUANTUM - 1)); - if (cleared_requested) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } -#endif /* SMALL_CACHE */ - - while(1) { - ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - - if (small_get_region_from_depot(szone, small_mag_ptr, mag_index, msize)) { - ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - } - - // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc(). - // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first - // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section. - // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the - // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation, - // and retry-ing threads succeed in the code just above. - if (!small_mag_ptr->alloc_underway) { - void *fresh_region; - - // time to create a new region (do this outside the magazine lock) - small_mag_ptr->alloc_underway = TRUE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - fresh_region = allocate_pages_securely(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, VM_MEMORY_MALLOC_SMALL); - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - - MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, SMALL_REGION_SIZE); // DTrace USDT Probe - - if (!fresh_region) { // out of memory! - small_mag_ptr->alloc_underway = FALSE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return NULL; - } - - ptr = small_malloc_from_region_no_lock(szone, small_mag_ptr, mag_index, msize, fresh_region); - - // we don't clear because this freshly allocated space is pristine - small_mag_ptr->alloc_underway = FALSE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return ptr; - } else { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - pthread_yield_np(); - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - } - } - /* NOTREACHED */ -} - -static NOINLINE void -free_small_botch(szone_t *szone, free_list_t *ptr) -{ - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - szone_error(szone, 1, "double free", ptr, NULL); -} - -static INLINE void -free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size) -{ - msize_t msize; - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - // ptr is known to be in small_region - if (known_size) { - msize = SMALL_MSIZE_FOR_BYTES(known_size + SMALL_QUANTUM - 1); - } else { - msize = SMALL_PTR_SIZE(ptr); - if (SMALL_PTR_IS_FREE(ptr)) { - free_small_botch(szone, ptr); - return; - } - } - - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - -#if SMALL_CACHE - // Depot does not participate in SMALL_CACHE since it can't be directly malloc()'d - if (DEPOT_MAGAZINE_INDEX != mag_index) { - - void *ptr2 = small_mag_ptr->mag_last_free; // Might be NULL - region_t rgn2 = small_mag_ptr->mag_last_free_rgn; - - /* check that we don't already have this pointer in the cache */ - if (ptr == (void *)((uintptr_t)ptr2 & ~ (SMALL_QUANTUM - 1))) { - free_small_botch(szone, ptr); - return; - } - - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) - memset(ptr, 0x55, SMALL_BYTES_FOR_MSIZE(msize)); - - small_mag_ptr->mag_last_free = (void *)(((uintptr_t)ptr) | msize); - small_mag_ptr->mag_last_free_rgn = small_region; - - if (!ptr2) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return; - } - - msize = (uintptr_t)ptr2 & (SMALL_QUANTUM - 1); - ptr = (void *)(((uintptr_t)ptr2) & ~(SMALL_QUANTUM - 1)); - small_region = rgn2; - } -#endif /* SMALL_CACHE */ - - // Now in the time it took to acquire the lock, the region may have migrated - // from one magazine to another. I.e. trailer->mag_index is volatile. - // In which case the magazine lock we obtained (namely magazines[mag_index].mag_lock) - // is stale. If so, keep on tryin' ... - region_trailer_t *trailer = REGION_TRAILER_FOR_SMALL_REGION(small_region); - mag_index_t refreshed_index; - - while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment - - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - - mag_index = refreshed_index; - small_mag_ptr = &(szone->small_magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - } - - if (small_free_no_lock(szone, small_mag_ptr, mag_index, small_region, ptr, msize)) - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - - CHECK(szone, __PRETTY_FUNCTION__); -} - -static void -print_small_free_list(szone_t *szone) -{ - free_list_t *ptr; - _SIMPLE_STRING b = _simple_salloc(); - mag_index_t mag_index; - - if (b) { - _simple_sappend(b, "small free sizes:\n"); - for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - grain_t slot = 0; - _simple_sprintf(b,"\tMagazine %d: ", mag_index); - while (slot < szone->num_small_slots) { - ptr = szone->small_magazines[mag_index].mag_free_list[slot]; - if (ptr) { - _simple_sprintf(b, "%s%y[%d]; ", (slot == szone->num_small_slots-1) ? ">=" : "", - (slot + 1) * SMALL_QUANTUM, free_list_count(szone, ptr)); - } - slot++; - } - _simple_sappend(b,"\n"); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static void -print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end) -{ - unsigned counts[1024]; - unsigned in_use = 0; - uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(region); - uintptr_t current = start + bytes_at_start; - uintptr_t limit = (uintptr_t)SMALL_REGION_END(region) - bytes_at_end; - msize_t msize_and_free; - msize_t msize; - unsigned ci; - _SIMPLE_STRING b; - uintptr_t pgTot = 0; - - if (region == HASHRING_REGION_DEALLOCATED) { - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Small region [unknown address] was returned to the OS\n"); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } - return; - } - - memset(counts, 0, sizeof(counts)); - while (current < limit) { - msize_and_free = *SMALL_METADATA_FOR_PTR(current); - msize = msize_and_free & ~ SMALL_IS_FREE; - if (!msize) { - malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize); - break; - } - if (!(msize_and_free & SMALL_IS_FREE)) { - // block in use - if (msize < 1024) - counts[msize]++; - in_use++; - } else { - uintptr_t pgLo = round_page(current + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); - - if (pgLo < pgHi) { - pgTot += (pgHi - pgLo); - } - } - current += SMALL_BYTES_FOR_MSIZE(msize); - } - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Small region [%p-%p, %y] \t", (void *)start, SMALL_REGION_END(region), (int)SMALL_REGION_SIZE); - _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_SMALL_REGION(region)); - _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_SMALL_REGION(region)); - if (bytes_at_end || bytes_at_start) - _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start); - if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_SMALL_REGION(region)) { - _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot); - } else { - _simple_sprintf(b, "Fragments subject to reclamation=%ly", pgTot); - } - if (verbose && in_use) { - _simple_sappend(b, "\n\tSizes in use: "); - for (ci = 0; ci < 1024; ci++) - if (counts[ci]) - _simple_sprintf(b, "%d[%d] ", SMALL_BYTES_FOR_MSIZE(ci), counts[ci]); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static boolean_t -small_free_list_check(szone_t *szone, grain_t slot) -{ - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - - unsigned count = 0; - free_list_t *ptr = szone->small_magazines[mag_index].mag_free_list[slot]; - msize_t msize_and_free; - free_list_t *previous = NULL; - - while (ptr) { - msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); - if (!(msize_and_free & SMALL_IS_FREE)) { - malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; - } - if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { - malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; - } - if (!small_region_for_ptr_no_lock(szone, ptr)) { - malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; - } - if (free_list_unchecksum_ptr(szone, &ptr->previous) != previous) { - malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; - } - previous = ptr; - ptr = free_list_unchecksum_ptr(szone, &ptr->next); - count++; - } - - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - } - return 1; -} - -/******************************************************************************* - * Large allocator implementation - ******************************************************************************/ -#pragma mark large allocator - -#if DEBUG_MALLOC - -static void -large_debug_print(szone_t *szone) -{ - unsigned index; - large_entry_t *range; - _SIMPLE_STRING b = _simple_salloc(); - - if (b) { - for (index = 0, range = szone->large_entries; index < szone->num_large_entries; index++, range++) - if (range->address) - _simple_sprintf(b, "%d: %p(%y); ", index, range->address, range->size); - - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} -#endif - -/* - * Scan the hash ring looking for an entry for the given pointer. - */ -static large_entry_t * -large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr) -{ - // result only valid with lock held - unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index; - unsigned index; - large_entry_t *range; - - if (!num_large_entries) - return NULL; - - hash_index = ((uintptr_t)ptr >> vm_page_shift) % num_large_entries; - index = hash_index; - - do { - range = szone->large_entries + index; - if (range->address == (vm_address_t)ptr) - return range; - if (0 == range->address) - return NULL; // end of chain - index++; - if (index == num_large_entries) - index = 0; - } while (index != hash_index); - - return NULL; -} - -static void -large_entry_insert_no_lock(szone_t *szone, large_entry_t range) -{ - unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index = (((uintptr_t)(range.address)) >> vm_page_shift) % num_large_entries; - unsigned index = hash_index; - large_entry_t *entry; - - // assert(szone->num_large_objects_in_use < szone->num_large_entries); /* must be called with room to spare */ - - do { - entry = szone->large_entries + index; - if (0 == entry->address) { - *entry = range; - return; // end of chain - } - index++; - if (index == num_large_entries) - index = 0; - } while (index != hash_index); - - // assert(0); /* must not fallthrough! */ -} - -// FIXME: can't we simply swap the (now empty) entry with the last entry on the collision chain for this hash slot? -static INLINE void -large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) -{ - unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index = entry - szone->large_entries; - unsigned index = hash_index; - large_entry_t range; - - // assert(entry->address == 0) /* caller must have cleared *entry */ - - do { - index++; - if (index == num_large_entries) - index = 0; - range = szone->large_entries[index]; - if (0 == range.address) - return; - szone->large_entries[index].address = (vm_address_t)0; - szone->large_entries[index].size = 0; - szone->large_entries[index].did_madvise_reusable = FALSE; - large_entry_insert_no_lock(szone, range); // this will reinsert in the - // proper place - } while (index != hash_index); - - // assert(0); /* since entry->address == 0, must not fallthrough! */ -} - -// FIXME: num should probably be a size_t, since you can theoretically allocate -// more than 2^32-1 large_threshold objects in 64 bit. -static INLINE large_entry_t * -large_entries_alloc_no_lock(szone_t *szone, unsigned num) -{ - size_t size = num * sizeof(large_entry_t); - - // Note that we allocate memory (via a system call) under a spin lock - // That is certainly evil, however it's very rare in the lifetime of a process - // The alternative would slow down the normal case - return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC_LARGE); -} - -static void -large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate) -{ - size_t size = num * sizeof(large_entry_t); - - range_to_deallocate->address = (vm_address_t)entries; - range_to_deallocate->size = round_page(size); -} - -static large_entry_t * -large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) -{ - // sets range_to_deallocate - unsigned old_num_entries = szone->num_large_entries; - large_entry_t *old_entries = szone->large_entries; - // always an odd number for good hashing - unsigned new_num_entries = (old_num_entries) ? old_num_entries * 2 + 1 : - ((vm_page_size / sizeof(large_entry_t)) - 1); - large_entry_t *new_entries = large_entries_alloc_no_lock(szone, new_num_entries); - unsigned index = old_num_entries; - large_entry_t oldRange; - - // if the allocation of new entries failed, bail - if (new_entries == NULL) - return NULL; - - szone->num_large_entries = new_num_entries; - szone->large_entries = new_entries; - - /* rehash entries into the new list */ - while (index--) { - oldRange = old_entries[index]; - if (oldRange.address) { - large_entry_insert_no_lock(szone, oldRange); - } - } - - if (old_entries) { - large_entries_free_no_lock(szone, old_entries, old_num_entries, range_to_deallocate); - } else { - range_to_deallocate->address = (vm_address_t)0; - range_to_deallocate->size = 0; - } - - return new_entries; -} - -// frees the specific entry in the size table -// returns a range to truly deallocate -static vm_range_t -large_entry_free_no_lock(szone_t *szone, large_entry_t *entry) -{ - vm_range_t range; - - range.address = entry->address; - range.size = entry->size; - - if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) { - protect((void *)range.address, range.size, PROT_READ | PROT_WRITE, szone->debug_flags); - range.address -= vm_page_size; - range.size += 2 * vm_page_size; - } - - entry->address = 0; - entry->size = 0; - entry->did_madvise_reusable = FALSE; - large_entries_rehash_after_entry_no_lock(szone, entry); - -#if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, (void *)range.address)) { - malloc_printf("*** freed entry %p still in use; num_large_entries=%d\n", - range.address, szone->num_large_entries); - large_debug_print(szone); - szone_sleep(); - } -#endif - return range; -} - -static NOINLINE kern_return_t -large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, - unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder) -{ - unsigned index = 0; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - large_entry_t *entries; - kern_return_t err; - vm_range_t range; - large_entry_t entry; - - err = reader(task, large_entries_address, sizeof(large_entry_t) * num_entries, (void **)&entries); - if (err) - return err; - - index = num_entries; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - range.address = large_entries_address; - range.size = round_page(num_entries * sizeof(large_entry_t)); - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &range, 1); - } - if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE)) { - while (index--) { - entry = entries[index]; - if (entry.address) { - range.address = entry.address; - range.size = entry.size; - buffer[count++] = range; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, - buffer, count); - count = 0; - } - } - } - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, - buffer, count); - } - return 0; -} - -static void * -large_malloc(szone_t *szone, size_t num_pages, unsigned char alignment, - boolean_t cleared_requested) -{ - void *addr; - vm_range_t range_to_deallocate; - size_t size; - large_entry_t large_entry; - - if (!num_pages) - num_pages = 1; // minimal allocation size for this szone - size = (size_t)num_pages << vm_page_shift; - range_to_deallocate.size = 0; - range_to_deallocate.address = 0; - -#if LARGE_CACHE - if (size < LARGE_CACHE_SIZE_ENTRY_LIMIT) { // Look for a large_entry_t on the death-row cache? - SZONE_LOCK(szone); - - int i, best = -1, idx = szone->large_entry_cache_newest, stop_idx = szone->large_entry_cache_oldest; - size_t best_size = SIZE_T_MAX; - - while (1) { // Scan large_entry_cache for best fit, starting with most recent entry - size_t this_size = szone->large_entry_cache[idx].size; - addr = (void *)szone->large_entry_cache[idx].address; - - if (0 == alignment || 0 == (((uintptr_t) addr) & (((uintptr_t) 1 << alignment) - 1))) { - if (size == this_size) { // size match! - best = idx; - best_size = this_size; - break; - } - - if (size <= this_size && this_size < best_size) { // improved fit? - best = idx; - best_size = this_size; - } - } - - if (idx == stop_idx) // exhausted live ring? - break; - - if (idx) - idx--; // bump idx down - else - idx = LARGE_ENTRY_CACHE_SIZE - 1; // wrap idx - } - - if (best > -1 && (best_size - size) < size) { //limit fragmentation to 50% - addr = (void *)szone->large_entry_cache[best].address; - boolean_t was_madvised_reusable = szone->large_entry_cache[best].did_madvise_reusable; - - // Compact live ring to fill entry now vacated at large_entry_cache[best] - // while preserving time-order - if (szone->large_entry_cache_oldest < szone->large_entry_cache_newest) { - - // Ring hasn't wrapped. Fill in from right. - for (i = best; i < szone->large_entry_cache_newest; ++i) - szone->large_entry_cache[i] = szone->large_entry_cache[i + 1]; - - szone->large_entry_cache_newest--; // Pull in right endpoint. - - } else if (szone->large_entry_cache_newest < szone->large_entry_cache_oldest) { - - // Ring has wrapped. Arrange to fill in from the contiguous side. - if (best <= szone->large_entry_cache_newest) { - // Fill from right. - for (i = best; i < szone->large_entry_cache_newest; ++i) - szone->large_entry_cache[i] = szone->large_entry_cache[i + 1]; - - if (0 < szone->large_entry_cache_newest) - szone->large_entry_cache_newest--; - else - szone->large_entry_cache_newest = LARGE_ENTRY_CACHE_SIZE - 1; - } else { - // Fill from left. - for ( i = best; i > szone->large_entry_cache_oldest; --i) - szone->large_entry_cache[i] = szone->large_entry_cache[i - 1]; - - if (szone->large_entry_cache_oldest < LARGE_ENTRY_CACHE_SIZE - 1) - szone->large_entry_cache_oldest++; - else - szone->large_entry_cache_oldest = 0; - } - - } else { - // By trichotomy, large_entry_cache_newest == large_entry_cache_oldest. - // That implies best == large_entry_cache_newest == large_entry_cache_oldest - // and the ring is now empty. - szone->large_entry_cache[best].address = 0; - szone->large_entry_cache[best].size = 0; - szone->large_entry_cache[best].did_madvise_reusable = FALSE; - } - - if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) { - // density of hash table too high; grow table - // we do that under lock to avoid a race - large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate); - if (entries == NULL) { - SZONE_UNLOCK(szone); - return NULL; - } - } - - large_entry.address = (vm_address_t)addr; - large_entry.size = best_size; - large_entry.did_madvise_reusable = FALSE; - large_entry_insert_no_lock(szone, large_entry); - - szone->num_large_objects_in_use ++; - szone->num_bytes_in_large_objects += best_size; - if (!was_madvised_reusable) - szone->large_entry_cache_reserve_bytes -= best_size; - - szone->large_entry_cache_bytes -= best_size; - - if (szone->flotsam_enabled && szone->large_entry_cache_bytes < SZONE_FLOTSAM_THRESHOLD_LOW) { - szone->flotsam_enabled = FALSE; - } - - SZONE_UNLOCK(szone); - - if (range_to_deallocate.size) { - // we deallocate outside the lock - deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); - } - - // Perform the madvise() outside the lock. - // Typically the madvise() is successful and we'll quickly return from this routine. - // In the unusual case of failure, reacquire the lock to unwind. -#if TARGET_OS_EMBEDDED - // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large - // cache block twice without MADV_FREE_REUSE in between. -#endif - if (was_madvised_reusable && -1 == madvise(addr, size, MADV_FREE_REUSE)) { - /* -1 return: VM map entry change makes this unfit for reuse. */ -#if DEBUG_MADVISE - szone_error(szone, 0, "large_malloc madvise(..., MADV_FREE_REUSE) failed", - addr, "length=%d\n", size); -#endif - - SZONE_LOCK(szone); - szone->num_large_objects_in_use--; - szone->num_bytes_in_large_objects -= large_entry.size; - - // Re-acquire "entry" after interval just above where we let go the lock. - large_entry_t *entry = large_entry_for_pointer_no_lock(szone, addr); - if (NULL == entry) { - szone_error(szone, 1, "entry for pointer being discarded from death-row vanished", addr, NULL); - SZONE_UNLOCK(szone); - } else { - - range_to_deallocate = large_entry_free_no_lock(szone, entry); - SZONE_UNLOCK(szone); - - if (range_to_deallocate.size) { - // we deallocate outside the lock - deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); - } - } - /* Fall through to allocate_pages() afresh. */ - } else { - if (cleared_requested) { - memset(addr, 0, size); - } - - return addr; - } - } else { - SZONE_UNLOCK(szone); - } - } - - range_to_deallocate.size = 0; - range_to_deallocate.address = 0; -#endif /* LARGE_CACHE */ - - addr = allocate_pages(szone, size, alignment, szone->debug_flags, VM_MEMORY_MALLOC_LARGE); - if (addr == NULL) { - return NULL; - } - - SZONE_LOCK(szone); - if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) { - // density of hash table too high; grow table - // we do that under lock to avoid a race - large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate); - if (entries == NULL) { - SZONE_UNLOCK(szone); - return NULL; - } - } - - large_entry.address = (vm_address_t)addr; - large_entry.size = size; - large_entry.did_madvise_reusable = FALSE; - large_entry_insert_no_lock(szone, large_entry); - - szone->num_large_objects_in_use ++; - szone->num_bytes_in_large_objects += size; - SZONE_UNLOCK(szone); - - if (range_to_deallocate.size) { - // we deallocate outside the lock - deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); - } - return addr; -} - -static NOINLINE void -free_large(szone_t *szone, void *ptr) -{ - // We have established ptr is page-aligned and neither tiny nor small - large_entry_t *entry; - vm_range_t vm_range_to_deallocate; - - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (entry) { -#if LARGE_CACHE -#ifndef MADV_CAN_REUSE -#define MADV_CAN_REUSE 9 /* per Francois, for testing until xnu is resubmitted to B&I */ -#endif - if (entry->size < LARGE_CACHE_SIZE_ENTRY_LIMIT && - -1 != madvise((void *)(entry->address), entry->size, MADV_CAN_REUSE)) { // Put the large_entry_t on the death-row cache? - int idx = szone->large_entry_cache_newest, stop_idx = szone->large_entry_cache_oldest; - large_entry_t this_entry = *entry; // Make a local copy, "entry" is volatile when lock is let go. - boolean_t reusable = TRUE; - boolean_t should_madvise = szone->large_entry_cache_reserve_bytes + this_entry.size > szone->large_entry_cache_reserve_limit; - - // Already freed? - // [Note that repeated entries in death-row risk vending the same entry subsequently - // to two different malloc() calls. By checking here the (illegal) double free - // is accommodated, matching the behavior of the previous implementation.] - while (1) { // Scan large_entry_cache starting with most recent entry - if (szone->large_entry_cache[idx].address == entry->address) { - szone_error(szone, 1, "pointer being freed already on death-row", ptr, NULL); - SZONE_UNLOCK(szone); - return; - } - - if (idx == stop_idx) // exhausted live ring? - break; - - if (idx) - idx--; // bump idx down - else - idx = LARGE_ENTRY_CACHE_SIZE - 1; // wrap idx - } - - SZONE_UNLOCK(szone); - - if (szone->debug_flags & SCALABLE_MALLOC_PURGEABLE) { // Are we a purgable zone? - int state = VM_PURGABLE_NONVOLATILE; // restore to default condition - - if (KERN_SUCCESS != vm_purgable_control(mach_task_self(), this_entry.address, VM_PURGABLE_SET_STATE, &state)) { - malloc_printf("*** can't vm_purgable_control(..., VM_PURGABLE_SET_STATE) for large freed block at %p\n", - this_entry.address); - reusable = FALSE; - } - } - - if (szone->large_legacy_reset_mprotect) { // Linked for Leopard? - // Accomodate Leopard apps that (illegally) mprotect() their own guard pages on large malloc'd allocations - int err = mprotect((void *)(this_entry.address), this_entry.size, PROT_READ | PROT_WRITE); - if (err) { - malloc_printf("*** can't reset protection for large freed block at %p\n", this_entry.address); - reusable = FALSE; - } - } - - // madvise(..., MADV_REUSABLE) death-row arrivals if hoarding would exceed large_entry_cache_reserve_limit - if (should_madvise) { - // Issue madvise to avoid paging out the dirtied free()'d pages in "entry" - MAGMALLOC_MADVFREEREGION((void *)szone, (void *)0, (void *)(this_entry.address), this_entry.size); // DTrace USDT Probe - -#if TARGET_OS_EMBEDDED - // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large - // cache block twice without MADV_FREE_REUSE in between. -#endif - if (-1 == madvise((void *)(this_entry.address), this_entry.size, MADV_FREE_REUSABLE)) { - /* -1 return: VM map entry change makes this unfit for reuse. */ -#if DEBUG_MADVISE - szone_error(szone, 0, "free_large madvise(..., MADV_FREE_REUSABLE) failed", - (void *)this_entry.address, "length=%d\n", this_entry.size); -#endif - reusable = FALSE; - } - } - - SZONE_LOCK(szone); - - // Re-acquire "entry" after interval just above where we let go the lock. - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (NULL == entry) { - szone_error(szone, 1, "entry for pointer being freed from death-row vanished", ptr, NULL); - SZONE_UNLOCK(szone); - return; - } - - // Add "entry" to death-row ring - if (reusable) { - int idx = szone->large_entry_cache_newest; // Most recently occupied - vm_address_t addr; - size_t adjsize; - - if (szone->large_entry_cache_newest == szone->large_entry_cache_oldest && - 0 == szone->large_entry_cache[idx].address) { - // Ring is empty, idx is good as it stands - addr = 0; - adjsize = 0; - } else { - // Extend the queue to the "right" by bumping up large_entry_cache_newest - if (idx == LARGE_ENTRY_CACHE_SIZE - 1) - idx = 0; // Wrap index - else - idx++; // Bump index - - if (idx == szone->large_entry_cache_oldest) { // Fully occupied - // Drop this entry from the cache and deallocate the VM - addr = szone->large_entry_cache[idx].address; - adjsize = szone->large_entry_cache[idx].size; - szone->large_entry_cache_bytes -= adjsize; - if (!szone->large_entry_cache[idx].did_madvise_reusable) - szone->large_entry_cache_reserve_bytes -= adjsize; - } else { - // Using an unoccupied cache slot - addr = 0; - adjsize = 0; - } - } - - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE)) - memset((void *)(entry->address), 0x55, entry->size); - - entry->did_madvise_reusable = should_madvise; // Was madvise()'d above? - if (!should_madvise) // Entered on death-row without madvise() => up the hoard total - szone->large_entry_cache_reserve_bytes += entry->size; - - szone->large_entry_cache_bytes += entry->size; - - if (!szone->flotsam_enabled && szone->large_entry_cache_bytes > SZONE_FLOTSAM_THRESHOLD_HIGH) { - szone->flotsam_enabled = TRUE; - } - - szone->large_entry_cache[idx] = *entry; - szone->large_entry_cache_newest = idx; - - szone->num_large_objects_in_use--; - szone->num_bytes_in_large_objects -= entry->size; - - (void)large_entry_free_no_lock(szone, entry); - - if (0 == addr) { - SZONE_UNLOCK(szone); - return; - } - - // Fall through to drop large_entry_cache_oldest from the cache, - // and then deallocate its pages. - - // Trim the queue on the "left" by bumping up large_entry_cache_oldest - if (szone->large_entry_cache_oldest == LARGE_ENTRY_CACHE_SIZE - 1) - szone->large_entry_cache_oldest = 0; - else - szone->large_entry_cache_oldest++; - - // we deallocate_pages, including guard pages, outside the lock - SZONE_UNLOCK(szone); - deallocate_pages(szone, (void *)addr, (size_t)adjsize, 0); - return; - } else { - /* fall through to discard an allocation that is not reusable */ - } - } -#endif /* LARGE_CACHE */ - - szone->num_large_objects_in_use--; - szone->num_bytes_in_large_objects -= entry->size; - - vm_range_to_deallocate = large_entry_free_no_lock(szone, entry); - } else { -#if DEBUG_MALLOC - large_debug_print(szone); -#endif - szone_error(szone, 1, "pointer being freed was not allocated", ptr, NULL); - SZONE_UNLOCK(szone); - return; - } - SZONE_UNLOCK(szone); // we release the lock asap - CHECK(szone, __PRETTY_FUNCTION__); - - // we deallocate_pages, including guard pages, outside the lock - if (vm_range_to_deallocate.address) { -#if DEBUG_MALLOC - // FIXME: large_entry_for_pointer_no_lock() needs the lock held ... - if (large_entry_for_pointer_no_lock(szone, (void *)vm_range_to_deallocate.address)) { - malloc_printf("*** invariant broken: %p still in use num_large_entries=%d\n", - vm_range_to_deallocate.address, szone->num_large_entries); - large_debug_print(szone); - szone_sleep(); - } -#endif - deallocate_pages(szone, (void *)vm_range_to_deallocate.address, (size_t)vm_range_to_deallocate.size, 0); - } -} - -static INLINE void * -large_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) -{ - size_t shrinkage = old_size - new_good_size; - - if (shrinkage) { - SZONE_LOCK(szone); - /* contract existing large entry */ - large_entry_t *large_entry = large_entry_for_pointer_no_lock(szone, ptr); - if (!large_entry) { - szone_error(szone, 1, "large entry reallocated is not properly in table", ptr, NULL); - SZONE_UNLOCK(szone); - return ptr; - } - - large_entry->address = (vm_address_t)ptr; - large_entry->size = new_good_size; - szone->num_bytes_in_large_objects -= shrinkage; - SZONE_UNLOCK(szone); // we release the lock asap - - deallocate_pages(szone, (void *)((uintptr_t)ptr + new_good_size), shrinkage, 0); - } - return ptr; -} - -static INLINE int -large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) -{ - vm_address_t addr = (vm_address_t)ptr + old_size; - large_entry_t *large_entry; - kern_return_t err; - - SZONE_LOCK(szone); - large_entry = large_entry_for_pointer_no_lock(szone, (void *)addr); - SZONE_UNLOCK(szone); - - if (large_entry) { // check if "addr = ptr + old_size" is already spoken for - return 0; // large pointer already exists in table - extension is not going to work - } - - new_size = round_page(new_size); - /* - * Ask for allocation at a specific address, and mark as realloc - * to request coalescing with previous realloc'ed extensions. - */ - err = vm_allocate(mach_task_self(), &addr, new_size - old_size, VM_MAKE_TAG(VM_MEMORY_REALLOC)); - if (err != KERN_SUCCESS) { - return 0; - } - - SZONE_LOCK(szone); - /* extend existing large entry */ - large_entry = large_entry_for_pointer_no_lock(szone, ptr); - if (!large_entry) { - szone_error(szone, 1, "large entry reallocated is not properly in table", ptr, NULL); - SZONE_UNLOCK(szone); - return 0; // Bail, leaking "addr" - } - - large_entry->address = (vm_address_t)ptr; - large_entry->size = new_size; - szone->num_bytes_in_large_objects += new_size - old_size; - SZONE_UNLOCK(szone); // we release the lock asap - - return 1; -} - -/********************* Zone call backs ************************/ -/* - * Mark these NOINLINE to avoid bloating the purgeable zone call backs - */ -static NOINLINE void -szone_free(szone_t *szone, void *ptr) -{ - region_t tiny_region; - region_t small_region; - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("in szone_free with %p\n", ptr); -#endif - if (!ptr) - return; - /* - * Try to free to a tiny region. - */ - if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) { - szone_error(szone, 1, "Non-aligned pointer being freed", ptr, NULL); - return; - } - if ((tiny_region = tiny_region_for_ptr_no_lock(szone, ptr)) != NULL) { - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { - szone_error(szone, 1, "Pointer to metadata being freed", ptr, NULL); - return; - } - free_tiny(szone, ptr, tiny_region, 0); - return; - } - - /* - * Try to free to a small region. - */ - if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) { - szone_error(szone, 1, "Non-aligned pointer being freed (2)", ptr, NULL); - return; - } - if ((small_region = small_region_for_ptr_no_lock(szone, ptr)) != NULL) { - if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { - szone_error(szone, 1, "Pointer to metadata being freed (2)", ptr, NULL); - return; - } - free_small(szone, ptr, small_region, 0); - return; - } - - /* check that it's a legal large allocation */ - if ((uintptr_t)ptr & (vm_page_size - 1)) { - szone_error(szone, 1, "non-page-aligned, non-allocated pointer being freed", ptr, NULL); - return; - } - free_large(szone, ptr); -} - -static NOINLINE void -szone_free_definite_size(szone_t *szone, void *ptr, size_t size) -{ -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("in szone_free_definite_size with %p\n", ptr); - - if (0 == size) { - szone_error(szone, 1, "pointer of size zero being freed", ptr, NULL); - return; - } - -#endif - if (!ptr) - return; - - /* - * Try to free to a tiny region. - */ - if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) { - szone_error(szone, 1, "Non-aligned pointer being freed", ptr, NULL); - return; - } - if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) { - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { - szone_error(szone, 1, "Pointer to metadata being freed", ptr, NULL); - return; - } - free_tiny(szone, ptr, TINY_REGION_FOR_PTR(ptr), size); - return; - } - - /* - * Try to free to a small region. - */ - if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) { - szone_error(szone, 1, "Non-aligned pointer being freed (2)", ptr, NULL); - return; - } - if (size <= szone->large_threshold) { - if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { - szone_error(szone, 1, "Pointer to metadata being freed (2)", ptr, NULL); - return; - } - free_small(szone, ptr, SMALL_REGION_FOR_PTR(ptr), size); - return; - } - - /* check that it's a legal large allocation */ - if ((uintptr_t)ptr & (vm_page_size - 1)) { - szone_error(szone, 1, "non-page-aligned, non-allocated pointer being freed", ptr, NULL); - return; - } - free_large(szone, ptr); -} - -static NOINLINE void * -szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested) -{ - void *ptr; - msize_t msize; - - if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) { - // think tiny - msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - if (!msize) - msize = 1; - ptr = tiny_malloc_should_clear(szone, msize, cleared_requested); - } else if (size <= szone->large_threshold) { - // think small - msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); - if (!msize) - msize = 1; - ptr = small_malloc_should_clear(szone, msize, cleared_requested); - } else { - // large - size_t num_pages = round_page(size) >> vm_page_shift; - if (num_pages == 0) /* Overflowed */ - ptr = 0; - else - ptr = large_malloc(szone, num_pages, 0, cleared_requested); - } -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("szone_malloc returned %p\n", ptr); -#endif - /* - * If requested, scribble on allocated memory. - */ - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && ptr && !cleared_requested && size) - memset(ptr, 0xaa, size); - - return ptr; -} - -static NOINLINE void * -szone_malloc(szone_t *szone, size_t size) { - return szone_malloc_should_clear(szone, size, 0); -} - -static NOINLINE void * -szone_calloc(szone_t *szone, size_t num_items, size_t size) -{ - size_t total_bytes = num_items * size; - - // Check for overflow of integer multiplication - if (num_items > 1) { -#if __LP64__ /* size_t is uint64_t */ - if ((num_items | size) & 0xffffffff00000000ul) { - // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic - __uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size); - if ((uint64_t)(product >> 64)) // compiles to test on upper register of register pair - return NULL; - } -#else /* size_t is uint32_t */ - if ((num_items | size) & 0xffff0000ul) { - // num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic - uint64_t product = ((uint64_t)num_items) * ((uint64_t)size); - if ((uint32_t)(product >> 32)) // compiles to test on upper register of register pair - return NULL; - } -#endif - } - - return szone_malloc_should_clear(szone, total_bytes, 1); -} - -static NOINLINE void * -szone_valloc(szone_t *szone, size_t size) -{ - void *ptr; - - if (size <= szone->large_threshold) { - ptr = szone_memalign(szone, vm_page_size, size); - } else { - size_t num_pages; - - num_pages = round_page(size) >> vm_page_shift; - ptr = large_malloc(szone, num_pages, 0, 0); - } - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("szone_valloc returned %p\n", ptr); -#endif - return ptr; -} - -/* Isolate PIC-base load (for __is_threaded) here. */ -static NOINLINE size_t -szone_size_try_large(szone_t *szone, const void *ptr) -{ - size_t size = 0; - large_entry_t *entry; - - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (entry) { - size = entry->size; - } - SZONE_UNLOCK(szone); -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("szone_size for %p returned %d\n", ptr, (unsigned)size); - } -#endif - return size; -} - -static NOINLINE size_t -szone_size(szone_t *szone, const void *ptr) -{ - boolean_t is_free; - msize_t msize, msize_and_free; - - if (!ptr) - return 0; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in szone_size for %p (szone=%p)\n", ptr, szone); - } -#endif - - /* - * Look for it in a tiny region. - */ - if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) - return 0; - if (tiny_region_for_ptr_no_lock(szone, ptr)) { - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) - return 0; - msize = get_tiny_meta_header(ptr, &is_free); - if (is_free) - return 0; -#if TINY_CACHE - { - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); - if (DEPOT_MAGAZINE_INDEX != mag_index) { - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~ (TINY_QUANTUM - 1))) - return 0; - } else { - for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~ (TINY_QUANTUM - 1))) - return 0; - } - } - } -#endif - return TINY_BYTES_FOR_MSIZE(msize); - } - - /* - * Look for it in a small region. - */ - if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) - return 0; - if (small_region_for_ptr_no_lock(szone, ptr)) { - if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) - return 0; - msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); - if (msize_and_free & SMALL_IS_FREE) - return 0; -#if SMALL_CACHE - { - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - if (DEPOT_MAGAZINE_INDEX != mag_index) { - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~ (SMALL_QUANTUM - 1))) - return 0; - } else { - for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~ (SMALL_QUANTUM - 1))) - return 0; - } - } - } -#endif - return SMALL_BYTES_FOR_MSIZE(msize_and_free); - } - - /* - * If not page-aligned, it cannot have come from a large allocation. - */ - if ((uintptr_t)ptr & (vm_page_size - 1)) - return 0; - - /* - * Look for it in a large entry. - */ - return szone_size_try_large(szone, ptr); -} - -static NOINLINE void * -szone_realloc(szone_t *szone, void *ptr, size_t new_size) -{ - size_t old_size, new_good_size, valid_size; - void *new_ptr; - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in szone_realloc for %p, %d\n", ptr, (unsigned)new_size); - } -#endif - if (NULL == ptr) { - // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. - return szone_malloc(szone, new_size); - } else if (0 == new_size) { - // If size is 0 and ptr is not a null pointer, the object pointed to is freed. - szone_free(szone, ptr); - // If size is 0, either a null pointer or a unique pointer that can be successfully passed - // to free() shall be returned. - return szone_malloc(szone, 1); - } - - old_size = szone_size(szone, ptr); - if (!old_size) { - szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL); - return NULL; - } - - new_good_size = szone_good_size(szone, new_size); - if (new_good_size == old_size) { // Existing allocation is best fit evar? - return ptr; - } - - /* - * If the new size suits the tiny allocator and the pointer being resized - * belongs to a tiny region, try to reallocate in-place. - */ - if (new_good_size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { - if (old_size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { - if (new_good_size <= (old_size >> 1)) { - /* - * Serious shrinkage (more than half). free() the excess. - */ - return tiny_try_shrink_in_place(szone, ptr, old_size, new_good_size); - } else if (new_good_size <= old_size) { - /* - * new_good_size smaller than old_size but not by much (less than half). - * Avoid thrashing at the expense of some wasted storage. - */ - return ptr; - } else if (tiny_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { // try to grow the allocation - return ptr; - } - } - - /* - * Else if the new size suits the small allocator and the pointer being resized - * belongs to a small region, and we're not protecting the small allocations - * try to reallocate in-place. - */ - } else if (new_good_size <= szone->large_threshold) { - if ((NUM_TINY_SLOTS - 1) * TINY_QUANTUM < old_size && old_size <= szone->large_threshold) { - if (new_good_size <= (old_size >> 1)) { - return small_try_shrink_in_place(szone, ptr, old_size, new_good_size); - } else if (new_good_size <= old_size) { - return ptr; - } else if (small_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { - return ptr; - } - } - /* - * Else if the allocation's a large allocation, try to reallocate in-place there. - */ - } else if (!(szone->debug_flags & SCALABLE_MALLOC_PURGEABLE) && // purgeable needs fresh allocation - (old_size > szone->large_threshold) && - (new_good_size > szone->large_threshold)) { - if (new_good_size <= (old_size >> 1)) { - return large_try_shrink_in_place(szone, ptr, old_size, new_good_size); - } else if (new_good_size <= old_size) { - return ptr; - } else if (large_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { - return ptr; - } - } - - /* - * Can't reallocate in place for whatever reason; allocate a new buffer and copy. - */ - if (new_good_size <= (old_size >> 1)) { - /* Serious shrinkage (more than half). FALL THROUGH to alloc/copy/free. */ - } else if (new_good_size <= old_size) { - return ptr; - } - - new_ptr = szone_malloc(szone, new_size); - if (new_ptr == NULL) - return NULL; - - /* - * If the allocation's large enough, try to copy using VM. If that fails, or - * if it's too small, just copy by hand. - */ - valid_size = MIN(old_size, new_size); - if ((valid_size < szone->vm_copy_threshold) || - vm_copy(mach_task_self(), (vm_address_t)ptr, valid_size, (vm_address_t)new_ptr)) - memcpy(new_ptr, ptr, valid_size); - szone_free(szone, ptr); - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size); - } -#endif - return new_ptr; -} - -static NOINLINE void * -szone_memalign(szone_t *szone, size_t alignment, size_t size) -{ - if ((size + alignment) < size) // size_t arithmetic wrapped! - return NULL; - - // alignment is gauranteed a power of 2 at least as large as sizeof(void *), hence non-zero. - // Since size + alignment didn't wrap, 0 <= size + alignment - 1 < size + alignment - size_t span = size + alignment - 1; - - if (alignment <= TINY_QUANTUM) { - return szone_malloc(szone, size); // Trivially satisfied by tiny, small, or large - - } else if (span <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) { - msize_t mspan = TINY_MSIZE_FOR_BYTES(span + TINY_QUANTUM - 1); - void *p = szone_malloc(szone, span); // avoids inlining tiny_malloc_should_clear(szone, mspan, 0); - - if (NULL == p) - return NULL; - - size_t offset = ((uintptr_t) p) & (alignment - 1); // p % alignment - size_t pad = (0 == offset) ? 0 : alignment - offset; // p + pad achieves desired alignment - - msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - msize_t mpad = TINY_MSIZE_FOR_BYTES(pad + TINY_QUANTUM - 1); - msize_t mwaste = mspan - msize - mpad; // excess blocks - - if (mpad > 0) { - void *q = (void *)(((uintptr_t) p) + pad); - - // Mark q as a block header and in-use, thus creating two blocks. - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)), - MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p))); - set_tiny_meta_header_in_use(q, msize); - tiny_mag_ptr->mag_num_objects++; - - // set_tiny_meta_header_in_use() "reaffirms" the block_header on the *following* block, so - // now set its in_use bit as well. But only if its within the original allocation made above. - if (mwaste > 0) - BITARRAY_SET(TINY_INUSE_FOR_HEADER(TINY_BLOCK_HEADER_FOR_PTR(q)), TINY_INDEX_FOR_PTR(q) + msize); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - - // Give up mpad blocks beginning at p to the tiny free list - // region_t r = TINY_REGION_FOR_PTR(p); - szone_free(szone, p); // avoids inlining free_tiny(szone, p, &r); - - p = q; // advance p to the desired alignment - } - - if (mwaste > 0) { - void *q = (void *)(((uintptr_t) p) + TINY_BYTES_FOR_MSIZE(msize)); - // Mark q as block header and in-use, thus creating two blocks. - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)), - MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p))); - set_tiny_meta_header_in_use(q, mwaste); - tiny_mag_ptr->mag_num_objects++; - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - - // Give up mwaste blocks beginning at q to the tiny free list - // region_t r = TINY_REGION_FOR_PTR(q); - szone_free(szone, q); // avoids inlining free_tiny(szone, q, &r); - } - - return p; // p has the desired size and alignment, and can later be free()'d - - } else if ((NUM_TINY_SLOTS - 1)*TINY_QUANTUM < size && alignment <= SMALL_QUANTUM) { - return szone_malloc(szone, size); // Trivially satisfied by small or large - - } else if (span <= szone->large_threshold) { - - if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) { - size = (NUM_TINY_SLOTS - 1)*TINY_QUANTUM + TINY_QUANTUM; // ensure block allocated by small does not have a tiny-possible size - span = size + alignment - 1; - } - - msize_t mspan = SMALL_MSIZE_FOR_BYTES(span + SMALL_QUANTUM - 1); - void *p = szone_malloc(szone, span); // avoid inlining small_malloc_should_clear(szone, mspan, 0); - - if (NULL == p) - return NULL; - - size_t offset = ((uintptr_t) p) & (alignment - 1); // p % alignment - size_t pad = (0 == offset) ? 0 : alignment - offset; // p + pad achieves desired alignment - - msize_t msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); - msize_t mpad = SMALL_MSIZE_FOR_BYTES(pad + SMALL_QUANTUM - 1); - msize_t mwaste = mspan - msize - mpad; // excess blocks - - if (mpad > 0) { - void *q = (void *)(((uintptr_t) p) + pad); - - // Mark q as block header and in-use, thus creating two blocks. - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)), - MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p))); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(p), SMALL_META_INDEX_FOR_PTR(p), mpad); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), msize + mwaste); - small_mag_ptr->mag_num_objects++; - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - - // Give up mpad blocks beginning at p to the small free list - // region_t r = SMALL_REGION_FOR_PTR(p); - szone_free(szone, p); // avoid inlining free_small(szone, p, &r); - - p = q; // advance p to the desired alignment - } - if (mwaste > 0) { - void *q = (void *)(((uintptr_t) p) + SMALL_BYTES_FOR_MSIZE(msize)); - // Mark q as block header and in-use, thus creating two blocks. - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)), - MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p))); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(p), SMALL_META_INDEX_FOR_PTR(p), msize); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), mwaste); - small_mag_ptr->mag_num_objects++; - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - - // Give up mwaste blocks beginning at q to the small free list - // region_t r = SMALL_REGION_FOR_PTR(q); - szone_free(szone, q); // avoid inlining free_small(szone, q, &r); - } - - return p; // p has the desired size and alignment, and can later be free()'d - - } else if (szone->large_threshold < size && alignment <= vm_page_size) { - return szone_malloc(szone, size); // Trivially satisfied by large - - } else { - // ensure block allocated by large does not have a small-possible size - size_t num_pages = round_page(MAX(szone->large_threshold + 1, size)) >> vm_page_shift; - void *p; - - if (num_pages == 0) /* Overflowed */ - p = NULL; - else - p = large_malloc(szone, num_pages, MAX(vm_page_shift, __builtin_ctz(alignment)), 0); - - return p; - } - /* NOTREACHED */ -} - -// given a size, returns the number of pointers allocated capable of holding -// that size, up to the limit specified by the 'count' argument. These pointers -// are stored in the 'results' array, which must be allocated by the caller. -// may return zero, since this function is only a best attempt at allocating -// the pointers. clients should be prepared to call malloc for any additional -// blocks they need. -static NOINLINE unsigned -szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) -{ - msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - unsigned found = 0; - mag_index_t mag_index = mag_get_thread_index(szone); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - // only bother implementing this for tiny - if (size > (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) - return 0; - // make sure to return objects at least one quantum in size - if (!msize) - msize = 1; - - CHECK(szone, __PRETTY_FUNCTION__); - - // We must lock the zone now, since tiny_malloc_from_free_list assumes that - // the caller has done so. - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - - // with the zone locked, allocate objects from the free list until all - // sufficiently large objects have been exhausted, or we have met our quota - // of objects to allocate. - while (found < count) { - void *ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); - if (!ptr) - break; - - *results++ = ptr; - found++; - } - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return found; -} - -/* Try caching the tiny_region and checking if the next ptr hits there. */ -static NOINLINE void -szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) -{ - unsigned cc = 0; - void *ptr; - region_t tiny_region = NULL; - boolean_t is_free; - msize_t msize; - magazine_t *tiny_mag_ptr = NULL; - mag_index_t mag_index = -1; - - // frees all the pointers in to_be_freed - // note that to_be_freed may be overwritten during the process - if (!count) - return; - - CHECK(szone, __PRETTY_FUNCTION__); - while (cc < count) { - ptr = to_be_freed[cc]; - if (ptr) { - if (NULL == tiny_region || tiny_region != TINY_REGION_FOR_PTR(ptr)) { // region same as last iteration? - if (tiny_mag_ptr) { // non-NULL iff magazine lock taken - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - tiny_mag_ptr = NULL; - } - - tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); - - if (tiny_region) { - tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(tiny_region), - MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region)); - mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region); - } - } - if (tiny_region) { - // this is a tiny pointer - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) - break; // pointer to metadata; let the standard free deal with it - msize = get_tiny_meta_header(ptr, &is_free); - if (is_free) - break; // a double free; let the standard free deal with it - - if (!tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize)) { - // Arrange to re-acquire magazine lock - tiny_mag_ptr = NULL; - tiny_region = NULL; - } - to_be_freed[cc] = NULL; - } else { - // No region in this zone claims ptr; let the standard free deal with it - break; - } - } - cc++; - } - - if (tiny_mag_ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - tiny_mag_ptr = NULL; - } - - CHECK(szone, __PRETTY_FUNCTION__); - while (count--) { - ptr = to_be_freed[count]; - if (ptr) - szone_free(szone, ptr); - } -} - -// FIXME: Suppose one of the locks is held? -static void -szone_destroy(szone_t *szone) -{ - size_t index; - large_entry_t *large; - vm_range_t range_to_deallocate; - -#if LARGE_CACHE - SZONE_LOCK(szone); - - /* disable any memory pressure responder */ - szone->flotsam_enabled = FALSE; - - // stack allocated copy of the death-row cache - int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest; - large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE]; - - memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache)); - - szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0; - szone->large_entry_cache[0].address = 0x0; - szone->large_entry_cache[0].size = 0; - szone->large_entry_cache_bytes = 0; - szone->large_entry_cache_reserve_bytes = 0; - - SZONE_UNLOCK(szone); - - // deallocate the death-row cache outside the zone lock - while (idx != idx_max) { - deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); - if (++idx == LARGE_ENTRY_CACHE_SIZE) idx = 0; - } - if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) { - deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); - } -#endif - - /* destroy large entries */ - index = szone->num_large_entries; - while (index--) { - large = szone->large_entries + index; - if (large->address) { - // we deallocate_pages, including guard pages - deallocate_pages(szone, (void *)(large->address), large->size, szone->debug_flags); - } - } - large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate); - if (range_to_deallocate.size) - deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0); - - /* destroy tiny regions */ - for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) - if ((HASHRING_OPEN_ENTRY != szone->tiny_region_generation->hashed_regions[index]) && - (HASHRING_REGION_DEALLOCATED != szone->tiny_region_generation->hashed_regions[index])) - deallocate_pages(szone, szone->tiny_region_generation->hashed_regions[index], TINY_REGION_SIZE, 0); - - /* destroy small regions */ - for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) - if ((HASHRING_OPEN_ENTRY != szone->small_region_generation->hashed_regions[index]) && - (HASHRING_REGION_DEALLOCATED != szone->small_region_generation->hashed_regions[index])) - deallocate_pages(szone, szone->small_region_generation->hashed_regions[index], SMALL_REGION_SIZE, 0); - - /* destroy region hash rings, if any */ - if (szone->tiny_region_generation->hashed_regions != szone->initial_tiny_regions) { - size_t size = round_page(szone->tiny_region_generation->num_regions_allocated * sizeof(region_t)); - deallocate_pages(szone, szone->tiny_region_generation->hashed_regions, size, 0); - } - if (szone->small_region_generation->hashed_regions != szone->initial_small_regions) { - size_t size = round_page(szone->small_region_generation->num_regions_allocated * sizeof(region_t)); - deallocate_pages(szone, szone->small_region_generation->hashed_regions, size, 0); - } - - /* Now destroy the separate szone region */ - if (szone->cpu_id_key != (pthread_key_t) -1) - (void)pthread_key_delete(szone->cpu_id_key); - deallocate_pages(szone, (void *)&(szone->tiny_magazines[-1]), TINY_MAGAZINE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); - deallocate_pages(szone, (void *)&(szone->small_magazines[-1]), SMALL_MAGAZINE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); - deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0); -} - -static NOINLINE size_t -szone_good_size(szone_t *szone, size_t size) -{ - msize_t msize; - - // Find a good size for this tiny allocation. - if (size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { - msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - if (!msize) - msize = 1; - return TINY_BYTES_FOR_MSIZE(msize); - } - - // Find a good size for this small allocation. - if (size <= szone->large_threshold) { - msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); - if (!msize) - msize = 1; - return SMALL_BYTES_FOR_MSIZE(msize); - } - - // Check for integer overflow on the size, since unlike the two cases above, - // there is no upper bound on allocation size at this point. - if (size > round_page(size)) - return (size_t)(-1LL); - -#if DEBUG_MALLOC - // It is not acceptable to see a size of zero here, since that means we - // failed to catch a request for zero bytes in the tiny check, or the size - // overflowed to zero during some arithmetic. - if (size == 0) - malloc_printf("szone_good_size() invariant broken %y\n", size); -#endif - return round_page(size); -} - -unsigned szone_check_counter = 0; -unsigned szone_check_start = 0; -unsigned szone_check_modulo = 1; - -static NOINLINE boolean_t -szone_check_all(szone_t *szone, const char *function) -{ - size_t index; - - /* check tiny regions - chould check region count */ - for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) { - region_t tiny = szone->tiny_region_generation->hashed_regions[index]; - - if (HASHRING_REGION_DEALLOCATED == tiny) - continue; - - if (tiny) { - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(tiny), MAGAZINE_INDEX_FOR_TINY_REGION(tiny)); - - if (!tiny_check_region(szone, tiny)) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, 1, "check: tiny region incorrect", NULL, - "*** tiny region %ld incorrect szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - } - } - /* check tiny free lists */ - for (index = 0; index < NUM_TINY_SLOTS; ++index) { - if (!tiny_free_list_check(szone, index)) { - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, 1, "check: tiny free list incorrect", NULL, - "*** tiny free list incorrect (slot=%ld) szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - } - - /* check small regions - could check region count */ - for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) { - region_t small = szone->small_region_generation->hashed_regions[index]; - - if (HASHRING_REGION_DEALLOCATED == small) - continue; - - if (small) { - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(small), MAGAZINE_INDEX_FOR_SMALL_REGION(small)); - - if (!small_check_region(szone, small)) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, 1, "check: small region incorrect", NULL, - "*** small region %ld incorrect szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - } - } - /* check small free lists */ - for (index = 0; index < szone->num_small_slots; ++index) { - if (!small_free_list_check(szone, index)) { - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, 1, "check: small free list incorrect", NULL, - "*** small free list incorrect (slot=%ld) szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - } - - return 1; -} - -static boolean_t -szone_check(szone_t *szone) -{ - if ((++szone_check_counter % 10000) == 0) - _malloc_printf(ASL_LEVEL_NOTICE, "at szone_check counter=%d\n", szone_check_counter); - - if (szone_check_counter < szone_check_start) - return 1; - - if (szone_check_counter % szone_check_modulo) - return 1; - - return szone_check_all(szone, ""); -} - -static kern_return_t -szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, vm_range_recorder_t recorder) -{ - szone_t *szone; - kern_return_t err; - - if (!reader) reader = _szone_default_reader; - - err = reader(task, zone_address, sizeof(szone_t), (void **)&szone); - if (err) return err; - - err = tiny_in_use_enumerator(task, context, type_mask, szone, reader, recorder); - if (err) return err; - - err = small_in_use_enumerator(task, context, type_mask, szone, reader, recorder); - if (err) return err; - - err = large_in_use_enumerator(task, context, type_mask, - (vm_address_t)szone->large_entries, szone->num_large_entries, reader, recorder); - return err; -} - -// Following method is deprecated: use scalable_zone_statistics instead -void -scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) -{ - szone_t *szone = (void *)zone; - unsigned info[13]; - - // We do not lock to facilitate debug - - size_t s = 0; - unsigned t = 0; - size_t u = 0; - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; - t += szone->tiny_magazines[mag_index].mag_num_objects; - u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; - } - - info[4] = t; - info[5] = u; - - for (t = 0, u = 0, mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - s += szone->small_magazines[mag_index].mag_bytes_free_at_start; - s += szone->small_magazines[mag_index].mag_bytes_free_at_end; - t += szone->small_magazines[mag_index].mag_num_objects; - u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; - } - - info[6] = t; - info[7] = u; - - info[8] = szone->num_large_objects_in_use; - info[9] = szone->num_bytes_in_large_objects; - - info[10] = 0; // DEPRECATED szone->num_huge_entries; - info[11] = 0; // DEPRECATED szone->num_bytes_in_huge_objects; - - info[12] = szone->debug_flags; - - info[0] = info[4] + info[6] + info[8] + info[10]; - info[1] = info[5] + info[7] + info[9] + info[11]; - - info[3] = (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE + - (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE + info[9] + info[11]; - - info[2] = info[3] - s; - memcpy(info_to_fill, info, sizeof(unsigned)*count); -} - -// FIXME: consistent picture requires locking! -static NOINLINE void -szone_print(szone_t *szone, boolean_t verbose) -{ - unsigned info[13]; - size_t index; - region_t region; - - scalable_zone_info((void *)szone, info, 13); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "Scalable zone %p: inUse=%u(%y) touched=%y allocated=%y flags=%d\n", - szone, info[0], info[1], info[2], info[3], info[12]); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "\ttiny=%u(%y) small=%u(%y) large=%u(%y) huge=%u(%y)\n", - info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11]); - // tiny - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "%lu tiny regions:\n", szone->num_tiny_regions); - if (szone->num_tiny_regions_dealloc) - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "[%lu tiny regions have been vm_deallocate'd]\n", szone->num_tiny_regions_dealloc); - for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) { - region = szone->tiny_region_generation->hashed_regions[index]; - if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(region); - print_tiny_region(verbose, region, - (region == szone->tiny_magazines[mag_index].mag_last_region) ? - szone->tiny_magazines[mag_index].mag_bytes_free_at_start : 0, - (region == szone->tiny_magazines[mag_index].mag_last_region) ? - szone->tiny_magazines[mag_index].mag_bytes_free_at_end : 0); - } - } - if (verbose) - print_tiny_free_list(szone); - // small - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "%lu small regions:\n", szone->num_small_regions); - if (szone->num_small_regions_dealloc) - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "[%lu small regions have been vm_deallocate'd]\n", szone->num_small_regions_dealloc); - for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) { - region = szone->small_region_generation->hashed_regions[index]; - if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(region); - print_small_region(szone, verbose, region, - (region == szone->small_magazines[mag_index].mag_last_region) ? - szone->small_magazines[mag_index].mag_bytes_free_at_start : 0, - (region == szone->small_magazines[mag_index].mag_last_region) ? - szone->small_magazines[mag_index].mag_bytes_free_at_end : 0); - } - } - if (verbose) - print_small_free_list(szone); -} - -static void -szone_log(malloc_zone_t *zone, void *log_address) -{ - szone_t *szone = (szone_t *)zone; - - szone->log_address = log_address; -} - -static void -szone_force_lock(szone_t *szone) -{ - mag_index_t i; - - for (i = 0; i < szone->num_tiny_magazines; ++i) { - SZONE_MAGAZINE_PTR_LOCK(szone, (&(szone->tiny_magazines[i]))); - } - SZONE_MAGAZINE_PTR_LOCK(szone, (&(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]))); - - for (i = 0; i < szone->num_small_magazines; ++i) { - SZONE_MAGAZINE_PTR_LOCK(szone, (&(szone->small_magazines[i]))); - } - SZONE_MAGAZINE_PTR_LOCK(szone, (&(szone->small_magazines[DEPOT_MAGAZINE_INDEX]))); - - SZONE_LOCK(szone); -} - -static void -szone_force_unlock(szone_t *szone) -{ - mag_index_t i; - - SZONE_UNLOCK(szone); - - for (i = -1; i < szone->num_small_magazines; ++i) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->small_magazines[i]))); - } - - for (i = -1; i < szone->num_tiny_magazines; ++i) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->tiny_magazines[i]))); - } -} - -static boolean_t -szone_locked(szone_t *szone) -{ - mag_index_t i; - int tookLock; - - tookLock = SZONE_TRY_LOCK(szone); - if (tookLock == 0) - return 1; - SZONE_UNLOCK(szone); - - for (i = -1; i < szone->num_small_magazines; ++i) { - tookLock = SZONE_MAGAZINE_PTR_TRY_LOCK(szone, (&(szone->small_magazines[i]))); - if (tookLock == 0) - return 1; - SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->small_magazines[i]))); - } - - for (i = -1; i < szone->num_tiny_magazines; ++i) { - tookLock = SZONE_MAGAZINE_PTR_TRY_LOCK(szone, (&(szone->tiny_magazines[i]))); - if (tookLock == 0) - return 1; - SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->tiny_magazines[i]))); - } - return 0; -} - -static size_t -szone_pressure_relief(szone_t *szone, size_t goal) -{ -#if LARGE_CACHE - if (!szone->flotsam_enabled) - return 0; - - SZONE_LOCK(szone); - - // stack allocated copy of the death-row cache - int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest; - large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE]; - - memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache)); - - szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0; - szone->large_entry_cache[0].address = 0x0; - szone->large_entry_cache[0].size = 0; - szone->large_entry_cache_bytes = 0; - szone->large_entry_cache_reserve_bytes = 0; - - szone->flotsam_enabled = FALSE; - - SZONE_UNLOCK(szone); - - // deallocate the death-row cache outside the zone lock - size_t total = 0; - while (idx != idx_max) { - deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); - total += local_entry_cache[idx].size; - if (++idx == LARGE_ENTRY_CACHE_SIZE) idx = 0; - } - if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) { - deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); - total += local_entry_cache[idx].size; - } - MAGMALLOC_PRESSURERELIEF((void *)szone, goal, total); // DTrace USDT Probe - return total; -#else - return 0; -#endif -} - -boolean_t -scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone) -{ - szone_t *szone = (szone_t *)zone; - - switch (subzone) { - case 0: - { - size_t s = 0; - unsigned t = 0; - size_t u = 0; - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; - t += szone->tiny_magazines[mag_index].mag_num_objects; - u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; - } - - stats->blocks_in_use = t; - stats->size_in_use = u; - stats->size_allocated = (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE; - stats->max_size_in_use = stats->size_allocated - s; - return 1; - } - case 1: - { - size_t s = 0; - unsigned t = 0; - size_t u = 0; - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - s += szone->small_magazines[mag_index].mag_bytes_free_at_start; - s += szone->small_magazines[mag_index].mag_bytes_free_at_end; - t += szone->small_magazines[mag_index].mag_num_objects; - u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; - } - - stats->blocks_in_use = t; - stats->size_in_use = u; - stats->size_allocated = (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE; - stats->max_size_in_use = stats->size_allocated - s; - return 1; - } - case 2: - stats->blocks_in_use = szone->num_large_objects_in_use; - stats->size_in_use = szone->num_bytes_in_large_objects; - stats->max_size_in_use = stats->size_allocated = stats->size_in_use; - return 1; - case 3: - stats->blocks_in_use = 0; // DEPRECATED szone->num_huge_entries; - stats->size_in_use = 0; // DEPRECATED szone->num_bytes_in_huge_objects; - stats->max_size_in_use = stats->size_allocated = 0; - return 1; - } - return 0; -} - -static void -szone_statistics(szone_t *szone, malloc_statistics_t *stats) -{ - size_t large; - - size_t s = 0; - unsigned t = 0; - size_t u = 0; - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; - t += szone->tiny_magazines[mag_index].mag_num_objects; - u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; - } - - for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - s += szone->small_magazines[mag_index].mag_bytes_free_at_start; - s += szone->small_magazines[mag_index].mag_bytes_free_at_end; - t += szone->small_magazines[mag_index].mag_num_objects; - u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; - } - - large = szone->num_bytes_in_large_objects + 0; // DEPRECATED szone->num_bytes_in_huge_objects; - - stats->blocks_in_use = t + szone->num_large_objects_in_use + 0; // DEPRECATED szone->num_huge_entries; - stats->size_in_use = u + large; - stats->max_size_in_use = stats->size_allocated = - (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE + - (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE + large; - // Now we account for the untouched areas - stats->max_size_in_use -= s; -} - -static void * -legacy_zeroing_large_malloc(szone_t *szone, size_t size) { - if (size > LARGE_THRESHOLD) // Leopard and earlier returned a ZFOD range, so ... - return szone_calloc(szone, 1, size); // Clear to zero always, ham-handedly touching in each page - else - return szone_malloc(szone, size); -} - -static void * -legacy_zeroing_large_valloc(szone_t *szone, size_t size) { - void *p = szone_valloc(szone, size); - - // Leopard and earlier returned a ZFOD range, so ... - memset(p, 0, size); // Clear to zero always, ham-handedly touching in each page - return p; -} - -void zeroify_scalable_zone(malloc_zone_t *zone) -{ - szone_t *szone = (szone_t *)zone; - - if (szone) { - mprotect(szone, sizeof(szone->basic_zone), PROT_READ | PROT_WRITE); - szone->basic_zone.malloc = (void *)legacy_zeroing_large_malloc; - szone->basic_zone.valloc = (void *)legacy_zeroing_large_valloc; - mprotect(szone, sizeof(szone->basic_zone), PROT_READ); - } -} - -static const struct malloc_introspection_t szone_introspect = { - (void *)szone_ptr_in_use_enumerator, - (void *)szone_good_size, - (void *)szone_check, - (void *)szone_print, - szone_log, - (void *)szone_force_lock, - (void *)szone_force_unlock, - (void *)szone_statistics, - (void *)szone_locked, - NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */ -}; // marked as const to spare the DATA section - -malloc_zone_t * -create_scalable_zone(size_t initial_size, unsigned debug_flags) -{ - szone_t *szone; - uint64_t hw_memsize = 0; - - /* - * Sanity-check our build-time assumptions about the size of a page. - * Since we have sized various things assuming the default page size, - * attempting to determine it dynamically is not useful. - */ - if ((vm_page_size != _vm_page_size) || (vm_page_shift != _vm_page_shift)) { - malloc_printf("*** FATAL ERROR - machine page size does not match our assumptions.\n"); - exit(-1); - } - -#if defined(__i386__) || defined(__x86_64__) - if (_COMM_PAGE_VERSION_REQD > (*((short *) _COMM_PAGE_VERSION))) { // _COMM_PAGE_CPU_NUMBER must be present at runtime - malloc_printf("*** ERROR - comm page version mismatch.\n"); - exit(-1); - } -#endif - - /* get memory for the zone. */ - szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC); - if (!szone) - return NULL; - - /* set up the szone structure */ -#if 0 -#warning CHECK_REGIONS enabled - debug_flags |= CHECK_REGIONS; -#endif -#if 0 -#warning LOG enabled - szone->log_address = ~0; -#endif - szone->trg[0].nextgen = &(szone->trg[1]); - szone->trg[1].nextgen = &(szone->trg[0]); - szone->tiny_region_generation = &(szone->trg[0]); - - szone->tiny_region_generation->hashed_regions = szone->initial_tiny_regions; - szone->tiny_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS; - szone->tiny_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT; - - szone->srg[0].nextgen = &(szone->srg[1]); - szone->srg[1].nextgen = &(szone->srg[0]); - szone->small_region_generation = &(szone->srg[0]); - - szone->small_region_generation->hashed_regions = szone->initial_small_regions; - szone->small_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS; - szone->small_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT; - - - /* - * Initialize variables that size the free list for SMALL allocations based - * upon the amount of memory in the system. Switch to a larger number of - * free list entries at 1GB. - */ -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - if ((hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE) >= (1ULL << 30)) -#else - size_t uint64_t_size = sizeof(hw_memsize); - - if (0 == sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0) && - hw_memsize >= (1ULL << 30)) -#endif - { - szone->is_largemem = 1; - szone->num_small_slots = NUM_SMALL_SLOTS_LARGEMEM; - szone->large_threshold = LARGE_THRESHOLD_LARGEMEM; - szone->vm_copy_threshold = VM_COPY_THRESHOLD_LARGEMEM; - } else { - szone->is_largemem = 0; - szone->num_small_slots = NUM_SMALL_SLOTS; - szone->large_threshold = LARGE_THRESHOLD; - szone->vm_copy_threshold = VM_COPY_THRESHOLD; - } -#if LARGE_CACHE - szone->large_entry_cache_reserve_limit = - hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%] - - /* Reset protection when returning a previous large allocation? */ - int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System"); - if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 112) /* CFSystemVersionSnowLeopard */) - szone->large_legacy_reset_mprotect = TRUE; - else - szone->large_legacy_reset_mprotect = FALSE; -#endif - - // Initialize the security token. - szone->cookie = (uintptr_t)malloc_entropy[0]; - - // Prepare ASLR -#if __i386__ || __LP64__ || TARGET_OS_EMBEDDED -#if __i386__ - uintptr_t stackbase = 0x8fe00000; - int entropic_bits = 3; -#elif __LP64__ - uintptr_t stackbase = USRSTACK64; - int entropic_bits = 16; -#else - uintptr_t stackbase = USRSTACK; - int entropic_bits = 3; -#endif - if (0 != _dyld_get_image_slide((const struct mach_header*)_NSGetMachExecuteHeader())) { - if (0 == entropic_address) { - uintptr_t t = stackbase - MAXSSIZ - ((uintptr_t) (malloc_entropy[1] & ((1 << entropic_bits) - 1)) << SMALL_BLOCKS_ALIGN); - (void)__sync_bool_compare_and_swap(&entropic_limit, 0, t); // Just one initialization please - (void)__sync_bool_compare_and_swap(&entropic_address, 0, t - ENTROPIC_KABILLION); // Just one initialization please - } - debug_flags &= ~DISABLE_ASLR; - } else { - debug_flags |= DISABLE_ASLR; - } - -#else - debug_flags |= DISABLE_ASLR; -#endif - - szone->basic_zone.version = 8; - szone->basic_zone.size = (void *)szone_size; - szone->basic_zone.malloc = (void *)szone_malloc; - szone->basic_zone.calloc = (void *)szone_calloc; - szone->basic_zone.valloc = (void *)szone_valloc; - szone->basic_zone.free = (void *)szone_free; - szone->basic_zone.realloc = (void *)szone_realloc; - szone->basic_zone.destroy = (void *)szone_destroy; - szone->basic_zone.batch_malloc = (void *)szone_batch_malloc; - szone->basic_zone.batch_free = (void *)szone_batch_free; - szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; - szone->basic_zone.memalign = (void *)szone_memalign; - szone->basic_zone.free_definite_size = (void *)szone_free_definite_size; - szone->basic_zone.pressure_relief = (void *)szone_pressure_relief; - - szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */ - szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */ - mprotect(szone, sizeof(szone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */ - - szone->debug_flags = debug_flags; - LOCK_INIT(szone->large_szone_lock); - -#if defined(__ppc__) || defined(__ppc64__) - /* - * In the interest of compatibility for PPC applications executing via Rosetta, - * arrange to zero-fill allocations as occurred by side effect in Leopard and earlier. - */ - zeroify_scalable_zone((malloc_zone_t *)szone); -#endif - -#if defined(__i386__) || defined(__x86_64__) - szone->cpu_id_key = (pthread_key_t) -1; // Unused. _COMM_PAGE_CPU_NUMBER preferred. -#else - int err; - if ((err = pthread_key_create(&(szone->cpu_id_key), NULL))) { - malloc_printf("*** ERROR -pthread_key_create failure err=%d.\n", err); - szone->cpu_id_key = (pthread_key_t) -1; - } -#endif - - // Query the number of configured processors. - // Uniprocessor case gets just one tiny and one small magazine (whose index is zero). This gives - // the same behavior as the original scalable malloc. MP gets per-CPU magazines - // that scale (way) better. -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - int nproc = *(uint8_t *)(uintptr_t)_COMM_PAGE_NCPUS; -#else - int nproc = sysconf(_SC_NPROCESSORS_CONF); -#endif - szone->num_tiny_magazines = (nproc > 1) ? MIN(nproc, TINY_MAX_MAGAZINES) : 1; - - // FIXME vm_allocate() based on number of configured CPUs - magazine_t *tiny_magazines = allocate_pages(NULL, TINY_MAGAZINE_PAGED_SIZE, 0, - SCALABLE_MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC); - if (NULL == tiny_magazines) - return NULL; - - szone->tiny_magazines = &(tiny_magazines[1]); // szone->tiny_magazines[-1] is the Depot - - // The magazines are indexed in [0 .. (num_tiny_magazines - 1)] - // Find the smallest power of 2 that exceeds (num_tiny_magazines - 1) - szone->num_tiny_magazines_mask_shift = 0; - int i = 1; - while( i <= (szone->num_tiny_magazines - 1) ) { - szone->num_tiny_magazines_mask_shift++; - i <<= 1; - } - - // Now if i <= TINY_MAX_MAGAZINES we'll never access tiny_magazines[] out of bounds. - if (i > TINY_MAX_MAGAZINES) { - malloc_printf("*** FATAL ERROR - magazine mask exceeds allocated magazines.\n"); - exit(-1); - } - - // Reduce i by 1 to obtain a mask covering [0 .. (num_tiny_magazines - 1)] - szone->num_tiny_magazines_mask = i - 1; // A mask used for hashing to a magazine index (and a safety aid) -#if TARGET_OS_EMBEDDED - szone->last_tiny_advise = 0; -#endif - - // Init the tiny_magazine locks - LOCK_INIT(szone->tiny_regions_lock); - LOCK_INIT(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX].magazine_lock); - for (i = 0; i < szone->num_tiny_magazines; ++i) { - LOCK_INIT(szone->tiny_magazines[i].magazine_lock); - } - - szone->num_small_magazines = (nproc > 1) ? MIN(nproc, SMALL_MAX_MAGAZINES) : 1; - - // FIXME vm_allocate() based on number of configured CPUs - magazine_t *small_magazines = allocate_pages(NULL, SMALL_MAGAZINE_PAGED_SIZE, 0, - SCALABLE_MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC); - if (NULL == small_magazines) - return NULL; - - szone->small_magazines = &(small_magazines[1]); // szone->small_magazines[-1] is the Depot - - // The magazines are indexed in [0 .. (num_small_magazines - 1)] - // Find the smallest power of 2 that exceeds (num_small_magazines - 1) - szone->num_small_magazines_mask_shift = 0; - while( i <= (szone->num_small_magazines - 1) ) { - szone->num_small_magazines_mask_shift++; - i <<= 1; - } - - // Now if i <= SMALL_MAX_MAGAZINES we'll never access small_magazines[] out of bounds. - if (i > SMALL_MAX_MAGAZINES) { - malloc_printf("*** FATAL ERROR - magazine mask exceeds allocated magazines.\n"); - exit(-1); - } - - // Reduce i by 1 to obtain a mask covering [0 .. (num_small_magazines - 1)] - szone->num_small_magazines_mask = i - 1; // A mask used for hashing to a magazine index (and a safety aid) -#if TARGET_OS_EMBEDDED - szone->last_small_advise = 0; -#endif - - // Init the small_magazine locks - LOCK_INIT(szone->small_regions_lock); - LOCK_INIT(szone->small_magazines[DEPOT_MAGAZINE_INDEX].magazine_lock); - for (i = 0; i < szone->num_small_magazines; ++i) { - LOCK_INIT(szone->small_magazines[i].magazine_lock); - } - - CHECK(szone, __PRETTY_FUNCTION__); - return (malloc_zone_t *)szone; -} - -// -// purgeable zones have their own "large" allocation pool, but share "tiny" and "large" -// heaps with a helper_zone identified in the call to create_purgeable_zone() -// -static size_t -purgeable_size(szone_t *szone, const void *ptr) -{ - // Only claim our large allocations, leave the shared tiny/small for the helper zone to claim. - return szone_size_try_large(szone, ptr); -} - -static void * -purgeable_malloc(szone_t *szone, size_t size) { - if (size <= szone->large_threshold) - return szone_malloc(szone->helper_zone, size); - else - return szone_malloc(szone, size); -} - -static void * -purgeable_calloc(szone_t *szone, size_t num_items, size_t size) -{ - size_t total_bytes = num_items * size; - - // Check for overflow of integer multiplication - if (num_items > 1) { -#if __LP64__ /* size_t is uint64_t */ - if ((num_items | size) & 0xffffffff00000000ul) { - // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic - __uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size); - if ((uint64_t)(product >> 64)) // compiles to test on upper register of register pair - return NULL; - } -#else /* size_t is uint32_t */ - if ((num_items | size) & 0xffff0000ul) { - // num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic - uint64_t product = ((uint64_t)num_items) * ((uint64_t)size); - if ((uint32_t)(product >> 32)) // compiles to test on upper register of register pair - return NULL; - } -#endif - } - - if (total_bytes <= szone->large_threshold) - return szone_calloc(szone->helper_zone, 1, total_bytes); - else - return szone_calloc(szone, 1, total_bytes); -} - -static void * -purgeable_valloc(szone_t *szone, size_t size) -{ - if (size <= szone->large_threshold) - return szone_valloc(szone->helper_zone, size); - else - return szone_valloc(szone, size); -} - -static void -purgeable_free(szone_t *szone, void *ptr) -{ - large_entry_t *entry; - - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - SZONE_UNLOCK(szone); - if (entry) { - return free_large(szone, ptr); - } else { - return szone_free(szone->helper_zone, ptr); - } -} - -static void -purgeable_free_definite_size(szone_t *szone, void *ptr, size_t size) -{ - if (size <= szone->large_threshold) - return szone_free_definite_size(szone->helper_zone, ptr, size); - else - return szone_free_definite_size(szone, ptr, size); -} - -static void * -purgeable_realloc(szone_t *szone, void *ptr, size_t new_size) -{ - size_t old_size; - - if (NULL == ptr) { - // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. - return purgeable_malloc(szone, new_size); - } else if (0 == new_size) { - // If size is 0 and ptr is not a null pointer, the object pointed to is freed. - purgeable_free(szone, ptr); - // If size is 0, either a null pointer or a unique pointer that can be successfully passed - // to free() shall be returned. - return purgeable_malloc(szone, 1); - } - - old_size = purgeable_size(szone, ptr); // Now ptr can be safely size()'d - if (!old_size) - old_size = szone_size(szone->helper_zone, ptr); - - if (!old_size) { - szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL); - return NULL; - } - - // Distinguish 4 cases: {oldsize, newsize} x { <= , > large_threshold } - // and deal with the allocation crossing from the purgeable zone to the helper zone and vice versa. - if (old_size <= szone->large_threshold) { - if (new_size <= szone->large_threshold) - return szone_realloc(szone->helper_zone, ptr, new_size); - else { - // allocation crosses from helper to purgeable zone - void * new_ptr = purgeable_malloc(szone, new_size); - if (new_ptr) { - memcpy(new_ptr, ptr, old_size); - szone_free_definite_size(szone->helper_zone, ptr, old_size); - } - return new_ptr; // in state VM_PURGABLE_NONVOLATILE - } - } else { - if (new_size <= szone->large_threshold) { - // allocation crosses from purgeable to helper zone - void * new_ptr = szone_malloc(szone->helper_zone, new_size); - if (new_ptr) { - memcpy(new_ptr, ptr, new_size); - purgeable_free_definite_size(szone, ptr, old_size); - } - return new_ptr; - } else { - void * new_ptr = purgeable_malloc(szone, new_size); - if (new_ptr) { - memcpy(new_ptr, ptr, MIN(old_size, new_size)); - purgeable_free_definite_size(szone, ptr, old_size); - } - return new_ptr; // in state VM_PURGABLE_NONVOLATILE - } - } - /* NOTREACHED */ -} - -static void -purgeable_destroy(szone_t *szone) -{ - /* destroy large entries */ - size_t index = szone->num_large_entries; - large_entry_t *large; - vm_range_t range_to_deallocate; - - while (index--) { - large = szone->large_entries + index; - if (large->address) { - // we deallocate_pages, including guard pages - deallocate_pages(szone, (void *)(large->address), large->size, szone->debug_flags); - } - } - large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate); - if (range_to_deallocate.size) - deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0); - - /* Now destroy the separate szone region */ - deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0); -} - -static unsigned -purgeable_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) -{ - return szone_batch_malloc(szone->helper_zone, size, results, count); -} - -static void -purgeable_batch_free(szone_t *szone, void **to_be_freed, unsigned count) -{ - return szone_batch_free(szone->helper_zone, to_be_freed, count); -} - -static void * -purgeable_memalign(szone_t *szone, size_t alignment, size_t size) -{ - if (size <= szone->large_threshold) - return szone_memalign(szone->helper_zone, alignment, size); - else - return szone_memalign(szone, alignment, size); -} - -static kern_return_t -purgeable_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, vm_range_recorder_t recorder) -{ - szone_t *szone; - kern_return_t err; - - if (!reader) reader = _szone_default_reader; - - err = reader(task, zone_address, sizeof(szone_t), (void **)&szone); - if (err) return err; - - err = large_in_use_enumerator(task, context, type_mask, - (vm_address_t)szone->large_entries, szone->num_large_entries, reader, recorder); - return err; -} - -static size_t -purgeable_good_size(szone_t *szone, size_t size) -{ - if (size <= szone->large_threshold) - return szone_good_size(szone->helper_zone, size); - else - return szone_good_size(szone, size); -} - -static boolean_t -purgeable_check(szone_t *szone) -{ - return 1; -} - -static void -purgeable_print(szone_t *szone, boolean_t verbose) -{ - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "Scalable zone %p: inUse=%u(%y) flags=%d\n", - szone, szone->num_large_objects_in_use, szone->num_bytes_in_large_objects, szone->debug_flags); -} - -static void -purgeable_log(malloc_zone_t *zone, void *log_address) -{ - szone_t *szone = (szone_t *)zone; - - szone->log_address = log_address; -} - -static void -purgeable_force_lock(szone_t *szone) -{ - SZONE_LOCK(szone); -} - -static void -purgeable_force_unlock(szone_t *szone) -{ - SZONE_UNLOCK(szone); -} - -static void -purgeable_statistics(szone_t *szone, malloc_statistics_t *stats) -{ - stats->blocks_in_use = szone->num_large_objects_in_use; - stats->size_in_use = stats->max_size_in_use = stats->size_allocated = szone->num_bytes_in_large_objects; -} - -static boolean_t -purgeable_locked(szone_t *szone) -{ - int tookLock; - - tookLock = SZONE_TRY_LOCK(szone); - if (tookLock == 0) - return 1; - SZONE_UNLOCK(szone); - return 0; -} - -static size_t -purgeable_pressure_relief(szone_t *szone, size_t goal) -{ - return szone_pressure_relief(szone, goal) + szone_pressure_relief(szone->helper_zone, goal); -} - -static const struct malloc_introspection_t purgeable_introspect = { - (void *)purgeable_ptr_in_use_enumerator, - (void *)purgeable_good_size, - (void *)purgeable_check, - (void *)purgeable_print, - purgeable_log, - (void *)purgeable_force_lock, - (void *)purgeable_force_unlock, - (void *)purgeable_statistics, - (void *)purgeable_locked, - NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */ -}; // marked as const to spare the DATA section - -__private_extern__ malloc_zone_t * -create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags) -{ - szone_t *szone; - uint64_t hw_memsize = 0; - - /* get memory for the zone. */ - szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC); - if (!szone) - return NULL; - - /* set up the szone structure */ -#if 0 -#warning LOG enabled - szone->log_address = ~0; -#endif - -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE; -#else - size_t uint64_t_size = sizeof(hw_memsize); - - sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0); -#endif - /* Purgeable zone does not participate in the adaptive "largemem" sizing. */ - szone->is_largemem = 0; - szone->large_threshold = LARGE_THRESHOLD; - szone->vm_copy_threshold = VM_COPY_THRESHOLD; - -#if LARGE_CACHE - szone->large_entry_cache_reserve_limit = - hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%] - - /* Reset protection when returning a previous large allocation? */ - int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System"); - if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 112) /* CFSystemVersionSnowLeopard */) - szone->large_legacy_reset_mprotect = TRUE; - else - szone->large_legacy_reset_mprotect = FALSE; -#endif - - szone->basic_zone.version = 8; - szone->basic_zone.size = (void *)purgeable_size; - szone->basic_zone.malloc = (void *)purgeable_malloc; - szone->basic_zone.calloc = (void *)purgeable_calloc; - szone->basic_zone.valloc = (void *)purgeable_valloc; - szone->basic_zone.free = (void *)purgeable_free; - szone->basic_zone.realloc = (void *)purgeable_realloc; - szone->basic_zone.destroy = (void *)purgeable_destroy; - szone->basic_zone.batch_malloc = (void *)purgeable_batch_malloc; - szone->basic_zone.batch_free = (void *)purgeable_batch_free; - szone->basic_zone.introspect = (struct malloc_introspection_t *)&purgeable_introspect; - szone->basic_zone.memalign = (void *)purgeable_memalign; - szone->basic_zone.free_definite_size = (void *)purgeable_free_definite_size; - szone->basic_zone.pressure_relief = (void *)purgeable_pressure_relief; - - szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */ - szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */ - mprotect(szone, sizeof(szone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */ - - szone->debug_flags = debug_flags | SCALABLE_MALLOC_PURGEABLE; - - /* Purgeable zone does not support SCALABLE_MALLOC_ADD_GUARD_PAGES. */ - if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) { - _malloc_printf(ASL_LEVEL_INFO, "purgeable zone does not support guard pages\n"); - szone->debug_flags &= ~SCALABLE_MALLOC_ADD_GUARD_PAGES; - } - - LOCK_INIT(szone->large_szone_lock); - - szone->helper_zone = (struct szone_s *)malloc_default_zone; - - CHECK(szone, __PRETTY_FUNCTION__); - return (malloc_zone_t *)szone; -} - -/* - * For use by CheckFix: create a new zone whose behavior is, apart from - * the use of death-row and per-CPU magazines, that of Leopard. - */ -static NOINLINE void * -legacy_valloc(szone_t *szone, size_t size) -{ - void *ptr; - size_t num_pages; - - num_pages = round_page(size) >> vm_page_shift; - ptr = large_malloc(szone, num_pages, 0, TRUE); -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("legacy_valloc returned %p\n", ptr); -#endif - return ptr; -} - -__private_extern__ malloc_zone_t * -create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags) -{ - malloc_zone_t *mzone = create_scalable_zone(initial_size, debug_flags); - szone_t *szone = (szone_t *)mzone; - - if (!szone) - return NULL; - - szone->is_largemem = 0; - szone->num_small_slots = NUM_SMALL_SLOTS; - szone->large_threshold = LARGE_THRESHOLD; - szone->vm_copy_threshold = VM_COPY_THRESHOLD; - - mprotect(szone, sizeof(szone->basic_zone), PROT_READ | PROT_WRITE); - szone->basic_zone.valloc = (void *)legacy_valloc; - szone->basic_zone.free_definite_size = NULL; - mprotect(szone, sizeof(szone->basic_zone), PROT_READ); - - return mzone; -} - -/********* Support code for emacs unexec ************/ - -/* History of freezedry version numbers: - * - * 1) Old malloc (before the scalable malloc implementation in this file - * existed). - * 2) Original freezedrying code for scalable malloc. This code was apparently - * based on the old freezedrying code and was fundamentally flawed in its - * assumption that tracking allocated memory regions was adequate to fake - * operations on freezedried memory. This doesn't work, since scalable - * malloc does not store flags in front of large page-aligned allocations. - * 3) Original szone-based freezedrying code. - * 4) Fresher malloc with tiny zone - * 5) 32/64bit compatible malloc - * 6) Metadata within 1MB and 8MB region for tiny and small - * - * No version backward compatibility is provided, but the version number does - * make it possible for malloc_jumpstart() to return an error if the application - * was freezedried with an older version of malloc. - */ -#define MALLOC_FREEZEDRY_VERSION 6 - -typedef struct { - unsigned version; - unsigned nszones; - szone_t *szones; -} malloc_frozen; - -static void * -frozen_malloc(szone_t *zone, size_t new_size) -{ - return malloc(new_size); -} - -static void * -frozen_calloc(szone_t *zone, size_t num_items, size_t size) -{ - return calloc(num_items, size); -} - -static void * -frozen_valloc(szone_t *zone, size_t new_size) -{ - return valloc(new_size); -} - -static void * -frozen_realloc(szone_t *zone, void *ptr, size_t new_size) -{ - size_t old_size = szone_size(zone, ptr); - void *new_ptr; - - if (new_size <= old_size) { - return ptr; - } - new_ptr = malloc(new_size); - if (old_size > 0) { - memcpy(new_ptr, ptr, old_size); - } - return new_ptr; -} - -static void -frozen_free(szone_t *zone, void *ptr) -{ -} - -static void -frozen_destroy(szone_t *zone) -{ -} - -/********* Pseudo-private API for emacs unexec ************/ - -/* - * malloc_freezedry() records all of the szones in use, so that they can be - * partially reconstituted by malloc_jumpstart(). Due to the differences - * between reconstituted memory regions and those created by the szone code, - * care is taken not to reallocate from the freezedried memory, except in the - * case of a non-growing realloc(). - * - * Due to the flexibility provided by the zone registration mechanism, it is - * impossible to implement generic freezedrying for any zone type. This code - * only handles applications that use the szone allocator, so malloc_freezedry() - * returns 0 (error) if any non-szone zones are encountered. - */ - -uintptr_t -malloc_freezedry(void) -{ - extern unsigned malloc_num_zones; - extern malloc_zone_t **malloc_zones; - malloc_frozen *data; - unsigned i; - - /* Allocate space in which to store the freezedry state. */ - data = (malloc_frozen *) malloc(sizeof(malloc_frozen)); - - /* Set freezedry version number so that malloc_jumpstart() can check for compatibility. */ - data->version = MALLOC_FREEZEDRY_VERSION; - - /* Allocate the array of szone pointers. */ - data->nszones = malloc_num_zones; - data->szones = (szone_t *) calloc(malloc_num_zones, sizeof(szone_t)); - - /* - * Fill in the array of szone structures. They are copied rather than - * referenced, since the originals are likely to be clobbered during malloc - * initialization. - */ - for (i = 0; i < malloc_num_zones; i++) { - if (strcmp(malloc_zones[i]->zone_name, "DefaultMallocZone")) { - /* Unknown zone type. */ - free(data->szones); - free(data); - return 0; - } - memcpy(&data->szones[i], malloc_zones[i], sizeof(szone_t)); - } - - return((uintptr_t)data); -} - -int -malloc_jumpstart(uintptr_t cookie) -{ - malloc_frozen *data = (malloc_frozen *)cookie; - unsigned i; - - if (data->version != MALLOC_FREEZEDRY_VERSION) { - /* Unsupported freezedry version. */ - return 1; - } - - for (i = 0; i < data->nszones; i++) { - /* Set function pointers. Even the functions that stay the same must be - * set, since there are no guarantees that they will be mapped to the - * same addresses. */ - data->szones[i].basic_zone.size = (void *) szone_size; - data->szones[i].basic_zone.malloc = (void *) frozen_malloc; - data->szones[i].basic_zone.calloc = (void *) frozen_calloc; - data->szones[i].basic_zone.valloc = (void *) frozen_valloc; - data->szones[i].basic_zone.free = (void *) frozen_free; - data->szones[i].basic_zone.realloc = (void *) frozen_realloc; - data->szones[i].basic_zone.destroy = (void *) frozen_destroy; - data->szones[i].basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; - - /* Register the freezedried zone. */ - malloc_zone_register(&data->szones[i].basic_zone); - } - - return 0; -} diff --git a/src/libc/gen/magmallocProvider.d b/src/libc/gen/magmallocProvider.d deleted file mode 100644 index 11b7adddd..000000000 --- a/src/libc/gen/magmallocProvider.d +++ /dev/null @@ -1,17 +0,0 @@ -provider magmalloc { - probe refreshIndex(void *, int, int); - probe depotRegion(void *, int, void *, int, int); - probe recircRegion(void *, int, void *, int, int); - probe allocRegion(void *, int, void *, int); - probe deallocRegion(void *, void *, int); - probe madvfreeRegion(void *, void *, void *, int); - probe pressureRelief(void *, int, int); - probe mallocErrorBreak(); -}; - -#pragma D attributes Evolving/Evolving/ISA provider magmalloc provider -#pragma D attributes Private/Private/Unknown provider magmalloc module -#pragma D attributes Private/Private/Unknown provider magmalloc function -#pragma D attributes Evolving/Evolving/ISA provider magmalloc name -#pragma D attributes Evolving/Evolving/ISA provider magmalloc args - diff --git a/src/libc/gen/malloc.3 b/src/libc/gen/malloc.3 deleted file mode 100644 index 542d4cc7e..000000000 --- a/src/libc/gen/malloc.3 +++ /dev/null @@ -1,283 +0,0 @@ -.\" Copyright (c) 2006 Apple Computer, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd Aug 13, 2008 -.Dt MALLOC 3 -.Os -.Sh NAME -.Nm calloc , -.Nm free , -.Nm malloc , -.Nm realloc , -.Nm reallocf , -.Nm valloc -.Nd memory allocation -.Sh SYNOPSIS -.In stdlib.h -.Ft void * -.Fo calloc -.Fa "size_t count" -.Fa "size_t size" -.Fc -.Ft void -.Fo free -.Fa "void *ptr" -.Fc -.Ft void * -.Fo malloc -.Fa "size_t size" -.Fc -.Ft void * -.Fo realloc -.Fa "void *ptr" -.Fa "size_t size" -.Fc -.Ft void * -.Fo reallocf -.Fa "void *ptr" -.Fa "size_t size" -.Fc -.Ft void * -.Fo valloc -.Fa "size_t size" -.Fc -.Sh DESCRIPTION -The -.Fn malloc , -.Fn calloc , -.Fn valloc , -.Fn realloc , -and -.Fn reallocf -functions allocate memory. -The allocated memory is aligned such that it can be used for any data type, -including AltiVec- and SSE-related types. -The -.Fn free -function frees allocations that were created via the preceding allocation -functions. -.Pp -The -.Fn malloc -function allocates -.Fa size -bytes of memory and returns a pointer to the allocated memory. -.Pp -The -.Fn calloc -function contiguously allocates enough space for -.Fa count -objects that are -.Fa size -bytes of memory each and returns a pointer to the allocated memory. -The allocated memory is filled with bytes of value zero. -.Pp -The -.Fn valloc -function allocates -.Fa size -bytes of memory and returns a pointer to the allocated memory. -The allocated memory is aligned on a page boundary. -.Pp -The -.Fn realloc -function tries to change the size of the allocation pointed to by -.Fa ptr -to -.Fa size , -and returns -.Fa ptr . -If there is not enough room to enlarge the memory allocation pointed to by -.Fa ptr , -.Fn realloc -creates a new allocation, copies as much of the old data pointed to by -.Fa ptr -as will fit to the new allocation, frees the old allocation, and returns a -pointer to the allocated memory. -If -.Fa ptr -is -.Dv NULL , -.Fn realloc -is identical to a call to -.Fn malloc -for -.Fa size -bytes. -If -.Fa size -is zero and -.Fa ptr -is not -.Dv NULL , -a new, minimum sized object is allocated and the original object is freed. -When extending a region allocated with calloc(3), realloc(3) does not guarantee -that the additional memory is also zero-filled. -.Pp -The -.Fn reallocf -function is identical to the -.Fn realloc -function, except that it -will free the passed pointer when the requested memory cannot be allocated. -This is a -.Fx -specific API designed to ease the problems with traditional coding styles -for realloc causing memory leaks in libraries. -.Pp -The -.Fn free -function deallocates the memory allocation pointed to by -.Fa ptr . If -.Fa ptr -is a NULL pointer, no operation is performed. -.Sh RETURN VALUES -If successful, -.Fn calloc , -.Fn malloc , -.Fn realloc , -.Fn reallocf , -and -.Fn valloc -functions return a pointer to allocated memory. -If there is an error, they return a -.Dv NULL -pointer and set -.Va errno -to -.Er ENOMEM . -.Pp -For -.Fn realloc , -the input pointer is still valid if reallocation failed. -For -.Fn reallocf , -the input pointer will have been freed if reallocation failed. -.Pp -The -.Fn free -function does not return a value. -.Sh DEBUGGING ALLOCATION ERRORS -A number of facilities are provided to aid in debugging allocation errors in -applications. -These facilities are primarily controlled via environment variables. -The recognized environment variables and their meanings are documented below. -.Sh ENVIRONMENT -The following environment variables change the behavior of the -allocation-related functions. -.Bl -tag -width ".Ev MallocStackLoggingNoCompact" -.It Ev MallocLogFile -Create/append messages to the given file path -.Fa -instead of writing to the standard error. -.It Ev MallocGuardEdges -If set, add a guard page before and after each large block. -.It Ev MallocDoNotProtectPrelude -If set, do not add a guard page before large blocks, -even if the -.Ev MallocGuardEdges -environment variable is set. -.It Ev MallocDoNotProtectPostlude -If set, do not add a guard page after large blocks, -even if the -.Ev MallocGuardEdges -environment variable is set. -.It Ev MallocStackLogging -If set, record all stacks, so that tools like -.Nm leaks -can be used. -.It Ev MallocStackLoggingNoCompact -If set, record all stacks in a manner that is compatible with the -.Nm malloc_history -program. -.It Ev MallocStackLoggingDirectory -If set, records stack logs to the directory specified instead of saving them to the default location (/tmp). -.It Ev MallocScribble -If set, fill memory that has been allocated with 0xaa bytes. -This increases the likelihood that a program making assumptions about the contents of -freshly allocated memory will fail. -Also if set, fill memory that has been deallocated with 0x55 bytes. -This increases the likelihood that a program will fail due to accessing memory -that is no longer allocated. -.It Ev MallocCheckHeapStart -If set, specifies the number of allocations -.Fa -to wait before begining periodic heap checks every -.Fa -as specified by -.Ev MallocCheckHeapEach . -If -.Ev MallocCheckHeapStart -is set but -.Ev MallocCheckHeapEach -is not specified, the default check repetition is 1000. -.It Ev MallocCheckHeapEach -If set, run a consistency check on the heap every -.Fa -operations. -.Ev MallocCheckHeapEach -is only meaningful if -.Ev MallocCheckHeapStart -is also set. -.It Ev MallocCheckHeapSleep -Sets the number of seconds to sleep (waiting for a debugger to attach) when -.Ev MallocCheckHeapStart -is set and a heap corruption is detected. -The default is 100 seconds. -Setting this to zero means not to sleep at all. -Setting this to a negative number means to sleep (for the positive number of -seconds) only the very first time a heap corruption is detected. -.It Ev MallocCheckHeapAbort -When -.Ev MallocCheckHeapStart -is set and this is set to a non-zero value, causes -.Xr abort 3 -to be called if a heap corruption is detected, instead of any sleeping. -.It Ev MallocErrorAbort -If set, causes -.Xr abort 3 -to be called if an error was encountered in -.Xr malloc 3 -or -.Xr free 3 -, such as a calling -.Xr free 3 -on a pointer previously freed. -.It Ev MallocCorruptionAbort -Similar to -.Ev -MallocErrorAbort -but will not abort in out of memory conditions, making it more useful to catch -only those errors which will cause memory corruption. -MallocCorruptionAbort is always set on 64-bit processes. -.It Ev MallocHelp -If set, print a list of environment variables that are paid heed to by the -allocation-related functions, along with short descriptions. -The list should correspond to this documentation. -.El -.Sh DIAGNOSTIC MESSAGES -.Sh SEE ALSO -.Xr leaks 1 , -.Xr malloc_history 1 , -.Xr abort 3 , -.Xr malloc_size 3 , -.Xr malloc_zone_malloc 3 , -.Xr posix_memalign 3 , -.Xr libgmalloc 3 diff --git a/src/libc/gen/malloc.c b/src/libc/gen/malloc.c deleted file mode 100644 index 4ec54f5ed..000000000 --- a/src/libc/gen/malloc.c +++ /dev/null @@ -1,1528 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999, 2006-2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include "magmallocProvider.h" -#include /* for NSVersionOfLinkTimeLibrary() */ - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#import "scalable_malloc.h" -#import "stack_logging.h" -#import "malloc_printf.h" -#import "_simple.h" -#import "CrashReporterClient.h" - -/* - * MALLOC_ABSOLUTE_MAX_SIZE - There are many instances of addition to a - * user-specified size_t, which can cause overflow (and subsequent crashes) - * for values near SIZE_T_MAX. Rather than add extra "if" checks everywhere - * this occurs, it is easier to just set an absolute maximum request size, - * and immediately return an error if the requested size exceeds this maximum. - * Of course, values less than this absolute max can fail later if the value - * is still too large for the available memory. The largest value added - * seems to be PAGE_SIZE (in the macro round_page()), so to be safe, we set - * the maximum to be 2 * PAGE_SIZE less than SIZE_T_MAX. - */ -#define MALLOC_ABSOLUTE_MAX_SIZE (SIZE_T_MAX - (2 * PAGE_SIZE)) - -#define USE_SLEEP_RATHER_THAN_ABORT 0 - -typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip); - -__private_extern__ pthread_lock_t _malloc_lock = 0; // initialized in __libc_init - -/* The following variables are exported for the benefit of performance tools - * - * It should always be safe to first read malloc_num_zones, then read - * malloc_zones without taking the lock, if only iteration is required and - * provided that when malloc_destroy_zone is called all prior operations on that - * zone are complete and no further calls referencing that zone can be made. - */ -unsigned malloc_num_zones = 0; -unsigned malloc_num_zones_allocated = 0; -malloc_zone_t **malloc_zones = 0; -malloc_logger_t *malloc_logger = NULL; - -unsigned malloc_debug_flags = 0; - -unsigned malloc_check_start = 0; // 0 means don't check -unsigned malloc_check_counter = 0; -unsigned malloc_check_each = 1000; - -/* global flag to suppress ASL logging e.g. for syslogd */ -int _malloc_no_asl_log = 0; - -static int malloc_check_sleep = 100; // default 100 second sleep -static int malloc_check_abort = 0; // default is to sleep, not abort - -static int malloc_debug_file = STDERR_FILENO; -/* - * State indicated by malloc_def_zone_state - * 0 - the default zone has not yet been created - * 1 - a Malloc* environment variable has been set - * 2 - the default zone has been created and an environment variable scan done - * 3 - a new default zone has been created and another environment variable scan - */ -__private_extern__ int malloc_def_zone_state = 0; - -static const char Malloc_Facility[] = "com.apple.Libsystem.malloc"; - -#define MALLOC_LOCK() LOCK(_malloc_lock) -#define MALLOC_UNLOCK() UNLOCK(_malloc_lock) - -/* - * Counters that coordinate zone destruction (in malloc_zone_unregister) with - * find_registered_zone (here abbreviated as FRZ). - */ -static int counterAlice = 0, counterBob = 0; -static int *pFRZCounterLive= &counterAlice, *pFRZCounterDrain = &counterBob; - -#define MALLOC_LOG_TYPE_ALLOCATE stack_logging_type_alloc -#define MALLOC_LOG_TYPE_DEALLOCATE stack_logging_type_dealloc -#define MALLOC_LOG_TYPE_HAS_ZONE stack_logging_flag_zone -#define MALLOC_LOG_TYPE_CLEARED stack_logging_flag_cleared - -/********* Utilities ************/ -__private_extern__ uint64_t malloc_entropy[2] = {0, 0}; - -void __malloc_entropy_setup(const char *apple[]) __attribute__ ((visibility ("hidden"))); - -static int -__entropy_from_kernel(const char *str) -{ - unsigned long long val; - char tmp[20], *p; - int idx = 0; - - /* Skip over key to the first value */ - str = strchr(str, '='); - if (str == NULL) - return 0; - str++; - - while (str && idx < sizeof(malloc_entropy)/sizeof(malloc_entropy[0])) { - strlcpy(tmp, str, 20); - p = strchr(tmp, ','); - if (p) *p = '\0'; - val = strtoull(tmp, NULL, 0); - malloc_entropy[idx] = (uint64_t)val; - idx++; - if ((str = strchr(str, ',')) != NULL) - str++; - } - return idx; -} - -void -__malloc_entropy_setup(const char *apple[]) -{ - const char **p; - for (p = apple; p && *p; p++) { - if (strstr(*p, "malloc_entropy") == *p) { - if (sizeof(malloc_entropy)/sizeof(malloc_entropy[0]) == __entropy_from_kernel(*p)) - return; - else - break; - } - } - - malloc_entropy[0] = ((uint64_t)arc4random()) << 32 | ((uint64_t)arc4random()); - malloc_entropy[1] = ((uint64_t)arc4random()) << 32 | ((uint64_t)arc4random()); - return; -} - -static inline malloc_zone_t * find_registered_zone(const void *, size_t *) __attribute__((always_inline)); -static inline malloc_zone_t * -find_registered_zone(const void *ptr, size_t *returned_size) { - // Returns a zone which contains ptr, else NULL - - if (0 == malloc_num_zones) { - if (returned_size) *returned_size = 0; - return NULL; - } - - // The default zone is registered in malloc_zones[0]. There's no danger that it will ever be unregistered. - // So don't advance the FRZ counter yet. - malloc_zone_t *zone = malloc_zones[0]; - size_t size = zone->size(zone, ptr); - if (size) { // Claimed by this zone? - if (returned_size) *returned_size = size; - return zone; - } - - int *pFRZCounter = pFRZCounterLive; // Capture pointer to the counter of the moment - __sync_fetch_and_add(pFRZCounter, 1); // Advance this counter -- our thread is in FRZ - - unsigned index; - unsigned limit = malloc_num_zones; - malloc_zone_t **zones = &malloc_zones[1]; - - for (index = 1; index < limit; ++index, ++zones) { - zone = *zones; - size = zone->size(zone, ptr); - if (size) { // Claimed by this zone? - if (returned_size) *returned_size = size; - __sync_fetch_and_sub(pFRZCounter, 1); // our thread is leaving FRZ - return zone; - } - } - // Unclaimed by any zone. - if (returned_size) *returned_size = 0; - __sync_fetch_and_sub(pFRZCounter, 1); // our thread is leaving FRZ - return NULL; -} - -__private_extern__ __attribute__((noinline)) void -malloc_error_break(void) { - // Provides a non-inlined place for various malloc error procedures to call - // that will be called after an error message appears. It does not make - // sense for developers to call this function, so it is marked - // __private_extern__ to prevent it from becoming API. -#ifndef DARLING - MAGMALLOC_MALLOCERRORBREAK(); // DTrace USDT probe -#endif -} - -__private_extern__ boolean_t __stack_logging_locked(); - -__private_extern__ __attribute__((noinline)) __attribute__((used)) int -malloc_gdb_po_unsafe(void) { - // In order to implement "po" other data formatters in gdb, the debugger - // calls functions that call malloc. The debugger will only run one thread - // of the program in this case, so if another thread is holding a zone lock, - // gdb may deadlock in this case. - // - // Iterate over the zones in malloc_zones, and call "trylock" on the zone - // lock. If trylock succeeds, unlock it, otherwise return "locked". Returns - // 0 == safe, 1 == locked/unsafe. - - if (__stack_logging_locked()) - return 1; - - malloc_zone_t **zones = malloc_zones; - unsigned i, e = malloc_num_zones; - - for (i = 0; i != e; ++i) { - malloc_zone_t *zone = zones[i]; - - // Version must be >= 5 to look at the new introspection field. - if (zone->version < 5) - continue; - - if (zone->introspect->zone_locked && zone->introspect->zone_locked(zone)) - return 1; - } - return 0; -} - -/********* Creation and destruction ************/ - -static void set_flags_from_environment(void); - -static void -malloc_zone_register_while_locked(malloc_zone_t *zone) { - size_t protect_size; - unsigned i; - - /* scan the list of zones, to see if this zone is already registered. If - * so, print an error message and return. */ - for (i = 0; i != malloc_num_zones; ++i) - if (zone == malloc_zones[i]) { - _malloc_printf(ASL_LEVEL_ERR, "Attempted to register zone more than once: %p\n", zone); - return; - } - - if (malloc_num_zones == malloc_num_zones_allocated) { - size_t malloc_zones_size = malloc_num_zones * sizeof(malloc_zone_t *); - size_t alloc_size = malloc_zones_size + vm_page_size; - - malloc_zone_t **new_zones = mmap(0, alloc_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, VM_MAKE_TAG(VM_MEMORY_MALLOC), 0); - - /* If there were previously allocated malloc zones, we need to copy them - * out of the previous array and into the new zones array */ - if (malloc_zones) - memcpy(new_zones, malloc_zones, malloc_zones_size); - - /* Update the malloc_zones pointer, which we leak if it was previously - * allocated, and the number of zones allocated */ - protect_size = alloc_size; - malloc_zones = new_zones; - malloc_num_zones_allocated = alloc_size / sizeof(malloc_zone_t *); - } else { - /* If we don't need to reallocate zones, we need to briefly change the - * page protection the malloc zones to allow writes */ - protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); - mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); - } - malloc_zones[malloc_num_zones++] = zone; - - /* Finally, now that the zone is registered, disallow write access to the - * malloc_zones array */ - mprotect(malloc_zones, protect_size, PROT_READ); - //_malloc_printf(ASL_LEVEL_INFO, "Registered malloc_zone %p in malloc_zones %p [%u zones, %u bytes]\n", zone, malloc_zones, malloc_num_zones, protect_size); -} - -static void -_malloc_initialize(void) { - MALLOC_LOCK(); - if (malloc_def_zone_state < 2) { - unsigned n; - malloc_zone_t *zone; - - malloc_def_zone_state += 2; - set_flags_from_environment(); // will only set flags up to two times - n = malloc_num_zones; - zone = create_scalable_zone(0, malloc_debug_flags); - malloc_zone_register_while_locked(zone); - malloc_set_zone_name(zone, "DefaultMallocZone"); - if (n != 0) { // make the default first, for efficiency - unsigned protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); - malloc_zone_t *hold = malloc_zones[0]; - - if(hold->zone_name && strcmp(hold->zone_name, "DefaultMallocZone") == 0) { - malloc_set_zone_name(hold, NULL); - } - - mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); - malloc_zones[0] = malloc_zones[n]; - malloc_zones[n] = hold; - mprotect(malloc_zones, protect_size, PROT_READ); - } - // _malloc_printf(ASL_LEVEL_INFO, "%d registered zones\n", malloc_num_zones); - // _malloc_printf(ASL_LEVEL_INFO, "malloc_zones is at %p; malloc_num_zones is at %p\n", (unsigned)&malloc_zones, (unsigned)&malloc_num_zones); - } - MALLOC_UNLOCK(); -} - -static inline malloc_zone_t *inline_malloc_default_zone(void) __attribute__((always_inline)); -static inline malloc_zone_t * -inline_malloc_default_zone(void) { - if (malloc_def_zone_state < 2) _malloc_initialize(); - // _malloc_printf(ASL_LEVEL_INFO, "In inline_malloc_default_zone with %d %d\n", malloc_num_zones, malloc_has_debug_zone); - return malloc_zones[0]; -} - -malloc_zone_t * -malloc_default_zone(void) { - return inline_malloc_default_zone(); -} - -static inline malloc_zone_t *inline_malloc_default_scalable_zone(void) __attribute__((always_inline)); -static inline malloc_zone_t * -inline_malloc_default_scalable_zone(void) { - unsigned index; - - if (malloc_def_zone_state < 2) _malloc_initialize(); - // _malloc_printf(ASL_LEVEL_INFO, "In inline_malloc_default_scalable_zone with %d %d\n", malloc_num_zones, malloc_has_debug_zone); - - MALLOC_LOCK(); - for (index = 0; index < malloc_num_zones; ++index) { - malloc_zone_t *z = malloc_zones[index]; - - if(z->zone_name && strcmp(z->zone_name, "DefaultMallocZone") == 0) { - MALLOC_UNLOCK(); - return z; - } - } - MALLOC_UNLOCK(); - - malloc_printf("*** malloc_default_scalable_zone() failed to find 'DefaultMallocZone'\n"); - return NULL; // FIXME: abort() instead? -} - -malloc_zone_t * -malloc_default_purgeable_zone(void) { - static malloc_zone_t *dpz; - - if (!dpz) { - // - // PR_7288598: Must pass a *scalable* zone (szone) as the helper for create_purgeable_zone(). - // Take care that the zone so obtained is not subject to interposing. - // - malloc_zone_t *tmp = create_purgeable_zone(0, inline_malloc_default_scalable_zone(), malloc_debug_flags); - malloc_zone_register(tmp); - malloc_set_zone_name(tmp, "DefaultPurgeableMallocZone"); - if (!__sync_bool_compare_and_swap(&dpz, NULL, tmp)) - malloc_destroy_zone(tmp); - } - return dpz; -} - -// For debugging, allow stack logging to both memory and disk to compare their results. -static void -stack_logging_log_stack_debug(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip) -{ - __disk_stack_logging_log_stack(type_flags, zone_ptr, size, ptr_arg, return_val, num_hot_to_skip); - stack_logging_log_stack(type_flags, zone_ptr, size, ptr_arg, return_val, num_hot_to_skip); -} - -static void -set_flags_from_environment(void) { - const char *flag; - int fd; - char **env = * _NSGetEnviron(); - char **p; - char *c; - - if (malloc_debug_file != STDERR_FILENO) { - close(malloc_debug_file); - malloc_debug_file = STDERR_FILENO; - } -#if __LP64__ - malloc_debug_flags = SCALABLE_MALLOC_ABORT_ON_CORRUPTION; // Set always on 64-bit processes -#else - int libSystemVersion = NSVersionOfLinkTimeLibrary("System"); - if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 126) /* Lion or greater */) - malloc_debug_flags = 0; - else - malloc_debug_flags = SCALABLE_MALLOC_ABORT_ON_CORRUPTION; -#endif - stack_logging_enable_logging = 0; - stack_logging_dontcompact = 0; - malloc_logger = NULL; - malloc_check_start = 0; - malloc_check_each = 1000; - malloc_check_abort = 0; - malloc_check_sleep = 100; - /* - * Given that all environment variables start with "Malloc" we optimize by scanning quickly - * first the environment, therefore avoiding repeated calls to getenv(). - * If we are setu/gid these flags are ignored to prevent a malicious invoker from changing - * our behaviour. - */ - for (p = env; (c = *p) != NULL; ++p) { - if (!strncmp(c, "Malloc", 6)) { - if (issetugid()) - return; - break; - } - } - if (c == NULL) - return; - flag = getenv("MallocLogFile"); - if (flag) { - fd = open(flag, O_WRONLY|O_APPEND|O_CREAT, 0644); - if (fd >= 0) { - malloc_debug_file = fd; - fcntl(fd, F_SETFD, 0); // clear close-on-exec flag XXX why? - } else { - malloc_printf("Could not open %s, using stderr\n", flag); - } - } - if (getenv("MallocGuardEdges")) { - malloc_debug_flags |= SCALABLE_MALLOC_ADD_GUARD_PAGES; - _malloc_printf(ASL_LEVEL_INFO, "protecting edges\n"); - if (getenv("MallocDoNotProtectPrelude")) { - malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_PRELUDE; - _malloc_printf(ASL_LEVEL_INFO, "... but not protecting prelude guard page\n"); - } - if (getenv("MallocDoNotProtectPostlude")) { - malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE; - _malloc_printf(ASL_LEVEL_INFO, "... but not protecting postlude guard page\n"); - } - } - flag = getenv("MallocStackLogging"); - if (!flag) { - flag = getenv("MallocStackLoggingNoCompact"); - stack_logging_dontcompact = 1; - } - // For debugging, the MallocStackLogging or MallocStackLoggingNoCompact environment variables can be set to - // values of "memory", "disk", or "both" to control which stack logging mechanism to use. Those strings appear - // in the flag variable, and the strtoul() call below will return 0, so then we can do string comparison on the - // value of flag. The default stack logging now is disk stack logging, since memory stack logging is not 64-bit-aware. - if (flag) { - unsigned long val = strtoul(flag, NULL, 0); - if (val == 1) val = 0; - if (val == -1) val = 0; - if (val) { - malloc_logger = (void *)val; - _malloc_printf(ASL_LEVEL_INFO, "recording stacks using recorder %p\n", malloc_logger); - } else if (strcmp(flag,"memory") == 0) { - malloc_logger = (malloc_logger_t *)stack_logging_log_stack; - _malloc_printf(ASL_LEVEL_INFO, "recording malloc stacks in memory using standard recorder\n"); - } else if (strcmp(flag,"both") == 0) { - malloc_logger = stack_logging_log_stack_debug; - _malloc_printf(ASL_LEVEL_INFO, "recording malloc stacks to both memory and disk for comparison debugging\n"); - } else { // the default is to log to disk - malloc_logger = __disk_stack_logging_log_stack; - _malloc_printf(ASL_LEVEL_INFO, "recording malloc stacks to disk using standard recorder\n"); - } - stack_logging_enable_logging = 1; - if (stack_logging_dontcompact) { - if (malloc_logger == __disk_stack_logging_log_stack) { - _malloc_printf(ASL_LEVEL_INFO, "stack logging compaction turned off; size of log files on disk can increase rapidly\n"); - } else { - _malloc_printf(ASL_LEVEL_INFO, "stack logging compaction turned off; VM can increase rapidly\n"); - } - } - } - if (getenv("MallocScribble")) { - malloc_debug_flags |= SCALABLE_MALLOC_DO_SCRIBBLE; - _malloc_printf(ASL_LEVEL_INFO, "enabling scribbling to detect mods to free blocks\n"); - } - if (getenv("MallocErrorAbort")) { - malloc_debug_flags |= SCALABLE_MALLOC_ABORT_ON_ERROR; - _malloc_printf(ASL_LEVEL_INFO, "enabling abort() on bad malloc or free\n"); - } -#if __LP64__ - /* initialization above forces SCALABLE_MALLOC_ABORT_ON_CORRUPTION of 64-bit processes */ -#else - flag = getenv("MallocCorruptionAbort"); - if (flag && (flag[0] == '0')) { // Set from an environment variable in 32-bit processes - malloc_debug_flags &= ~SCALABLE_MALLOC_ABORT_ON_CORRUPTION; - } else if (flag) { - malloc_debug_flags |= SCALABLE_MALLOC_ABORT_ON_CORRUPTION; - } -#endif - flag = getenv("MallocCheckHeapStart"); - if (flag) { - malloc_check_start = strtoul(flag, NULL, 0); - if (malloc_check_start == 0) malloc_check_start = 1; - if (malloc_check_start == -1) malloc_check_start = 1; - flag = getenv("MallocCheckHeapEach"); - if (flag) { - malloc_check_each = strtoul(flag, NULL, 0); - if (malloc_check_each == 0) malloc_check_each = 1; - if (malloc_check_each == -1) malloc_check_each = 1; - } - _malloc_printf(ASL_LEVEL_INFO, "checks heap after %dth operation and each %d operations\n", malloc_check_start, malloc_check_each); - flag = getenv("MallocCheckHeapAbort"); - if (flag) - malloc_check_abort = strtol(flag, NULL, 0); - if (malloc_check_abort) - _malloc_printf(ASL_LEVEL_INFO, "will abort on heap corruption\n"); - else { - flag = getenv("MallocCheckHeapSleep"); - if (flag) - malloc_check_sleep = strtol(flag, NULL, 0); - if (malloc_check_sleep > 0) - _malloc_printf(ASL_LEVEL_INFO, "will sleep for %d seconds on heap corruption\n", malloc_check_sleep); - else if (malloc_check_sleep < 0) - _malloc_printf(ASL_LEVEL_INFO, "will sleep once for %d seconds on heap corruption\n", -malloc_check_sleep); - else - _malloc_printf(ASL_LEVEL_INFO, "no sleep on heap corruption\n"); - } - } - if (getenv("MallocHelp")) { - _malloc_printf(ASL_LEVEL_INFO, - "environment variables that can be set for debug:\n" - "- MallocLogFile to create/append messages to file instead of stderr\n" - "- MallocGuardEdges to add 2 guard pages for each large block\n" - "- MallocDoNotProtectPrelude to disable protection (when previous flag set)\n" - "- MallocDoNotProtectPostlude to disable protection (when previous flag set)\n" - "- MallocStackLogging to record all stacks. Tools like leaks can then be applied\n" - "- MallocStackLoggingNoCompact to record all stacks. Needed for malloc_history\n" - "- MallocStackLoggingDirectory to set location of stack logs, which can grow large; default is /tmp\n" - "- MallocScribble to detect writing on free blocks and missing initializers:\n" - " 0x55 is written upon free and 0xaa is written on allocation\n" - "- MallocCheckHeapStart to start checking the heap after operations\n" - "- MallocCheckHeapEach to repeat the checking of the heap after operations\n" - "- MallocCheckHeapSleep to sleep seconds on heap corruption\n" - "- MallocCheckHeapAbort to abort on heap corruption if is non-zero\n" - "- MallocCorruptionAbort to abort on malloc errors, but not on out of memory for 32-bit processes\n" - " MallocCorruptionAbort is always set on 64-bit processes\n" - "- MallocErrorAbort to abort on any malloc error, including out of memory\n" - "- MallocHelp - this help!\n"); - } -} - -malloc_zone_t * -malloc_create_zone(vm_size_t start_size, unsigned flags) -{ - malloc_zone_t *zone; - - /* start_size doesn't seemed to actually be used, but we test anyways */ - if (start_size > MALLOC_ABSOLUTE_MAX_SIZE) { - return NULL; - } - if (malloc_def_zone_state < 2) _malloc_initialize(); - zone = create_scalable_zone(start_size, flags | malloc_debug_flags); - malloc_zone_register(zone); - return zone; -} - -/* - * For use by CheckFix: establish a new default zone whose behavior is, apart from - * the use of death-row and per-CPU magazines, that of Leopard. - */ -void -malloc_create_legacy_default_zone(void) -{ - malloc_zone_t *zone; - int i; - - if (malloc_def_zone_state < 2) _malloc_initialize(); - zone = create_legacy_scalable_zone(0, malloc_debug_flags); - - MALLOC_LOCK(); - malloc_zone_register_while_locked(zone); - - // - // Establish the legacy scalable zone just created as the default zone. - // - malloc_zone_t *hold = malloc_zones[0]; - if(hold->zone_name && strcmp(hold->zone_name, "DefaultMallocZone") == 0) { - malloc_set_zone_name(hold, NULL); - } - malloc_set_zone_name(zone, "DefaultMallocZone"); - - unsigned protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); - mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); - - // assert(zone == malloc_zones[malloc_num_zones - 1]; - for (i = malloc_num_zones - 1; i > 0; --i) { - malloc_zones[i] = malloc_zones[i - 1]; - } - malloc_zones[0] = zone; - - mprotect(malloc_zones, protect_size, PROT_READ); - MALLOC_UNLOCK(); -} - -void -malloc_destroy_zone(malloc_zone_t *zone) { - malloc_set_zone_name(zone, NULL); // Deallocate zone name wherever it may reside PR_7701095 - malloc_zone_unregister(zone); - zone->destroy(zone); -} - -/********* Block creation and manipulation ************/ - -static void -internal_check(void) { - static vm_address_t *frames = NULL; - static unsigned num_frames; - if (malloc_zone_check(NULL)) { - if (!frames) vm_allocate(mach_task_self(), (void *)&frames, vm_page_size, 1); - thread_stack_pcs(frames, vm_page_size/sizeof(vm_address_t) - 1, &num_frames); - } else { - _SIMPLE_STRING b = _simple_salloc(); - if (b) - _simple_sprintf(b, "*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1); - else - _malloc_printf(MALLOC_PRINTF_NOLOG, "*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1); - malloc_printf("*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1); - if (frames) { - unsigned index = 1; - if (b) { - _simple_sappend(b, "Stack for last operation where the malloc check succeeded: "); - while (index < num_frames) _simple_sprintf(b, "%p ", frames[index++]); - malloc_printf("%s\n(Use 'atos' for a symbolic stack)\n", _simple_string(b)); - } else { - /* - * Should only get here if vm_allocate() can't get a single page of - * memory, implying _simple_asl_log() would also fail. So we just - * print to the file descriptor. - */ - _malloc_printf(MALLOC_PRINTF_NOLOG, "Stack for last operation where the malloc check succeeded: "); - while (index < num_frames) _malloc_printf(MALLOC_PRINTF_NOLOG, "%p ", frames[index++]); - _malloc_printf(MALLOC_PRINTF_NOLOG, "\n(Use 'atos' for a symbolic stack)\n"); - } - } - if (malloc_check_each > 1) { - unsigned recomm_each = (malloc_check_each > 10) ? malloc_check_each/10 : 1; - unsigned recomm_start = (malloc_check_counter > malloc_check_each+1) ? malloc_check_counter-1-malloc_check_each : 1; - malloc_printf("*** Recommend using 'setenv MallocCheckHeapStart %d; setenv MallocCheckHeapEach %d' to narrow down failure\n", recomm_start, recomm_each); - } - if (malloc_check_abort) { - CRSetCrashLogMessage(b ? _simple_string(b) : "*** MallocCheckHeap: FAILED check"); - abort(); - } else if (b) - _simple_sfree(b); - if (malloc_check_sleep > 0) { - _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping for %d seconds to leave time to attach\n", - malloc_check_sleep); - sleep(malloc_check_sleep); - } else if (malloc_check_sleep < 0) { - _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping once for %d seconds to leave time to attach\n", - -malloc_check_sleep); - sleep(-malloc_check_sleep); - malloc_check_sleep = 0; - } - } - malloc_check_start += malloc_check_each; -} - -void * -malloc_zone_malloc(malloc_zone_t *zone, size_t size) { - void *ptr; - if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { - internal_check(); - } - if (size > MALLOC_ABSOLUTE_MAX_SIZE) { - return NULL; - } - ptr = zone->malloc(zone, size); - if (malloc_logger) - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); - return ptr; -} - -void * -malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { - void *ptr; - if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { - internal_check(); - } - if (size > MALLOC_ABSOLUTE_MAX_SIZE) { - return NULL; - } - ptr = zone->calloc(zone, num_items, size); - if (malloc_logger) - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE | MALLOC_LOG_TYPE_CLEARED, (uintptr_t)zone, (uintptr_t)(num_items * size), 0, - (uintptr_t)ptr, 0); - return ptr; -} - -void * -malloc_zone_valloc(malloc_zone_t *zone, size_t size) { - void *ptr; - if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { - internal_check(); - } - if (size > MALLOC_ABSOLUTE_MAX_SIZE) { - return NULL; - } - ptr = zone->valloc(zone, size); - if (malloc_logger) - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); - return ptr; -} - -void * -malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) { - void *new_ptr; - if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { - internal_check(); - } - if (size > MALLOC_ABSOLUTE_MAX_SIZE) { - return NULL; - } - new_ptr = zone->realloc(zone, ptr, size); - if (malloc_logger) - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, (uintptr_t)size, - (uintptr_t)new_ptr, 0); - return new_ptr; -} - -void -malloc_zone_free(malloc_zone_t *zone, void *ptr) { - if (malloc_logger) - malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0); - if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { - internal_check(); - } - zone->free(zone, ptr); -} - -static void -malloc_zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size) { - if (malloc_logger) - malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0); - if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { - internal_check(); - } - zone->free_definite_size(zone, ptr, size); -} - -malloc_zone_t * -malloc_zone_from_ptr(const void *ptr) { - if (!ptr) - return NULL; - else - return find_registered_zone(ptr, NULL); -} - -void * -malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) { - void *ptr; - if (zone->version < 5) // Version must be >= 5 to look at the new memalign field. - return NULL; - if (!(zone->memalign)) - return NULL; - if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { - internal_check(); - } - if (size > MALLOC_ABSOLUTE_MAX_SIZE) { - return NULL; - } - if (alignment < sizeof( void *) || // excludes 0 == alignment - 0 != (alignment & (alignment - 1))) { // relies on sizeof(void *) being a power of two. - return NULL; - } - ptr = zone->memalign(zone, alignment, size); - if (malloc_logger) - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); - return ptr; -} - -/********* Functions for zone implementors ************/ - -void -malloc_zone_register(malloc_zone_t *zone) { - MALLOC_LOCK(); - malloc_zone_register_while_locked(zone); - MALLOC_UNLOCK(); -} - -void -malloc_zone_unregister(malloc_zone_t *z) { - unsigned index; - - if (malloc_num_zones == 0) - return; - - MALLOC_LOCK(); - for (index = 0; index < malloc_num_zones; ++index) { - if (z != malloc_zones[index]) - continue; - - // Modify the page to be allow write access, so that we can update the - // malloc_zones array. - size_t protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); - mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); - - // If we found a match, replace it with the entry at the end of the list, shrink the list, - // and leave the end of the list intact to avoid racing with find_registered_zone(). - - malloc_zones[index] = malloc_zones[malloc_num_zones - 1]; - --malloc_num_zones; - - mprotect(malloc_zones, protect_size, PROT_READ); - - // Exchange the roles of the FRZ counters. The counter that has captured the number of threads presently - // executing *inside* find_regiatered_zone is swapped with the counter drained to zero last time through. - // The former is then allowed to drain to zero while this thread yields. - int *p = pFRZCounterLive; - pFRZCounterLive = pFRZCounterDrain; - pFRZCounterDrain = p; - __sync_synchronize(); // Full memory barrier - - while (0 != *pFRZCounterDrain) { pthread_yield_np(); } - - MALLOC_UNLOCK(); - - return; - } - MALLOC_UNLOCK(); - malloc_printf("*** malloc_zone_unregister() failed for %p\n", z); -} - -void -malloc_set_zone_name(malloc_zone_t *z, const char *name) { - char *newName; - - mprotect(z, sizeof(malloc_zone_t), PROT_READ | PROT_WRITE); - if (z->zone_name) { - free((char *)z->zone_name); - z->zone_name = NULL; - } - if (name) { - size_t buflen = strlen(name) + 1; - newName = malloc_zone_malloc(z, buflen); - if (newName) { - strlcpy(newName, name, buflen); - z->zone_name = (const char *)newName; - } else { - z->zone_name = NULL; - } - } - mprotect(z, sizeof(malloc_zone_t), PROT_READ); -} - -const char * -malloc_get_zone_name(malloc_zone_t *zone) { - return zone->zone_name; -} - -/* - * XXX malloc_printf now uses _simple_*printf. It only deals with a - * subset of printf format specifiers, but it doesn't call malloc. - */ - -__private_extern__ void -_malloc_vprintf(int flags, const char *format, va_list ap) -{ - _SIMPLE_STRING b; - - if (_malloc_no_asl_log || (flags & MALLOC_PRINTF_NOLOG) || (b = _simple_salloc()) == NULL) { - if (!(flags & MALLOC_PRINTF_NOPREFIX)) { - if (__is_threaded) { - /* XXX somewhat rude 'knowing' that pthread_t is a pointer */ - _simple_dprintf(malloc_debug_file, "%s(%d,%p) malloc: ", getprogname(), getpid(), (void *)pthread_self()); - } else { - _simple_dprintf(malloc_debug_file, "%s(%d) malloc: ", getprogname(), getpid()); - } - } - _simple_vdprintf(malloc_debug_file, format, ap); - return; - } - if (!(flags & MALLOC_PRINTF_NOPREFIX)) { - if (__is_threaded) { - /* XXX somewhat rude 'knowing' that pthread_t is a pointer */ - _simple_sprintf(b, "%s(%d,%p) malloc: ", getprogname(), getpid(), (void *)pthread_self()); - } else { - _simple_sprintf(b, "%s(%d) malloc: ", getprogname(), getpid()); - } - } - _simple_vsprintf(b, format, ap); - _simple_put(b, malloc_debug_file); - _simple_asl_log(flags & MALLOC_PRINTF_LEVEL_MASK, Malloc_Facility, _simple_string(b)); - _simple_sfree(b); -} - -__private_extern__ void -_malloc_printf(int flags, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - _malloc_vprintf(flags, format, ap); - va_end(ap); -} - -void -malloc_printf(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - _malloc_vprintf(ASL_LEVEL_ERR, format, ap); - va_end(ap); -} - -/********* Generic ANSI callouts ************/ - -void * -malloc(size_t size) { - void *retval; - retval = malloc_zone_malloc(inline_malloc_default_zone(), size); - if (retval == NULL) { - errno = ENOMEM; - } - return retval; -} - -void * -calloc(size_t num_items, size_t size) { - void *retval; - retval = malloc_zone_calloc(inline_malloc_default_zone(), num_items, size); - if (retval == NULL) { - errno = ENOMEM; - } - return retval; -} - -void -free(void *ptr) { - malloc_zone_t *zone; - size_t size; - if (!ptr) - return; - zone = find_registered_zone(ptr, &size); - if (!zone) { - malloc_printf("*** error for object %p: pointer being freed was not allocated\n" - "*** set a breakpoint in malloc_error_break to debug\n", ptr); - malloc_error_break(); - if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION|SCALABLE_MALLOC_ABORT_ON_ERROR))) { - _SIMPLE_STRING b = _simple_salloc(); - if (b) { - _simple_sprintf(b, "*** error for object %p: pointer being freed was not allocated\n", ptr); - CRSetCrashLogMessage(_simple_string(b)); - } else { - CRSetCrashLogMessage("*** error: pointer being freed was not allocated\n"); - } - abort(); - } - } else if (zone->version >= 6 && zone->free_definite_size) - malloc_zone_free_definite_size(zone, ptr, size); - else - malloc_zone_free(zone, ptr); -} - -void * -realloc(void *in_ptr, size_t new_size) { - void *retval = NULL; - void *old_ptr; - malloc_zone_t *zone; - size_t old_size = 0; - - // SUSv3: "If size is 0 and ptr is not a null pointer, the object - // pointed to is freed. If the space cannot be allocated, the object - // shall remain unchanged." Also "If size is 0, either a null pointer - // or a unique pointer that can be successfully passed to free() shall - // be returned." We choose to allocate a minimum size object by calling - // malloc_zone_malloc with zero size, which matches "If ptr is a null - // pointer, realloc() shall be equivalent to malloc() for the specified - // size." So we only free the original memory if the allocation succeeds. - old_ptr = (new_size == 0) ? NULL : in_ptr; - if (!old_ptr) { - retval = malloc_zone_malloc(inline_malloc_default_zone(), new_size); - } else { - zone = find_registered_zone(old_ptr, &old_size); - if (!zone) { - malloc_printf("*** error for object %p: pointer being realloc'd was not allocated\n" - "*** set a breakpoint in malloc_error_break to debug\n", old_ptr); - malloc_error_break(); - if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION|SCALABLE_MALLOC_ABORT_ON_ERROR))) { - _SIMPLE_STRING b = _simple_salloc(); - if (b) { - _simple_sprintf(b, "*** error for object %p: pointer being realloc'd was not allocated\n", old_ptr); - CRSetCrashLogMessage(_simple_string(b)); - } else { - CRSetCrashLogMessage("*** error: pointer being realloc'd was not allocated\n"); - } - abort(); - } - } else { - retval = malloc_zone_realloc(zone, old_ptr, new_size); - } - } - if (retval == NULL) { - errno = ENOMEM; - } else if (new_size == 0) { - free(in_ptr); - } - return retval; -} - -void * -valloc(size_t size) { - void *retval; - malloc_zone_t *zone = inline_malloc_default_zone(); - retval = malloc_zone_valloc(zone, size); - if (retval == NULL) { - errno = ENOMEM; - } - return retval; -} - -extern void -vfree(void *ptr) { - free(ptr); -} - -size_t -malloc_size(const void *ptr) { - size_t size = 0; - - if (!ptr) - return size; - - (void)find_registered_zone(ptr, &size); - return size; -} - -size_t -malloc_good_size (size_t size) { - malloc_zone_t *zone = inline_malloc_default_zone(); - return zone->introspect->good_size(zone, size); -} - -/* - * The posix_memalign() function shall allocate size bytes aligned on a boundary specified by alignment, - * and shall return a pointer to the allocated memory in memptr. - * The value of alignment shall be a multiple of sizeof( void *), that is also a power of two. - * Upon successful completion, the value pointed to by memptr shall be a multiple of alignment. - * - * Upon successful completion, posix_memalign() shall return zero; otherwise, - * an error number shall be returned to indicate the error. - * - * The posix_memalign() function shall fail if: - * EINVAL - * The value of the alignment parameter is not a power of two multiple of sizeof( void *). - * ENOMEM - * There is insufficient memory available with the requested alignment. - */ - -int -posix_memalign(void **memptr, size_t alignment, size_t size) -{ - void *retval; - - /* POSIX is silent on NULL == memptr !?! */ - - retval = malloc_zone_memalign(inline_malloc_default_zone(), alignment, size); - if (retval == NULL) { - // To avoid testing the alignment constraints redundantly, we'll rely on the - // test made in malloc_zone_memalign to vet each request. Only if that test fails - // and returns NULL, do we arrive here to detect the bogus alignment and give the - // required EINVAL return. - if (alignment < sizeof( void *) || // excludes 0 == alignment - 0 != (alignment & (alignment - 1))) { // relies on sizeof(void *) being a power of two. - return EINVAL; - } - return ENOMEM; - } else { - *memptr = retval; // Set iff allocation succeeded - return 0; - } -} - -static malloc_zone_t * -find_registered_purgeable_zone(void *ptr) { - if (!ptr) - return NULL; - - /* - * Look for a zone which contains ptr. If that zone does not have the purgeable malloc flag - * set, or the allocation is too small, do nothing. Otherwise, set the allocation volatile. - * FIXME: for performance reasons, we should probably keep a separate list of purgeable zones - * and only search those. - */ - size_t size = 0; - malloc_zone_t *zone = find_registered_zone(ptr, &size); - - /* FIXME: would really like a zone->introspect->flags->purgeable check, but haven't determined - * binary compatibility impact of changing the introspect struct yet. */ - if (!zone) - return NULL; - - /* Check to make sure pointer is page aligned and size is multiple of page size */ - if ((size < vm_page_size) || ((size % vm_page_size) != 0)) - return NULL; - - return zone; -} - -void -malloc_make_purgeable(void *ptr) { - malloc_zone_t *zone = find_registered_purgeable_zone(ptr); - if (!zone) - return; - - int state = VM_PURGABLE_VOLATILE; - vm_purgable_control(mach_task_self(), (vm_address_t)ptr, VM_PURGABLE_SET_STATE, &state); - return; -} - -/* Returns true if ptr is valid. Ignore the return value from vm_purgeable_control and only report - * state. */ -int -malloc_make_nonpurgeable(void *ptr) { - malloc_zone_t *zone = find_registered_purgeable_zone(ptr); - if (!zone) - return 0; - - int state = VM_PURGABLE_NONVOLATILE; - vm_purgable_control(mach_task_self(), (vm_address_t)ptr, VM_PURGABLE_SET_STATE, &state); - - if (state == VM_PURGABLE_EMPTY) - return EFAULT; - - return 0; -} - -size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) -{ - if (!zone) { - unsigned index = 0; - size_t total = 0; - - // Take lock to defend against malloc_destroy_zone() - MALLOC_LOCK(); - while (index < malloc_num_zones) { - zone = malloc_zones[index++]; - if (zone->version < 8) - continue; - if (NULL == zone->pressure_relief) - continue; - if (0 == goal) /* Greedy */ - total += zone->pressure_relief(zone, 0); - else if (goal > total) - total += zone->pressure_relief(zone, goal - total); - else /* total >= goal */ - break; - } - MALLOC_UNLOCK(); - return total; - } else { - // Assumes zone is not destroyed for the duration of this call - if (zone->version < 8) - return 0; - if (NULL == zone->pressure_relief) - return 0; - return zone->pressure_relief(zone, goal); - } -} - -/********* Batch methods ************/ - -unsigned -malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested) { - unsigned (*batch_malloc)(malloc_zone_t *, size_t, void **, unsigned) = zone-> batch_malloc; - if (! batch_malloc) - return 0; - if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { - internal_check(); - } - unsigned batched = batch_malloc(zone, size, results, num_requested); - if (malloc_logger) { - unsigned index = 0; - while (index < batched) { - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)results[index], 0); - index++; - } - } - return batched; -} - -void -malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num) { - if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { - internal_check(); - } - if (malloc_logger) { - unsigned index = 0; - while (index < num) { - malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)to_be_freed[index], 0, 0, 0); - index++; - } - } - void (*batch_free)(malloc_zone_t *, void **, unsigned) = zone-> batch_free; - if (batch_free) { - batch_free(zone, to_be_freed, num); - } else { - void (*free_fun)(malloc_zone_t *, void *) = zone->free; - while (num--) { - void *ptr = *to_be_freed++; - free_fun(zone, ptr); - } - } -} - -/********* Functions for performance tools ************/ - -static kern_return_t -_malloc_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) { - *ptr = (void *)address; - return 0; -} - -kern_return_t -malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count) { - // Note that the 2 following addresses are not correct if the address of the target is different from your own. This notably occurs if the address of System.framework is slid (e.g. different than at B & I ) - vm_address_t remote_malloc_zones = (vm_address_t)&malloc_zones; - vm_address_t remote_malloc_num_zones = (vm_address_t)&malloc_num_zones; - kern_return_t err; - vm_address_t zones_address; - vm_address_t *zones_address_ref; - unsigned num_zones; - unsigned *num_zones_ref; - if (!reader) reader = _malloc_default_reader; - // printf("Read malloc_zones at address %p should be %p\n", &malloc_zones, malloc_zones); - err = reader(task, remote_malloc_zones, sizeof(void *), (void **)&zones_address_ref); - // printf("Read malloc_zones[%p]=%p\n", remote_malloc_zones, *zones_address_ref); - if (err) { - malloc_printf("*** malloc_get_all_zones: error reading zones_address at %p\n", (unsigned)remote_malloc_zones); - return err; - } - zones_address = *zones_address_ref; - // printf("Reading num_zones at address %p\n", remote_malloc_num_zones); - err = reader(task, remote_malloc_num_zones, sizeof(unsigned), (void **)&num_zones_ref); - if (err) { - malloc_printf("*** malloc_get_all_zones: error reading num_zones at %p\n", (unsigned)remote_malloc_num_zones); - return err; - } - num_zones = *num_zones_ref; - // printf("Read malloc_num_zones[%p]=%d\n", remote_malloc_num_zones, num_zones); - *count = num_zones; - // printf("malloc_get_all_zones succesfully found %d zones\n", num_zones); - err = reader(task, zones_address, sizeof(malloc_zone_t *) * num_zones, (void **)addresses); - if (err) { - malloc_printf("*** malloc_get_all_zones: error reading zones at %p\n", &zones_address); - return err; - } - // printf("malloc_get_all_zones succesfully read %d zones\n", num_zones); - return err; -} - -/********* Debug helpers ************/ - -void -malloc_zone_print_ptr_info(void *ptr) { - malloc_zone_t *zone; - if (!ptr) return; - zone = malloc_zone_from_ptr(ptr); - if (zone) { - printf("ptr %p in registered zone %p\n", ptr, zone); - } else { - printf("ptr %p not in heap\n", ptr); - } -} - -boolean_t -malloc_zone_check(malloc_zone_t *zone) { - boolean_t ok = 1; - if (!zone) { - unsigned index = 0; - while (index < malloc_num_zones) { - zone = malloc_zones[index++]; - if (!zone->introspect->check(zone)) ok = 0; - } - } else { - ok = zone->introspect->check(zone); - } - return ok; -} - -void -malloc_zone_print(malloc_zone_t *zone, boolean_t verbose) { - if (!zone) { - unsigned index = 0; - while (index < malloc_num_zones) { - zone = malloc_zones[index++]; - zone->introspect->print(zone, verbose); - } - } else { - zone->introspect->print(zone, verbose); - } -} - -void -malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) { - if (!zone) { - memset(stats, 0, sizeof(*stats)); - unsigned index = 0; - while (index < malloc_num_zones) { - zone = malloc_zones[index++]; - malloc_statistics_t this_stats; - zone->introspect->statistics(zone, &this_stats); - stats->blocks_in_use += this_stats.blocks_in_use; - stats->size_in_use += this_stats.size_in_use; - stats->max_size_in_use += this_stats.max_size_in_use; - stats->size_allocated += this_stats.size_allocated; - } - } else { - zone->introspect->statistics(zone, stats); - } -} - -void -malloc_zone_log(malloc_zone_t *zone, void *address) { - if (!zone) { - unsigned index = 0; - while (index < malloc_num_zones) { - zone = malloc_zones[index++]; - zone->introspect->log(zone, address); - } - } else { - zone->introspect->log(zone, address); - } -} - -/********* Misc other entry points ************/ - -static void -DefaultMallocError(int x) { -#if USE_SLEEP_RATHER_THAN_ABORT - malloc_printf("*** error %d\n", x); - sleep(3600); -#else - _SIMPLE_STRING b = _simple_salloc(); - if (b) { - _simple_sprintf(b, "*** error %d", x); - malloc_printf("%s\n", _simple_string(b)); - CRSetCrashLogMessage(_simple_string(b)); - } else { - _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error %d", x); - CRSetCrashLogMessage("*** DefaultMallocError called"); - } - abort(); -#endif -} - -void (* -malloc_error(void (*func)(int)))(int) { - return DefaultMallocError; -} - -/* Stack logging fork-handling prototypes */ -extern void __stack_logging_fork_prepare(); -extern void __stack_logging_fork_parent(); -extern void __stack_logging_fork_child(); -extern void __stack_logging_early_finished(); - -void -_malloc_fork_prepare() { - /* Prepare the malloc module for a fork by insuring that no thread is in a malloc critical section */ - unsigned index = 0; - MALLOC_LOCK(); - while (index < malloc_num_zones) { - malloc_zone_t *zone = malloc_zones[index++]; - zone->introspect->force_lock(zone); - } - __stack_logging_fork_prepare(); -} - -void -_malloc_fork_parent() { - /* Called in the parent process after a fork() to resume normal operation. */ - unsigned index = 0; - __stack_logging_fork_parent(); - MALLOC_UNLOCK(); - while (index < malloc_num_zones) { - malloc_zone_t *zone = malloc_zones[index++]; - zone->introspect->force_unlock(zone); - } -} - -void -_malloc_fork_child() { - /* Called in the child process after a fork() to resume normal operation. In the MTASK case we also have to change memory inheritance so that the child does not share memory with the parent. */ - unsigned index = 0; - __stack_logging_fork_child(); - MALLOC_UNLOCK(); - while (index < malloc_num_zones) { - malloc_zone_t *zone = malloc_zones[index++]; - zone->introspect->force_unlock(zone); - } -} - -/* - * A Glibc-like mstats() interface. - * - * Note that this interface really isn't very good, as it doesn't understand - * that we may have multiple allocators running at once. We just massage - * the result from malloc_zone_statistics in any case. - */ -struct mstats -mstats(void) -{ - malloc_statistics_t s; - struct mstats m; - - malloc_zone_statistics(NULL, &s); - m.bytes_total = s.size_allocated; - m.chunks_used = s.blocks_in_use; - m.bytes_used = s.size_in_use; - m.chunks_free = 0; - m.bytes_free = m.bytes_total - m.bytes_used; /* isn't this somewhat obvious? */ - - return(m); -} - -boolean_t -malloc_zone_enable_discharge_checking(malloc_zone_t *zone) -{ - if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields. - return FALSE; - if (NULL == zone->introspect->enable_discharge_checking) - return FALSE; - return zone->introspect->enable_discharge_checking(zone); -} - -void -malloc_zone_disable_discharge_checking(malloc_zone_t *zone) -{ - if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields. - return; - if (NULL == zone->introspect->disable_discharge_checking) - return; - zone->introspect->disable_discharge_checking(zone); -} - -void -malloc_zone_discharge(malloc_zone_t *zone, void *memory) -{ - if (NULL == zone) - zone = malloc_zone_from_ptr(memory); - if (NULL == zone) - return; - if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields. - return; - if (NULL == zone->introspect->discharge) - return; - zone->introspect->discharge(zone, memory); -} - -void -malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)) -{ - if (!zone) { - unsigned index = 0; - while (index < malloc_num_zones) { - zone = malloc_zones[index++]; - if (zone->version < 7) - continue; - if (NULL == zone->introspect->enumerate_discharged_pointers) - continue; - zone->introspect->enumerate_discharged_pointers(zone, report_discharged); - } - } else { - if (zone->version < 7) - return; - if (NULL == zone->introspect->enumerate_discharged_pointers) - return; - zone->introspect->enumerate_discharged_pointers(zone, report_discharged); - } -} - -/***************** OBSOLETE ENTRY POINTS ********************/ - -#if PHASE_OUT_OLD_MALLOC -#error PHASE OUT THE FOLLOWING FUNCTIONS -#else -#warning PHASE OUT THE FOLLOWING FUNCTIONS -#endif - -void -set_malloc_singlethreaded(boolean_t single) { - static boolean_t warned = 0; - if (!warned) { -#if PHASE_OUT_OLD_MALLOC - malloc_printf("*** OBSOLETE: set_malloc_singlethreaded(%d)\n", single); -#endif - warned = 1; - } -} - -void -malloc_singlethreaded() { - static boolean_t warned = 0; - if (!warned) { - malloc_printf("*** OBSOLETE: malloc_singlethreaded()\n"); - warned = 1; - } -} - -int -malloc_debug(int level) { - malloc_printf("*** OBSOLETE: malloc_debug()\n"); - return 0; -} diff --git a/src/libc/gen/malloc_printf.h b/src/libc/gen/malloc_printf.h deleted file mode 100644 index 5f10683e8..000000000 --- a/src/libc/gen/malloc_printf.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -extern void malloc_printf(const char *fmt, ...); - -#define MALLOC_PRINTF_LEVEL_MASK 0x0f -#define MALLOC_PRINTF_NOLOG 0x10 -#define MALLOC_PRINTF_NOPREFIX 0x20 - -extern void _malloc_printf(int flags, const char *fmt, ...); -extern void _malloc_vprintf(int flags, const char *fmt, va_list ap); diff --git a/src/libc/gen/malloc_size.3 b/src/libc/gen/malloc_size.3 deleted file mode 100644 index 378db96f8..000000000 --- a/src/libc/gen/malloc_size.3 +++ /dev/null @@ -1,55 +0,0 @@ -.\" Copyright (c) 2006 Apple Computer, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd May 23, 2006 -.Dt MALLOC_SIZE 3 -.Os -.Sh NAME -.Nm malloc_good_size , -.Nm malloc_size -.Nd memory allocation information -.Sh SYNOPSIS -.In malloc/malloc.h -.Ft size_t -.Fo malloc_good_size -.Fa "size_t size" -.Fc -.Ft size_t -.Fo malloc_size -.Fa "const void *ptr" -.Fc -.Sh DESCRIPTION -The -.Fn malloc_size -function returns the size of the memory block -that backs the allocation pointed to by -.Fa ptr . -The memory block size is always at least as large -as the allocation it backs, and may be larger. -.Pp -The -.Fn malloc_good_size -function rounds -.Fa size -up to a value that the allocator implementation can allocate -without adding any padding; -it then returns that rounded-up value. -.Sh SEE ALSO -.Xr malloc 3 diff --git a/src/libc/gen/malloc_zone_malloc.3 b/src/libc/gen/malloc_zone_malloc.3 deleted file mode 100644 index 52d4c19ea..000000000 --- a/src/libc/gen/malloc_zone_malloc.3 +++ /dev/null @@ -1,163 +0,0 @@ -.\" Copyright (c) 2008 Apple, Inc. All rights reserved. -.\" -.\" @APPLE_LICENSE_HEADER_START@ -.\" -.\" The contents of this file constitute Original Code as defined in and -.\" are subject to the Apple Public Source License Version 1.1 (the -.\" "License"). You may not use this file except in compliance with the -.\" License. Please obtain a copy of the License at -.\" http://www.apple.com/publicsource and read it before using this file. -.\" -.\" This Original Code and all software distributed under the License are -.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER -.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the -.\" License for the specific language governing rights and limitations -.\" under the License. -.\" -.\" @APPLE_LICENSE_HEADER_END@ -.\" -.Dd Aug 13, 2008 -.Dt MALLOC_ZONE_MALLOC 3 -.Os -.Sh NAME -.Nm malloc_create_zone , -.Nm malloc_destroy_zone , -.Nm malloc_default_zone , -.Nm malloc_zone_from_ptr , -.Nm malloc_zone_malloc , -.Nm malloc_zone_calloc , -.Nm malloc_zone_valloc , -.Nm malloc_zone_realloc , -.Nm malloc_zone_memalign , -.Nm malloc_zone_free -.Nd zone-based memory allocation -.Sh SYNOPSIS -.In malloc/malloc.h -.Ft malloc_zone_t * -.Fo malloc_create_zone -.Fa "vm_size_t start_size" -.Fa "unsigned flags" -.Fc -.Ft void -.Fo malloc_destroy_zone -.Fa "malloc_zone_t *zone" -.Fc -.Ft malloc_zone_t * -.Fo malloc_default_zone -.Fa void -.Fc -.Ft malloc_zone_t * -.Fo malloc_zone_from_ptr -.Fa "const void *ptr" -.Fc -.Ft void * -.Fo malloc_zone_malloc -.Fa "malloc_zone_t *zone" -.Fa "size_t size" -.Fc -.Ft void * -.Fo malloc_zone_calloc -.Fa "malloc_zone_t *zone" -.Fa "size_t num_items" -.Fa "size_t size" -.Fc -.Ft void * -.Fo malloc_zone_valloc -.Fa "malloc_zone_t *zone" -.Fa "size_t size" -.Fc -.Ft void * -.Fo malloc_zone_realloc -.Fa "malloc_zone_t *zone" -.Fa "void *ptr" -.Fa "size_t size" -.Fc -.Ft void * -.Fo malloc_zone_memalign -.Fa "malloc_zone_t *zone" -.Fa "size_t alignment" -.Fa "size_t size" -.Fc -.Ft void -.Fo malloc_zone_free -.Fa "malloc_zone_t *zone" -.Fa "void *ptr" -.Fc -.Sh DESCRIPTION -The -.Fn malloc_create_zone -function creates a malloc zone, advising an initial allocation of -.Fa start_size -bytes, and specifying -.Fa flags -The returned malloc zone can be used to provide custom allocation and -deallocation behavior, and to retrieve additional information about the -allocations in that zone. -At present there are no client settable flag values recognized by malloc_create_zone(), -the flags argument should always be passed as zero. -.Pp -The -.Fn malloc_destroy_zone -function deallocates all memory associated with objects in -.Fa zone -as well as -.Fa zone -itself. -.Pp -The -.Fn malloc_default_zone -function returns the default system malloc zone, used by -.Xr malloc 3 , -and -.Xr free 3 . -.Pp -The -.Fn malloc_zone_from_ptr -function returns a pointer to the malloc zone which contains -.Fa ptr -or NULL, if the pointer does not point to an allocated object in any current -malloc zone. -.Pp -The -.Fn malloc_zone_malloc , -.Fn malloc_zone_calloc , -.Fn malloc_zone_valloc , -.Fn malloc_zone_realloc , -.Fn malloc_zone_memalign , -and -.Fn malloc_zone_free -perform the same task on -.Fa zone -as their non-prefixed variants, -.Xr malloc 3 , -.Xr calloc 3 , -.Xr valloc 3 , -.Xr realloc 3 , -.Xr posix_memalign 3 , -and -.Xr free 3 perform on the default system malloc zone. -.Sh RETURN VALUES -The -.Fn malloc_create_zone , -.Fn malloc_default_zone , -and -.Fn malloc_zone_from_ptr -functions return a pointer to a malloc_zone_t structure, or NULL if there was -an error. -.Pp -The -.Fn malloc_zone_malloc , -.Fn malloc_zone_calloc , -.Fn malloc_zone_valloc , -.Fn malloc_zone_realloc , -and -.Fn malloc_zone_memalign -functions return a pointer to allocated memory. If there is an error, they -return a NULL pointer. They are not required to set -.Va errno . -.El -.Sh SEE ALSO -.Xr malloc 3 , -.Xr posix_memalign 3 diff --git a/src/libc/gen/nanosleep.c b/src/libc/gen/nanosleep.c index 1b560563c..71ad76c44 100644 --- a/src/libc/gen/nanosleep.c +++ b/src/libc/gen/nanosleep.c @@ -26,18 +26,23 @@ #include #include #include +#include #include - +#include #if __DARWIN_UNIX03 -#include "pthread_internals.h" #include +#include +#include +#include -#ifndef BUILDING_VARIANT +#if !defined(BUILDING_VARIANT) semaphore_t clock_sem = MACH_PORT_NULL; mach_port_t clock_port = MACH_PORT_NULL; -void _init_clock_port() { +void _init_clock_port(void); + +void _init_clock_port(void) { kern_return_t kr; mach_port_t host = mach_host_self(); @@ -60,7 +65,6 @@ extern mach_port_t clock_port; extern int __unix_conforming; #ifdef VARIANT_CANCELABLE -extern void _pthread_testcancel(pthread_t thread, int isconforming); extern int __semwait_signal(int cond_sem, int mutex_sem, int timeout, int relative, __int64_t tv_sec, __int32_t tv_nsec); #define SEMWAIT_SIGNAL __semwait_signal #else /* !VARIANT_CANCELABLE */ @@ -79,7 +83,7 @@ nanosleep(const struct timespec *requested_time, struct timespec *remaining_time __unix_conforming = 1; #ifdef VARIANT_CANCELABLE - _pthread_testcancel(pthread_self(), 1); + pthread_testcancel(); #endif /* VARIANT_CANCELABLE */ if ((requested_time == NULL) || (requested_time->tv_sec < 0) || (requested_time->tv_nsec >= NSEC_PER_SEC)) { @@ -227,7 +231,7 @@ muldiv128(uint64_t x, uint64_t y, uint64_t divisor, uint64_t *res) * answer from the lesser side. So if our estimate is too large * we need to decrease it until it is smaller. */ - while(backmul.high > temp.high || backmul.high == temp.high && backmul.low > temp.low) { + while(backmul.high > temp.high || (backmul.high == temp.high && backmul.low > temp.low)) { sub128_128(&backmul, &divisor128); uapprox--; } diff --git a/src/libc/gen/platfunc.c b/src/libc/gen/platfunc.c deleted file mode 100644 index 0f3bcba53..000000000 --- a/src/libc/gen/platfunc.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined(__i386__) || defined(__x86_64__) - -#include -#include -#include "platfunc.h" - -#define PLAT_CAP_MASK (kHasMMX | kHasSSE | kHasSSE2 | kHasSSE3 | kCache32 | kCache64 | kCache128 | kFastThreadLocalStorage | kHasSupplementalSSE3 | k64Bit | kHasSSE4_1 | kHasSSE4_2 | kHasAES | kInOrderPipeline | kSlow | kUP) - -inline static int __get_cpu_capabilities() { - return *((int32_t*)_COMM_PAGE_CPU_CAPABILITIES); -} - -inline static int num_cpus(int capabilities) { - return (capabilities & kNumCPUs) >> kNumCPUsShift; -} - -/* TODO: If 8151810 is fixed (or full support for visibility("internal") is added), change this to visibility("internal") */ -void __attribute__((visibility("hidden"))) *find_platform_function(const platfunc_descriptor *descriptors[]) { - int cap = __get_cpu_capabilities(), - have_cpus = num_cpus(cap); - - for (int i = 0; descriptors[i] != 0; i++) { - int musthave_cpus = num_cpus(descriptors[i]->musthave), - canthave_cpus = num_cpus(descriptors[i]->canthave); - uint32_t musthave = descriptors[i]->musthave & PLAT_CAP_MASK, - canthave = descriptors[i]->canthave & PLAT_CAP_MASK; - /* First check that the CPU supports all the features that are in musthave */ - if ((musthave & cap) != musthave) - continue; - /* Now check that the CPU doesn't have any of the features that are in canthave */ - if ((canthave & cap) != 0) - continue; - /* Special case check for the number of CPUs. */ - /* TODO: Should there be a way to specify < or > num cpus? */ - if (musthave_cpus != 0 && have_cpus != musthave_cpus) - continue; - if (canthave_cpus != 0 && have_cpus == canthave_cpus) - continue; - /* otherwise, we have found our preferred implementation */ - return descriptors[i]->address; - } - - // FIXME: Until we have capability detection working, we just pick the first available implementation and use it - // This will cause issues on systems with a worse CPU installed. - return descriptors[0]->address; - /* We didn't find an acceptable implementation. (bug in data structures!) */ - return NULL; -} - -#endif diff --git a/src/libc/gen/platfunc.h b/src/libc/gen/platfunc.h deleted file mode 100644 index 87e0fd6d8..000000000 --- a/src/libc/gen/platfunc.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2003-2010 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#if defined(__i386__) || defined(__x86_64__) - -#ifndef _I386_PLATFUNC_H -#define _I386_PLATFUNC_H - -#ifndef __ASSEMBLER__ -#include -#endif /* __ASSEMBLER__ */ - -// This is a shared macro which calls PLATFUNC_VARIANT_NAME which has different -// implementations in __ASSEMBLER__ and !__ASSEMBLER__ -#define PLATFUNC_DESCRIPTOR_NAME(name, variant) \ - PLATFUNC_VARIANT_NAME(platfunc_##name,variant) - -#ifdef __ASSEMBLER__ - -/* When trying to acquire a spinlock or mutex, we will spin in - * user mode for awhile, before entering the kernel to relinquish. - * MP_SPIN_TRIES is the initial value of _COMM_PAGE_SPIN_COUNT. - * The idea is that _COMM_PAGE_SPIN_COUNT will be adjusted up or - * down as the machine is plugged in/out, etc. - * At present spinlocks do not use _COMM_PAGE_SPIN_COUNT. - * They use MP_SPIN_TRIES directly. - */ -#define MP_SPIN_TRIES 1000 - -#define PLATFUNC_VARIANT_NAME(name, variant) _##name##$VARIANT$##variant - -#if defined (__i386__) -#define PLATFUNC_DESCRIPTOR_FIELD_POINTER .long -#define PLATFUNC_DESCRIPTOR_REFERENCE(name,variant) \ - .long PLATFUNC_DESCRIPTOR_NAME(name,variant) -#elif defined (__x86_64__) -#define PLATFUNC_DESCRIPTOR_FIELD_POINTER .quad -#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) \ - .quad PLATFUNC_DESCRIPTOR_NAME(name,variant) -#else -#error unsupported architecture -#endif - -#ifdef VARIANT_DYLD - -#define PLATFUNC_FUNCTION_START_GENERIC(name, variant, codetype, alignment) \ - PLATFUNC_FUNCTION_START(name,variant, codetype, alignment) \ - .globl _ ## name ;\ - _ ## name ## : - -#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) - -#else /* VARIANT_DYLD */ - -#define PLATFUNC_FUNCTION_START_GENERIC PLATFUNC_FUNCTION_START - -#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) \ - .const_data ;\ - .private_extern PLATFUNC_DESCRIPTOR_NAME(name,variant) ;\ - PLATFUNC_DESCRIPTOR_NAME(name,variant) ## : ;\ - PLATFUNC_DESCRIPTOR_FIELD_POINTER PLATFUNC_VARIANT_NAME(name,variant) ;\ - .long must ;\ - .long cant ;\ - .text - -#endif /* VARIANT_DYLD */ - -#define PLATFUNC_FUNCTION_START(name, variant, codetype, alignment) \ - .text ;\ - .align alignment, 0x90 ;\ - .private_extern PLATFUNC_VARIANT_NAME(name,variant) ;\ - PLATFUNC_VARIANT_NAME(name,variant) ## : - -#else /* __ASSEMBLER__ */ - -#define PLATFUNC_VARIANT_NAME(name, variant) name##$VARIANT$##variant -#define PLATFUNC_DESCRIPTOR_PROTOTYPE(name, variant) extern const platfunc_descriptor PLATFUNC_DESCRIPTOR_NAME(name,variant); -#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) &PLATFUNC_DESCRIPTOR_NAME(name,variant) - -#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) \ - extern void PLATFUNC_VARIANT_NAME(name,variant) (void); \ - const platfunc_descriptor PLATFUNC_DESCRIPTOR_NAME(name,variant) = { \ - .address = PLATFUNC_VARIANT_NAME(name,variant), \ - .musthave = must, \ - .canthave = cant \ - } - -/* - * Each potential platfunc routine is described by one of these. - * Note that the PLATFUNC_DESCRIPTOR macro (above), used in - * assembly language, must agree with this. - */ - -typedef struct platfunc_descriptor { - void *address; // address of code - uint32_t musthave; // _cpu_capability bits we must have - uint32_t canthave; // _cpu_capability bits we can't have -} platfunc_descriptor; - -void *find_platform_function(const platfunc_descriptor *descriptors[]); - -#endif /* __ASSEMBLER__ */ - -#endif /* _I386_PLATFUNC_H */ - -#endif /* __i386__ || __x86_64__ */ diff --git a/src/libc/gen/raise.c b/src/libc/gen/raise.c new file mode 100644 index 000000000..430e5da5f --- /dev/null +++ b/src/libc/gen/raise.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016 Apple, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include + +int raise(int sig) { + int error = pthread_kill(pthread_self(), sig); + switch (error) { + case 0: + return 0; + case ENOTSUP: + return kill(getpid(), sig); + default: + errno = error; + return -1; + } +} diff --git a/src/libc/gen/scalable_malloc.c b/src/libc/gen/scalable_malloc.c deleted file mode 100644 index 6ac0ae662..000000000 --- a/src/libc/gen/scalable_malloc.c +++ /dev/null @@ -1,4222 +0,0 @@ -/* - * Copyright (c) 1999, 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* Author: Bertrand Serlet, August 1999 */ - -#include "scalable_malloc.h" -#include "malloc_printf.h" -#include "_simple.h" - -#include - -#include -#include -#include -#include -#include -#include - -/********************* DEFINITIONS ************************/ - -#define DEBUG_MALLOC 0 // set to one to debug malloc itself - -#define DEBUG_CLIENT 0 // set to one to help debug a nasty memory smasher - -#if DEBUG_MALLOC -#warning DEBUG_MALLOC ENABLED -# define INLINE -# define ALWAYSINLINE -# define CHECK_LOCKED(szone, fun) \ -do { \ - if (__is_threaded && TRY_LOCK(szone->lock)) { \ - malloc_printf("*** lock was not set %p in %s\n", szone->lock, fun); \ - } \ -} while (0) -#else -# define INLINE __inline__ -# define ALWAYSINLINE __attribute__((always_inline)) -# define CHECK_LOCKED(szone, fun) {} -#endif - -/* - * Access to global variables is slow, so optimise our handling of vm_page_size - * and vm_page_shift. - */ -#define _vm_page_size vm_page_size /* to get to the originals */ -#define _vm_page_shift vm_page_shift -#define vm_page_size 4096 /* our normal working sizes */ -#define vm_page_shift 12 - -typedef unsigned short msize_t; // a size in multiples of SHIFT_SMALL_QUANTUM or SHIFT_TINY_QUANTUM - -typedef union { - void *p; - uintptr_t u; -} ptr_union; - -typedef struct { - ptr_union previous; - ptr_union next; -} free_list_t; - -typedef struct { - uintptr_t address_and_num_pages; - // this type represents both an address and a number of pages - // the low bits are the number of pages; the high bits are the address - // note that the exact number of bits used for depends on the page size - // also, this cannot represent pointers larger than 1 << (vm_page_shift * 2) -} compact_range_t; - -typedef unsigned char grain_t; - -#define CHECK_REGIONS (1 << 31) - -#define MAX_RECORDER_BUFFER 256 - -/********************* DEFINITIONS for tiny ************************/ - -/* - * Memory in the Tiny range is allocated from regions (heaps) pointed to by the szone's tiny_regions - * pointer. - * - * Each region is laid out as a heap, followed by a header block, all within - * a 1MB (2^20) block. This means there are 64520 16-byte blocks and the header is - * 16138 bytes, making the total 1048458 bytes, leaving 118 bytes unused. - * The header block is arranged: - * - * 0xfc080 - * header bits - * 0xfe001 - * 0xffffffff pad word - * 0xfe005 - * in-use bits - * 0xfff86 - * pad word (not written) - * 0xfff8a-0xfffff - * unused - * - * Each bitfield comprises NUM_TINY_BLOCKS bits, and refers to the corresponding TINY_QUANTUM block - * within the heap. - * - * The bitfields are used to encode the state of memory within the heap. The header bit indicates - * that the corresponding quantum is the first quantum in a block (either in use or free). The - * in-use bit is set for the header if the block has been handed out (allocated). If the header - * bit is not set, the in-use bit is invalid. - * - * The szone maintains an array of 32 freelists, each of which is used to hold - * free objects of the corresponding quantum size. - * - * A free block is laid out depending on its size, in order to fit all free - * blocks in 16 bytes, on both 32 and 64 bit platforms. One quantum blocks do - * not store their size in the block, instead relying on the header information - * to determine their size. Blocks of two or more quanta have room to store - * their size in the block, and store it both after the 'next' pointer, and in - * the last 2 bytes of the block. - * - * 1-quantum block - * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 : previous - * 0x4 0x08 : next - * end end - * - * >1-quantum block - * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 : previous - * 0x4 0x08 : next - * 0x8 0x10 : size (in quantum counts) - * end - 2 end - 2 : size (in quantum counts) - * end end - * - * All fields are pointer-sized, except for the size which is an unsigned short. - * - */ - -#define SHIFT_TINY_QUANTUM 4 // Required for AltiVec -#define TINY_QUANTUM (1 << SHIFT_TINY_QUANTUM) - -#define FOLLOWING_TINY_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM)) - -#define NUM_TINY_SLOTS 32 // number of slots for free-lists - -#define NUM_TINY_BLOCKS 64520 -#define SHIFT_TINY_CEIL_BLOCKS 16 // ceil(log2(NUM_TINY_BLOCKS)) -#define NUM_TINY_CEIL_BLOCKS (1 << SHIFT_TINY_CEIL_BLOCKS) -#define TINY_BLOCKS_ALIGN (SHIFT_TINY_CEIL_BLOCKS + SHIFT_TINY_QUANTUM) - -/* - * Enough room for the data, followed by the bit arrays (2-bits per block) plus 2 words of padding - * as our bitmap operators overflow, plus rounding to the nearest page. - */ -#define TINY_HEADER_SIZE ((NUM_TINY_BLOCKS >> 2) + 8) -#define TINY_REGION_SIZE ((NUM_TINY_BLOCKS * TINY_QUANTUM + TINY_HEADER_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1)) - -/* - * Beginning and end pointers for a region's heap. - */ -#define TINY_REGION_ADDRESS(region) ((void *)(region)) -#define TINY_REGION_END(region) (TINY_REGION_ADDRESS(region) + (NUM_TINY_BLOCKS * TINY_QUANTUM)) - -/* - * Locate the heap base for a pointer known to be within a tiny region. - */ -#define TINY_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << TINY_BLOCKS_ALIGN) - 1))) - -/* - * Convert between byte and msize units. - */ -#define TINY_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_TINY_QUANTUM) -#define TINY_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_TINY_QUANTUM) - -#ifdef __LP64__ -# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[8]) -#else -# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[4]) -#endif -#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] - -/* - * Locate the block header for a pointer known to be within a tiny region. - */ -#define TINY_HEADER_START (NUM_TINY_BLOCKS * TINY_QUANTUM) -#define TINY_BLOCK_HEADER_FOR_PTR(_p) ((void *)((uintptr_t)TINY_REGION_FOR_PTR(_p) + TINY_HEADER_START)) - -/* - * Locate the inuse map for a given block header pointer. - */ -#define TINY_INUSE_FOR_HEADER(_h) ((void *)((uintptr_t)(_h) + (NUM_TINY_BLOCKS >> 3) + 4)) - -/* - * Compute the bitmap index for a pointer known to be within a tiny region. - */ -#define TINY_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_CEIL_BLOCKS - 1)) - -#define TINY_CACHE 1 // This governs a last-free cache of 1 that bypasses the free-list - -#if ! TINY_CACHE -#warning TINY_CACHE turned off -#endif - -/********************* DEFINITIONS for small ************************/ - -/* - * Memory in the Small range is allocated from regions (heaps) pointed to by the szone's small_regions - * pointer. - * - * Each region is laid out as a heap, followed by the metadata array, all within an 8MB (2^23) block. - * The array is arranged as an array of shorts, one for each SMALL_QUANTUM in the heap. - * This means there are 16320 512-blocks and the array is 16320*2 bytes, which totals 8388480, leaving - * 128 bytes unused. - * - * The MSB of each short is set for the first quantum in a free block. The low 15 bits encode the - * block size (in SMALL_QUANTUM units), or are zero if the quantum is not the first in a block. - * - * The szone maintains an array of 32 freelists, each of which is used to hold free objects - * of the corresponding quantum size. - * - * A free block is laid out as: - * - * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 : previous - * 0x4 0x08 : next - * 0x8 0x10 : size (in quantum counts) - * end - 2 end - 2 : size (in quantum counts) - * end end - * - * All fields are pointer-sized, except for the size which is an unsigned short. - * - */ - -#define SMALL_IS_FREE (1 << 15) - -#define SHIFT_SMALL_QUANTUM (SHIFT_TINY_QUANTUM + 5) // 9 -#define SMALL_QUANTUM (1 << SHIFT_SMALL_QUANTUM) // 512 bytes - -#define FOLLOWING_SMALL_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_SMALL_QUANTUM)) - -#define NUM_SMALL_SLOTS 32 // number of slots for free-lists - -/* - * We can only represent up to 1<<15 for msize; but we choose to stay even below that to avoid the - * convention msize=0 => msize = (1<<15) - */ -#define NUM_SMALL_BLOCKS 16320 -#define SHIFT_SMALL_CEIL_BLOCKS 14 // ceil(log2(NUM_SMALL_BLOCKs)) -#define NUM_SMALL_CEIL_BLOCKS (1 << SHIFT_SMALL_CEIL_BLOCKS) -#define SMALL_BLOCKS_ALIGN (SHIFT_SMALL_CEIL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23 -#define SMALL_ARRAY_SIZE (NUM_SMALL_BLOCKS * 2) -#define SMALL_REGION_SIZE ((NUM_SMALL_BLOCKS * SMALL_QUANTUM + SMALL_ARRAY_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1)) // data + meta data - -#define SMALL_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] - -/* - * Convert between byte and msize units. - */ -#define SMALL_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_SMALL_QUANTUM) -#define SMALL_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_SMALL_QUANTUM) - - -#define SMALL_REGION_ADDRESS(region) ((unsigned char *)region) -#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region) + (NUM_SMALL_BLOCKS * SMALL_QUANTUM)) - -/* - * Locate the heap base for a pointer known to be within a small region. - */ -#define SMALL_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << SMALL_BLOCKS_ALIGN) - 1))) - -/* - * Locate the metadata base for a pointer known to be within a small region. - */ -#define SMALL_HEADER_START (NUM_SMALL_BLOCKS * SMALL_QUANTUM) -#define SMALL_META_HEADER_FOR_PTR(_p) ((msize_t *)((uintptr_t)SMALL_REGION_FOR_PTR(_p) + SMALL_HEADER_START)) - -/* - * Compute the metadata index for a pointer known to be within a small region. - */ -#define SMALL_META_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_CEIL_BLOCKS - 1)) - -/* - * Find the metadata word for a pointer known to be within a small region. - */ -#define SMALL_METADATA_FOR_PTR(_p) (SMALL_META_HEADER_FOR_PTR(_p) + SMALL_META_INDEX_FOR_PTR(_p)) - -/* - * Determine whether a pointer known to be within a small region points to memory which is free. - */ -#define SMALL_PTR_IS_FREE(_p) (*SMALL_METADATA_FOR_PTR(_p) & SMALL_IS_FREE) - -/* - * Extract the msize value for a pointer known to be within a small region. - */ -#define SMALL_PTR_SIZE(_p) (*SMALL_METADATA_FOR_PTR(_p) & ~SMALL_IS_FREE) - -#define PROTECT_SMALL 0 // Should be 0: 1 is too slow for normal use - -#define SMALL_CACHE 1 -#if !SMALL_CACHE -#warning SMALL_CACHE turned off -#endif - -/********************* DEFINITIONS for large and huge ***********************/ - -#define LARGE_THRESHOLD (15 * 1024) // at or above this use "large" - -#if (LARGE_THRESHOLD > NUM_SMALL_SLOTS * SMALL_QUANTUM) -#error LARGE_THRESHOLD should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM -#endif - -#define VM_COPY_THRESHOLD (40 * 1024) - // When all memory is touched after a copy, vm_copy() is always a lose - // But if the memory is only read, vm_copy() wins over memmove() at 3 or 4 pages (on a G3/300MHz) - // This must be larger than LARGE_THRESHOLD - -/* - * Given a large_entry, return the address of the allocated block. - */ -#define LARGE_ENTRY_ADDRESS(entry) \ - (void *)(((entry).address_and_num_pages >> vm_page_shift) << vm_page_shift) - -/* - * Given a large entry, return the number of pages or bytes in the allocated block. - */ -#define LARGE_ENTRY_NUM_PAGES(entry) \ - ((entry).address_and_num_pages & (vm_page_size - 1)) -#define LARGE_ENTRY_SIZE(entry) \ - (LARGE_ENTRY_NUM_PAGES(entry) << vm_page_shift) - -/* - * Compare a pointer with a large entry. - */ -#define LARGE_ENTRY_MATCHES(entry,ptr) \ - ((((entry).address_and_num_pages - (uintptr_t)(ptr)) >> vm_page_shift) == 0) - -#define LARGE_ENTRY_IS_EMPTY(entry) (((entry).address_and_num_pages) == 0) - -typedef compact_range_t large_entry_t; -typedef vm_range_t huge_entry_t; - -/******************************************************************************* - * Definitions for region hash - ******************************************************************************/ - -typedef void * region_t; - -#define INITIAL_NUM_REGIONS 63 // Must be odd to hash well - -/********************* zone itself ************************/ - -typedef struct { - malloc_zone_t basic_zone; - pthread_lock_t lock; - unsigned debug_flags; - void *log_address; - - /* Regions for tiny objects */ - size_t num_tiny_regions; - size_t num_tiny_regions_allocated; - region_t *tiny_regions; // hashed by location - region_t *last_tiny_region; - void *last_tiny_free; // low SHIFT_TINY_QUANTUM indicate the msize - unsigned tiny_bitmap; // cache of the 32 free lists - free_list_t *tiny_free_list[NUM_TINY_SLOTS]; // 31 free lists for 1*TINY_QUANTUM to 31*TINY_QUANTUM plus 1 for larger than 32*SMALL_QUANTUM - size_t tiny_bytes_free_at_end; // the last free region in the last block is treated as a big block in use that is not accounted for - unsigned num_tiny_objects; - size_t num_bytes_in_tiny_objects; - - /* Regions for small objects */ - size_t num_small_regions; - size_t num_small_regions_allocated; - region_t *small_regions; // hashed by location - region_t *last_small_region; - void *last_small_free; // low SHIFT_SMALL_QUANTUM indicate the msize - unsigned small_bitmap; // cache of the free list - free_list_t *small_free_list[NUM_SMALL_SLOTS]; - size_t small_bytes_free_at_end; // the last free region in the last block is treated as a big block in use that is not accounted for - unsigned num_small_objects; - size_t num_bytes_in_small_objects; - - /* large objects: vm_page_shift <= log2(size) < 2 *vm_page_shift */ - unsigned num_large_objects_in_use; - unsigned num_large_entries; - large_entry_t *large_entries; // hashed by location; null entries don't count - size_t num_bytes_in_large_objects; - - /* huge objects: log2(size) >= 2 *vm_page_shift */ - unsigned num_huge_entries; - huge_entry_t *huge_entries; - size_t num_bytes_in_huge_objects; - - /* Initial region list */ - region_t initial_tiny_regions[INITIAL_NUM_REGIONS]; - region_t initial_small_regions[INITIAL_NUM_REGIONS]; -} szone_t; - -#define SZONE_PAGED_SIZE ((sizeof(szone_t) + vm_page_size - 1) & ~ (vm_page_size - 1)) - -#if DEBUG_MALLOC || DEBUG_CLIENT -static void szone_sleep(void); -#endif -__private_extern__ void malloc_error_break(void); - -// msg prints after fmt, ... -static void szone_error(szone_t *szone, const char *msg, const void *ptr, const char *fmt, ...) __printflike(4, 5); - -static void protect(void *address, size_t size, unsigned protection, unsigned debug_flags); -static void *allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label); -static void deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags); -static kern_return_t _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr); - -static INLINE void free_list_checksum(szone_t *szone, free_list_t *ptr, const char *msg) ALWAYSINLINE; -static INLINE void free_list_set_checksum(szone_t *szone, free_list_t *ptr) ALWAYSINLINE; -static INLINE uintptr_t free_list_checksum_ptr(void *p) ALWAYSINLINE; -static INLINE void * free_list_unchecksum_ptr(ptr_union ptr) ALWAYSINLINE; -static unsigned free_list_count(const free_list_t *ptr); - -static INLINE msize_t get_tiny_meta_header(const void *ptr, boolean_t *is_free) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_in_use(const void *ptr, msize_t msize) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_middle(const void *ptr) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_free(const void *ptr, msize_t msize) ALWAYSINLINE; -static INLINE boolean_t tiny_meta_header_is_free(const void *ptr) ALWAYSINLINE; -static INLINE void *tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) ALWAYSINLINE; -static void tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize); -static void tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize); -static INLINE region_t *tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; -static INLINE void tiny_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) ALWAYSINLINE; -static void *tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize); -static INLINE boolean_t try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE; -static boolean_t tiny_check_region(szone_t *szone, region_t region); -static kern_return_t tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder); -static void *tiny_malloc_from_free_list(szone_t *szone, msize_t msize); -static INLINE void *tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE; -static INLINE void free_tiny(szone_t *szone, void *ptr, region_t *tiny_region) ALWAYSINLINE; -static void print_tiny_free_list(szone_t *szone); -static void print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_end); -static boolean_t tiny_free_list_check(szone_t *szone, grain_t slot); - -static INLINE void small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize) ALWAYSINLINE; -static INLINE void small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) ALWAYSINLINE; -static INLINE void small_meta_header_set_middle(msize_t *meta_headers, msize_t index) ALWAYSINLINE; -static void small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize); -static void small_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize); -static INLINE region_t *small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; -static INLINE void small_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) ALWAYSINLINE; -static void *small_malloc_from_region_no_lock(szone_t *szone, msize_t msize); -static INLINE boolean_t try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE; -static boolean_t szone_check_small_region(szone_t *szone, region_t region); -static kern_return_t small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder); -static void *small_malloc_from_free_list(szone_t *szone, msize_t msize); -static INLINE void *small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE; -static INLINE void *small_malloc_cleared_no_lock(szone_t *szone, msize_t msize) ALWAYSINLINE; -static INLINE void free_small(szone_t *szone, void *ptr, region_t *small_region) ALWAYSINLINE; -static void print_small_free_list(szone_t *szone); -static void print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_end); -static boolean_t small_free_list_check(szone_t *szone, grain_t grain); - -static region_t * hash_lookup_region_no_lock(region_t *regions, size_t num_entries, region_t r); -static void hash_region_insert_no_lock(region_t *regions, size_t num_entries, region_t r); -static region_t * hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries); -static region_t * hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, size_t *new_size); - -#if DEBUG_MALLOC -static void large_debug_print(szone_t *szone); -#endif -static large_entry_t *large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr); -static void large_entry_insert_no_lock(szone_t *szone, large_entry_t range); -static INLINE void large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) ALWAYSINLINE; -static INLINE large_entry_t *large_entries_alloc_no_lock(szone_t *szone, unsigned num) ALWAYSINLINE; -static void large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate); -static large_entry_t * large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate); -static vm_range_t large_free_no_lock(szone_t *szone, large_entry_t *entry); -static kern_return_t large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder); -static huge_entry_t *huge_entry_for_pointer_no_lock(szone_t *szone, const void *ptr); -static boolean_t huge_entry_append(szone_t *szone, huge_entry_t huge); -static kern_return_t huge_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t huge_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder); -static void *large_and_huge_malloc(szone_t *szone, size_t num_pages); -static INLINE void free_large_or_huge(szone_t *szone, void *ptr) ALWAYSINLINE; -static INLINE int try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE; - -static void szone_free(szone_t *szone, void *ptr); -static INLINE void *szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested) ALWAYSINLINE; -static void *szone_malloc(szone_t *szone, size_t size); -static void *szone_calloc(szone_t *szone, size_t num_items, size_t size); -static void *szone_valloc(szone_t *szone, size_t size); -static size_t szone_size(szone_t *szone, const void *ptr); -static void *szone_realloc(szone_t *szone, void *ptr, size_t new_size); -static unsigned szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count); -static void szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count); -static void szone_destroy(szone_t *szone); -static size_t szone_good_size(szone_t *szone, size_t size); - -static boolean_t szone_check_all(szone_t *szone, const char *function); -static boolean_t szone_check(szone_t *szone); -static kern_return_t szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder); -static void szone_print(szone_t *szone, boolean_t verbose); -static void szone_log(malloc_zone_t *zone, void *log_address); -static void szone_force_lock(szone_t *szone); -static void szone_force_unlock(szone_t *szone); - -static void szone_statistics(szone_t *szone, malloc_statistics_t *stats); - -static void *frozen_malloc(szone_t *zone, size_t new_size); -static void *frozen_calloc(szone_t *zone, size_t num_items, size_t size); -static void *frozen_valloc(szone_t *zone, size_t new_size); -static void *frozen_realloc(szone_t *zone, void *ptr, size_t new_size); -static void frozen_free(szone_t *zone, void *ptr); -static void frozen_destroy(szone_t *zone); - -#if DEBUG_MALLOC -# define LOG(szone,ptr) \ - (szone->log_address && (((uintptr_t)szone->log_address == -1) || (szone->log_address == (void *)(ptr)))) -#else -# define LOG(szone,ptr) 0 -#endif - -#define SZONE_LOCK(szone) \ - do { \ - LOCK(szone->lock); \ - } while (0) - -#define SZONE_UNLOCK(szone) \ - do { \ - UNLOCK(szone->lock); \ - } while (0) - -#define LOCK_AND_NOTE_LOCKED(szone,locked) \ -do { \ - CHECK(szone, __PRETTY_FUNCTION__); \ - locked = 1; SZONE_LOCK(szone); \ -} while (0) - -#if DEBUG_MALLOC || DEBUG_CLIENT -# define CHECK(szone,fun) \ - if ((szone)->debug_flags & CHECK_REGIONS) szone_check_all(szone, fun) -#else -# define CHECK(szone,fun) do {} while (0) -#endif - -/********************* VERY LOW LEVEL UTILITIES ************************/ - -#if DEBUG_MALLOC || DEBUG_CLIENT -static void -szone_sleep(void) -{ - - if (getenv("MallocErrorSleep")) { - _malloc_printf(ASL_LEVEL_NOTICE, "*** sleeping to help debug\n"); - sleep(3600); // to help debug - } -} -#endif - -// msg prints after fmt, ... -static __attribute__((noinline)) void -szone_error(szone_t *szone, const char *msg, const void *ptr, const char *fmt, ...) -{ - va_list ap; - _SIMPLE_STRING b = _simple_salloc(); - - if (szone) SZONE_UNLOCK(szone); - if (b) { - if (fmt) { - va_start(ap, fmt); - _simple_vsprintf(b, fmt, ap); - va_end(ap); - } - if (ptr) { - _simple_sprintf(b, "*** error for object %p: %s\n", ptr, msg); - } else { - _simple_sprintf(b, "*** error: %s\n", msg); - } - malloc_printf("%s*** set a breakpoint in malloc_error_break to debug\n", _simple_string(b)); - _simple_sfree(b); - } else { - /* - * Should only get here if vm_allocate() can't get a single page of - * memory, implying _simple_asl_log() would also fail. So we just - * print to the file descriptor. - */ - if (fmt) { - va_start(ap, fmt); - _malloc_vprintf(MALLOC_PRINTF_NOLOG, fmt, ap); - va_end(ap); - } - if (ptr) { - _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error for object %p: %s\n", ptr, msg); - } else { - _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error: %s\n", msg); - } - _malloc_printf(MALLOC_PRINTF_NOLOG, "*** set a breakpoint in malloc_error_break to debug\n"); - } - malloc_error_break(); -#if DEBUG_MALLOC - szone_print(szone, 1); - szone_sleep(); -#endif -#if DEBUG_CLIENT - szone_sleep(); -#endif - if (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_ERROR) abort(); -} - -static void -protect(void *address, size_t size, unsigned protection, unsigned debug_flags) -{ - kern_return_t err; - - if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_PRELUDE)) { - err = vm_protect(mach_task_self(), (vm_address_t)(uintptr_t)address - vm_page_size, vm_page_size, 0, protection); - if (err) { - malloc_printf("*** can't protect(%p) region for prelude guard page at %p\n", - protection,address - (1 << vm_page_shift)); - } - } - if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE)) { - err = vm_protect(mach_task_self(), (vm_address_t)(uintptr_t)address + size, vm_page_size, 0, protection); - if (err) { - malloc_printf("*** can't protect(%p) region for postlude guard page at %p\n", - protection, address + size); - } - } -} - -static void * -allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label) -{ - // align specifies a desired alignment (as a log) or 0 if no alignment requested - void *vm_addr; - uintptr_t addr, aligned_address; - boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; - size_t allocation_size = round_page(size); - size_t delta; - - if (align) add_guard_pages = 0; // too cumbersome to deal with that - if (!allocation_size) allocation_size = 1 << vm_page_shift; - if (add_guard_pages) allocation_size += 2 * (1 << vm_page_shift); - if (align) allocation_size += (size_t)1 << align; - vm_addr = mmap(0, allocation_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, VM_MAKE_TAG(vm_page_label), 0); - if ((uintptr_t)vm_addr == -1) { - szone_error(szone, "can't allocate region", NULL, "*** mmap(size=%lld) failed (error code=%d)\n", (long long)allocation_size, errno); - return NULL; - } - addr = (uintptr_t)vm_addr; - if (align) { - aligned_address = (addr + ((uintptr_t)1 << align) - 1) & ~ (((uintptr_t)1 << align) - 1); - if (aligned_address != addr) { - delta = aligned_address - addr; - if (munmap((void *)addr, delta) == -1) - malloc_printf("*** freeing unaligned header failed with %d\n", errno); - addr = aligned_address; - allocation_size -= delta; - } - if (allocation_size > size) { - if (munmap((void *)(addr + size), allocation_size - size) == -1) - malloc_printf("*** freeing unaligned footer failed with %d\n", errno); - } - } - if (add_guard_pages) { - addr += (uintptr_t)1 << vm_page_shift; - protect((void *)addr, size, 0, debug_flags); - } - return (void *)addr; -} - -static void -deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags) -{ - int err; - boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; - - if (add_guard_pages) { - addr -= 1 << vm_page_shift; - size += 2 * (1 << vm_page_shift); - } - err = munmap(addr, size); - if ((err == -1) && szone) - szone_error(szone, "Can't deallocate_pages region", addr, NULL); -} - -static kern_return_t -_szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) -{ - *ptr = (void *)address; - return 0; -} - -/********************* FREE LIST UTILITIES ************************/ - -// A free list entry is comprised of a pair of pointers, previous and next. -// Because the free list entries are previously freed objects, there is a -// non-zero chance that a misbehaved program will write to an allocated object -// after it has called free() on the pointer. This write would then potentially -// corrupt the previous and next pointers, leading to a crash. In order to -// detect this case, we take advantage of the fact that pointers are known to -// be at least 16 byte aligned, and thus have at least 4 trailing zero bits. -// When an entry is added to the free list, the previous and next pointers are -// shifted right by 2 bits, and then have the high and low 2 bits set, to act -// as guard bits. Before accessing a free list object, we verify that these -// bits are still set, and log an error if they are not. - -static INLINE void -free_list_checksum(szone_t *szone, free_list_t *ptr, const char *msg) -{ - uintptr_t ptrs = ptr->previous.u & ptr->next.u; - -#ifdef __LP64__ - ptrs = (ptrs << 2) | (ptrs >> (64-2)); -#else - ptrs = (ptrs << 2) | (ptrs >> (32-2)); -#endif - - if ((ptrs & 15) != 15) - szone_error(szone, "incorrect checksum for freed object " - "- object was probably modified after being freed.", ptr, NULL); -} - -static INLINE uintptr_t -free_list_checksum_ptr(void *p) -{ - ptr_union ptr; - ptr.p = p; - -#ifdef __LP64__ - return (ptr.u >> 2) | 0xC000000000000003ULL; -#else - return (ptr.u >> 2) | 0xC0000003U; -#endif -} - -static INLINE void * -free_list_unchecksum_ptr(ptr_union ptr) -{ - uintptr_t u = (ptr.u >> 2) << 4; - return (void *)u; -} - -static INLINE void -free_list_set_checksum(szone_t *szone, free_list_t *ptr) -{ - ptr->previous.u = free_list_checksum_ptr(ptr->previous.p); - ptr->next.u = free_list_checksum_ptr(ptr->next.p); -} - -static unsigned -free_list_count(const free_list_t *ptr) -{ - unsigned count = 0; - - while (ptr) { - count++; - ptr = free_list_unchecksum_ptr(ptr->next); - } - return count; -} - -/* XXX inconsistent use of BITMAP32 and BITARRAY operations could be cleaned up */ - -#define BITMAP32_SET(bitmap,bit) (bitmap |= 1 << (bit)) -#define BITMAP32_CLR(bitmap,bit) (bitmap &= ~ (1 << (bit))) -#define BITMAP32_BIT(bitmap,bit) ((bitmap >> (bit)) & 1) - -/* returns bit # of least-significant one bit, starting at 0 (undefined if !bitmap) */ -#define BITMAP32_CTZ(bitmap) (__builtin_ctz(bitmap)) - -/********************* TINY FREE LIST UTILITIES ************************/ - -// We encode the meta-headers as follows: -// Each quantum has an associated set of 2 bits: -// block_header when 1 says this block is the beginning of a block -// in_use when 1 says this block is in use -// so a block in use of size 3 is 1-1 0-X 0-X -// for a free block TINY_FREE_SIZE(ptr) carries the size and the bits are 1-0 X-X X-X -// for a block middle the bits are 0-0 - -// Attention double evaluation for these -#define BITARRAY_SET(bits,index) (bits[index>>3] |= (1 << (index & 7))) -#define BITARRAY_CLR(bits,index) (bits[index>>3] &= ~(1 << (index & 7))) -#define BITARRAY_BIT(bits,index) (((bits[index>>3]) >> (index & 7)) & 1) - -// Following is for start<8 and end<=start+32 -static void ALWAYSINLINE -bitarray_mclr(void *bits, unsigned start, unsigned end) { - unsigned word = OSReadLittleInt32(bits, 0); - unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1; - - if (end > 31) { - unsigned char *bytes = (unsigned char *)bits; - bytes[4] &= ~((1 << (end - 32)) - 1); - } else { - mask |= (0xFFFFFFFF << end); - } - OSWriteLittleInt32(bits, 0, word & mask); -} - -/* - * Obtain the size of a free tiny block (in msize_t units). - */ -static msize_t -get_tiny_free_size(const void *ptr) -{ - void *next_block = (void *)((uintptr_t)ptr + TINY_QUANTUM); - void *region_end = TINY_REGION_END(TINY_REGION_FOR_PTR(ptr)); - - // check whether the next block is outside the tiny region or a block header - // if so, then the size of this block is one, and there is no stored size. - if (next_block < region_end) - { - unsigned char *next_header = TINY_BLOCK_HEADER_FOR_PTR(next_block); - msize_t next_index = TINY_INDEX_FOR_PTR(next_block); - - if (!BITARRAY_BIT(next_header, next_index)) - return TINY_FREE_SIZE(ptr); - } - return 1; -} - -/* - * Get the size of the previous free block, which is stored in the last two - * bytes of the block. If the previous block is not free, then the result is - * undefined. - */ -static msize_t -get_tiny_previous_free_msize(const void *ptr) -{ - // check whether the previous block is in the tiny region and a block header - // if so, then the size of the previous block is one, and there is no stored - // size. - if (ptr != TINY_REGION_FOR_PTR(ptr)) - { - void *prev_block = (void *)((uintptr_t)ptr - TINY_QUANTUM); - unsigned char *prev_header = TINY_BLOCK_HEADER_FOR_PTR(prev_block); - msize_t prev_index = TINY_INDEX_FOR_PTR(prev_block); - if (BITARRAY_BIT(prev_header, prev_index)) - return 1; - return TINY_PREVIOUS_MSIZE(ptr); - } - // don't read possibly unmapped memory before the beginning of the region - return 0; -} - -static INLINE msize_t -get_tiny_meta_header(const void *ptr, boolean_t *is_free) -{ - // returns msize and is_free - // may return 0 for the msize component (meaning 65536) - unsigned char *block_header; - unsigned char *in_use; - msize_t index; - unsigned byte_index; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - index = TINY_INDEX_FOR_PTR(ptr); - byte_index = index >> 3; - - block_header += byte_index; - index &= 7; - *is_free = 0; - if (!BITMAP32_BIT(*block_header, index)) - return 0; - in_use = TINY_INUSE_FOR_HEADER(block_header); - if (!BITMAP32_BIT(*in_use, index)) { - *is_free = 1; - return get_tiny_free_size(ptr); - } - uint32_t *addr = (uint32_t *)((uintptr_t)block_header & ~3); - uint32_t word0 = OSReadLittleInt32(addr, 0) >> index; - uint32_t word1 = OSReadLittleInt32(addr, 4) << (8 - index); - uint32_t bits = (((uintptr_t)block_header & 3) * 8); // precision loss on LP64 OK here - uint32_t word = (word0 >> bits) | (word1 << (24 - bits)); - uint32_t result = ffs(word >> 1); - return result; -} - -static INLINE void -set_tiny_meta_header_in_use(const void *ptr, msize_t msize) -{ - unsigned char *block_header; - unsigned char *in_use; - msize_t index; - unsigned byte_index; - msize_t clr_msize; - unsigned end_bit; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - index = TINY_INDEX_FOR_PTR(ptr); - byte_index = index >> 3; - -#if DEBUG_MALLOC - if (msize >= 32) - malloc_printf("set_tiny_meta_header_in_use() invariant broken %p %d\n", ptr, msize); - if ((unsigned)index + (unsigned)msize > 0x10000) - malloc_printf("set_tiny_meta_header_in_use() invariant broken (2) %p %d\n", ptr, msize); -#endif - block_header += byte_index; - index &= 7; - BITMAP32_SET(*block_header, index); - in_use = TINY_INUSE_FOR_HEADER(block_header); - BITMAP32_SET(*in_use, index); - index++; - clr_msize = msize-1; - if (clr_msize) { - byte_index = index >> 3; - block_header += byte_index; in_use += byte_index; - index &= 7; - end_bit = index + clr_msize; - bitarray_mclr(block_header, index, end_bit); - bitarray_mclr(in_use, index, end_bit); - } - BITARRAY_SET(block_header, index+clr_msize); // we set the block_header bit for the following block to reaffirm next block is a block -#if DEBUG_MALLOC - { - boolean_t ff; - msize_t mf; - - mf = get_tiny_meta_header(ptr, &ff); - if (msize != mf) { - malloc_printf("setting header for tiny in_use %p : %d\n", ptr, msize); - malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff); - } - } -#endif -} - -static INLINE void -set_tiny_meta_header_middle(const void *ptr) -{ - // indicates this block is in the middle of an in use block - unsigned char *block_header; - unsigned char *in_use; - msize_t index; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); - - BITARRAY_CLR(block_header, index); - BITARRAY_CLR(in_use, index); -} - -static INLINE void -set_tiny_meta_header_free(const void *ptr, msize_t msize) -{ - // !msize is acceptable and means 65536 - unsigned char *block_header; - unsigned char *in_use; - msize_t index; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); - -#if DEBUG_MALLOC - if ((unsigned)index + (unsigned)msize > 0x10000) { - malloc_printf("setting header for tiny free %p msize too large: %d\n", ptr, msize); - } -#endif - BITARRAY_SET(block_header, index); - BITARRAY_CLR(in_use, index); - // mark the end of this block if msize is > 1. For msize == 0, the whole - // region is free, so there is no following block. For msize == 1, there is - // no space to write the size on 64 bit systems. The size for 1 quantum - // blocks is computed from the metadata bitmaps. - if (msize > 1) { - void *follower = FOLLOWING_TINY_PTR(ptr, msize); - TINY_PREVIOUS_MSIZE(follower) = msize; - TINY_FREE_SIZE(ptr) = msize; - } - if (msize == 0) { - TINY_FREE_SIZE(ptr) = msize; - } -#if DEBUG_MALLOC - boolean_t ff; - msize_t mf = get_tiny_meta_header(ptr, &ff); - if ((msize != mf) || !ff) { - malloc_printf("setting header for tiny free %p : %u\n", ptr, msize); - malloc_printf("reading header for tiny %p : %u %u\n", ptr, mf, ff); - } -#endif -} - -static INLINE boolean_t -tiny_meta_header_is_free(const void *ptr) -{ - unsigned char *block_header; - unsigned char *in_use; - msize_t index; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); - if (!BITARRAY_BIT(block_header, index)) - return 0; - return !BITARRAY_BIT(in_use, index); -} - -static INLINE void * -tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) -{ - // returns the previous block, assuming and verifying it's free - unsigned char *block_header; - unsigned char *in_use; - msize_t index; - msize_t previous_msize; - msize_t previous_index; - void *previous_ptr; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); - - if (!index) - return NULL; - if ((previous_msize = get_tiny_previous_free_msize(ptr)) > index) - return NULL; - - previous_index = index - previous_msize; - previous_ptr = (void *)(TINY_REGION_FOR_PTR(ptr) + TINY_BYTES_FOR_MSIZE(previous_index)); - if (!BITARRAY_BIT(block_header, previous_index)) - return NULL; - if (BITARRAY_BIT(in_use, previous_index)) - return NULL; - if (get_tiny_free_size(previous_ptr) != previous_msize) - return NULL; - - // conservative check did match true check - *prev_msize = previous_msize; - return previous_ptr; -} - -/* - * Adds an item to the proper free list, and also marks the meta-header of the - * block properly. - * Assumes szone has been locked - */ -static void -tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) -{ - grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; - free_list_t *free_ptr = ptr; - free_list_t *free_head = szone->tiny_free_list[slot]; - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } - if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { - szone_error(szone, "tiny_free_list_add_ptr: Unaligned ptr", ptr, NULL); - } -#endif - set_tiny_meta_header_free(ptr, msize); - if (free_head) { - free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); -#if DEBUG_MALLOC - if (free_list_unchecksum_ptr(free_head->previous)) { - szone_error(szone, "tiny_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr, - "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, free_head, free_head->previous.p); - } - if (! tiny_meta_header_is_free(free_head)) { - szone_error(szone, "tiny_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, - "ptr=%p slot=%d free_head=%p\n", ptr, slot, free_head); - } -#endif - free_head->previous.u = free_list_checksum_ptr(free_ptr); - } else { - BITMAP32_SET(szone->tiny_bitmap, slot); - } - free_ptr->previous.p = NULL; - free_ptr->next.p = free_head; - free_list_set_checksum(szone, free_ptr); - szone->tiny_free_list[slot] = free_ptr; -} - -/* - * Removes the item pointed to by ptr in the proper free list. - * Assumes szone has been locked - */ -static INLINE void -tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) -{ - grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; - free_list_t *free_ptr = ptr, *next, *previous; - free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__); - - next = free_list_unchecksum_ptr(free_ptr->next); - previous = free_list_unchecksum_ptr(free_ptr->previous); - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } -#endif - if (!previous) { - // The block to remove is the head of the free list -#if DEBUG_MALLOC - if (szone->tiny_free_list[slot] != ptr) { - szone_error(szone, "tiny_free_list_remove_ptr: Internal invariant broken (szone->tiny_free_list[slot])", ptr, - "ptr=%p slot=%d msize=%d szone->tiny_free_list[slot]=%p\n", - ptr, slot, msize, szone->tiny_free_list[slot]); - return; - } -#endif - szone->tiny_free_list[slot] = next; - if (!next) BITMAP32_CLR(szone->tiny_bitmap, slot); - } else { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - previous->next = free_ptr->next; - } - if (next) { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - next->previous = free_ptr->previous; - } -} - -/* - * tiny_region_for_ptr_no_lock - Returns the tiny region containing the pointer, - * or NULL if not found. - */ -static INLINE region_t * -tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) -{ - return hash_lookup_region_no_lock(szone->tiny_regions, - szone->num_tiny_regions_allocated, - TINY_REGION_FOR_PTR(ptr)); -} - -static INLINE void -tiny_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) -{ - size_t original_size = TINY_BYTES_FOR_MSIZE(msize); - void *next_block = ((char *)ptr + original_size); - msize_t previous_msize; - void *previous; - msize_t next_msize; - free_list_t *big_free_block; - free_list_t *after_next_block; - free_list_t *before_next_block; - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } - if (! msize) { - szone_error(szone, "trying to free tiny block that is too small", ptr, - "in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } -#endif - // We try to coalesce this block with the preceeding one - previous = tiny_previous_preceding_free(ptr, &previous_msize); - if (previous) { -#if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone,previous)) { - malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); - } -#endif - // clear the meta_header since this is no longer the start of a block - set_tiny_meta_header_middle(ptr); - tiny_free_list_remove_ptr(szone, previous, previous_msize); - ptr = previous; - msize += previous_msize; - } - // We try to coalesce with the next block - if ((next_block < TINY_REGION_END(*region)) && tiny_meta_header_is_free(next_block)) { - next_msize = get_tiny_free_size(next_block); -#if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone, next_block)) { - malloc_printf("in tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n", - ptr, msize, next_block, next_msize); - } -#endif - // If we are coalescing with the next block, and the next block is in - // the last slot of the free list, then we optimize this case here to - // avoid removing next_block from the slot 31 and then adding ptr back - // to slot 31. - if (next_msize >= NUM_TINY_SLOTS) { - msize += next_msize; - big_free_block = (free_list_t *)next_block; - free_list_checksum(szone, big_free_block, __PRETTY_FUNCTION__); - after_next_block = free_list_unchecksum_ptr(big_free_block->next); - before_next_block = free_list_unchecksum_ptr(big_free_block->previous); - if (!before_next_block) { - szone->tiny_free_list[NUM_TINY_SLOTS-1] = ptr; - } else { - before_next_block->next.u = free_list_checksum_ptr(ptr); - } - if (after_next_block) { - after_next_block->previous.u = free_list_checksum_ptr(ptr); - } - // we don't need to checksum these since they are already checksummed - ((free_list_t *)ptr)->previous = big_free_block->previous; - ((free_list_t *)ptr)->next = big_free_block->next; - - // clear the meta_header to enable coalescing backwards - set_tiny_meta_header_middle(big_free_block); - set_tiny_meta_header_free(ptr, msize); - goto tiny_free_ending; - } - tiny_free_list_remove_ptr(szone, next_block, next_msize); - set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards - msize += next_msize; - } -#if !TINY_CACHE - // The tiny cache already scribbles free blocks as they go through the - // cache, so we do not need to do it here. - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) { - memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize)); - } -#endif - tiny_free_list_add_ptr(szone, ptr, msize); - tiny_free_ending: - // When in proper debug mode we write on the memory to help debug memory smashers - szone->num_tiny_objects--; - szone->num_bytes_in_tiny_objects -= original_size; // we use original_size and not msize to avoid double counting the coalesced blocks -} - -// Allocates from the last region or a freshly allocated region -static void * -tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize) -{ - void *last_block, *ptr, *aligned_address; - unsigned char *last_header; - msize_t last_msize, last_index; - - // Before anything we transform any remaining tiny_bytes_free_at_end into a - // regular free block. We take special care here to update the bitfield - // information, since we are bypassing the normal free codepath. If there - // is more than one quanta worth of memory in tiny_bytes_free_at_end, then - // there will be two block headers: - // 1) header for the free space at end, msize = 1 - // 2) header inserted by set_tiny_meta_header_in_use after block - // We must clear the second one so that when the free block's size is - // queried, we do not think the block is only 1 quantum in size because - // of the second set header bit. - if (szone->tiny_bytes_free_at_end) { - last_block = TINY_REGION_END(szone->last_tiny_region) - szone->tiny_bytes_free_at_end; - last_msize = TINY_MSIZE_FOR_BYTES(szone->tiny_bytes_free_at_end); - last_header = TINY_BLOCK_HEADER_FOR_PTR(last_block); - last_index = TINY_INDEX_FOR_PTR(last_block); - - if (last_index != (NUM_TINY_BLOCKS - 1)) - BITARRAY_CLR(last_header, last_index + 1); - - tiny_free_list_add_ptr(szone, last_block, last_msize); - szone->tiny_bytes_free_at_end = 0; - } - // time to create a new region - aligned_address = allocate_pages(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, 0, VM_MEMORY_MALLOC_TINY); - if (!aligned_address) // out of memory! - return NULL; - // We set the padding after block_header to be all 1 - ((uint32_t *)(aligned_address + TINY_HEADER_START + (NUM_TINY_BLOCKS >> 3)))[0] = ~0; - - // Check to see if the hash ring of tiny regions needs to grow. Try to - // avoid the hash ring becoming too dense. - if (szone->num_tiny_regions_allocated < (2 * szone->num_tiny_regions)) { - region_t *new_regions; - size_t new_size; - new_regions = hash_regions_grow_no_lock(szone, szone->tiny_regions, - szone->num_tiny_regions_allocated, - &new_size); - // Do not deallocate the current tiny_regions allocation since someone may - // be iterating it. Instead, just leak it. - szone->tiny_regions = new_regions; - szone->num_tiny_regions_allocated = new_size; - } - // Insert the new region into the hash ring, and update malloc statistics - hash_region_insert_no_lock(szone->tiny_regions, - szone->num_tiny_regions_allocated, - aligned_address); - szone->last_tiny_region = aligned_address; - - szone->num_tiny_regions++; - ptr = aligned_address; - set_tiny_meta_header_in_use(ptr, msize); - szone->num_tiny_objects++; - szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(msize); - - // We put a header on the last block so that it appears in use (for coalescing, etc...) - set_tiny_meta_header_in_use(ptr + TINY_BYTES_FOR_MSIZE(msize), 1); - szone->tiny_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_region_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } -#endif - return ptr; -} - -static INLINE boolean_t -try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) -{ - // returns 1 on success - msize_t index; - msize_t old_msize; - unsigned next_index; - void *next_block; - boolean_t is_free; - msize_t next_msize, coalesced_msize, leftover_msize; - void *leftover; - - index = TINY_INDEX_FOR_PTR(ptr); - old_msize = TINY_MSIZE_FOR_BYTES(old_size); - next_index = index + old_msize; - - if (next_index >= NUM_TINY_BLOCKS) { - return 0; - } - next_block = (char *)ptr + old_size; - SZONE_LOCK(szone); - is_free = tiny_meta_header_is_free(next_block); - if (!is_free) { - SZONE_UNLOCK(szone); - return 0; // next_block is in use; - } - next_msize = get_tiny_free_size(next_block); - if (old_size + TINY_MSIZE_FOR_BYTES(next_msize) < new_size) { - SZONE_UNLOCK(szone); - return 0; // even with next block, not enough - } - tiny_free_list_remove_ptr(szone, next_block, next_msize); - set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards - coalesced_msize = TINY_MSIZE_FOR_BYTES(new_size - old_size + TINY_QUANTUM - 1); - leftover_msize = next_msize - coalesced_msize; - if (leftover_msize) { - leftover = next_block + TINY_BYTES_FOR_MSIZE(coalesced_msize); - tiny_free_list_add_ptr(szone, leftover, leftover_msize); - } - set_tiny_meta_header_in_use(ptr, old_msize + coalesced_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in try_realloc_tiny_in_place(), ptr=%p, msize=%d\n", ptr, old_msize + coalesced_msize); - } -#endif - szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(coalesced_msize); - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - return 1; -} - -static boolean_t -tiny_check_region(szone_t *szone, region_t region) -{ - uintptr_t start, ptr, region_end; - boolean_t prev_free = 0; - boolean_t is_free; - msize_t msize; - free_list_t *free_head; - void *follower, *previous, *next; - - /* establish region limits */ - start = (uintptr_t)TINY_REGION_ADDRESS(region); - ptr = start; - region_end = (uintptr_t)TINY_REGION_END(region); - - /* - * The last region may have a trailing chunk which has not been converted into inuse/freelist - * blocks yet. - */ - if (region == szone->last_tiny_region) - region_end -= szone->tiny_bytes_free_at_end; - - - /* - * Scan blocks within the region. - */ - while (ptr < region_end) { - /* - * If the first block is free, and its size is 65536 (msize = 0) then the entire region is - * free. - */ - msize = get_tiny_meta_header((void *)ptr, &is_free); - if (is_free && !msize && (ptr == start)) { - return 1; - } - - /* - * If the block's size is 65536 (msize = 0) then since we're not the first entry the size is - * corrupt. - */ - if (!msize) { - malloc_printf("*** invariant broken for tiny block %p this msize=%d - size is too small\n", - ptr, msize); - return 0; - } - - if (!is_free) { - /* - * In use blocks cannot be more than 31 quanta large. - */ - prev_free = 0; - if (msize > 31 * TINY_QUANTUM) { - malloc_printf("*** invariant broken for %p this tiny msize=%d[%p] - size is too large\n", - ptr, msize, msize); - return 0; - } - /* move to next block */ - ptr += TINY_BYTES_FOR_MSIZE(msize); - } else { - /* - * Free blocks must have been coalesced, we cannot have a free block following another - * free block. - */ - if (prev_free) { - malloc_printf("*** invariant broken for free block %p this tiny msize=%d: two free blocks in a row\n", - ptr, msize); - return 0; - } - prev_free = 1; - /* - * Check the integrity of this block's entry in its freelist. - */ - free_head = (free_list_t *)ptr; - free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); - previous = free_list_unchecksum_ptr(free_head->previous); - next = free_list_unchecksum_ptr(free_head->next); - if (previous && !tiny_meta_header_is_free(previous)) { - malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", - ptr, previous); - return 0; - } - if (next && !tiny_meta_header_is_free(next)) { - malloc_printf("*** invariant broken for %p (next in free list %p is not a free pointer)\n", - ptr, next); - return 0; - } - /* - * Check the free block's trailing size value. - */ - follower = FOLLOWING_TINY_PTR(ptr, msize); - if (((uintptr_t)follower != region_end) && (get_tiny_previous_free_msize(follower) != msize)) { - malloc_printf("*** invariant broken for tiny free %p followed by %p in region [%p-%p] " - "(end marker incorrect) should be %d; in fact %d\n", - ptr, follower, TINY_REGION_ADDRESS(region), region_end, msize, get_tiny_previous_free_msize(follower)); - return 0; - } - /* move to next block */ - ptr = (uintptr_t)follower; - } - } - /* - * Ensure that we scanned the entire region - */ - if (ptr != region_end) { - malloc_printf("*** invariant broken for region end %p - %p\n", ptr, region_end); - return 0; - } - /* - * Check the trailing block's integrity. - */ - if (region == szone->last_tiny_region) { - if (szone->tiny_bytes_free_at_end) { - msize = get_tiny_meta_header((void *)ptr, &is_free); - if (is_free || (msize != 1)) { - malloc_printf("*** invariant broken for blocker block %p - %d %d\n", ptr, msize, is_free); - } - } - } - return 1; -} - -static kern_return_t -tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder) -{ - size_t num_regions = szone->num_tiny_regions_allocated; - void *last_tiny_free = szone->last_tiny_free; - size_t index; - region_t *regions; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - kern_return_t err; - region_t region; - vm_range_t range; - vm_range_t admin_range; - vm_range_t ptr_range; - unsigned char *mapped_region; - unsigned char *block_header; - unsigned char *in_use; - unsigned block_index; - unsigned block_limit; - boolean_t is_free; - msize_t msize; - void *mapped_ptr; - unsigned bit; - vm_address_t last_tiny_free_ptr = 0; - msize_t last_tiny_free_msize = 0; - - if (last_tiny_free) { - last_tiny_free_ptr = (uintptr_t) last_tiny_free & ~(TINY_QUANTUM - 1); - last_tiny_free_msize = (uintptr_t) last_tiny_free & (TINY_QUANTUM - 1); - } - - err = reader(task, (vm_address_t)szone->tiny_regions, sizeof(region_t) * num_regions, (void **)®ions); - if (err) return err; - for (index = 0; index < num_regions; ++index) { - region = regions[index]; - if (region) { - range.address = (vm_address_t)TINY_REGION_ADDRESS(region); - range.size = (vm_size_t)TINY_REGION_SIZE; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - admin_range.address = range.address + TINY_HEADER_START; - admin_range.size = TINY_HEADER_SIZE; - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); - } - if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { - ptr_range.address = range.address; - ptr_range.size = NUM_TINY_BLOCKS * TINY_QUANTUM; - recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); - } - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - err = reader(task, range.address, range.size, (void **)&mapped_region); - if (err) - return err; - - block_header = (unsigned char *)(mapped_region + TINY_HEADER_START); - in_use = TINY_INUSE_FOR_HEADER(block_header); - block_index = 0; - block_limit = NUM_TINY_BLOCKS; - if (region == szone->last_tiny_region) - block_limit -= TINY_MSIZE_FOR_BYTES(szone->tiny_bytes_free_at_end); - - while (block_index < block_limit) { - vm_size_t block_offset = TINY_BYTES_FOR_MSIZE(block_index); - is_free = !BITARRAY_BIT(in_use, block_index); - if (is_free) { - mapped_ptr = mapped_region + block_offset; - - // mapped_region, the address at which 'range' in 'task' has been - // mapped into our process, is not necessarily aligned to - // TINY_BLOCKS_ALIGN. - // - // Since the code in get_tiny_free_size() assumes the pointer came - // from a properly aligned tiny region, and mapped_region is not - // necessarily aligned, then do the size calculation directly. - // If the next bit is set in the header bitmap, then the size is one - // quantum. Otherwise, read the size field. - if (!BITARRAY_BIT(block_header, block_index+1)) - msize = TINY_FREE_SIZE(mapped_ptr); - else - msize = 1; - - if (!msize) - break; - } else if (range.address + block_offset != last_tiny_free_ptr) { - msize = 1; - bit = block_index + 1; - while (! BITARRAY_BIT(block_header, bit)) { - bit++; - msize ++; - } - buffer[count].address = range.address + block_offset; - buffer[count].size = TINY_BYTES_FOR_MSIZE(msize); - count++; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } else { - // Block is not free but it matches last_tiny_free_ptr so even - // though it is not marked free in the bitmap, we treat it as if - // it is and move on - msize = last_tiny_free_msize; - } - block_index += msize; - } - } - } - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - } - return 0; -} - -static void * -tiny_malloc_from_free_list(szone_t *szone, msize_t msize) -{ - // Assumes we've locked the region - free_list_t *ptr; - msize_t this_msize; - grain_t slot = msize - 1; - free_list_t **free_list = szone->tiny_free_list; - free_list_t **the_slot = free_list + slot; - free_list_t *next; - free_list_t **limit; - unsigned bitmap; - msize_t leftover_msize; - free_list_t *leftover_ptr; - - // Assumes locked - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - - // Look for an exact match by checking the freelist for this msize. - // - ptr = *the_slot; - if (ptr) { - next = free_list_unchecksum_ptr(ptr->next); - if (next) { - next->previous = ptr->previous; - } else { - BITMAP32_CLR(szone->tiny_bitmap, slot); - } - *the_slot = next; - this_msize = msize; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize); - } -#endif - goto return_tiny_alloc; - } - - // Mask off the bits representing slots holding free blocks smaller than the - // size we need. If there are no larger free blocks, try allocating from - // the free space at the end of the tiny region. - bitmap = szone->tiny_bitmap & ~ ((1 << slot) - 1); - if (!bitmap) - goto try_tiny_malloc_from_end; - - slot = BITMAP32_CTZ(bitmap); - limit = free_list + NUM_TINY_SLOTS - 1; - free_list += slot; - - // Iterate over freelists looking for free blocks, starting at first list - // which is not empty, and contains blocks which are large enough to satisfy - // our request. - while (free_list < limit) { - ptr = *free_list; - if (ptr) { - next = free_list_unchecksum_ptr(ptr->next); - *free_list = next; - this_msize = get_tiny_free_size(ptr); - if (next) { - next->previous = ptr->previous; - } else { - BITMAP32_CLR(szone->tiny_bitmap, this_msize - 1); - } - goto add_leftover_and_proceed; - } - free_list++; - } - - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than 31 * tiny quantum size. - // If the last freelist is not empty, and the head contains a block that is - // larger than our request, then the remainder is put back on the free list. - ptr = *limit; - if (ptr) { - free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); - this_msize = get_tiny_free_size(ptr); - next = free_list_unchecksum_ptr(ptr->next); - if (this_msize - msize >= NUM_TINY_SLOTS) { - // the leftover will go back to the free list, so we optimize by - // modifying the free list rather than a pop and push of the head - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); - *limit = leftover_ptr; - if (next) { - next->previous.u = free_list_checksum_ptr(leftover_ptr); - } - leftover_ptr->previous = ptr->previous; - leftover_ptr->next = ptr->next; - set_tiny_meta_header_free(leftover_ptr, leftover_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize); - } -#endif - this_msize = msize; - goto return_tiny_alloc; - } - if (next) { - next->previous = ptr->previous; - } - *limit = next; - goto add_leftover_and_proceed; - } - -try_tiny_malloc_from_end: - // Let's see if we can use szone->tiny_bytes_free_at_end - if (szone->tiny_bytes_free_at_end >= TINY_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)(TINY_REGION_END(szone->last_tiny_region) - szone->tiny_bytes_free_at_end); - szone->tiny_bytes_free_at_end -= TINY_BYTES_FOR_MSIZE(msize); - if (szone->tiny_bytes_free_at_end) { - // let's add an in use block after ptr to serve as boundary - set_tiny_meta_header_in_use((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize), 1); - } - this_msize = msize; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize); - } -#endif - goto return_tiny_alloc; - } - return NULL; - -add_leftover_and_proceed: - if (!this_msize || (this_msize > msize)) { - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); - } -#endif - tiny_free_list_add_ptr(szone, leftover_ptr, leftover_msize); - this_msize = msize; - } - -return_tiny_alloc: - szone->num_tiny_objects++; - szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(this_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); - } -#endif - set_tiny_meta_header_in_use(ptr, this_msize); - return ptr; -} - -static INLINE void * -tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) -{ - boolean_t locked = 0; - void *ptr; - -#if DEBUG_MALLOC - if (!msize) { - szone_error(szone, "invariant broken (!msize) in allocation (region)", NULL, NULL); - return(NULL); - } -#endif -#if TINY_CACHE - ptr = szone->last_tiny_free; - if ((((uintptr_t)ptr) & (TINY_QUANTUM - 1)) == msize) { - // we have a candidate - let's lock to make sure - LOCK_AND_NOTE_LOCKED(szone, locked); - if (ptr == szone->last_tiny_free) { - szone->last_tiny_free = NULL; - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - ptr = (void *)((uintptr_t)ptr & ~ (TINY_QUANTUM - 1)); - if (cleared_requested) { - memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); - } -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_should_clear(), tiny cache ptr=%p, msize=%d\n", ptr, msize); - } -#endif - return ptr; - } - } -#endif - // Except in rare occasions where we need to add a new region, we are going to end up locking, so we might as well lock right away to avoid doing unnecessary optimistic probes - if (!locked) LOCK_AND_NOTE_LOCKED(szone, locked); - ptr = tiny_malloc_from_free_list(szone, msize); - if (ptr) { - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - ptr = tiny_malloc_from_region_no_lock(szone, msize); - // we don't clear because this freshly allocated space is pristine - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - return ptr; -} - -static INLINE void -free_tiny(szone_t *szone, void *ptr, region_t *tiny_region) -{ - msize_t msize; - boolean_t is_free; -#if TINY_CACHE - void *ptr2; -#endif - - // ptr is known to be in tiny_region - SZONE_LOCK(szone); -#if TINY_CACHE - ptr2 = szone->last_tiny_free; - /* check that we don't already have this pointer in the cache */ - if (ptr == (void *)((uintptr_t)ptr2 & ~ (TINY_QUANTUM - 1))) { - szone_error(szone, "double free", ptr, NULL); - return; - } -#endif /* TINY_CACHE */ - msize = get_tiny_meta_header(ptr, &is_free); - if (is_free) { - szone_error(szone, "double free", ptr, NULL); - return; - } -#if DEBUG_MALLOC - if (!msize) { - malloc_printf("*** szone_free() block in use is too large: %p\n", ptr); - return; - } -#endif -#if TINY_CACHE - if (msize < TINY_QUANTUM) { // to see if the bits fit in the last 4 bits - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) - memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize)); - szone->last_tiny_free = (void *)(((uintptr_t)ptr) | msize); - if (!ptr2) { - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - return; - } - msize = (uintptr_t)ptr2 & (TINY_QUANTUM - 1); - ptr = (void *)(((uintptr_t)ptr2) & ~(TINY_QUANTUM - 1)); - tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); - if (!tiny_region) { - szone_error(szone, "double free (tiny cache)", ptr, NULL); - } - } -#endif - tiny_free_no_lock(szone, tiny_region, ptr, msize); - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); -} - -static void -print_tiny_free_list(szone_t *szone) -{ - grain_t slot = 0; - free_list_t *ptr; - _SIMPLE_STRING b = _simple_salloc(); - - if (b) { - _simple_sappend(b, "tiny free sizes: "); - while (slot < NUM_TINY_SLOTS) { - ptr = szone->tiny_free_list[slot]; - if (ptr) { - _simple_sprintf(b, "%s%y[%d]; ", (slot == NUM_TINY_SLOTS-1) ? ">=" : "", (slot+1)*TINY_QUANTUM, free_list_count(ptr)); - } - slot++; - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static void -print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_end) -{ - unsigned counts[1024]; - unsigned in_use = 0; - uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(region); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)TINY_REGION_END(region) - bytes_at_end; - boolean_t is_free; - msize_t msize; - unsigned ci; - _SIMPLE_STRING b; - - memset(counts, 0, 1024 * sizeof(unsigned)); - while (current < limit) { - msize = get_tiny_meta_header((void *)current, &is_free); - if (is_free & !msize && (current == start)) { - // first block is all free - break; - } - if (!msize) { - malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize); - break; - } - if (!is_free) { - // block in use - if (msize > 32) - malloc_printf("*** error at %p msize for in_use is %d\n", (void *)current, msize); - if (msize < 1024) - counts[msize]++; - in_use++; - } - current += TINY_BYTES_FOR_MSIZE(msize); - } - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Tiny region [%p-%p, %y]\t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE); - _simple_sprintf(b, "In_use=%d ", in_use); - if (bytes_at_end) _simple_sprintf(b, "untouched=%ly", bytes_at_end); - if (verbose && in_use) { - _simple_sappend(b, "\n\tSizes in use: "); - for (ci = 0; ci < 1024; ci++) - if (counts[ci]) - _simple_sprintf(b, "%d[%d]", TINY_BYTES_FOR_MSIZE(ci), counts[ci]); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static boolean_t -tiny_free_list_check(szone_t *szone, grain_t slot) -{ - unsigned count = 0; - free_list_t *ptr = szone->tiny_free_list[slot]; - free_list_t *previous = NULL; - boolean_t is_free; - - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - while (ptr) { - free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); - is_free = tiny_meta_header_is_free(ptr); - if (! is_free) { - malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - return 0; - } - if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { - malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - return 0; - } - if (!tiny_region_for_ptr_no_lock(szone, ptr)) { - malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr); - return 0; - } - if (free_list_unchecksum_ptr(ptr->previous) != previous) { - malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr); - return 0; - } - previous = ptr; - ptr = free_list_unchecksum_ptr(ptr->next); - count++; - } - return 1; -} - -/********************* SMALL FREE LIST UTILITIES ************************/ - -/* - * Mark a block as free. Only the first quantum of a block is marked thusly, - * the remainder are marked "middle". - */ -static INLINE void -small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize) -{ - meta_headers[index] = msize | SMALL_IS_FREE; -} - -/* - * Mark a block as in use. Only the first quantum of a block is marked thusly, - * the remainder are marked "middle". - */ -static INLINE void -small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) -{ - meta_headers[index] = msize; -} - -/* - * Mark a quantum as being the second or later in a block. - */ -static INLINE void -small_meta_header_set_middle(msize_t *meta_headers, msize_t index) -{ - meta_headers[index] = 0; -} - -// Adds an item to the proper free list -// Also marks the header of the block properly -// Assumes szone has been locked -static void -small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) -{ - grain_t slot = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1; - free_list_t *free_ptr = ptr; - free_list_t *free_head = szone->small_free_list[slot]; - void *follower; - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } - if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { - szone_error(szone, "small_free_list_add_ptr: Unaligned ptr", ptr, NULL); - } -#endif - if (free_head) { - free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); -#if DEBUG_MALLOC - if (free_list_unchecksum_ptr(free_head->previous)) { - szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr, - "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, free_head, free_head->previous.p); - } - if (!SMALL_PTR_IS_FREE(free_head)) { - szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, - "ptr=%p slot=%d free_head=%p\n", ptr, slot, free_head); - } -#endif - free_head->previous.u = free_list_checksum_ptr(free_ptr); - } else { - BITMAP32_SET(szone->small_bitmap, slot); - } - free_ptr->previous.p = NULL; - free_ptr->next.p = free_head; - free_list_set_checksum(szone, free_ptr); - szone->small_free_list[slot] = free_ptr; - follower = ptr + SMALL_BYTES_FOR_MSIZE(msize); - SMALL_PREVIOUS_MSIZE(follower) = msize; -} - -// Removes item in the proper free list -// msize could be read, but all callers have it so we pass it in -// Assumes szone has been locked -static void -small_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) -{ - grain_t slot = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1; - free_list_t *free_ptr = ptr, *next, *previous; - free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__); - - next = free_list_unchecksum_ptr(free_ptr->next); - previous = free_list_unchecksum_ptr(free_ptr->previous); - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } -#endif - if (!previous) { - // The block to remove is the head of the free list -#if DEBUG_MALLOC - if (szone->small_free_list[slot] != ptr) { - szone_error(szone, "small_free_list_remove_ptr: Internal invariant broken (szone->small_free_list[grain])", ptr, - "ptr=%p slot=%d msize=%d szone->small_free_list[slot]=%p\n", - ptr, slot, msize, szone->small_free_list[slot]); - return; - } -#endif - szone->small_free_list[slot] = next; - if (!next) BITMAP32_CLR(szone->small_bitmap, slot); - } else { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - previous->next = free_ptr->next; - } - if (next) { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - next->previous = free_ptr->previous; - } -} - -static INLINE region_t * -small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) -{ - return hash_lookup_region_no_lock(szone->small_regions, - szone->num_small_regions_allocated, - SMALL_REGION_FOR_PTR(ptr)); -} - -static INLINE void -small_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) -{ - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned index = SMALL_META_INDEX_FOR_PTR(ptr); - size_t original_size = SMALL_BYTES_FOR_MSIZE(msize); - unsigned char *next_block = ((unsigned char *)ptr + original_size); - msize_t next_index = index + msize; - msize_t previous_msize, next_msize; - void *previous; - - // Assumes locked - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } - if (! msize) { - szone_error(szone, "trying to free small block that is too small", ptr, - "in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } -#endif - // We try to coalesce this block with the preceeding one - if (index && (SMALL_PREVIOUS_MSIZE(ptr) <= index)) { - previous_msize = SMALL_PREVIOUS_MSIZE(ptr); - if (meta_headers[index - previous_msize] == (previous_msize | SMALL_IS_FREE)) { - previous = ptr - SMALL_BYTES_FOR_MSIZE(previous_msize); - // previous is really to be coalesced -#if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone,previous)) { - malloc_printf("in small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); - } -#endif - small_free_list_remove_ptr(szone, previous, previous_msize); - small_meta_header_set_middle(meta_headers, index); - ptr = previous; - msize += previous_msize; - index -= previous_msize; - } - } - // We try to coalesce with the next block - if ((next_block < SMALL_REGION_END(*region)) && (meta_headers[next_index] & SMALL_IS_FREE)) { - // next block is free, we coalesce - next_msize = meta_headers[next_index] & ~ SMALL_IS_FREE; -#if DEBUG_MALLOC - if (LOG(szone,ptr)) malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n", ptr, msize, next_block, next_msize); -#endif - small_free_list_remove_ptr(szone, next_block, next_msize); - small_meta_header_set_middle(meta_headers, next_index); - msize += next_msize; - } - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) { - if (!msize) { - szone_error(szone, "incorrect size information - block header was damaged", ptr, NULL); - } else { - memset(ptr, 0x55, SMALL_BYTES_FOR_MSIZE(msize)); - } - } - small_free_list_add_ptr(szone, ptr, msize); - small_meta_header_set_is_free(meta_headers, index, msize); - szone->num_small_objects--; - szone->num_bytes_in_small_objects -= original_size; // we use original_size and not msize to avoid double counting the coalesced blocks -} - -static void * -small_malloc_from_region_no_lock(szone_t *szone, msize_t msize) -{ - void *last_block; - void *ptr; - void *new_address; - msize_t *meta_headers; - msize_t index ; - msize_t msize_left; - - // Allocates from the last region or a freshly allocated region - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - // Before anything we transform the small_bytes_free_at_end - if any - to a regular free block - if (szone->small_bytes_free_at_end) { - last_block = (void *)(SMALL_REGION_END(szone->last_small_region) - szone->small_bytes_free_at_end); - small_free_list_add_ptr(szone, last_block, SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end)); - *SMALL_METADATA_FOR_PTR(last_block) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end) | SMALL_IS_FREE; - szone->small_bytes_free_at_end = 0; - } - // time to create a new region - new_address = allocate_pages(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, - 0, VM_MEMORY_MALLOC_SMALL); - if (!new_address) - return NULL; - - ptr = new_address; - meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - index = 0; - - // Check to see if the hash ring of small regions needs to grow. Try to - // avoid the hash ring becoming too dense. - if (szone->num_small_regions_allocated < (2 * szone->num_small_regions)) { - region_t *new_regions; - size_t new_size; - new_regions = hash_regions_grow_no_lock(szone, szone->small_regions, - szone->num_small_regions_allocated, - &new_size); - // Do not deallocate the current small_regions allocation since someone - // may be iterating it. Instead, just leak it. - szone->small_regions = new_regions; - szone->num_small_regions_allocated = new_size; - } - // Insert the new region into the hash ring, and update malloc statistics - hash_region_insert_no_lock(szone->small_regions, - szone->num_small_regions_allocated, - new_address); - szone->last_small_region = new_address; - - // we bump the number of regions AFTER we have changes the regions pointer - // to enable finding a small region without taking the lock - // - // FIXME: naive assumption assumes memory ordering coherence between this - // and other CPUs. This also applies to the near-identical code in - // tiny_malloc_from_region_no_lock. - szone->num_small_regions++; - small_meta_header_set_in_use(meta_headers, index, msize); - msize_left = NUM_SMALL_BLOCKS - index; - szone->num_small_objects++; - szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(msize); - // add a big free block - index += msize; msize_left -= msize; - meta_headers[index] = msize_left; - szone->small_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(msize_left); - return ptr; -} - -static INLINE boolean_t -try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) -{ - // returns 1 on success - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned index = SMALL_META_INDEX_FOR_PTR(ptr); - msize_t old_msize = SMALL_MSIZE_FOR_BYTES(old_size); - msize_t new_msize = SMALL_MSIZE_FOR_BYTES(new_size + SMALL_QUANTUM - 1); - void *next_block = (char *)ptr + old_size; - unsigned next_index = index + old_msize; - msize_t next_msize_and_free; - msize_t next_msize; - msize_t leftover_msize; - void *leftover; - unsigned leftover_index; - - if (next_index >= NUM_SMALL_BLOCKS) { - return 0; - } -#if DEBUG_MALLOC - if ((uintptr_t)next_block & (SMALL_QUANTUM - 1)) { - szone_error(szone, "internal invariant broken in realloc(next_block)", next_block, NULL); - } - if (meta_headers[index] != old_msize) - malloc_printf("*** try_realloc_small_in_place incorrect old %d %d\n", - meta_headers[index], old_msize); -#endif - SZONE_LOCK(szone); - /* - * Look for a free block immediately afterwards. If it's large enough, we can consume (part of) - * it. - */ - next_msize_and_free = meta_headers[next_index]; - next_msize = next_msize_and_free & ~ SMALL_IS_FREE; - if (!(next_msize_and_free & SMALL_IS_FREE) || (old_msize + next_msize < new_msize)) { - SZONE_UNLOCK(szone); - return 0; - } - /* - * The following block is big enough; pull it from its freelist and chop off enough to satisfy - * our needs. - */ - small_free_list_remove_ptr(szone, next_block, next_msize); - small_meta_header_set_middle(meta_headers, next_index); - leftover_msize = old_msize + next_msize - new_msize; - if (leftover_msize) { - /* there's some left, so put the remainder back */ - leftover = (unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(new_msize); - small_free_list_add_ptr(szone, leftover, leftover_msize); - leftover_index = index + new_msize; - small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize); - } -#if DEBUG_MALLOC - if (SMALL_BYTES_FOR_MSIZE(new_msize) >= LARGE_THRESHOLD) { - malloc_printf("*** realloc in place for %p exceeded msize=%d\n", new_msize); - } -#endif - small_meta_header_set_in_use(meta_headers, index, new_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in szone_realloc(), ptr=%p, msize=%d\n", ptr, *SMALL_METADATA_FOR_PTR(ptr)); - } -#endif - szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(new_msize - old_msize); - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - return 1; -} - -static boolean_t -szone_check_small_region(szone_t *szone, region_t region) -{ - unsigned char *ptr = SMALL_REGION_ADDRESS(region); - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned char *region_end = SMALL_REGION_END(region); - msize_t prev_free = 0; - unsigned index; - msize_t msize_and_free; - msize_t msize; - free_list_t *free_head; - void *previous, *next; - msize_t *follower; - - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - if (region == szone->last_small_region) region_end -= szone->small_bytes_free_at_end; - while (ptr < region_end) { - index = SMALL_META_INDEX_FOR_PTR(ptr); - msize_and_free = meta_headers[index]; - if (!(msize_and_free & SMALL_IS_FREE)) { - // block is in use - msize = msize_and_free; - if (!msize) { - malloc_printf("*** invariant broken: null msize ptr=%p num_small_regions=%d end=%p\n", - ptr, szone->num_small_regions, region_end); - return 0; - } - if (msize > (LARGE_THRESHOLD / SMALL_QUANTUM)) { - malloc_printf("*** invariant broken for %p this small msize=%d - size is too large\n", - ptr, msize_and_free); - return 0; - } - ptr += SMALL_BYTES_FOR_MSIZE(msize); - prev_free = 0; - } else { - // free pointer - msize = msize_and_free & ~ SMALL_IS_FREE; - free_head = (free_list_t *)ptr; - follower = (msize_t *)FOLLOWING_SMALL_PTR(ptr, msize); - if (!msize) { - malloc_printf("*** invariant broken for free block %p this msize=%d\n", ptr, msize); - return 0; - } - if (prev_free) { - malloc_printf("*** invariant broken for %p (2 free in a row)\n", ptr); - return 0; - } - free_list_checksum(szone, free_head, __PRETTY_FUNCTION__); - previous = free_list_unchecksum_ptr(free_head->previous); - next = free_list_unchecksum_ptr(free_head->next); - if (previous && !SMALL_PTR_IS_FREE(previous)) { - malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", - ptr, free_head->previous); - return 0; - } - if (next && !SMALL_PTR_IS_FREE(next)) { - malloc_printf("*** invariant broken for %p (next is not a free pointer)\n", ptr); - return 0; - } - if (SMALL_PREVIOUS_MSIZE(follower) != msize) { - malloc_printf("*** invariant broken for small free %p followed by %p in region [%p-%p] " - "(end marker incorrect) should be %d; in fact %d\n", - ptr, follower, SMALL_REGION_ADDRESS(region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower)); - return 0; - } - ptr = (unsigned char *)follower; - prev_free = SMALL_IS_FREE; - } - } - return 1; -} - -static kern_return_t -small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder) -{ - size_t num_regions = szone->num_small_regions_allocated; - void *last_small_free = szone->last_small_free; - size_t index; - region_t *regions; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - kern_return_t err; - region_t region; - vm_range_t range; - vm_range_t admin_range; - vm_range_t ptr_range; - unsigned char *mapped_region; - msize_t *block_header; - unsigned block_index; - unsigned block_limit; - msize_t msize_and_free; - msize_t msize; - vm_address_t last_small_free_ptr = 0; - msize_t last_small_free_msize = 0; - - if (last_small_free) { - last_small_free_ptr = (uintptr_t)last_small_free & ~(SMALL_QUANTUM - 1); - last_small_free_msize = (uintptr_t)last_small_free & (SMALL_QUANTUM - 1); - } - - err = reader(task, (vm_address_t)szone->small_regions, sizeof(region_t) * num_regions, (void **)®ions); - if (err) return err; - for (index = 0; index < num_regions; ++index) { - region = regions[index]; - if (region) { - range.address = (vm_address_t)SMALL_REGION_ADDRESS(region); - range.size = SMALL_REGION_SIZE; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - admin_range.address = range.address + SMALL_HEADER_START; - admin_range.size = SMALL_ARRAY_SIZE; - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); - } - if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { - ptr_range.address = range.address; - ptr_range.size = NUM_SMALL_BLOCKS * SMALL_QUANTUM; - recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); - } - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - err = reader(task, range.address, range.size, (void **)&mapped_region); - if (err) return err; - block_header = (msize_t *)(mapped_region + SMALL_HEADER_START); - block_index = 0; - block_limit = NUM_SMALL_BLOCKS; - if (region == szone->last_small_region) - block_limit -= SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end); - while (block_index < block_limit) { - msize_and_free = block_header[block_index]; - msize = msize_and_free & ~ SMALL_IS_FREE; - if (! (msize_and_free & SMALL_IS_FREE) && - range.address + SMALL_BYTES_FOR_MSIZE(block_index) != last_small_free_ptr) { - // Block in use - buffer[count].address = range.address + SMALL_BYTES_FOR_MSIZE(block_index); - buffer[count].size = SMALL_BYTES_FOR_MSIZE(msize); - count++; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } - block_index += msize; - } - } - } - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - } - return 0; -} - -static void * -small_malloc_from_free_list(szone_t *szone, msize_t msize) -{ - free_list_t *ptr; - msize_t this_msize; - grain_t slot = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1; - free_list_t **free_list = szone->small_free_list; - free_list_t *next; - free_list_t **limit; - unsigned bitmap = szone->small_bitmap & ~ ((1 << slot) - 1); - msize_t leftover_msize; - free_list_t *leftover_ptr; - msize_t *meta_headers; - unsigned leftover_index; - - // Assumes locked - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - - // Mask off the bits representing slots holding free blocks smaller than the - // size we need. If there are no larger free blocks, try allocating from - // the free space at the end of the tiny region. - if (!bitmap) - goto try_small_from_end; - - slot = BITMAP32_CTZ(bitmap); - limit = free_list + NUM_SMALL_SLOTS - 1; - free_list += slot; - - // Iterate over freelists looking for free blocks, starting at first list - // which is not empty, and contains blocks which are large enough to satisfy - // our request. - while (free_list < limit) { - ptr = *free_list; - if (ptr) { - next = free_list_unchecksum_ptr(ptr->next); - *free_list = next; - this_msize = SMALL_PTR_SIZE(ptr); - if (next) { - next->previous = ptr->previous; - } else { - BITMAP32_CLR(szone->small_bitmap, this_msize - 1); - } - goto add_leftover_and_proceed; - } - free_list++; - } - - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than 31 * small quantum size. - // If the last freelist is not empty, and the head contains a block that is - // larger than our request, then the remainder is put back on the free list. - // - // FIXME: This code doesn't have the optimization from the 'tiny' codepath - // that optimizes for the this_msize >= 2 * num slots - // FIXME: this code also seems somewhat bogus. There's a check for - // this_msize >= msize, but by definition we can't ask for a small - // block larger than 31 small quanta, and every free block in this - // slot has to be at least that large. - ptr = *limit; - while (ptr) { - free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); - next = free_list_unchecksum_ptr(ptr->next); - this_msize = SMALL_PTR_SIZE(ptr); - if (this_msize >= msize) { - small_free_list_remove_ptr(szone, ptr, this_msize); - goto add_leftover_and_proceed; - } - ptr = next; - } - -try_small_from_end: - // Let's see if we can use szone->small_bytes_free_at_end - if (szone->small_bytes_free_at_end >= SMALL_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)(SMALL_REGION_END(szone->last_small_region) - szone->small_bytes_free_at_end); - szone->small_bytes_free_at_end -= SMALL_BYTES_FOR_MSIZE(msize); - if (szone->small_bytes_free_at_end) { - // let's mark this block as in use to serve as boundary - *SMALL_METADATA_FOR_PTR((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end); - } - this_msize = msize; - goto return_small_alloc; - } - return NULL; - -add_leftover_and_proceed: - if (this_msize > msize) { - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); - } -#endif - small_free_list_add_ptr(szone, leftover_ptr, leftover_msize); - meta_headers = SMALL_META_HEADER_FOR_PTR(leftover_ptr); - leftover_index = SMALL_META_INDEX_FOR_PTR(leftover_ptr); - small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize); - this_msize = msize; - } - -return_small_alloc: - szone->num_small_objects++; - szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(this_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); - } -#endif - *SMALL_METADATA_FOR_PTR(ptr) = this_msize; - return ptr; -} - -static INLINE void * -small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) -{ - boolean_t locked = 0; -#if SMALL_CACHE - void *ptr; -#endif - -#if SMALL_CACHE - ptr = (void *)szone->last_small_free; - if ((((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) == msize) { - // we have a candidate - let's lock to make sure - LOCK_AND_NOTE_LOCKED(szone, locked); - if (ptr == (void *)szone->last_small_free) { - szone->last_small_free = NULL; - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - ptr = (void *)((uintptr_t)ptr & ~ (SMALL_QUANTUM - 1)); - if (cleared_requested) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - } -#endif - // Except in rare occasions where we need to add a new region, we are going to end up locking, - // so we might as well lock right away to avoid doing unnecessary optimistic probes - if (!locked) LOCK_AND_NOTE_LOCKED(szone, locked); - ptr = small_malloc_from_free_list(szone, msize); - if (ptr) { - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - ptr = small_malloc_from_region_no_lock(szone, msize); - // we don't clear because this freshly allocated space is pristine - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - return ptr; -} - -// tries to allocate a small, cleared block -static INLINE void * -small_malloc_cleared_no_lock(szone_t *szone, msize_t msize) -{ - void *ptr; - - // Assumes already locked - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - ptr = small_malloc_from_free_list(szone, msize); - if (ptr) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - return ptr; - } else { - ptr = small_malloc_from_region_no_lock(szone, msize); - // we don't clear because this freshly allocated space is pristine - } - return ptr; -} - -static INLINE void -free_small(szone_t *szone, void *ptr, region_t *small_region) -{ - msize_t msize = SMALL_PTR_SIZE(ptr); -#if SMALL_CACHE - void *ptr2; -#endif - - // ptr is known to be in small_region - SZONE_LOCK(szone); -#if SMALL_CACHE - ptr2 = szone->last_small_free; - /* check that we don't already have this pointer in the cache */ - if (ptr == (void *)((uintptr_t)ptr2 & ~ (SMALL_QUANTUM - 1))) { - szone_error(szone, "double free", ptr, NULL); - return; - } -#endif - if (SMALL_PTR_IS_FREE(ptr)) { - szone_error(szone, "double free", ptr, NULL); - return; - } -#if SMALL_CACHE - szone->last_small_free = (void *)(((uintptr_t)ptr) | msize); - if (!ptr2) { - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - return; - } - msize = (uintptr_t)ptr2 & (SMALL_QUANTUM - 1); - ptr = (void *)(((uintptr_t)ptr2) & ~ (SMALL_QUANTUM - 1)); - small_region = small_region_for_ptr_no_lock(szone, ptr); - if (!small_region) { - szone_error(szone, "double free (small cache)", ptr, NULL); - return; - } -#endif - small_free_no_lock(szone, small_region, ptr, msize); - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); -} - -static void -print_small_free_list(szone_t *szone) -{ - grain_t grain = 0; - free_list_t *ptr; - _SIMPLE_STRING b = _simple_salloc(); - - if (b) { - _simple_sappend(b, "small free sizes: "); - while (grain < NUM_SMALL_SLOTS) { - ptr = szone->small_free_list[grain]; - if (ptr) { - _simple_sprintf(b, "%s%y[%d]; ", (grain == NUM_SMALL_SLOTS-1) ? ">=" : "", (grain + 1) * SMALL_QUANTUM, free_list_count(ptr)); - } - grain++; - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static void -print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_end) -{ - unsigned counts[1024]; - unsigned in_use = 0; - void *start = SMALL_REGION_ADDRESS(region); - void *limit = SMALL_REGION_END(region) - bytes_at_end; - msize_t msize_and_free; - msize_t msize; - unsigned ci; - _SIMPLE_STRING b; - - memset(counts, 0, 1024 * sizeof(unsigned)); - while (start < limit) { - msize_and_free = *SMALL_METADATA_FOR_PTR(start); - msize = msize_and_free & ~ SMALL_IS_FREE; - if (!(msize_and_free & SMALL_IS_FREE)) { - // block in use - if (msize < 1024) - counts[msize]++; - in_use++; - } - start += SMALL_BYTES_FOR_MSIZE(msize); - } - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Small region [%p-%p, %y]\tIn_use=%d ", - SMALL_REGION_ADDRESS(region), SMALL_REGION_END(region), (int)SMALL_REGION_SIZE, in_use); - if (bytes_at_end) - _simple_sprintf(b, "Untouched=%ly", bytes_at_end); - if (verbose && in_use) { - _simple_sappend(b, "\n\tSizes in use: "); - for (ci = 0; ci < 1024; ci++) - if (counts[ci]) - _simple_sprintf(b, "%d[%d] ", SMALL_BYTES_FOR_MSIZE(ci), counts[ci]); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static boolean_t -small_free_list_check(szone_t *szone, grain_t grain) -{ - unsigned count = 0; - free_list_t *ptr = szone->small_free_list[grain]; - free_list_t *previous = NULL; - msize_t msize_and_free; - - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - while (ptr) { - msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); - count++; - if (!(msize_and_free & SMALL_IS_FREE)) { - malloc_printf("*** in-use ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr); - return 0; - } - if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { - malloc_printf("*** unaligned ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr); - return 0; - } - if (!small_region_for_ptr_no_lock(szone, ptr)) { - malloc_printf("*** ptr not in szone grain=%d count=%d ptr=%p\n", grain, count, ptr); - return 0; - } - free_list_checksum(szone, ptr, __PRETTY_FUNCTION__); - if (free_list_unchecksum_ptr(ptr->previous) != previous) { - malloc_printf("*** previous incorrectly set grain=%d count=%d ptr=%p\n", grain, count, ptr); - return 0; - } - previous = ptr; - ptr = free_list_unchecksum_ptr(ptr->next); - } - return 1; -} - -/******************************************************************************* - * Region hash implementation - * - * This is essentially a duplicate of the existing Large allocator hash, minus - * the ability to remove entries. The two should be combined eventually. - ******************************************************************************/ -#pragma mark region hash - -/* - * hash_lookup_region_no_lock - Scan a hash ring looking for an entry for a - * given region. - * - * FIXME: If consecutive queries of the same region are likely, a one-entry - * cache would likely be a significant performance win here. - */ -static region_t * -hash_lookup_region_no_lock(region_t *regions, size_t num_entries, region_t r) { - size_t index, hash_index; - region_t *entry; - - if (!num_entries) - return 0; - - index = hash_index = ((uintptr_t)r >> 20) % num_entries; - do { - entry = regions + index; - if (*entry == 0) - return 0; - if (*entry == r) - return entry; - if (++index == num_entries) - index = 0; - } while (index != hash_index); - return 0; -} - -/* - * hash_region_insert_no_lock - Insert a region into the hash ring. - */ -static void -hash_region_insert_no_lock(region_t *regions, size_t num_entries, region_t r) { - size_t index, hash_index; - region_t *entry; - - index = hash_index = ((uintptr_t)r >> 20) % num_entries; - do { - entry = regions + index; - if (*entry == 0) { - *entry = r; - return; - } - if (++index == num_entries) - index = 0; - } while (index != hash_index); -} - -/* - * hash_regions_alloc_no_lock - Allocate space for a number of entries. This - * must be a VM allocation as to avoid recursing between allocating a new small - * region, and asking the small region to allocate space for the new list of - * regions. - */ -static region_t * -hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries) -{ - size_t size = num_entries * sizeof(region_t); - return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC); -} - -/* - * hash_regions_grow_no_lock - Grow the hash ring, and rehash the entries. - * Return the new region and new size to update the szone. Do not deallocate - * the old entries since someone may still be allocating them. - */ -static region_t * -hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, - size_t *new_size) -{ - // double in size and allocate memory for the regions - *new_size = old_size * 2 + 1; - region_t *new_regions = hash_regions_alloc_no_lock(szone, *new_size); - - // rehash the entries into the new list - size_t index; - for (index = 0; index < old_size; ++index) { - region_t r = regions[index]; - if (r != 0) - hash_region_insert_no_lock(new_regions, *new_size, r); - } - return new_regions; -} - -/******************************************************************************* - * Large allocator implementation - ******************************************************************************/ -#pragma mark large allocator - -#if DEBUG_MALLOC - -static void -large_debug_print(szone_t *szone) -{ - unsigned num_large_entries = szone->num_large_entries; - unsigned index = num_large_entries; - large_entry_t *range; - _SIMPLE_STRING b = _simple_salloc(); - - if (b) { - for (index = 0, range = szone->large_entries; index < szone->num_large_entries; index++, range++) - if (!LARGE_ENTRY_IS_EMPTY(*range)) - _simple_sprintf(b, "%d: %p(%y); ", index, LARGE_ENTRY_ADDRESS(*range), LARGE_ENTRY_SIZE(*range)); - - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} -#endif - -/* - * Scan the hash ring looking for an entry for the given pointer. - */ -static large_entry_t * -large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr) -{ - // result only valid with lock held - unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index; - unsigned index; - large_entry_t *range; - - if (!num_large_entries) - return NULL; - hash_index = ((uintptr_t)ptr >> vm_page_shift) % num_large_entries; - index = hash_index; - do { - range = szone->large_entries + index; - if (LARGE_ENTRY_MATCHES(*range, ptr)) - return range; - if (LARGE_ENTRY_IS_EMPTY(*range)) - return NULL; // end of chain - index++; - if (index == num_large_entries) - index = 0; - } while (index != hash_index); - return NULL; -} - -static void -large_entry_insert_no_lock(szone_t *szone, large_entry_t range) -{ - unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index = (range.address_and_num_pages >> vm_page_shift) % num_large_entries; - unsigned index = hash_index; - large_entry_t *entry; - - do { - entry = szone->large_entries + index; - if (LARGE_ENTRY_IS_EMPTY(*entry)) { - *entry = range; - return; // end of chain - } - index++; - if (index == num_large_entries) - index = 0; - } while (index != hash_index); -} - -static INLINE void -large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) -{ - unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index = entry - szone->large_entries; - unsigned index = hash_index; - large_entry_t range; - - do { - index++; - if (index == num_large_entries) - index = 0; - range = szone->large_entries[index]; - if (LARGE_ENTRY_IS_EMPTY(range)) - return; - szone->large_entries[index].address_and_num_pages = 0; - large_entry_insert_no_lock(szone, range); // this will reinsert in the - // proper place - } while (index != hash_index); -} - -static INLINE large_entry_t * -large_entries_alloc_no_lock(szone_t *szone, unsigned num) -{ - size_t size = num * sizeof(large_entry_t); - boolean_t is_vm_allocation = size >= LARGE_THRESHOLD; - - if (is_vm_allocation) { - // Note that we allocate memory (via a system call) under a spin lock - // That is certainly evil, however it's very rare in the lifetime of a process - // The alternative would slow down the normal case - return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC_LARGE); - } else { - return small_malloc_cleared_no_lock(szone, SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1)); - } -} - -static void -large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate) -{ - // returns range to deallocate - size_t size = num * sizeof(large_entry_t); - boolean_t is_vm_allocation = size >= LARGE_THRESHOLD; - region_t *region; - msize_t msize_and_free; - - if (is_vm_allocation) { - range_to_deallocate->address = (vm_address_t)entries; - range_to_deallocate->size = round_page(size); - } else { - range_to_deallocate->size = 0; - region = small_region_for_ptr_no_lock(szone, entries); - msize_and_free = *SMALL_METADATA_FOR_PTR(entries); - if (msize_and_free & SMALL_IS_FREE) { - szone_error(szone, "object already freed being freed", entries, NULL); - return; - } - small_free_no_lock(szone, region, entries, msize_and_free); - } -} - -static large_entry_t * -large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) -{ - // sets range_to_deallocate - unsigned old_num_entries = szone->num_large_entries; - large_entry_t *old_entries = szone->large_entries; - unsigned new_num_entries = (old_num_entries) ? old_num_entries * 2 + 1 : 63; // always an odd number for good hashing - large_entry_t *new_entries = large_entries_alloc_no_lock(szone, new_num_entries); - unsigned index = old_num_entries; - large_entry_t oldRange; - - // if the allocation of new entries failed, bail - if (new_entries == NULL) - return NULL; - - szone->num_large_entries = new_num_entries; - szone->large_entries = new_entries; - - /* rehash entries into the new list */ - while (index--) { - oldRange = old_entries[index]; - if (!LARGE_ENTRY_IS_EMPTY(oldRange)) { - large_entry_insert_no_lock(szone, oldRange); - } - } - if (old_entries) { - large_entries_free_no_lock(szone, old_entries, old_num_entries, range_to_deallocate); - } else { - range_to_deallocate->size = 0; - } - return new_entries; -} - -// frees the specific entry in the size table -// returns a range to truly deallocate -static vm_range_t -large_free_no_lock(szone_t *szone, large_entry_t *entry) -{ - vm_range_t range; - - range.address = (vm_address_t)LARGE_ENTRY_ADDRESS(*entry); - range.size = (vm_size_t)LARGE_ENTRY_SIZE(*entry); - szone->num_large_objects_in_use--; - szone->num_bytes_in_large_objects -= range.size; - if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) { - protect((void *)range.address, range.size, VM_PROT_READ | VM_PROT_WRITE, szone->debug_flags); - range.address -= vm_page_size; - range.size += 2 * vm_page_size; - } - entry->address_and_num_pages = 0; - large_entries_rehash_after_entry_no_lock(szone, entry); -#if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, (void *)range.address)) { - malloc_printf("*** freed entry %p still in use; num_large_entries=%d\n", - range.address, szone->num_large_entries); - large_debug_print(szone); - szone_sleep(); - } -#endif - return range; -} - -static kern_return_t -large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder) -{ - unsigned index = 0; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - large_entry_t *entries; - kern_return_t err; - vm_range_t range; - large_entry_t entry; - - err = reader(task, large_entries_address, sizeof(large_entry_t) * num_entries, (void **)&entries); - if (err) - return err; - index = num_entries; - if ((type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) && - (num_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD)) { - range.address = large_entries_address; - range.size = round_page(num_entries * sizeof(large_entry_t)); - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &range, 1); - } - if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE)) - while (index--) { - entry = entries[index]; - if (!LARGE_ENTRY_IS_EMPTY(entry)) { - range.address = (vm_address_t)LARGE_ENTRY_ADDRESS(entry); - range.size = (vm_size_t)LARGE_ENTRY_SIZE(entry); - buffer[count++] = range; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count); - count = 0; - } - } - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE - | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count); - } - return 0; -} - -/********************* HUGE ENTRY UTILITIES ************************/ - -static huge_entry_t * -huge_entry_for_pointer_no_lock(szone_t *szone, const void *ptr) -{ - unsigned index; - huge_entry_t *huge; - - for (index = szone->num_huge_entries, huge = szone->huge_entries; - index > 0; - index--, huge++) { - - if ((void *)huge->address == ptr) - return huge; - } - return NULL; -} - -static boolean_t -huge_entry_append(szone_t *szone, huge_entry_t huge) -{ - huge_entry_t *new_huge_entries = NULL, *old_huge_entries; - unsigned num_huge_entries; - - // We do a little dance with locking because doing allocation (even in the - // default szone) may cause something to get freed in this szone, with a - // deadlock - // Returns 1 on success - SZONE_LOCK(szone); - for (;;) { - num_huge_entries = szone->num_huge_entries; - SZONE_UNLOCK(szone); - /* check for counter wrap */ - if ((num_huge_entries + 1) < num_huge_entries) - return 0; - /* stale allocation from last time around the loop? */ - if (new_huge_entries) - szone_free(szone, new_huge_entries); - new_huge_entries = szone_malloc(szone, (num_huge_entries + 1) * sizeof(huge_entry_t)); - if (new_huge_entries == NULL) - return 0; - SZONE_LOCK(szone); - if (num_huge_entries == szone->num_huge_entries) { - // No change - our malloc still applies - old_huge_entries = szone->huge_entries; - if (num_huge_entries) { - memcpy(new_huge_entries, old_huge_entries, num_huge_entries * sizeof(huge_entry_t)); - } - new_huge_entries[szone->num_huge_entries++] = huge; - szone->huge_entries = new_huge_entries; - SZONE_UNLOCK(szone); - szone_free(szone, old_huge_entries); - return 1; - } - // try again! - } -} - -static kern_return_t -huge_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t huge_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder) -{ - huge_entry_t *entries; - kern_return_t err; - - err = reader(task, huge_entries_address, sizeof(huge_entry_t) * num_entries, (void **)&entries); - if (err) - return err; - if (num_entries) - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, entries, num_entries); - - return 0; -} - -static void * -large_and_huge_malloc(szone_t *szone, size_t num_pages) -{ - void *addr; - vm_range_t range_to_deallocate; - huge_entry_t huge_entry; - size_t size; - large_entry_t large_entry; - - if (!num_pages) - num_pages = 1; // minimal allocation size for this szone - size = (size_t)num_pages << vm_page_shift; - range_to_deallocate.size = 0; - if (num_pages >= (1 << vm_page_shift)) { - addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MEMORY_MALLOC_HUGE); - if (addr == NULL) - return NULL; - huge_entry.size = size; - huge_entry.address = (vm_address_t)addr; - if (!huge_entry_append(szone, huge_entry)) - return NULL; // we are leaking the allocation here - SZONE_LOCK(szone); - szone->num_bytes_in_huge_objects += size; - } else { - - addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MEMORY_MALLOC_LARGE); -#if DEBUG_MALLOC - if (LOG(szone, addr)) - malloc_printf("in szone_malloc true large allocation at %p for %ly\n", (void *)addr, size); -#endif - SZONE_LOCK(szone); - if (addr == NULL) { - SZONE_UNLOCK(szone); - return NULL; - } -#if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, addr)) { - malloc_printf("freshly allocated is already in use: %p\n", addr); - large_debug_print(szone); - szone_sleep(); - } -#endif - if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) { - // density of hash table too high; grow table - // we do that under lock to avoid a race - large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate); - if (entries == NULL) { - SZONE_UNLOCK(szone); - return NULL; - } - } - large_entry.address_and_num_pages = (uintptr_t)addr | num_pages; -#if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, addr)) { - malloc_printf("entry about to be added already in use: %p\n", addr); - large_debug_print(szone); - szone_sleep(); - } -#endif - large_entry_insert_no_lock(szone, large_entry); -#if DEBUG_MALLOC - if (!large_entry_for_pointer_no_lock(szone, (void *)addr)) { - malloc_printf("can't find entry just added\n"); - large_debug_print(szone); - szone_sleep(); - } -#endif - szone->num_large_objects_in_use ++; - szone->num_bytes_in_large_objects += size; - } - SZONE_UNLOCK(szone); - if (range_to_deallocate.size) { - deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); // we deallocate outside the lock - } - return (void *)addr; -} - -static INLINE void -free_large_or_huge(szone_t *szone, void *ptr) -{ - // We have established ptr is page-aligned and not tiny nor small - large_entry_t *entry; - vm_range_t vm_range_to_deallocate; - huge_entry_t *huge; - - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (entry) { - vm_range_to_deallocate = large_free_no_lock(szone, entry); -#if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, ptr)) { - malloc_printf("*** just after freeing %p still in use num_large_entries=%d\n", ptr, szone->num_large_entries); - large_debug_print(szone); - szone_sleep(); - } -#endif - } else if ((huge = huge_entry_for_pointer_no_lock(szone, ptr))) { - vm_range_to_deallocate = *huge; - *huge = szone->huge_entries[--szone->num_huge_entries]; // last entry fills that spot - szone->num_bytes_in_huge_objects -= (size_t)vm_range_to_deallocate.size; - } else { -#if DEBUG_MALLOC - large_debug_print(szone); -#endif - szone_error(szone, "pointer being freed was not allocated", ptr, NULL); - return; - } - SZONE_UNLOCK(szone); // we release the lock asap - CHECK(szone, __PRETTY_FUNCTION__); - // we deallocate_pages, including guard pages - if (vm_range_to_deallocate.address) { -#if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, (void *)vm_range_to_deallocate.address)) { - malloc_printf("*** invariant broken: %p still in use num_large_entries=%d\n", vm_range_to_deallocate.address, szone->num_large_entries); - large_debug_print(szone); - szone_sleep(); - } -#endif - deallocate_pages(szone, (void *)vm_range_to_deallocate.address, (size_t)vm_range_to_deallocate.size, 0); - } -} - -static INLINE int -try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) -{ - vm_address_t addr = (vm_address_t)ptr + old_size; - large_entry_t *large_entry, saved_entry; - huge_entry_t *huge_entry, huge; - kern_return_t err; - -#if DEBUG_MALLOC - if (old_size != ((old_size >> vm_page_shift) << vm_page_shift)) { - malloc_printf("*** old_size is %d\n", old_size); - } -#endif - SZONE_LOCK(szone); - large_entry = large_entry_for_pointer_no_lock(szone, (void *)addr); - SZONE_UNLOCK(szone); - if (large_entry) { - return 0; // large pointer already exists in table - extension is not going to work - } - new_size = round_page(new_size); - /* - * Ask for allocation at a specific address, and mark as realloc - * to request coalescing with previous realloc'ed extensions. - */ - err = vm_allocate(mach_task_self(), &addr, new_size - old_size, VM_MAKE_TAG(VM_MEMORY_REALLOC)); - if (err != KERN_SUCCESS) { - return 0; - } - SZONE_LOCK(szone); - /* - * If the new size is still under the large/huge threshold, we can just - * extend the existing large block. - * - * Note: this logic is predicated on the understanding that an allocated - * block can never really shrink, so that the new size will always be - * larger than the old size. - * - * Note: the use of 1 << vm_page_shift here has to do with the subdivision - * of the bits in the large_entry_t, and not the size of a page (directly). - */ - if ((new_size >> vm_page_shift) < (1 << vm_page_shift)) { - /* extend existing large entry */ - large_entry = large_entry_for_pointer_no_lock(szone, ptr); - if (!large_entry) { - szone_error(szone, "large entry reallocated is not properly in table", ptr, NULL); - /* XXX will cause fault on next reference to entry */ - } - large_entry->address_and_num_pages = (uintptr_t)ptr | (new_size >> vm_page_shift); - szone->num_bytes_in_large_objects += new_size - old_size; - } else if ((old_size >> vm_page_shift) >= (1 << vm_page_shift)) { - /* extend existing huge entry */ - huge_entry = huge_entry_for_pointer_no_lock(szone, ptr); - if (!huge_entry) { - szone_error(szone, "huge entry reallocated is not properly in table", ptr, NULL); - /* XXX will cause fault on next reference to huge_entry */ - } - huge_entry->size = new_size; - szone->num_bytes_in_huge_objects += new_size - old_size; - } else { - /* need to convert large entry to huge entry */ - - /* release large entry, note we still have the VM allocation */ - large_entry = large_entry_for_pointer_no_lock(szone, ptr); - saved_entry = *large_entry; // in case we need to put it back - large_free_no_lock(szone, large_entry); - - /* and get a huge entry */ - huge.address = (vm_address_t)ptr; - huge.size = new_size; /* fix up size */ - SZONE_UNLOCK(szone); - if (huge_entry_append(szone, huge)) { - szone->num_bytes_in_huge_objects += new_size; - return 1; // success! - } - SZONE_LOCK(szone); - // we leak memory (the extra space appended) but data structures are correct - large_entry_insert_no_lock(szone, saved_entry); // this will reinsert the large entry - } - SZONE_UNLOCK(szone); // we release the lock asap - return 1; -} - -/********************* Zone call backs ************************/ - -static void -szone_free(szone_t *szone, void *ptr) -{ - region_t *tiny_region; - region_t *small_region; - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("in szone_free with %p\n", ptr); -#endif - if (!ptr) - return; - /* - * Try to free to a tiny region. - */ - if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) { - szone_error(szone, "Non-aligned pointer being freed", ptr, NULL); - return; - } - if ((tiny_region = tiny_region_for_ptr_no_lock(szone, ptr)) != NULL) { - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { - szone_error(szone, "Pointer to metadata being freed", ptr, NULL); - return; - } - free_tiny(szone, ptr, tiny_region); - return; - } - - /* - * Try to free to a small region. - */ - if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) { - szone_error(szone, "Non-aligned pointer being freed (2)", ptr, NULL); - return; - } - if ((small_region = small_region_for_ptr_no_lock(szone, ptr)) != NULL) { - if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { - szone_error(szone, "Pointer to metadata being freed (2)", ptr, NULL); - return; - } - free_small(szone, ptr, small_region); - return; - } - - /* check that it's a legal large/huge allocation */ - if ((uintptr_t)ptr & (vm_page_size - 1)) { - szone_error(szone, "non-page-aligned, non-allocated pointer being freed", ptr, NULL); - return; - } - free_large_or_huge(szone, ptr); -} - -static INLINE void * -szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested) -{ - void *ptr; - msize_t msize; - - if (size <= 31*TINY_QUANTUM) { - // think tiny - msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - if (!msize) - msize = 1; - ptr = tiny_malloc_should_clear(szone, msize, cleared_requested); - } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (size < LARGE_THRESHOLD)) { - // think small - msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); - if (! msize) msize = 1; - ptr = small_malloc_should_clear(szone, msize, cleared_requested); - } else { - // large or huge - size_t num_pages = round_page(size) >> vm_page_shift; - if (num_pages == 0) /* Overflowed */ - ptr = 0; - else - ptr = large_and_huge_malloc(szone, num_pages); - } -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("szone_malloc returned %p\n", ptr); -#endif - /* - * If requested, scribble on allocated memory. - */ - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && ptr && !cleared_requested && size) - memset(ptr, 0xaa, size); - - return ptr; -} - -static void * -szone_malloc(szone_t *szone, size_t size) { - return szone_malloc_should_clear(szone, size, 0); -} - -static void * -szone_calloc(szone_t *szone, size_t num_items, size_t size) -{ - size_t total_bytes = num_items * size; - if ((num_items > 1) && (size != 0) && ((total_bytes / size) != num_items)) - return NULL; - return szone_malloc_should_clear(szone, total_bytes, 1); -} - -static void * -szone_valloc(szone_t *szone, size_t size) -{ - void *ptr; - size_t num_pages; - - num_pages = round_page(size) >> vm_page_shift; - ptr = large_and_huge_malloc(szone, num_pages); -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("szone_valloc returned %p\n", ptr); -#endif - return ptr; -} - -static size_t -szone_size(szone_t *szone, const void *ptr) -{ - size_t size = 0; - boolean_t is_free; - msize_t msize, msize_and_free; - large_entry_t *entry; - huge_entry_t *huge; - - if (!ptr) - return 0; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in szone_size for %p (szone=%p)\n", ptr, szone); - } -#endif - - /* - * Look for it in a tiny region. - */ - if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) - return 0; - if (tiny_region_for_ptr_no_lock(szone, ptr)) { - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) - return 0; - msize = get_tiny_meta_header(ptr, &is_free); - return (is_free) ? 0 : TINY_BYTES_FOR_MSIZE(msize); - } - - /* - * Look for it in a small region. - */ - if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) - return 0; - if (small_region_for_ptr_no_lock(szone, ptr)) { - if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) - return 0; - msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); - return (msize_and_free & SMALL_IS_FREE) ? 0 : SMALL_BYTES_FOR_MSIZE(msize_and_free); - } - - /* - * If not page-aligned, it cannot have come from a large or huge allocation. - */ - if ((uintptr_t)ptr & (vm_page_size - 1)) - return(0); - - /* - * Look for it in a large or huge entry. - */ - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (entry) { - size = LARGE_ENTRY_SIZE(*entry); - } else if ((huge = huge_entry_for_pointer_no_lock(szone, ptr))) { - size = huge->size; - } - SZONE_UNLOCK(szone); -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("szone_size for %p returned %d\n", ptr, (unsigned)size); - } -#endif - return size; -} - -static void * -szone_realloc(szone_t *szone, void *ptr, size_t new_size) -{ - size_t old_size; - void *new_ptr; - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in szone_realloc for %p, %d\n", ptr, (unsigned)new_size); - } -#endif - if (!ptr) { - ptr = szone_malloc(szone, new_size); - return ptr; - } - old_size = szone_size(szone, ptr); - if (!old_size) { - szone_error(szone, "pointer being reallocated was not allocated", ptr, NULL); - return NULL; - } - /* we never shrink an allocation */ - if (old_size >= new_size) - return ptr; - - /* - * If the old and new sizes both suit the tiny allocator, try to reallocate in-place. - */ - if ((new_size + TINY_QUANTUM - 1) <= 31 * TINY_QUANTUM) { - if (try_realloc_tiny_in_place(szone, ptr, old_size, new_size)) { - return ptr; - } - - /* - * If the old and new sizes both suit the small allocator, and we're not protecting the - * small allocations, try to reallocate in-place. - */ - } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && - ((new_size + SMALL_QUANTUM - 1) < LARGE_THRESHOLD) && - (old_size > 31 * TINY_QUANTUM)) { - if (try_realloc_small_in_place(szone, ptr, old_size, new_size)) { - return ptr; - } - - /* - * If the allocation's a large or huge allocation, try to reallocate in-place there. - */ - } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (old_size > LARGE_THRESHOLD)) { - if (try_realloc_large_or_huge_in_place(szone, ptr, old_size, new_size)) { - return ptr; - } - } - - /* - * Can't reallocate in place for whatever reason; allocate a new buffer and copy. - */ - new_ptr = szone_malloc(szone, new_size); - if (new_ptr == NULL) - return NULL; - - /* - * If the allocation's large enough, try to copy using VM. If that fails, or - * if it's too small, just copy by hand. - */ - if ((old_size < VM_COPY_THRESHOLD) || - vm_copy(mach_task_self(), (vm_address_t)ptr, old_size, (vm_address_t)new_ptr)) - memcpy(new_ptr, ptr, old_size); - szone_free(szone, ptr); - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size); - } -#endif - return new_ptr; -} - -// given a size, returns the number of pointers allocated capable of holding -// that size, up to the limit specified by the 'count' argument. These pointers -// are stored in the 'results' array, which must be allocated by the caller. -// may return zero, since this function is only a best attempt at allocating -// the pointers. clients should be prepared to call malloc for any additional -// blocks they need. -static unsigned -szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) -{ - msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - unsigned found = 0; - - // only bother implementing this for tiny - if (size > 31*TINY_QUANTUM) - return 0; - // make sure to return objects at least one quantum in size - if (!msize) - msize = 1; - - CHECK(szone, __PRETTY_FUNCTION__); - - // We must lock the zone now, since tiny_malloc_from_free_list assumes that - // the caller has done so. - SZONE_LOCK(szone); - - // with the zone locked, allocate objects from the free list until all - // sufficiently large objects have been exhausted, or we have met our quota - // of objects to allocate. - while (found < count) { - void *ptr = tiny_malloc_from_free_list(szone, msize); - if (!ptr) - break; - - *results++ = ptr; - found++; - } - SZONE_UNLOCK(szone); - return found; -} - -static void -szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) -{ - unsigned cc = 0; - void *ptr; - region_t *tiny_region; - boolean_t is_free; - msize_t msize; - - // frees all the pointers in to_be_freed - // note that to_be_freed may be overwritten during the process - if (!count) - return; - CHECK(szone, __PRETTY_FUNCTION__); - SZONE_LOCK(szone); - while (cc < count) { - ptr = to_be_freed[cc]; - if (ptr) { - /* XXX this really slows us down */ - tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); - if (tiny_region) { - // this is a tiny pointer - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) - break; // pointer to metadata; let the standard free deal with it - msize = get_tiny_meta_header(ptr, &is_free); - if (is_free) - break; // a double free; let the standard free deal with it - tiny_free_no_lock(szone, tiny_region, ptr, msize); - to_be_freed[cc] = NULL; - } - } - cc++; - } - SZONE_UNLOCK(szone); - CHECK(szone, __PRETTY_FUNCTION__); - while (count--) { - ptr = to_be_freed[count]; - if (ptr) - szone_free(szone, ptr); - } -} - -static void -szone_destroy(szone_t *szone) -{ - size_t index; - large_entry_t *large; - vm_range_t range_to_deallocate; - huge_entry_t *huge; - - /* destroy large entries */ - index = szone->num_large_entries; - while (index--) { - large = szone->large_entries + index; - if (!LARGE_ENTRY_IS_EMPTY(*large)) { - // we deallocate_pages, including guard pages - deallocate_pages(szone, (void *)LARGE_ENTRY_ADDRESS(*large), LARGE_ENTRY_SIZE(*large), szone->debug_flags); - } - } - if (szone->num_large_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD) { - // we do not free in the small chunk case - large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate); - if (range_to_deallocate.size) - deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0); - } - - /* destroy huge entries */ - index = szone->num_huge_entries; - while (index--) { - huge = szone->huge_entries + index; - deallocate_pages(szone, (void *)huge->address, huge->size, szone->debug_flags); - } - - /* destroy tiny regions */ - for (index = 0; index < szone->num_tiny_regions_allocated; ++index) - if (szone->tiny_regions[index]) - deallocate_pages(szone, szone->tiny_regions[index], TINY_REGION_SIZE, 0); - - /* destroy small regions */ - for (index = 0; index < szone->num_small_regions_allocated; ++index) - if (szone->small_regions[index]) - deallocate_pages(szone, szone->small_regions[index], SMALL_REGION_SIZE, 0); - - /* destroy region hash rings, if any */ - if (szone->tiny_regions != szone->initial_tiny_regions) { - size_t size = round_page(szone->num_tiny_regions_allocated * sizeof(region_t)); - deallocate_pages(szone, szone->tiny_regions, size, 0); - } - if (szone->small_regions != szone->initial_small_regions) { - size_t size = round_page(szone->num_small_regions_allocated * sizeof(region_t)); - deallocate_pages(szone, szone->small_regions, size, 0); - } - /* Now destroy the separate szone region */ - deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); -} - -static size_t -szone_good_size(szone_t *szone, size_t size) -{ - msize_t msize; - unsigned num_pages; - - if (size <= 31 * TINY_QUANTUM) { - // think tiny - msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - if (! msize) msize = 1; - return TINY_BYTES_FOR_MSIZE(msize); - } - if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (size < LARGE_THRESHOLD)) { - // think small - msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); - if (! msize) msize = 1; - return SMALL_BYTES_FOR_MSIZE(msize); - } else { - num_pages = round_page(size) >> vm_page_shift; - if (!num_pages) - num_pages = 1; // minimal allocation size for this - return num_pages << vm_page_shift; - } -} - -unsigned szone_check_counter = 0; -unsigned szone_check_start = 0; -unsigned szone_check_modulo = 1; - -static boolean_t -szone_check_all(szone_t *szone, const char *function) -{ - size_t index; - - SZONE_LOCK(szone); - CHECK_LOCKED(szone, __PRETTY_FUNCTION__); - - /* check tiny regions - chould check region count */ - for (index = 0; index < szone->num_tiny_regions_allocated; ++index) { - region_t tiny = szone->tiny_regions[index]; - if (tiny && !tiny_check_region(szone, tiny)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, "check: tiny region incorrect", NULL, - "*** tiny region %d incorrect szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - } - /* check tiny free lists */ - for (index = 0; index < NUM_TINY_SLOTS; ++index) { - if (!tiny_free_list_check(szone, index)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, "check: tiny free list incorrect", NULL, - "*** tiny free list incorrect (slot=%d) szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - } - /* check small regions - could check region count */ - for (index = 0; index < szone->num_small_regions_allocated; ++index) { - region_t small = szone->small_regions[index]; - if (small && !szone_check_small_region(szone, small)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, "check: small region incorrect", NULL, - "*** small region %d incorrect szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - } - /* check small free lists */ - for (index = 0; index < NUM_SMALL_SLOTS; ++index) { - if (!small_free_list_check(szone, index)) { - SZONE_UNLOCK(szone); - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, "check: small free list incorrect", NULL, - "*** small free list incorrect (grain=%d) szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - } - SZONE_UNLOCK(szone); - return 1; -} - -static boolean_t -szone_check(szone_t *szone) -{ - if ((++szone_check_counter % 10000) == 0) - _malloc_printf(ASL_LEVEL_NOTICE, "at szone_check counter=%d\n", szone_check_counter); - if (szone_check_counter < szone_check_start) - return 1; - if (szone_check_counter % szone_check_modulo) - return 1; - return szone_check_all(szone, ""); -} - -static kern_return_t -szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder) -{ - szone_t *szone; - kern_return_t err; - - if (!reader) reader = _szone_default_reader; - err = reader(task, zone_address, sizeof(szone_t), (void **)&szone); - if (err) return err; - err = tiny_in_use_enumerator(task, context, type_mask, szone, reader, recorder); - if (err) return err; - err = small_in_use_enumerator(task, context, type_mask, szone, reader, recorder); - if (err) return err; - err = large_in_use_enumerator(task, context, type_mask, - (vm_address_t)szone->large_entries, szone->num_large_entries, reader, - recorder); - if (err) return err; - err = huge_in_use_enumerator(task, context, type_mask, - (vm_address_t)szone->huge_entries, szone->num_huge_entries, reader, - recorder); - return err; -} - -// Following method is deprecated: use scalable_zone_statistics instead -void -scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) -{ - szone_t *szone = (void *)zone; - unsigned info[13]; - - // We do not lock to facilitate debug - info[4] = szone->num_tiny_objects; - info[5] = szone->num_bytes_in_tiny_objects; - info[6] = szone->num_small_objects; - info[7] = szone->num_bytes_in_small_objects; - info[8] = szone->num_large_objects_in_use; - info[9] = szone->num_bytes_in_large_objects; - info[10] = szone->num_huge_entries; - info[11] = szone->num_bytes_in_huge_objects; - info[12] = szone->debug_flags; - info[0] = info[4] + info[6] + info[8] + info[10]; - info[1] = info[5] + info[7] + info[9] + info[11]; - info[3] = szone->num_tiny_regions * TINY_REGION_SIZE + szone->num_small_regions * SMALL_REGION_SIZE + info[9] + info[11]; - info[2] = info[3] - szone->tiny_bytes_free_at_end - szone->small_bytes_free_at_end; - memcpy(info_to_fill, info, sizeof(unsigned)*count); -} - -static void -szone_print(szone_t *szone, boolean_t verbose) -{ - unsigned info[13]; - size_t index; - region_t region; - - SZONE_LOCK(szone); - scalable_zone_info((void *)szone, info, 13); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "Scalable zone %p: inUse=%d(%y) touched=%y allocated=%y flags=%d\n", - szone, info[0], info[1], info[2], info[3], info[12]); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "\ttiny=%d(%y) small=%d(%y) large=%d(%y) huge=%d(%y)\n", - info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11]); - // tiny - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "%d tiny regions:\n", szone->num_tiny_regions); - for (index = 0; index < szone->num_tiny_regions_allocated; ++index) { - region = szone->tiny_regions[index]; - if (region) - print_tiny_region(verbose, region, (region == szone->last_tiny_region) ? - szone->tiny_bytes_free_at_end : 0); - } - if (verbose) - print_tiny_free_list(szone); - // small - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "%d small regions:\n", szone->num_small_regions); - for (index = 0; index < szone->num_small_regions_allocated; ++index) { - region = szone->small_regions[index]; - if (region) - print_small_region(szone, verbose, region, - (region == szone->last_small_region) ? - szone->small_bytes_free_at_end : 0); - } - if (verbose) - print_small_free_list(szone); - SZONE_UNLOCK(szone); -} - -static void -szone_log(malloc_zone_t *zone, void *log_address) -{ - szone_t *szone = (szone_t *)zone; - - szone->log_address = log_address; -} - -static void -szone_force_lock(szone_t *szone) -{ - SZONE_LOCK(szone); -} - -static void -szone_force_unlock(szone_t *szone) -{ - SZONE_UNLOCK(szone); -} - -boolean_t -scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone) -{ - szone_t *szone = (szone_t *)zone; - - switch (subzone) { - case 0: - stats->blocks_in_use = szone->num_tiny_objects; - stats->size_in_use = szone->num_bytes_in_tiny_objects; - stats->size_allocated = szone->num_tiny_regions * TINY_REGION_SIZE; - stats->max_size_in_use = stats->size_allocated - szone->tiny_bytes_free_at_end; - return 1; - case 1: - stats->blocks_in_use = szone->num_small_objects; - stats->size_in_use = szone->num_bytes_in_small_objects; - stats->size_allocated = szone->num_small_regions * SMALL_REGION_SIZE; - stats->max_size_in_use = stats->size_allocated - szone->small_bytes_free_at_end; - return 1; - case 2: - stats->blocks_in_use = szone->num_large_objects_in_use; - stats->size_in_use = szone->num_bytes_in_large_objects; - stats->max_size_in_use = stats->size_allocated = stats->size_in_use; - return 1; - case 3: - stats->blocks_in_use = szone->num_huge_entries; - stats->size_in_use = szone->num_bytes_in_huge_objects; - stats->max_size_in_use = stats->size_allocated = stats->size_in_use; - return 1; - } - return 0; -} - -static void -szone_statistics(szone_t *szone, malloc_statistics_t *stats) -{ - size_t big_and_huge; - - stats->blocks_in_use = - szone->num_tiny_objects + - szone->num_small_objects + - szone->num_large_objects_in_use + - szone->num_huge_entries; - big_and_huge = szone->num_bytes_in_large_objects + szone->num_bytes_in_huge_objects; - stats->size_in_use = szone->num_bytes_in_tiny_objects + szone->num_bytes_in_small_objects + big_and_huge; - stats->max_size_in_use = stats->size_allocated = - szone->num_tiny_regions * TINY_REGION_SIZE + - szone->num_small_regions * SMALL_REGION_SIZE + - big_and_huge ; - - // Now we account for the untouched areas - stats->max_size_in_use -= szone->tiny_bytes_free_at_end; - stats->max_size_in_use -= szone->small_bytes_free_at_end; -} - -static const struct malloc_introspection_t szone_introspect = { - (void *)szone_ptr_in_use_enumerator, - (void *)szone_good_size, - (void *)szone_check, - (void *)szone_print, - szone_log, - (void *)szone_force_lock, - (void *)szone_force_unlock, - (void *)szone_statistics -}; // marked as const to spare the DATA section - -malloc_zone_t * -create_scalable_zone(size_t initial_size, unsigned debug_flags) -{ - szone_t *szone; - - /* - * Sanity-check our build-time assumptions about the size of a page. - * Since we have sized various things assuming the default page size, - * attempting to determine it dynamically is not useful. - */ - if ((vm_page_size != _vm_page_size) || (vm_page_shift != _vm_page_shift)) { - malloc_printf("*** FATAL ERROR - machine page size does not match our assumptions.\n"); - exit(-1); - } - - /* get memory for the zone, which is now separate from any region. - add guard pages to prevent walking from any other vm allocations - to here and overwriting the function pointers in basic_zone. */ - szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, - SCALABLE_MALLOC_ADD_GUARD_PAGES, - VM_MEMORY_MALLOC); - if (!szone) - return NULL; - /* set up the szone structure */ - szone->tiny_regions = szone->initial_tiny_regions; - szone->small_regions = szone->initial_small_regions; - szone->num_tiny_regions_allocated = INITIAL_NUM_REGIONS; - szone->num_small_regions_allocated = INITIAL_NUM_REGIONS; - szone->basic_zone.version = 3; - szone->basic_zone.size = (void *)szone_size; - szone->basic_zone.malloc = (void *)szone_malloc; - szone->basic_zone.calloc = (void *)szone_calloc; - szone->basic_zone.valloc = (void *)szone_valloc; - szone->basic_zone.free = (void *)szone_free; - szone->basic_zone.realloc = (void *)szone_realloc; - szone->basic_zone.destroy = (void *)szone_destroy; - szone->basic_zone.batch_malloc = (void *)szone_batch_malloc; - szone->basic_zone.batch_free = (void *)szone_batch_free; - szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; - szone->debug_flags = debug_flags; - LOCK_INIT(szone->lock); - -#if 0 -#warning CHECK_REGIONS enabled - debug_flags |= CHECK_REGIONS; -#endif -#if 0 -#warning LOG enabled - szone->log_address = ~0; -#endif - CHECK(szone, __PRETTY_FUNCTION__); - return (malloc_zone_t *)szone; -} - -/********* Support code for emacs unexec ************/ - -/* History of freezedry version numbers: - * - * 1) Old malloc (before the scalable malloc implementation in this file - * existed). - * 2) Original freezedrying code for scalable malloc. This code was apparently - * based on the old freezedrying code and was fundamentally flawed in its - * assumption that tracking allocated memory regions was adequate to fake - * operations on freezedried memory. This doesn't work, since scalable - * malloc does not store flags in front of large page-aligned allocations. - * 3) Original szone-based freezedrying code. - * 4) Fresher malloc with tiny zone - * 5) 32/64bit compatible malloc - * 6) Metadata within 1MB and 8MB region for tiny and small - * - * No version backward compatibility is provided, but the version number does - * make it possible for malloc_jumpstart() to return an error if the application - * was freezedried with an older version of malloc. - */ -#define MALLOC_FREEZEDRY_VERSION 6 - -typedef struct { - unsigned version; - unsigned nszones; - szone_t *szones; -} malloc_frozen; - -static void * -frozen_malloc(szone_t *zone, size_t new_size) -{ - return malloc(new_size); -} - -static void * -frozen_calloc(szone_t *zone, size_t num_items, size_t size) -{ - return calloc(num_items, size); -} - -static void * -frozen_valloc(szone_t *zone, size_t new_size) -{ - return valloc(new_size); -} - -static void * -frozen_realloc(szone_t *zone, void *ptr, size_t new_size) -{ - size_t old_size = szone_size(zone, ptr); - void *new_ptr; - - if (new_size <= old_size) { - return ptr; - } - new_ptr = malloc(new_size); - if (old_size > 0) { - memcpy(new_ptr, ptr, old_size); - } - return new_ptr; -} - -static void -frozen_free(szone_t *zone, void *ptr) -{ -} - -static void -frozen_destroy(szone_t *zone) -{ -} - -/********* Pseudo-private API for emacs unexec ************/ - -/* - * malloc_freezedry() records all of the szones in use, so that they can be - * partially reconstituted by malloc_jumpstart(). Due to the differences - * between reconstituted memory regions and those created by the szone code, - * care is taken not to reallocate from the freezedried memory, except in the - * case of a non-growing realloc(). - * - * Due to the flexibility provided by the zone registration mechanism, it is - * impossible to implement generic freezedrying for any zone type. This code - * only handles applications that use the szone allocator, so malloc_freezedry() - * returns 0 (error) if any non-szone zones are encountered. - */ - -uintptr_t -malloc_freezedry(void) -{ - extern unsigned malloc_num_zones; - extern malloc_zone_t **malloc_zones; - malloc_frozen *data; - unsigned i; - - /* Allocate space in which to store the freezedry state. */ - data = (malloc_frozen *) malloc(sizeof(malloc_frozen)); - - /* Set freezedry version number so that malloc_jumpstart() can check for compatibility. */ - data->version = MALLOC_FREEZEDRY_VERSION; - - /* Allocate the array of szone pointers. */ - data->nszones = malloc_num_zones; - data->szones = (szone_t *) calloc(malloc_num_zones, sizeof(szone_t)); - - /* - * Fill in the array of szone structures. They are copied rather than - * referenced, since the originals are likely to be clobbered during malloc - * initialization. - */ - for (i = 0; i < malloc_num_zones; i++) { - if (strcmp(malloc_zones[i]->zone_name, "DefaultMallocZone")) { - /* Unknown zone type. */ - free(data->szones); - free(data); - return 0; - } - memcpy(&data->szones[i], malloc_zones[i], sizeof(szone_t)); - } - - return((uintptr_t)data); -} - -int -malloc_jumpstart(uintptr_t cookie) -{ - malloc_frozen *data = (malloc_frozen *)cookie; - unsigned i; - - if (data->version != MALLOC_FREEZEDRY_VERSION) { - /* Unsupported freezedry version. */ - return 1; - } - - for (i = 0; i < data->nszones; i++) { - /* Set function pointers. Even the functions that stay the same must be - * set, since there are no guarantees that they will be mapped to the - * same addresses. */ - data->szones[i].basic_zone.size = (void *) szone_size; - data->szones[i].basic_zone.malloc = (void *) frozen_malloc; - data->szones[i].basic_zone.calloc = (void *) frozen_calloc; - data->szones[i].basic_zone.valloc = (void *) frozen_valloc; - data->szones[i].basic_zone.free = (void *) frozen_free; - data->szones[i].basic_zone.realloc = (void *) frozen_realloc; - data->szones[i].basic_zone.destroy = (void *) frozen_destroy; - data->szones[i].basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; - - /* Register the freezedried zone. */ - malloc_zone_register(&data->szones[i].basic_zone); - } - - return 0; -} - diff --git a/src/libc/gen/scalable_malloc.h b/src/libc/gen/scalable_malloc.h deleted file mode 100644 index d6cf189cf..000000000 --- a/src/libc/gen/scalable_malloc.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#define SCALABLE_MALLOC_ADD_GUARD_PAGES (1 << 0) - // add a guard page before and after each VM region to help debug -#define SCALABLE_MALLOC_DONT_PROTECT_PRELUDE (1 << 1) - // do not protect prelude page -#define SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE (1 << 2) - // do not protect postlude page -#define SCALABLE_MALLOC_DO_SCRIBBLE (1 << 3) - // write 0x55 onto free blocks -#define SCALABLE_MALLOC_ABORT_ON_ERROR (1 << 4) - // call abort() on any malloc error, such as double free or out of memory. -#define SCALABLE_MALLOC_PURGEABLE (1 << 5) - // allocate objects such that they may be used with VM purgability APIs -#define SCALABLE_MALLOC_ABORT_ON_CORRUPTION (1 << 6) - // call abort() on malloc errors, but not on out of memory. - -extern malloc_zone_t *create_scalable_zone(size_t initial_size, unsigned debug_flags); - /* Create a new zone that scales for small objects or large objects */ - -extern malloc_zone_t *create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags); - /* Create a new zone that supports malloc_make{un}purgeable() discipline. */ - -extern malloc_zone_t *create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags); - /* - * For use by CheckFix: create a new zone whose behavior is, apart from - * the use of death-row and per-CPU magazines, that of Leopard. - */ - -/***** Private API for debug and performance tools ********/ - -extern boolean_t scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone); - /* Fills stats with some statistics; - 1 is returned on success; else 0 is returned - Currently: subzone=0 => tiny; subzone=1 => small; subzone=2 => large; subzone=3 => huge; any other subzone => returns 0 - */ - diff --git a/src/libc/gen/setlogin.c b/src/libc/gen/setlogin.c index eb3495a46..b81cb1fc9 100644 --- a/src/libc/gen/setlogin.c +++ b/src/libc/gen/setlogin.c @@ -55,12 +55,25 @@ #include +#include +#include +#include extern int __setlogin(const char* name); -extern int _logname_valid; /* shared with getlogin() */ +extern pthread_mutex_t __logname_mutex; +extern char *__logname; int setlogin(const char* name) { - return (_logname_valid = __setlogin(name)); + pthread_mutex_lock(&__logname_mutex); + + int res = __setlogin(name); + if (res == 0 && __logname != NULL) { + __logname[0] = 0; + } + + pthread_mutex_unlock(&__logname_mutex); + + return res; } diff --git a/src/libc/gen/stack_logging.c b/src/libc/gen/stack_logging.c deleted file mode 100644 index 6fcc0b519..000000000 --- a/src/libc/gen/stack_logging.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 1999, 2000, 2002-2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* Bertrand from vmutils -> CF -> System */ - -#import "stack_logging.h" -#import "malloc_printf.h" - -#import -#import -#import -#include -#import -#import -#import - -extern void spin_lock(int *); -extern void spin_unlock(int *); -extern void thread_stack_pcs(vm_address_t *, unsigned, unsigned *); - -static inline void *allocate_pages(unsigned) __attribute__((always_inline)); -static inline void *allocate_pages(unsigned bytes) { - void *address; - if (vm_allocate(mach_task_self(), (vm_address_t *)&address, bytes, - VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)| TRUE)) { - malloc_printf("*** out of memory while stack logging\n"); - CRSetCrashLogMessage("*** out of memory while stack logging\n"); - abort(); - } - return (void *)address; -} - -static inline void deallocate_pages(void *, unsigned) __attribute__((always_inline)); -static inline void deallocate_pages(void *ptr, unsigned bytes) { - vm_deallocate(mach_task_self(), (vm_address_t)ptr, bytes); -} - -static inline void copy_pages(const void *, void *, unsigned) __attribute__((always_inline)); -static inline void copy_pages(const void *source, void *dest, unsigned bytes) { - if (vm_copy(mach_task_self(), (vm_address_t)source, bytes, (vm_address_t)dest)) memmove(dest, source, bytes); -} - -/*************** Uniquing stack ***********/ - -#define MAX_COLLIDE 8 - -#define MAX_NUM_PC 512 - -static int enter_pair_in_table(unsigned *table, unsigned numPages, unsigned *uniquedParent, unsigned thisPC) { - // uniquedParent is in-out; return 1 is collisions max not exceeded - unsigned base = numPages * vm_page_size / (sizeof(int)*2*2); - unsigned hash = base + (((*uniquedParent) << 4) ^ (thisPC >> 2)) % (base - 1); // modulo odd number for hashing - unsigned collisions = MAX_COLLIDE; - while (collisions--) { - unsigned *head = table + hash*2; - if (! head[0] && !head[1]) { - /* end of chain; store this entry! */ - /* Note that we need to test for both head[0] and head[1] as (0, -1) is a valid entry */ - head[0] = thisPC; - head[1] = *uniquedParent; - *uniquedParent = hash; - return 1; - } - if ((head[0] == thisPC) && (head[1] == *uniquedParent)) { - /* we found the proper entry, the value for the pair is the entry offset */ - *uniquedParent = hash; - return 1; - } - hash++; - if (hash == base*2) hash = base; - } - return 0; -} - -unsigned stack_logging_get_unique_stack(unsigned **table, unsigned *table_num_pages, unsigned *stack_entries, unsigned count, unsigned num_hot_to_skip) { - unsigned uniquedParent = (unsigned)-1; - // we skip the warmest entries that are an artefact of the code - while (num_hot_to_skip--) { - if (count > 0) { stack_entries++; count--; } - } - while (count--) { - unsigned thisPC = stack_entries[count]; - while (!enter_pair_in_table(*table, *table_num_pages, &uniquedParent, thisPC)) { - unsigned *newTable; - unsigned oldBytes = (*table_num_pages) * vm_page_size; - newTable = allocate_pages(oldBytes*2); - copy_pages(*table, newTable, oldBytes); - deallocate_pages(*table, oldBytes); - *table_num_pages *= 2; - *table = newTable; - } - } - return uniquedParent; -} - -/*************** Logging stack and arguments ***********/ - -stack_logging_record_list_t *stack_logging_the_record_list = NULL; - -int stack_logging_enable_logging = 0; -int stack_logging_dontcompact = 0; -int stack_logging_finished_init = 0; -int stack_logging_postponed = 0; - -static int stack_logging_spin_lock = 0; - -static stack_logging_record_list_t *GrowLogRecords(stack_logging_record_list_t *records, unsigned desiredNumRecords) { - stack_logging_record_list_t *new_records; - unsigned old_size = records->overall_num_bytes; - if (desiredNumRecords*sizeof(stack_logging_record_t)+sizeof(stack_logging_record_list_t) < records->overall_num_bytes) return records; - records->overall_num_bytes += records->overall_num_bytes + vm_page_size; // in order to always get an even number of pages - new_records = allocate_pages(records->overall_num_bytes); - copy_pages(records, new_records, old_size); - deallocate_pages(records, old_size); - return new_records; -} - -static void prepare_to_log_stack(void) { - if (!stack_logging_the_record_list) { - unsigned totalSize = 4 * vm_page_size; - stack_logging_the_record_list = allocate_pages(totalSize); - memset(stack_logging_the_record_list, 0, sizeof(stack_logging_record_list_t)); - stack_logging_the_record_list->overall_num_bytes = totalSize; - stack_logging_the_record_list->uniquing_table_num_pages = 128; - stack_logging_the_record_list->uniquing_table = allocate_pages(stack_logging_the_record_list->uniquing_table_num_pages * vm_page_size); - } -} - -void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_to_skip) { - stack_logging_record_t *rec; - if (!stack_logging_enable_logging) return; - // printf("stack_logging_log_stack 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result); - if (type & stack_logging_flag_zone) { - // just process it now and be done with it! - arg1 = arg2; arg2 = arg3; arg3 = 0; type &= ~stack_logging_flag_zone; - } - if (type & stack_logging_flag_calloc) { - // just process it now and be done with it! - arg1 *= arg2; arg2 = arg3; arg3 = 0; type &= ~stack_logging_flag_calloc; - } - if (type & stack_logging_flag_object) { - unsigned *class = (unsigned *)(uintptr_t)arg1; - arg1 = arg2 + class[5]; // corresponds to the instance_size field - arg2 = 0; arg3 = 0; type = stack_logging_type_alloc; - } - if (type & stack_logging_flag_cleared) { - type &= ~stack_logging_flag_cleared; - } - if (type & stack_logging_flag_handle) { - if (stack_logging_type_alloc) { - if (!result) return; - stack_logging_log_stack(stack_logging_type_alloc, 0, 0, 0, result, num_hot_to_skip+1); - stack_logging_log_stack(stack_logging_type_alloc, arg1, 0, 0, *((int *)(uintptr_t)result), num_hot_to_skip+1); - return; - } - if (stack_logging_type_dealloc) { - if (!arg1) return; - stack_logging_log_stack(stack_logging_type_dealloc, *((int *)(uintptr_t)arg1), 0, 0, 0, num_hot_to_skip+1); - stack_logging_log_stack(stack_logging_type_dealloc, arg1, 0, 0, 0, num_hot_to_skip+1); - return; - } - fprintf(stderr, "*** Unknown logging type: 0x%x\n", type); - } - if (type == stack_logging_flag_set_handle_size) { - if (!arg1) return; - // Thanks to a horrible hack, arg3 contains the prvious handle value - if (arg3 == *((int *)(uintptr_t)arg1)) return; - stack_logging_log_stack(stack_logging_type_dealloc, arg3, 0, 0, 0, num_hot_to_skip+1); - stack_logging_log_stack(stack_logging_type_alloc, arg2, 0, 0, *((int *)(uintptr_t)arg1), num_hot_to_skip+1); - return; - } - if (type == (stack_logging_type_dealloc|stack_logging_type_alloc)) { - if (arg1 == result) return; // realloc had no effect, skipping - if (!arg1) { - // realloc(NULL, size) same as malloc(size) - type = stack_logging_type_alloc; arg1 = arg2; arg2 = arg3; arg3 = 0; - } else { - // realloc(arg1, arg2) -> result is same as free(arg1); malloc(arg2) -> result - stack_logging_log_stack(stack_logging_type_dealloc, arg1, 0, 0, 0, num_hot_to_skip+1); - stack_logging_log_stack(stack_logging_type_alloc, arg2, 0, 0, result, num_hot_to_skip+1); - return; - } - } - if (type == stack_logging_type_dealloc) { - // simple free - if (!arg1) return; // free(nil) - } - prepare_to_log_stack(); - spin_lock(&stack_logging_spin_lock); - stack_logging_the_record_list = GrowLogRecords(stack_logging_the_record_list, stack_logging_the_record_list->num_records + 1); - rec = stack_logging_the_record_list->records + stack_logging_the_record_list->num_records; - // We take care of the common case of alloc-dealloc - if (!stack_logging_dontcompact && stack_logging_the_record_list->num_records && (type == stack_logging_type_dealloc) && arg1 && ((rec-1)->type == stack_logging_type_alloc) && (arg1 == STACK_LOGGING_DISGUISE((rec-1)->address))) { - stack_logging_the_record_list->num_records--; - // printf("Erased previous record in alloc-dealloc sequence\n"); - } else { - unsigned stack_entries[MAX_NUM_PC]; - unsigned count = 0; - rec->type = type; - if (type == stack_logging_type_dealloc) { - rec->argument = 0; - rec->address = STACK_LOGGING_DISGUISE(arg1); // we disguise the address - } else if (type == stack_logging_type_alloc) { - rec->argument = arg1; - rec->address = STACK_LOGGING_DISGUISE(result); // we disguise the address - } else { - rec->argument = arg2; - rec->address = STACK_LOGGING_DISGUISE(arg1); // we disguise the address - } - // printf("Before getting samples 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result); - thread_stack_pcs((vm_address_t *)stack_entries, MAX_NUM_PC - 1, &count); - // We put at the bottom of the stack a marker that denotes the thread (+1 for good measure...) - stack_entries[count++] = (int)(uintptr_t)pthread_self() + 1; - /* now let's unique the sample */ - // printf("Uniquing 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result); - rec->uniqued_stack = stack_logging_get_unique_stack(&stack_logging_the_record_list->uniquing_table, &stack_logging_the_record_list->uniquing_table_num_pages, stack_entries, count, num_hot_to_skip+2); // we additionally skip the warmest 2 entries that are an artefact of the code - stack_logging_the_record_list->num_records++; - } - spin_unlock(&stack_logging_spin_lock); -} - -static kern_return_t default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) { - *ptr = (void *)address; - return 0; -} - -static kern_return_t get_remote_records(task_t task, memory_reader_t reader, stack_logging_record_list_t **records) { - // sets records - vm_address_t *remote_records_address_ref; - kern_return_t err; - *records = NULL; - err = reader(task, (vm_address_t)&stack_logging_the_record_list, sizeof(vm_address_t), (void **)&remote_records_address_ref); - if (err) return err; - if (!*remote_records_address_ref) { - // printf("stack_logging: no stack record\n"); - return 0; - } - // printf("stack_logging: stack records at %p\n", (void *)(*remote_records_address_ref)); - // printf("stack_logging: reading %d bytes\n", sizeof(stack_logging_record_list_t)); - err = reader(task, *remote_records_address_ref, sizeof(stack_logging_record_list_t), (void **)records); // get the list head - if (err) return err; - // printf("stack_logging: overall num bytes = %d\n", records->overall_num_bytes); - return reader(task, *remote_records_address_ref, (*records)->overall_num_bytes, (void **)records); -} - -kern_return_t stack_logging_get_frames(task_t task, memory_reader_t reader, vm_address_t address, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames) { - stack_logging_record_list_t *records; - kern_return_t err; - unsigned index; - unsigned disguised = STACK_LOGGING_DISGUISE(address); - if (!reader) reader = default_reader; - *num_frames = 0; - err = get_remote_records(task, reader, &records); - if (err || !records) return err; - // printf("stack_logging: %d records\n", records->num_records); - index = 0; - while (index < records->num_records) { - stack_logging_record_t *record = records->records + index; - if (record->address == disguised) { - return stack_logging_frames_for_uniqued_stack(task, reader, record->uniqued_stack, stack_frames_buffer, max_stack_frames, num_frames); - } - index++; - } - fprintf(stderr, "*** stack_logging: no record found for %p\n", address); - return 0; -} - -kern_return_t stack_logging_enumerate_records(task_t task, memory_reader_t reader, vm_address_t address, void enumerator(stack_logging_record_t, void *), void *context) { - stack_logging_record_list_t *records; - kern_return_t err; - unsigned index; - unsigned disguised = STACK_LOGGING_DISGUISE(address); - if (!reader) reader = default_reader; - err = get_remote_records(task, reader, &records); - if (err || !records) return err; - // printf("stack_logging: %d records\n", records->num_records); - index = 0; - while (index < records->num_records) { - stack_logging_record_t *record = records->records + index; - if (!address || (record->address == disguised)) enumerator(*record, context); - index++; - } - return 0; -} - -kern_return_t stack_logging_frames_for_uniqued_stack(task_t task, memory_reader_t reader, unsigned uniqued_stack, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames) { - stack_logging_record_list_t *records; - unsigned *uniquing_table; - kern_return_t err; - if (!reader) reader = default_reader; - *num_frames = 0; - err = get_remote_records(task, reader, &records); - if (err || !records) return err; - err = reader(task, (vm_address_t)records->uniquing_table, records->uniquing_table_num_pages * vm_page_size, (void **)&uniquing_table); - if (err) return err; - while (max_stack_frames && (uniqued_stack != -1)) { - unsigned thisPC; - if ((uniqued_stack * 2 + 1) * sizeof(unsigned) >= records->uniquing_table_num_pages * vm_page_size) { - fprintf(stderr, "*** stack_logging: Invalid uniqued stack 0x%x", uniqued_stack); - break; - } - thisPC = uniquing_table[uniqued_stack * 2]; - uniqued_stack = uniquing_table[uniqued_stack * 2 + 1]; - if (!thisPC && !uniqued_stack) { - // Invalid entry - fprintf(stderr, "*** stack_logging: Invalid entry 0x%x", thisPC); - break; - } - stack_frames_buffer[0] = thisPC; - stack_frames_buffer++; - (*num_frames)++; - max_stack_frames--; - } - return 0; -} diff --git a/src/libc/gen/stack_logging.h b/src/libc/gen/stack_logging.h deleted file mode 100644 index 5f0137ab7..000000000 --- a/src/libc/gen/stack_logging.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#define stack_logging_type_free 0 -#define stack_logging_type_generic 1 /* anything that is not allocation/deallocation */ -#define stack_logging_type_alloc 2 /* malloc, realloc, etc... */ -#define stack_logging_type_dealloc 4 /* free, realloc, etc... */ - -// Following flags are absorbed by stack_logging_log_stack() -#define stack_logging_flag_zone 8 /* NSZoneMalloc, etc... */ -#define stack_logging_flag_calloc 16 /* multiply arguments to get the size */ -#define stack_logging_flag_object 32 /* NSAllocateObject(Class, extraBytes, zone) */ -#define stack_logging_flag_cleared 64 /* for NewEmptyHandle */ -#define stack_logging_flag_handle 128 /* for Handle (de-)allocation routines */ -#define stack_logging_flag_set_handle_size 256 /* (Handle, newSize) treated specially */ - -/* Macro used to disguise addresses so that leak finding can work */ -#define STACK_LOGGING_DISGUISE(address) ((address) ^ 0x00005555) /* nicely idempotent */ - -extern int stack_logging_enable_logging; /* when clear, no logging takes place */ -extern int stack_logging_dontcompact; /* default is to compact; when set does not compact alloc/free logs; useful for tracing history */ -extern int stack_logging_finished_init; /* set after we've returned from the Libsystem initialiser */ -extern int stack_logging_postponed; /* set if we needed to postpone logging till after initialisation */ - - -extern void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_to_skip); - /* This is the old log-to-memory logger, which is now deprecated. It remains for compatibility with performance tools that haven't been updated to disk_stack_logging_log_stack() yet. */ - -extern void __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip); - /* Fits as the malloc_logger; logs malloc/free/realloc events and can log custom events if called directly */ - - -/* 64-bit-aware stack log access. As new SPI, these routines are prefixed with double-underscore to avoid conflict with Libsystem clients. */ - -typedef struct { - uint32_t type_flags; - uint64_t stack_identifier; - uint64_t argument; - mach_vm_address_t address; -} mach_stack_logging_record_t; - -extern kern_return_t __mach_stack_logging_set_file_path(task_t task, char* file_path); - -extern kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); - /* Gets the last allocation record (malloc, realloc, or free) about address */ - -extern kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context); - /* Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records */ - -extern kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); - /* Given a uniqued_stack fills stack_frames_buffer */ - - -#pragma mark - -#pragma mark Legacy - -/* The following is the old 32-bit-only, in-process-memory stack logging. This is deprecated and clients should move to the above 64-bit-aware disk stack logging SPI. */ - -typedef struct { - unsigned type; - unsigned uniqued_stack; - unsigned argument; - unsigned address; /* disguised, to avoid confusing leaks */ -} stack_logging_record_t; - -typedef struct { - unsigned overall_num_bytes; - unsigned num_records; - unsigned lock; /* 0 means OK to lock; used for inter-process locking */ - unsigned *uniquing_table; /* allocated using vm_allocate() */ - /* hashtable organized as (PC, uniqued parent) - Only the second half of the table is active - To enable us to grow dynamically */ - unsigned uniquing_table_num_pages; /* number of pages of the table */ - unsigned extra_retain_count; /* not used by stack_logging_log_stack */ - unsigned filler[2]; /* align to cache lines for better performance */ - stack_logging_record_t records[0]; /* records follow here */ -} stack_logging_record_list_t; - -extern stack_logging_record_list_t *stack_logging_the_record_list; - /* This is the global variable containing all logs */ - -extern kern_return_t stack_logging_get_frames(task_t task, memory_reader_t reader, vm_address_t address, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames); - /* Gets the last record in stack_logging_the_record_list about address */ - -#define STACK_LOGGING_ENUMERATION_PROVIDED 1 // temporary to avoid dependencies between projects - -extern kern_return_t stack_logging_enumerate_records(task_t task, memory_reader_t reader, vm_address_t address, void enumerator(stack_logging_record_t, void *), void *context); - /* Gets all the records about address; - If !address, gets all records */ - -extern kern_return_t stack_logging_frames_for_uniqued_stack(task_t task, memory_reader_t reader, unsigned uniqued_stack, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames); - /* Given a uniqued_stack fills stack_frames_buffer */ - - - -extern void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *num); - /* Convenience to fill buffer with the PCs of the frames, starting with the hot frames; - num: returned number of frames - */ - diff --git a/src/libc/gen/stack_logging_disk.c b/src/libc/gen/stack_logging_disk.c deleted file mode 100644 index e5ef9a68f..000000000 --- a/src/libc/gen/stack_logging_disk.c +++ /dev/null @@ -1,1729 +0,0 @@ -/* - * Copyright (c) 2007-2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "stack_logging.h" -#include "malloc_printf.h" -#include "_simple.h" // as included by malloc.c, this defines ASL_LEVEL_INFO - -#pragma mark - -#pragma mark Defines - -#ifdef TEST_DISK_STACK_LOGGING -#define _malloc_printf fprintf -#undef ASL_LEVEL_INFO -#define ASL_LEVEL_INFO stderr -#else -#define _malloc_printf malloc_printf -#endif - -#define STACK_LOGGING_MAX_STACK_SIZE 512 -#define STACK_LOGGING_BLOCK_WRITING_SIZE 8192 -#define STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED 3 - -#define BACKTRACE_UNIQUING_DEBUG 0 - -// The expansion factor controls the shifting up of table size. A factor of 1 will double the size upon expanding, -// 2 will quadruple the size, etc. Maintaining a 66% fill in an ideal table requires the collision allowance to -// increase by 3 for every quadrupling of the table size (although this the constant applied to insertion -// performance O(c*n)) -#define EXPAND_FACTOR 2 -#define COLLISION_GROWTH_RATE 3 - -// For a uniquing table, the useful node size is slots := floor(table_byte_size / (2 * sizeof(mach_vm_address_t))) -// Some useful numbers for the initial max collision value (desiring 66% fill): -// 16K-23K slots -> 16 collisions -// 24K-31K slots -> 17 collisions -// 32K-47K slots -> 18 collisions -// 48K-79K slots -> 19 collisions -// 80K-96K slots -> 20 collisions -#define INITIAL_MAX_COLLIDE 19 -#define DEFAULT_UNIQUING_PAGE_SIZE 256 - -#pragma mark - -#pragma mark Macros - -#define STACK_LOGGING_FLAGS(longlongvar) (uint8_t)((uint64_t)(longlongvar) >> 56) -#define STACK_LOGGING_OFFSET(longlongvar) ((longlongvar) & 0x00FFFFFFFFFFFFFFull) -#define STACK_LOGGING_OFFSET_AND_FLAGS(longlongvar, realshortvar) (((uint64_t)(longlongvar) & 0x00FFFFFFFFFFFFFFull) | ((uint64_t)(realshortvar) << 56)) - -#pragma mark - -#pragma mark Types - -typedef struct { - uintptr_t argument; - uintptr_t address; - uint64_t offset_and_flags; // top 8 bits are actually the flags! -} stack_logging_index_event; - -typedef struct { - uint32_t argument; - uint32_t address; - uint64_t offset_and_flags; // top 8 bits are actually the flags! -} stack_logging_index_event32; - -typedef struct { - uint64_t argument; - uint64_t address; - uint64_t offset_and_flags; // top 8 bits are actually the flags! -} stack_logging_index_event64; - -#pragma pack(push,4) -typedef struct { - uint64_t numPages; // number of pages of the table - uint64_t numNodes; - uint64_t tableSize; - uint64_t untouchableNodes; - mach_vm_address_t table_address; - int32_t max_collide; - // 'table_address' is just an always 64-bit version of the pointer-sized 'table' field to remotely read; - // it's important that the offset of 'table_address' in the struct does not change between 32 and 64-bit. -#if BACKTRACE_UNIQUING_DEBUG - uint64_t nodesFull; - uint64_t backtracesContained; -#endif - mach_vm_address_t *table; // allocated using vm_allocate() -} backtrace_uniquing_table; -#pragma pack(pop) - -// for storing/looking up allocations that haven't yet be written to disk; consistent size across 32/64-bit processes. -// It's important that these fields don't change alignment due to the architecture because they may be accessed from an -// analyzing process with a different arch - hence the pragmas. -#pragma pack(push,4) -typedef struct { - uint64_t start_index_offset; - uint32_t next_free_index_buffer_offset; - mach_vm_address_t uniquing_table_address; - char index_buffer[STACK_LOGGING_BLOCK_WRITING_SIZE]; - backtrace_uniquing_table *uniquing_table; -} stack_buffer_shared_memory; -#pragma pack(pop) - -// target process address -> record table (for __mach_stack_logging_get_frames) -typedef struct { - uint64_t address; - uint64_t index_file_offset; -} remote_index_node; - -// for caching index information client-side: -typedef struct { - size_t cache_size; - size_t cache_node_capacity; - uint32_t collision_allowance; - remote_index_node *table_memory; // this can be malloced; it's on the client side. - stack_buffer_shared_memory *shmem; // shared memory - stack_buffer_shared_memory snapshot; // memory snapshot of the remote process' shared memory - uint32_t last_pre_written_index_size; - uint64_t last_index_file_offset; - backtrace_uniquing_table uniquing_table; // snapshot of the remote process' uniquing table -} remote_index_cache; - -// for reading stack history information from remote processes: -typedef struct { - task_t remote_task; - pid_t remote_pid; - int32_t task_is_64_bit; - int32_t in_use_count; - FILE *index_file_stream; - remote_index_cache *cache; -} remote_task_file_streams; - -#pragma mark - -#pragma mark Constants/Globals - -static OSSpinLock stack_logging_lock = OS_SPINLOCK_INIT; - -// support for multi-threaded forks -extern void __stack_logging_fork_prepare(); -extern void __stack_logging_fork_parent(); -extern void __stack_logging_fork_child(); -extern void __stack_logging_early_finished(); - -// support for gdb and others checking for stack_logging locks -__private_extern__ boolean_t __stack_logging_locked(); - -// single-thread access variables -static stack_buffer_shared_memory *pre_write_buffers; -static vm_address_t *stack_buffer; -static uintptr_t last_logged_malloc_address = 0; - -// Constants to define stack logging file path names. -// Files will get written as /tmp/stack-logs...XXXXXX.index -// unless the base directory is specified otherwise with MallocStackLoggingDirectory. -// In this case, a file /tmp/stack-logs...XXXXXX.link will also be created. -static const char *stack_log_file_base_name = "stack-logs."; -static const char *stack_log_file_suffix = ".index"; -static const char *stack_log_link_suffix = ".link"; - -static void *stack_log_path_buffers = NULL; -static char *stack_log_location = NULL; -static char *stack_log_reference_file = NULL; -char *__stack_log_file_path__ = NULL; -static int index_file_descriptor = -1; - -// for accessing remote log files -static remote_task_file_streams remote_fds[STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED]; -static uint32_t next_remote_task_fd = 0; -static uint32_t remote_task_fd_count = 0; -static OSSpinLock remote_fd_list_lock = OS_SPINLOCK_INIT; - -// activation variables -static int logging_use_compaction = 1; // set this to zero to always disable compaction. - -// We set malloc_logger to NULL to disable logging, if we encounter errors -// during file writing -typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip); -extern malloc_logger_t *malloc_logger; - -#pragma mark - -#pragma mark In-Memory Backtrace Uniquing - -static __attribute__((always_inline)) -inline void* -allocate_pages(uint64_t memSize) -{ - mach_vm_address_t allocatedMem = 0ull; - if (mach_vm_allocate(mach_task_self(), &allocatedMem, memSize, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)) != KERN_SUCCESS) { - malloc_printf("allocate_pages(): virtual memory exhaused!\n"); - } - return (void*)(uintptr_t)allocatedMem; -} - -static __attribute__((always_inline)) -inline int -deallocate_pages(void* memPointer, uint64_t memSize) -{ - return mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)memPointer, memSize); -} - -static backtrace_uniquing_table* -__create_uniquing_table(void) -{ - backtrace_uniquing_table *uniquing_table = (backtrace_uniquing_table*)allocate_pages((uint64_t)round_page(sizeof(backtrace_uniquing_table))); - if (!uniquing_table) return NULL; - bzero(uniquing_table, sizeof(backtrace_uniquing_table)); - uniquing_table->numPages = DEFAULT_UNIQUING_PAGE_SIZE; - uniquing_table->tableSize = uniquing_table->numPages * vm_page_size; - uniquing_table->numNodes = ((uniquing_table->tableSize / (sizeof(mach_vm_address_t) * 2)) >> 1) << 1; // make sure it's even. - uniquing_table->table = (mach_vm_address_t*)(uintptr_t)allocate_pages(uniquing_table->tableSize); - uniquing_table->table_address = (uintptr_t)uniquing_table->table; - uniquing_table->max_collide = INITIAL_MAX_COLLIDE; - uniquing_table->untouchableNodes = 0; - -#if BACKTRACE_UNIQUING_DEBUG - malloc_printf("create_uniquing_table(): creating. size: %lldKB == %lldMB, numnodes: %lld (%lld untouchable)\n", uniquing_table->tableSize >> 10, uniquing_table->tableSize >> 20, uniquing_table->numNodes, uniquing_table->untouchableNodes); - malloc_printf("create_uniquing_table(): table: %p; end: %p\n", uniquing_table->table, (void*)((uintptr_t)uniquing_table->table + (uintptr_t)uniquing_table->tableSize)); -#endif - return uniquing_table; -} - -static void -__destroy_uniquing_table(backtrace_uniquing_table* table) -{ - deallocate_pages(table->table, table->tableSize); - deallocate_pages(table, sizeof(backtrace_uniquing_table)); -} - -static void -__expand_uniquing_table(backtrace_uniquing_table *uniquing_table) -{ - mach_vm_address_t *oldTable = uniquing_table->table; - uint64_t oldsize = uniquing_table->tableSize; - uint64_t oldnumnodes = uniquing_table->numNodes; - - uniquing_table->numPages = uniquing_table->numPages << EXPAND_FACTOR; - uniquing_table->tableSize = uniquing_table->numPages * vm_page_size; - uniquing_table->numNodes = ((uniquing_table->tableSize / (sizeof(mach_vm_address_t) * 2)) >> 1) << 1; // make sure it's even. - mach_vm_address_t *newTable = (mach_vm_address_t*)(uintptr_t)allocate_pages(uniquing_table->tableSize); - - uniquing_table->table = newTable; - uniquing_table->table_address = (uintptr_t)uniquing_table->table; - uniquing_table->max_collide = uniquing_table->max_collide + COLLISION_GROWTH_RATE; - - if (mach_vm_copy(mach_task_self(), (mach_vm_address_t)(uintptr_t)oldTable, oldsize, (mach_vm_address_t)(uintptr_t)newTable) != KERN_SUCCESS) { - malloc_printf("expandUniquingTable(): VMCopyFailed\n"); - } - uniquing_table->untouchableNodes = oldnumnodes; - -#if BACKTRACE_UNIQUING_DEBUG - malloc_printf("expandUniquingTable(): expanded from nodes full: %lld of: %lld (~%2d%%); to nodes: %lld (inactive = %lld); unique bts: %lld\n", - uniquing_table->nodesFull, oldnumnodes, (int)(((uniquing_table->nodesFull * 100.0) / (double)oldnumnodes) + 0.5), - uniquing_table->numNodes, uniquing_table->untouchableNodes, uniquing_table->backtracesContained); - malloc_printf("expandUniquingTable(): allocate: %p; end: %p\n", newTable, (void*)((uintptr_t)newTable + (uintptr_t)(uniquing_table->tableSize))); - malloc_printf("expandUniquingTable(): deallocate: %p; end: %p\n", oldTable, (void*)((uintptr_t)oldTable + (uintptr_t)oldsize)); -#endif - - if (deallocate_pages(oldTable, oldsize) != KERN_SUCCESS) { - malloc_printf("expandUniquingTable(): mach_vm_deallocate failed. [%p]\n", uniquing_table->table); - } -} - -static int -__enter_frames_in_table(backtrace_uniquing_table *uniquing_table, uint64_t *foundIndex, mach_vm_address_t *frames, int32_t count) -{ - // The hash values need to be the same size as the addresses (because we use the value -1), for clarity, define a new type - typedef mach_vm_address_t hash_index_t; - - mach_vm_address_t thisPC; - hash_index_t hash, uParent = (hash_index_t)(-1ll), modulus = (uniquing_table->numNodes-uniquing_table->untouchableNodes-1); - int32_t collisions, lcopy = count, returnVal = 1; - hash_index_t hash_multiplier = ((uniquing_table->numNodes - uniquing_table->untouchableNodes)/(uniquing_table->max_collide*2+1)); - mach_vm_address_t *node; - while (--lcopy >= 0) { - thisPC = frames[lcopy]; - - // hash = initialHash(uniquing_table, uParent, thisPC); - hash = uniquing_table->untouchableNodes + (((uParent << 4) ^ (thisPC >> 2)) % modulus); - collisions = uniquing_table->max_collide; - - while (collisions--) { - node = uniquing_table->table + (hash * 2); - - if (*node == 0 && node[1] == 0) { - // blank; store this entry! - // Note that we need to test for both head[0] and head[1] as (0, -1) is a valid entry - node[0] = thisPC; - node[1] = uParent; - uParent = hash; -#if BACKTRACE_UNIQUING_DEBUG - uniquing_table->nodesFull++; - if (lcopy == 0) { - uniquing_table->backtracesContained++; - } -#endif - break; - } - if (*node == thisPC && node[1] == uParent) { - // hit! retrieve index and go. - uParent = hash; - break; - } - - hash += collisions * hash_multiplier + 1; - - if (hash >= uniquing_table->numNodes) { - hash -= (uniquing_table->numNodes - uniquing_table->untouchableNodes); // wrap around. - } - } - - if (collisions < 0) { - returnVal = 0; - break; - } - } - - if (returnVal) *foundIndex = uParent; - - return returnVal; -} - -static void -__unwind_stack_from_table_index(backtrace_uniquing_table *uniquing_table, uint64_t index_pos, mach_vm_address_t *out_frames_buffer, uint32_t *out_frames_count, uint32_t max_frames) -{ - mach_vm_address_t *node = uniquing_table->table + (index_pos * 2); - uint32_t foundFrames = 0; - if (index_pos < uniquing_table->numNodes) { - while (foundFrames < max_frames) { - out_frames_buffer[foundFrames++] = node[0]; - if (node[1] == (mach_vm_address_t)(-1ll)) break; - node = uniquing_table->table + (node[1] * 2); - } - } - - *out_frames_count = foundFrames; -} - -#pragma mark - -#pragma mark Disk Stack Logging - -static void delete_log_files(void); // pre-declare -static int delete_logging_file(char *log_location); - -static void -append_int(char * filename, pid_t pid, size_t maxLength) -{ - size_t len = strlen(filename); - - uint32_t count = 0; - pid_t value = pid; - while (value > 0) { - value /= 10; - count++; - } - - if (len + count >= maxLength) return; // don't modify the string if it would violate maxLength - - filename[len + count] = '\0'; - - value = pid; - uint32_t i; - for (i = 0 ; i < count ; i ++) { - filename[len + count - 1 - i] = '0' + value % 10; - value /= 10; - } -} - -/* - * if we needed to call confstr during init then setting this - * flag will postpone stack logging until after Libsystem's initialiser has run. - */ -static void -postpone_stack_logging(void) -{ - _malloc_printf(ASL_LEVEL_INFO, "stack logging postponed until after initialization.\n"); - stack_logging_postponed = 1; -} - -/* - * Check various temporary directory options starting with _PATH_TMP and use confstr. - * Allocating and releasing target buffer is the caller's responsibility. - */ -static bool -get_writeable_temp_dir(char* target) -{ - if (!target) return false; - if (-1 != access(_PATH_TMP, W_OK)) { - strlcpy(target, _PATH_TMP, (size_t)PATH_MAX); - return true; - } - if (getenv("TMPDIR") && (-1 != access(getenv("TMPDIR"), W_OK))) { - strlcpy(target, getenv("TMPDIR"), (size_t)PATH_MAX); - return true; - } - if (stack_logging_finished_init) { - size_t n = confstr(_CS_DARWIN_USER_TEMP_DIR, target, (size_t) PATH_MAX); - if ((n > 0) && (n < PATH_MAX)) return true; - n = confstr(_CS_DARWIN_USER_CACHE_DIR, target, (size_t) PATH_MAX); - if ((n > 0) && (n < PATH_MAX)) return true; - } else { - /* Can't call confstr during init, so postpone - logging till after */ - postpone_stack_logging(); - } - /* No writeable tmp directory found. Maybe shd try /private/var/tmp for device here ... */ - *target = '\0'; - return false; -} - -/* - * If successful, returns path to log file that was created, otherwise NULL. - * - * The log could be in one of 3 places (in decreasing order of preference) - * - * 1) value of environment variable MallocStackLoggingDirectory - * 2) the temp directory /tmp for desktop apps and internal apps on devices, or - * 3) the sandbox location + tmp/ in case of 3rd party apps on the device. - * - * For 1 and 3, we create a .link file with the path of the file. We prefer to - * create this file in /tmp, but if we are unable to (device 3rd party case), - * we create it in the same location as the .index file and issue a message - * in syslog asking for it to be copied to /tmp to enable tools. - * - */ -static char * -create_log_file(void) -{ - pid_t pid = getpid(); - const char *progname = getprogname(); - char *created_log_location = NULL; - - if (stack_log_path_buffers == NULL) { - /* - * on first use, allocate buffers directly from the OS without - * using malloc - */ - - stack_log_path_buffers = allocate_pages((uint64_t)round_page(3*PATH_MAX)); - if (stack_log_path_buffers == NULL) { - _malloc_printf(ASL_LEVEL_INFO, "unable to allocate memory for path buffers\n"); - return NULL; - } - - stack_log_location = &((char *)stack_log_path_buffers)[0*PATH_MAX]; - stack_log_reference_file = &((char *)stack_log_path_buffers)[1*PATH_MAX]; - __stack_log_file_path__ = &((char *)stack_log_path_buffers)[2*PATH_MAX]; - } - - // WARNING! use of snprintf can induce malloc() calls - bool use_alternate_location = false; - char *evn_log_directory = getenv("MallocStackLoggingDirectory"); - size_t stack_log_len; - if (evn_log_directory && *evn_log_directory) { - use_alternate_location = true; - strlcpy(stack_log_location, evn_log_directory, (size_t)PATH_MAX); - } - if (!use_alternate_location || (access(stack_log_location, W_OK) == -1)) { - if (!get_writeable_temp_dir(stack_log_location)) { - if (!stack_logging_postponed) { - _malloc_printf(ASL_LEVEL_INFO, "No writeable tmp dir\n"); - } - return NULL; - } - if (0 != strcmp(stack_log_location, _PATH_TMP)) - use_alternate_location = true; - } - stack_log_len = strlen(stack_log_location); - // add the '/' only if it's not already there. - if (stack_log_location[stack_log_len-1] != '/') { - strlcat(stack_log_location, "/", (size_t)PATH_MAX); - ++stack_log_len; - } - - strlcpy(__stack_log_file_path__, stack_log_location, (size_t)PATH_MAX); - - strlcat(__stack_log_file_path__, stack_log_file_base_name, (size_t)PATH_MAX); - append_int(__stack_log_file_path__, pid, (size_t)PATH_MAX); - if (progname && progname[0] != '\0') { - strlcat(__stack_log_file_path__, ".", (size_t)PATH_MAX); - strlcat(__stack_log_file_path__, progname, (size_t)PATH_MAX); - } - if (!use_alternate_location) strlcat(__stack_log_file_path__, ".XXXXXX", (size_t)PATH_MAX); - strlcat(__stack_log_file_path__, stack_log_file_suffix, (size_t)PATH_MAX); - - // Securely create the log file. - if ((index_file_descriptor = mkstemps(__stack_log_file_path__, (int)strlen(stack_log_file_suffix))) != -1) { - _malloc_printf(ASL_LEVEL_INFO, "stack logs being written into %s\n", __stack_log_file_path__); - created_log_location = __stack_log_file_path__; - } else { - _malloc_printf(ASL_LEVEL_INFO, "unable to create stack logs at %s\n", stack_log_location); - if (use_alternate_location) delete_logging_file(stack_log_reference_file); - stack_log_reference_file[0] = '\0'; - stack_log_location[0] = '\0'; - __stack_log_file_path__[0] = '\0'; - created_log_location = NULL; - return created_log_location; - } - - // in the case where the user has specified an alternate location, drop a reference file - // in /tmp with the suffix 'stack_log_link_suffix' (".link") and save the path of the - // stack logging file there. - bool use_alternate_link_location = false; - if (use_alternate_location) { - strlcpy(stack_log_reference_file, _PATH_TMP, (size_t)PATH_MAX); - if (access(stack_log_reference_file, W_OK) == -1) { - strlcpy(stack_log_reference_file, stack_log_location, (size_t)PATH_MAX); - use_alternate_link_location = true; - } - strlcat(stack_log_reference_file, stack_log_file_base_name, (size_t)PATH_MAX); - append_int(stack_log_reference_file, pid, (size_t)PATH_MAX); - if (progname && progname[0] != '\0') { - strlcat(stack_log_reference_file, ".", (size_t)PATH_MAX); - strlcat(stack_log_reference_file, progname, (size_t)PATH_MAX); - } - if (!use_alternate_link_location) - strlcat(stack_log_reference_file, ".XXXXXX", (size_t)PATH_MAX); - strlcat(stack_log_reference_file, ".XXXXXX", (size_t)PATH_MAX); - strlcat(stack_log_reference_file, stack_log_link_suffix, (size_t)PATH_MAX); - - int link_file_descriptor = mkstemps(stack_log_reference_file, (int)strlen(stack_log_link_suffix)); - if (link_file_descriptor == -1) { - _malloc_printf(ASL_LEVEL_INFO, "unable to create stack reference file %s at %s\n", - stack_log_reference_file, stack_log_location); - } else { - ssize_t written = write(link_file_descriptor, __stack_log_file_path__, strlen(__stack_log_file_path__)); - if (written < (ssize_t)strlen(__stack_log_file_path__)) { - _malloc_printf(ASL_LEVEL_INFO, "unable to write to stack reference file %s at %s\n", - stack_log_reference_file, stack_log_location); - } else { - const char *description_string = "\n(This is a reference file to the stack logs at the path above.)\n"; - write(link_file_descriptor, description_string, strlen(description_string)); - } - } - close(link_file_descriptor); - } - if (use_alternate_link_location) { - _malloc_printf(ASL_LEVEL_INFO, "Please issue: cp %s %s\n", stack_log_reference_file, _PATH_TMP); - } - return created_log_location; -} - -// Check to see if the log file is actually a reference to another location -static int -log_file_is_reference(char *log_location, char *out_reference_loc_buffer, size_t max_reference_path_size) -{ - if (log_location == NULL || log_location[0] == '\0') return 0; - - size_t log_len = strlen(log_location); - size_t link_suffix_len = strlen(stack_log_link_suffix); - if (log_len < link_suffix_len || strncmp(log_location+log_len-link_suffix_len, stack_log_link_suffix, link_suffix_len) != 0) { - // not a reference file. - return 0; - } - - if (!out_reference_loc_buffer || max_reference_path_size == 0) return 1; - - FILE *reference_file = fopen(log_location, "r"); - if (reference_file == NULL) { - // if unable to open the file, it may be because another user created it; no need to warn. - out_reference_loc_buffer[0] = '\0'; - return 1; - } - - char *ret = fgets(out_reference_loc_buffer, (int)max_reference_path_size, reference_file); - if (!ret) { - out_reference_loc_buffer[0] = '\0'; - _malloc_printf(ASL_LEVEL_INFO, "unable to read from stack logging reference file at %s\n", log_location); - return 1; - } else { - size_t read_line_len = strlen(out_reference_loc_buffer); - if (read_line_len >= 1 && out_reference_loc_buffer[read_line_len-1] == '\n') { - out_reference_loc_buffer[read_line_len-1] = '\0'; - } - } - - fclose(reference_file); - - return 1; -} - -// This function may be called from either the target process when exiting, or from either the the target process or -// a stack log analysis process, when reaping orphaned stack log files. -// Returns -1 if the files exist and they couldn't be removed, returns 0 otherwise. -static int -delete_logging_file(char *log_location) -{ - if (log_location == NULL || log_location[0] == '\0') return 0; - - struct stat statbuf; - if (unlink(log_location) != 0 && stat(log_location, &statbuf) == 0) { - return -1; - } - return 0; -} - -// This function will be called from atexit() in the target process. -static void -delete_log_files(void) -{ - if (__stack_log_file_path__ && __stack_log_file_path__[0]) { - if (delete_logging_file(__stack_log_file_path__) == 0) { - _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", __stack_log_file_path__); - __stack_log_file_path__[0] = '\0'; - } else { - _malloc_printf(ASL_LEVEL_INFO, "unable to delete stack logs from %s\n", __stack_log_file_path__); - } - } - if (stack_log_reference_file && stack_log_reference_file[0]) { - delete_logging_file(stack_log_reference_file); - } -} - -static bool -is_process_running(pid_t pid) -{ - struct kinfo_proc kpt[1]; - size_t size = sizeof(struct kinfo_proc); - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - - sysctl(mib, 4, kpt, &size, NULL, (size_t)0); // size is either 1 or 0 entries when we ask for a single pid - - return (size==sizeof(struct kinfo_proc)); -} - -// The log files can be quite large and aren't too useful after the process that created them no longer exists. -// Normally they should get removed when the process exits, but if the process crashed the log files might remain. -// So, reap any stack log files for processes that no longer exist. -// -// lf the remove_for_this_pid flag is set, then any log files that already exist for the current process will also be deleted. -// Those log files are probably the result of this process having been exec'ed from another one (without a fork()). -// The remove_for_this_pid flag is only set for a target process (one just starting logging); a stack logging "client" -// process reaps log files too, but if we're using stack logging on the client process itself, then we don't want to remove -// its own log files. -static void -reap_orphaned_log_files(bool remove_for_this_pid) -{ - DIR *dp; - struct dirent *entry; - char prefix_name[PATH_MAX]; - char pathname[PATH_MAX]; - pid_t current_pid = getpid(); - - if ((dp = opendir(_PATH_TMP)) == NULL) { - return; - } - - strlcpy(prefix_name, stack_log_file_base_name, (size_t)PATH_MAX); - size_t prefix_length = strlen(prefix_name); - - while ( (entry = readdir(dp)) != NULL ) { - if ( entry->d_type != DT_DIR && entry->d_type != DT_LNK && ( strncmp( entry->d_name, prefix_name, prefix_length) == 0 ) ) { - long pid = strtol(&entry->d_name[prefix_length], (char **)NULL, 10); - if ( (! is_process_running((pid_t)pid)) || (remove_for_this_pid && (pid_t)pid == current_pid) ) { - strlcpy(pathname, _PATH_TMP, (size_t)PATH_MAX); - strlcat(pathname, entry->d_name, (size_t)PATH_MAX); - char reference_file_buffer[PATH_MAX]; - bool pathname_is_ref_file = false; - if (log_file_is_reference(pathname, reference_file_buffer, (size_t)PATH_MAX) && *reference_file_buffer) { - pathname_is_ref_file = true; - if (delete_logging_file(reference_file_buffer) == 0) { - if (remove_for_this_pid && pid == current_pid) { - _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", reference_file_buffer); - } else { - _malloc_printf(ASL_LEVEL_INFO, "process %ld no longer exists, stack logs deleted from %s\n", pid, reference_file_buffer); - } - } - } - if (delete_logging_file(pathname) == 0) { - if (remove_for_this_pid && pid == current_pid) { - if (!pathname_is_ref_file) _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", pathname); - } else { - if (!pathname_is_ref_file) _malloc_printf(ASL_LEVEL_INFO, "process %ld no longer exists, stack logs deleted from %s\n", pid, pathname); - } - char shmem_name_string[PATH_MAX]; - strlcpy(shmem_name_string, stack_log_file_base_name, (size_t)PATH_MAX); - append_int(shmem_name_string, (pid_t)pid, (size_t)PATH_MAX); - if (pid != current_pid) shm_unlink(shmem_name_string); - } - } - } - } - closedir(dp); -} - -/* - * Since there a many errors that could cause stack logging to get disabled, this is a convenience method - * for disabling any future logging in this process and for informing the user. - */ -static void -disable_stack_logging(void) -{ - _malloc_printf(ASL_LEVEL_INFO, "stack logging disabled due to previous errors.\n"); - stack_logging_enable_logging = 0; - malloc_logger = NULL; -} - -/* A wrapper around write() that will try to reopen the index/stack file and - * write to it if someone closed it underneath us (e.g. the process we just - * started decide to close all file descriptors except stin/err/out). Some - * programs like to do that and calling abort() on them is rude. - */ -static ssize_t -robust_write(int fd, const void *buf, size_t nbyte) { - extern int errno; - ssize_t written = write(fd, buf, nbyte); - if (written == -1 && errno == EBADF) { - char *file_to_reopen = NULL; - int *fd_to_reset = NULL; - - // descriptor was closed on us. We need to reopen it - if (fd == index_file_descriptor) { - file_to_reopen = __stack_log_file_path__; - fd_to_reset = &index_file_descriptor; - } else { - // We don't know about this file. Return (and abort()). - _malloc_printf(ASL_LEVEL_INFO, "Unknown file descriptor; expecting stack logging index file\n"); - return -1; - } - - // The file *should* already exist. If not, fail. - fd = open(file_to_reopen, O_WRONLY | O_APPEND); - if (fd < 3) { - // If we somehow got stdin/out/err, we need to relinquish them and - // get another fd. - int fds_to_close[3] = { 0 }; - while (fd < 3) { - if (fd == -1) { - _malloc_printf(ASL_LEVEL_INFO, "unable to re-open stack logging file %s\n", file_to_reopen); - delete_log_files(); - return -1; - } - fds_to_close[fd] = 1; - fd = dup(fd); - } - - // We have an fd we like. Close the ones we opened. - if (fds_to_close[0]) close(0); - if (fds_to_close[1]) close(1); - if (fds_to_close[2]) close(2); - } - - *fd_to_reset = fd; - written = write(fd, buf, nbyte); - } - return written; -} - -static void -flush_data(void) -{ - ssize_t written; // signed size_t - size_t remaining; - char * p; - - if (index_file_descriptor == -1) { - if (create_log_file() == NULL) { - return; - } - } - - // Write the events before the index so that hopefully the events will be on disk if the index refers to them. - p = pre_write_buffers->index_buffer; - remaining = (size_t)pre_write_buffers->next_free_index_buffer_offset; - while (remaining > 0) { - written = robust_write(index_file_descriptor, p, remaining); - if (written == -1) { - _malloc_printf(ASL_LEVEL_INFO, "Unable to write to stack logging file %s (%s)\n", - __stack_log_file_path__, strerror(errno)); - disable_stack_logging(); - return; - } - p += written; - remaining -= written; - } - - pre_write_buffers->start_index_offset += pre_write_buffers->next_free_index_buffer_offset; - pre_write_buffers->next_free_index_buffer_offset = 0; -} - -static void -prepare_to_log_stacks(void) -{ - if (!pre_write_buffers) { - last_logged_malloc_address = 0ul; - logging_use_compaction = (stack_logging_dontcompact ? 0 : logging_use_compaction); - - // Create a shared memory region to hold the pre-write index and stack buffers. This will allow remote analysis processes to access - // these buffers to get logs for even the most recent allocations. The remote process will need to pause this process to assure that - // the contents of these buffers don't change while being inspected. - char shmem_name_string[PATH_MAX]; - strlcpy(shmem_name_string, stack_log_file_base_name, (size_t)PATH_MAX); - append_int(shmem_name_string, getpid(), (size_t)PATH_MAX); - - int shmid = shm_open(shmem_name_string, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (shmid < 0) { - // Failed to create shared memory region; turn off stack logging. - _malloc_printf(ASL_LEVEL_INFO, "error while allocating shared memory for disk-based stack logging output buffers\n"); - disable_stack_logging(); - return; - } - - size_t full_shared_mem_size = sizeof(stack_buffer_shared_memory); - ftruncate(shmid, (off_t)full_shared_mem_size); - pre_write_buffers = (stack_buffer_shared_memory*)mmap(0, full_shared_mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, (off_t)0); - close(shmid); - - if (MAP_FAILED == pre_write_buffers) { - _malloc_printf(ASL_LEVEL_INFO, "error mapping in shared memory for disk-based stack logging output buffers\n"); - disable_stack_logging(); - return; - } - - // Store and use the buffer offsets in shared memory so that they can be accessed remotely - pre_write_buffers->start_index_offset = 0ull; - pre_write_buffers->next_free_index_buffer_offset = 0; - - // create the backtrace uniquing table - pre_write_buffers->uniquing_table = __create_uniquing_table(); - pre_write_buffers->uniquing_table_address = (mach_vm_address_t)(uintptr_t)pre_write_buffers->uniquing_table; - if (!pre_write_buffers->uniquing_table) { - _malloc_printf(ASL_LEVEL_INFO, "error while allocating stack uniquing table\n"); - disable_stack_logging(); - return; - } - - uint64_t stack_buffer_sz = (uint64_t)round_page(sizeof(vm_address_t) * STACK_LOGGING_MAX_STACK_SIZE); - stack_buffer = (vm_address_t*)allocate_pages(stack_buffer_sz); - if (!stack_buffer) { - _malloc_printf(ASL_LEVEL_INFO, "error while allocating stack trace buffer\n"); - disable_stack_logging(); - return; - } - - // malloc() can be called by the following, so these need to be done outside the stack_logging_lock but after the buffers have been set up. - atexit(delete_log_files); // atexit() can call malloc() - reap_orphaned_log_files(true); // this calls opendir() which calls malloc() - - // this call ensures that the log files exist; analyzing processes will rely on this assumption. - if (create_log_file() == NULL) { - /* postponement support requires cleaning up these structures now */ - __destroy_uniquing_table(pre_write_buffers->uniquing_table); - deallocate_pages(stack_buffer, stack_buffer_sz); - stack_buffer = NULL; - - munmap(pre_write_buffers, full_shared_mem_size); - pre_write_buffers = NULL; - - if (!stack_logging_postponed) { - disable_stack_logging(); - } - return; - } - } -} - -void -__disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip) -{ - if (!stack_logging_enable_logging || stack_logging_postponed) return; - - // check incoming data - if (type_flags & stack_logging_type_alloc && type_flags & stack_logging_type_dealloc) { - uintptr_t swapper = size; - size = ptr_arg; - ptr_arg = swapper; - if (ptr_arg == return_val) return; // realloc had no effect, skipping - - if (ptr_arg == 0) { // realloc(NULL, size) same as malloc(size) - type_flags ^= stack_logging_type_dealloc; - } else { - // realloc(arg1, arg2) -> result is same as free(arg1); malloc(arg2) -> result - __disk_stack_logging_log_stack(stack_logging_type_dealloc, zone_ptr, ptr_arg, (uintptr_t)0, (uintptr_t)0, num_hot_to_skip + 1); - __disk_stack_logging_log_stack(stack_logging_type_alloc, zone_ptr, size, (uintptr_t)0, return_val, num_hot_to_skip + 1); - return; - } - } - if (type_flags & stack_logging_type_dealloc) { - if (size) { - ptr_arg = size; - size = 0; - } else return; // free(nil) - } - if (type_flags & stack_logging_type_alloc && return_val == 0) return; // alloc that failed - - type_flags &= 0x7; - - // now actually begin - prepare_to_log_stacks(); - - // since there could have been a fatal (to stack logging) error such as the log files not being created, check this variable before continuing - if (!stack_logging_enable_logging || stack_logging_postponed) return; - - vm_address_t self_thread = (vm_address_t)pthread_self(); // use pthread_self() rather than mach_thread_self() to avoid system call - - // lock and enter - OSSpinLockLock(&stack_logging_lock); - - if (!stack_logging_enable_logging) { - OSSpinLockUnlock(&stack_logging_lock); - return; - } - - // compaction - if (last_logged_malloc_address && (type_flags & stack_logging_type_dealloc) && STACK_LOGGING_DISGUISE(ptr_arg) == last_logged_malloc_address) { - // *waves hand* the last allocation never occurred - pre_write_buffers->next_free_index_buffer_offset -= (uint32_t)sizeof(stack_logging_index_event); - last_logged_malloc_address = 0ul; - - OSSpinLockUnlock(&stack_logging_lock); - return; - } - - // gather stack - uint32_t count; - thread_stack_pcs(stack_buffer, STACK_LOGGING_MAX_STACK_SIZE-1, &count); // only gather up to STACK_LOGGING_MAX_STACK_SIZE-1 since we append thread id - stack_buffer[count++] = self_thread + 1; // stuffing thread # in the coldest slot. Add 1 to match what the old stack logging did. - num_hot_to_skip += 2; - if (count <= num_hot_to_skip) { - // Oops! Didn't get a valid backtrace from thread_stack_pcs(). - OSSpinLockUnlock(&stack_logging_lock); - return; - } - - // unique stack in memory - count -= num_hot_to_skip; -#if __LP64__ - mach_vm_address_t *frames = (mach_vm_address_t*)stack_buffer + num_hot_to_skip; -#else - mach_vm_address_t frames[STACK_LOGGING_MAX_STACK_SIZE]; - uint32_t i; - for (i = 0; i < count; i++) { - frames[i] = stack_buffer[i+num_hot_to_skip]; - } -#endif - - uint64_t uniqueStackIdentifier = (uint64_t)(-1ll); - while (!__enter_frames_in_table(pre_write_buffers->uniquing_table, &uniqueStackIdentifier, frames, (int32_t)count)) { - __expand_uniquing_table(pre_write_buffers->uniquing_table); - } - - stack_logging_index_event current_index; - if (type_flags & stack_logging_type_alloc) { - current_index.address = STACK_LOGGING_DISGUISE(return_val); - current_index.argument = size; - if (logging_use_compaction) { - last_logged_malloc_address = current_index.address; // disguised - } - } else { - current_index.address = STACK_LOGGING_DISGUISE(ptr_arg); - current_index.argument = 0ul; - last_logged_malloc_address = 0ul; - } - current_index.offset_and_flags = STACK_LOGGING_OFFSET_AND_FLAGS(uniqueStackIdentifier, type_flags); - -// the following line is a good debugging tool for logging each allocation event as it happens. -// malloc_printf("{0x%lx, %lld}\n", STACK_LOGGING_DISGUISE(current_index.address), uniqueStackIdentifier); - - // flush the data buffer to disk if necessary - if (pre_write_buffers->next_free_index_buffer_offset + sizeof(stack_logging_index_event) >= STACK_LOGGING_BLOCK_WRITING_SIZE) { - flush_data(); - } - - // store bytes in buffers - memcpy(pre_write_buffers->index_buffer+pre_write_buffers->next_free_index_buffer_offset, ¤t_index, sizeof(stack_logging_index_event)); - pre_write_buffers->next_free_index_buffer_offset += (uint32_t)sizeof(stack_logging_index_event); - - OSSpinLockUnlock(&stack_logging_lock); -} - -void -__stack_logging_fork_prepare() { - OSSpinLockLock(&stack_logging_lock); -} - -void -__stack_logging_fork_parent() { - OSSpinLockUnlock(&stack_logging_lock); -} - -void -__stack_logging_fork_child() { - malloc_logger = NULL; - stack_logging_enable_logging = 0; - OSSpinLockUnlock(&stack_logging_lock); -} - -void -__stack_logging_early_finished() { - stack_logging_finished_init = 1; - stack_logging_postponed = 0; -} - -boolean_t -__stack_logging_locked() -{ - bool acquired_lock = OSSpinLockTry(&stack_logging_lock); - if (acquired_lock) OSSpinLockUnlock(&stack_logging_lock); - return (acquired_lock ? false : true); -} - -#pragma mark - -#pragma mark Remote Stack Log Access - -#pragma mark - Design notes: - -/* - -this first one will look through the index, find the "stack_identifier" (i.e. the offset in the log file), and call the third function listed here. -extern kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *num_frames); - // Gets the last allocation record about address - -if !address, will load index and iterate through (expensive) -else will load just index, search for stack, and then use third function here to retrieve. (also expensive) -extern kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context); - // Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records - -this function will load the stack file, look for the stack, and follow up to STACK_LOGGING_FORCE_FULL_BACKTRACE_EVERY references to reconstruct. -extern kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); - // Given a uniqued_stack fills stack_frames_buffer - -*/ - -#pragma mark - caching - -__attribute__((always_inline)) static inline size_t -hash_index(uint64_t address, size_t max_pos) { - return (size_t)((address >> 2) % (max_pos-1)); // simplicity rules. -} - -__attribute__((always_inline)) static inline size_t -hash_multiplier(size_t capacity, uint32_t allowed_collisions) { - return (capacity/(allowed_collisions*2+1)); -} - -__attribute__((always_inline)) static inline size_t -next_hash(size_t hash, size_t multiplier, size_t capacity, uint32_t collisions) { - hash += multiplier * collisions; - if (hash >= capacity) hash -= capacity; - return hash; -} - -static void -transfer_node(remote_index_cache *cache, remote_index_node *old_node) -{ - uint32_t collisions = 0; - size_t pos = hash_index(old_node->address, cache->cache_node_capacity); - size_t multiplier = hash_multiplier(cache->cache_node_capacity, cache->collision_allowance); - do { - if (cache->table_memory[pos].address == old_node->address) { // hit like this shouldn't happen. - fprintf(stderr, "impossible collision! two address==address lists! (transfer_node)\n"); - break; - } else if (cache->table_memory[pos].address == 0) { // empty - cache->table_memory[pos] = *old_node; - break; - } else { - collisions++; - pos = next_hash(pos, multiplier, cache->cache_node_capacity, collisions); - } - } while (collisions <= cache->collision_allowance); - - if (collisions > cache->collision_allowance) { - fprintf(stderr, "reporting bad hash function! disk stack logging reader %lu bit. (transfer_node)\n", sizeof(void*)*8); - } -} - -static void -expand_cache(remote_index_cache *cache) -{ - // keep old stats - size_t old_node_capacity = cache->cache_node_capacity; - remote_index_node *old_table = cache->table_memory; - - // double size - cache->cache_size <<= 2; - cache->cache_node_capacity <<= 2; - cache->collision_allowance += 3; - cache->table_memory = (void*)calloc(cache->cache_node_capacity, sizeof(remote_index_node)); - - // repopulate (expensive!) - size_t i; - for (i = 0; i < old_node_capacity; i++) { - if (old_table[i].address) { - transfer_node(cache, &old_table[i]); - } - } - free(old_table); -// printf("cache expanded to %0.2f mb (eff: %3.0f%%, capacity: %lu, nodes: %llu, llnodes: %llu)\n", ((float)(cache->cache_size))/(1 << 20), ((float)(cache->cache_node_count)*100.0)/((float)(cache->cache_node_capacity)), cache->cache_node_capacity, cache->cache_node_count, cache->cache_llnode_count); -} - -static void -insert_node(remote_index_cache *cache, uint64_t address, uint64_t index_file_offset) -{ - uint32_t collisions = 0; - size_t pos = hash_index(address, cache->cache_node_capacity); - size_t multiplier = hash_multiplier(cache->cache_node_capacity, cache->collision_allowance); - - bool inserted = false; - while (!inserted) { - if (cache->table_memory[pos].address == 0ull || cache->table_memory[pos].address == address) { // hit or empty - cache->table_memory[pos].address = address; - cache->table_memory[pos].index_file_offset = index_file_offset; - inserted = true; - break; - } - - collisions++; - pos = next_hash(pos, multiplier, cache->cache_node_capacity, collisions); - - if (collisions > cache->collision_allowance) { - expand_cache(cache); - pos = hash_index(address, cache->cache_node_capacity); - multiplier = hash_multiplier(cache->cache_node_capacity, cache->collision_allowance); - collisions = 0; - } - } - -} - -static void -update_cache_for_file_streams(remote_task_file_streams *descriptors) -{ - remote_index_cache *cache = descriptors->cache; - - // create from scratch if necessary. - if (!cache) { - descriptors->cache = cache = (remote_index_cache*)calloc((size_t)1, sizeof(remote_index_cache)); - cache->cache_node_capacity = 1 << 14; - cache->collision_allowance = 17; - cache->last_index_file_offset = 0; - cache->cache_size = cache->cache_node_capacity*sizeof(remote_index_node); - cache->table_memory = (void*)calloc(cache->cache_node_capacity, sizeof(remote_index_node)); - - // now map in the shared memory, if possible - char shmem_name_string[PATH_MAX]; - strlcpy(shmem_name_string, stack_log_file_base_name, (size_t)PATH_MAX); - append_int(shmem_name_string, descriptors->remote_pid, (size_t)PATH_MAX); - - int shmid = shm_open(shmem_name_string, O_RDWR, S_IRUSR | S_IWUSR); - if (shmid >= 0) { - cache->shmem = mmap(0, sizeof(stack_buffer_shared_memory), PROT_READ | PROT_WRITE, MAP_SHARED, shmid, (off_t)0); - close(shmid); - } - - if (shmid < 0 || cache->shmem == MAP_FAILED) { - // failed to connect to the shared memory region; warn and continue. - _malloc_printf(ASL_LEVEL_INFO, "warning: unable to connect to remote process' shared memory; allocation histories may not be up-to-date.\n"); - } - } - - // suspend and see how much updating there is to do. there are three scenarios, listed below - bool update_snapshot = false; - if (descriptors->remote_task != mach_task_self()) { - task_suspend(descriptors->remote_task); - } - - struct stat file_statistics; - fstat(fileno(descriptors->index_file_stream), &file_statistics); - size_t read_size = (descriptors->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); - uint64_t read_this_update = 0; - - // the delta indecies is a complex number; there are three cases: - // 1. there is no shared memory (or we can't connect); diff the last_index_file_offset from the filesize. - // 2. the only updates have been in shared memory; disk file didn't change at all. delta_indecies should be zero, scan snapshot only. - // 3. the updates have flushed to disk, meaning that most likely there is new data on disk that wasn't read from shared memory. - // correct delta_indecies for the pre-scanned amount and read the new data from disk and shmem. - uint64_t delta_indecies = (file_statistics.st_size - cache->last_index_file_offset) / read_size; - uint32_t last_snapshot_scan_index = 0; - if (delta_indecies && cache->shmem) { - // case 3: add cache scanned to known from disk and recalc - cache->last_index_file_offset += cache->snapshot.next_free_index_buffer_offset; - delta_indecies = (file_statistics.st_size - cache->last_index_file_offset) / read_size; - update_snapshot = true; - } else if (cache->shmem) { - // case 2: set the last snapshot scan count so we don't rescan something we've seen. - last_snapshot_scan_index = cache->snapshot.next_free_index_buffer_offset / (uint32_t)read_size; - } - - // no update necessary for the file; check if need a snapshot. - if (delta_indecies == 0) { - if (cache->shmem && !update_snapshot) { - update_snapshot = (cache->shmem->next_free_index_buffer_offset != cache->snapshot.next_free_index_buffer_offset); - } - } - - // if a snapshot is necessary, memcpy from remote frozen process' memory - // note: there were two ways to do this - spin lock or suspend. suspend allows us to - // analyze processes even if they were artificially suspended. with a lock, there'd be - // worry that the target was suspended with the lock taken. - if (update_snapshot) { - memcpy(&cache->snapshot, cache->shmem, sizeof(stack_buffer_shared_memory)); - // also need to update our version of the remote uniquing table - vm_address_t local_uniquing_address = 0ul; - mach_msg_type_number_t local_uniquing_size = 0; - mach_vm_size_t desired_size = round_page(sizeof(backtrace_uniquing_table)); - kern_return_t err; - if ((err = mach_vm_read(descriptors->remote_task, cache->shmem->uniquing_table_address, desired_size, &local_uniquing_address, &local_uniquing_size)) != KERN_SUCCESS - || local_uniquing_size != desired_size) { - fprintf(stderr, "error while attempting to mach_vm_read remote stack uniquing table (%d): %s\n", err, mach_error_string(err)); - } else { - // the mach_vm_read was successful, so acquire the uniquing table - - // need to re-read the table, so deallocate the current memory - if (cache->uniquing_table.table) mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)(cache->uniquing_table.table), cache->uniquing_table.tableSize); - - // the following line gathers the uniquing table structure data, but the actual table memory is invalid since it's a pointer from the - // remote process. this pointer will be mapped shared in a few lines. - cache->uniquing_table = *((backtrace_uniquing_table*)local_uniquing_address); - - vm_address_t local_table_address = 0ul; - mach_msg_type_number_t local_table_size = 0; - - err = mach_vm_read(descriptors->remote_task, cache->uniquing_table.table_address, cache->uniquing_table.tableSize, &local_table_address, &local_table_size); - if (err == KERN_SUCCESS) cache->uniquing_table.table = (mach_vm_address_t*)local_table_address; - else cache->uniquing_table.table = NULL; - - mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)local_uniquing_address, (mach_vm_size_t)local_uniquing_size); - } - } - - // resume - if (descriptors->remote_task != mach_task_self()) { - task_resume(descriptors->remote_task); - } - - if (!update_snapshot && delta_indecies == 0) return; // absolutely no updating needed. - - FILE *the_index = (descriptors->index_file_stream); - - // prepare for the read; target process could be 32 or 64 bit. - - stack_logging_index_event32 *target_32_index = NULL; - stack_logging_index_event64 *target_64_index = NULL; - - // perform the update from the file - uint32_t i; - if (delta_indecies) { - char bufferSpace[4096]; // 4 kb - target_32_index = (stack_logging_index_event32*)bufferSpace; - target_64_index = (stack_logging_index_event64*)bufferSpace; - size_t number_slots = (size_t)(4096/read_size); - - size_t read_count = 0; - if (fseeko(the_index, (off_t)(cache->last_index_file_offset), SEEK_SET)) { - fprintf(stderr, "error while attempting to cache information from remote stack index file. (update_cache_for_file_streams)\n"); - } - off_t current_index_position = cache->last_index_file_offset; - do { - number_slots = (size_t)MIN(delta_indecies - read_this_update, number_slots); - read_count = fread(bufferSpace, read_size, number_slots, the_index); - if (descriptors->task_is_64_bit) { - for (i = 0; i < read_count; i++) { - insert_node(cache, STACK_LOGGING_DISGUISE(target_64_index[i].address), (uint64_t)current_index_position); - read_this_update++; - current_index_position += read_size; - } - } else { - for (i = 0; i < read_count; i++) { - insert_node(cache, (mach_vm_address_t)STACK_LOGGING_DISGUISE(target_32_index[i].address), (uint64_t)current_index_position); - read_this_update++; - current_index_position += read_size; - } - } - } while (read_count); - - if (read_this_update < delta_indecies) { - fprintf(stderr, "insufficient data in remote stack index file; expected more records.\n"); - } - cache->last_index_file_offset += read_this_update * read_size; - } - - if (update_snapshot) { - target_32_index = (stack_logging_index_event32*)(cache->snapshot.index_buffer); - target_64_index = (stack_logging_index_event64*)(cache->snapshot.index_buffer); - - uint32_t free_snapshot_scan_index = cache->snapshot.next_free_index_buffer_offset / (uint32_t)read_size; - off_t current_index_position = cache->snapshot.start_index_offset; - if (descriptors->task_is_64_bit) { - for (i = last_snapshot_scan_index; i < free_snapshot_scan_index; i++) { - insert_node(cache, STACK_LOGGING_DISGUISE(target_64_index[i].address), (uint64_t)(current_index_position + (i * read_size))); - } - } else { - for (i = last_snapshot_scan_index; i < free_snapshot_scan_index; i++) { - insert_node(cache, (mach_vm_address_t)STACK_LOGGING_DISGUISE(target_32_index[i].address), (uint64_t)(current_index_position + (i * read_size))); - } - } - } -} - -static void -destroy_cache_for_file_streams(remote_task_file_streams *descriptors) -{ - if (descriptors->cache->shmem) { - munmap(descriptors->cache->shmem, sizeof(stack_buffer_shared_memory)); - } - free(descriptors->cache->table_memory); - free(descriptors->cache); - descriptors->cache = NULL; -} - -#pragma mark - internal - -// In the stack log analysis process, find the stack logging files for target process -// by scanning the temporary directory for directory entries with names of the form "stack-logs.." -// If we find such a directory then open the stack logging files in there. -// We might also have been passed the file path if the client first read it from __stack_log_file_path__ -// global variable in the target task, as will be needed if the .link cannot be put in /tmp. -static void -open_log_files(pid_t pid, char* file_path, remote_task_file_streams *this_task_streams) -{ - DIR *dp; - struct dirent *entry; - char prefix_name[PATH_MAX]; - char pathname[PATH_MAX]; - - reap_orphaned_log_files(false); // reap any left-over log files (for non-existant processes, but not for this analysis process) - - if (file_path != NULL) { - this_task_streams->index_file_stream = fopen(file_path, "r"); - return; - } - - if ((dp = opendir(_PATH_TMP)) == NULL) { - return; - } - - // It's OK to use snprintf in this routine since it should only be called by the clients - // of stack logging, and thus calls to malloc are OK. - snprintf(prefix_name, (size_t)PATH_MAX, "%s%d.", stack_log_file_base_name, pid); // make sure to use "%s%d." rather than just "%s%d" to match the whole pid - size_t prefix_length = strlen(prefix_name); - - while ( (entry = readdir(dp)) != NULL ) { - if ( strncmp( entry->d_name, prefix_name, prefix_length) == 0 ) { - snprintf(pathname, (size_t)PATH_MAX, "%s%s", _PATH_TMP, entry->d_name); - char reference_file[PATH_MAX]; - if (log_file_is_reference(pathname, reference_file, (size_t)PATH_MAX)) { - this_task_streams->index_file_stream = fopen(reference_file, "r"); - } else { - this_task_streams->index_file_stream = fopen(pathname, "r"); - } - - break; - } - } - closedir(dp); -} - -static remote_task_file_streams* -retain_file_streams_for_task(task_t task, char* file_path) -{ - if (task == MACH_PORT_NULL) return NULL; - - OSSpinLockLock(&remote_fd_list_lock); - - // see if they're already in use - uint32_t i = 0; - for (i = 0; i < remote_task_fd_count; i++) { - if (remote_fds[i].remote_task == task) { - remote_fds[i].in_use_count++; - OSSpinLockUnlock(&remote_fd_list_lock); - return &remote_fds[i]; - } - } - - // open them - uint32_t failures = 0; - if (remote_task_fd_count == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) { - while (remote_fds[next_remote_task_fd].in_use_count > 0) { - next_remote_task_fd++; - if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) next_remote_task_fd = 0; - failures++; - if (failures >= STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) { - OSSpinLockUnlock(&remote_fd_list_lock); - return NULL; - } - } - fclose(remote_fds[next_remote_task_fd].index_file_stream); - destroy_cache_for_file_streams(&remote_fds[next_remote_task_fd]); - } - - pid_t pid; - kern_return_t err = pid_for_task(task, &pid); - if (err != KERN_SUCCESS) { - OSSpinLockUnlock(&remote_fd_list_lock); - return NULL; - } - - remote_task_file_streams *this_task_streams = &remote_fds[next_remote_task_fd]; - - open_log_files(pid, file_path, this_task_streams); - - // check if opens failed - if (this_task_streams->index_file_stream == NULL) { - if (this_task_streams->index_file_stream) fclose(this_task_streams->index_file_stream); - OSSpinLockUnlock(&remote_fd_list_lock); - return NULL; - } - - // check if target pid is running 64-bit - int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; - struct kinfo_proc processInfo; - size_t bufsize = sizeof(processInfo); - if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, (size_t)0) == 0 && bufsize > 0) { - this_task_streams->task_is_64_bit = processInfo.kp_proc.p_flag & P_LP64; - } else { - this_task_streams->task_is_64_bit = 0; - } - - // otherwise set vars and go - this_task_streams->in_use_count = 1; - this_task_streams->remote_task = task; - this_task_streams->remote_pid = pid; - next_remote_task_fd++; - if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) next_remote_task_fd = 0; - remote_task_fd_count = MIN(remote_task_fd_count + 1, STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED); - - OSSpinLockUnlock(&remote_fd_list_lock); - return this_task_streams; -} - -static void -release_file_streams_for_task(task_t task) -{ - OSSpinLockLock(&remote_fd_list_lock); - - // decrement in-use count - uint32_t i = 0; - for (i = 0; i < remote_task_fd_count; i++) { - if (remote_fds[i].remote_task == task) { - remote_fds[i].in_use_count--; - break; - } - } - - OSSpinLockUnlock(&remote_fd_list_lock); -} - -#pragma mark - extern - -// -// The following is used by client tools like malloc_history and Instruments to pass along the path -// of the index file as read from the target task's __stack_log_file_path__ variable (set in this file) -// Eventually, at a suitable point, this additional argument should just be added to the other APIs below. -// -kern_return_t -__mach_stack_logging_set_file_path(task_t task, char* file_path) -{ - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, file_path); - if (remote_fd == NULL) { - return KERN_FAILURE; - } - return KERN_SUCCESS; -} - -kern_return_t -__mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count) -{ - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL); - if (remote_fd == NULL) { - return KERN_FAILURE; - } - - update_cache_for_file_streams(remote_fd); - - uint32_t collisions = 0; - size_t hash = hash_index(address, remote_fd->cache->cache_node_capacity); - size_t multiplier = hash_multiplier(remote_fd->cache->cache_node_capacity, remote_fd->cache->collision_allowance); - uint64_t located_file_position = 0; - - bool found = false; - do { - if (remote_fd->cache->table_memory[hash].address == address) { // hit! - located_file_position = remote_fd->cache->table_memory[hash].index_file_offset; - found = true; - break; - } else if (remote_fd->cache->table_memory[hash].address == 0ull) { // failure! - break; - } - - collisions++; - hash = next_hash(hash, multiplier, remote_fd->cache->cache_node_capacity, collisions); - - } while (collisions <= remote_fd->cache->collision_allowance); - - if (found) { - // prepare for the read; target process could be 32 or 64 bit. - stack_logging_index_event32 *target_32_index = NULL; - stack_logging_index_event64 *target_64_index = NULL; - - if (located_file_position >= remote_fd->cache->last_index_file_offset) { - // must be in shared memory - if (remote_fd->cache->shmem) { - if (remote_fd->task_is_64_bit) { - target_64_index = (stack_logging_index_event64*)(remote_fd->cache->snapshot.index_buffer + (located_file_position - remote_fd->cache->snapshot.start_index_offset)); - located_file_position = STACK_LOGGING_OFFSET(target_64_index->offset_and_flags); - } else { - target_32_index = (stack_logging_index_event32*)(remote_fd->cache->snapshot.index_buffer + (located_file_position - remote_fd->cache->snapshot.start_index_offset)); - located_file_position = STACK_LOGGING_OFFSET(target_32_index->offset_and_flags); - } - } else { - found = false; - } - - } else { - // it's written to disk - char bufferSpace[128]; - - size_t read_size = (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); - fseeko(remote_fd->index_file_stream, (off_t)located_file_position, SEEK_SET); - size_t read_count = fread(bufferSpace, read_size, (size_t)1, remote_fd->index_file_stream); - if (read_count) { - if (remote_fd->task_is_64_bit) { - target_64_index = (stack_logging_index_event64*)bufferSpace; - located_file_position = STACK_LOGGING_OFFSET(target_64_index->offset_and_flags); - } else { - target_32_index = (stack_logging_index_event32*)bufferSpace; - located_file_position = STACK_LOGGING_OFFSET(target_32_index->offset_and_flags); - } - } else { - found = false; - } - } - } - - release_file_streams_for_task(task); - - if (!found) { - return KERN_FAILURE; - } - - return __mach_stack_logging_frames_for_uniqued_stack(task, located_file_position, stack_frames_buffer, max_stack_frames, count); -} - - -kern_return_t -__mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context) -{ - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL); - if (remote_fd == NULL) { - return KERN_FAILURE; - } - - bool reading_all_addresses = (address == 0 ? true : false); - mach_stack_logging_record_t pass_record; - kern_return_t err = KERN_SUCCESS; - - // update (read index file once and only once) - update_cache_for_file_streams(remote_fd); - - FILE *the_index = (remote_fd->index_file_stream); - - // prepare for the read; target process could be 32 or 64 bit. - char bufferSpace[2048]; // 2 kb - stack_logging_index_event32 *target_32_index = (stack_logging_index_event32*)bufferSpace; - stack_logging_index_event64 *target_64_index = (stack_logging_index_event64*)bufferSpace; - uint32_t target_addr_32 = (uint32_t)STACK_LOGGING_DISGUISE((uint32_t)address); - uint64_t target_addr_64 = STACK_LOGGING_DISGUISE((uint64_t)address); - size_t read_size = (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); - size_t number_slots = (size_t)(2048/read_size); - uint64_t total_slots = remote_fd->cache->last_index_file_offset / read_size; - - // perform the search - size_t read_count = 0; - int64_t current_file_offset = 0; - uint32_t i; - do { - // at this point, we need to read index events; read them from the file until it's necessary to grab them from the shared memory snapshot - // and crop file reading to the point where we last scanned - number_slots = (size_t)MIN(number_slots, total_slots); - - // if out of file to read (as of the time we entered this function), try to use shared memory snapshot - if (number_slots == 0) { - if (remote_fd->cache->shmem && remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset > (uint64_t)current_file_offset) { - // use shared memory - target_32_index = (stack_logging_index_event32*)remote_fd->cache->snapshot.index_buffer; - target_64_index = (stack_logging_index_event64*)remote_fd->cache->snapshot.index_buffer; - read_count = (uint32_t)(remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset - current_file_offset) / read_size; - current_file_offset += read_count * read_size; - } else { - break; - } - } else { - // get and save index (enumerator could modify) - fseeko(the_index, current_file_offset, SEEK_SET); - read_count = fread(bufferSpace, read_size, number_slots, the_index); - current_file_offset = ftello(the_index); - total_slots -= read_count; - } - - if (remote_fd->task_is_64_bit) { - for (i = 0; i < read_count; i++) { - if (reading_all_addresses || target_64_index[i].address == target_addr_64) { - pass_record.address = STACK_LOGGING_DISGUISE(target_64_index[i].address); - pass_record.argument = target_64_index[i].argument; - pass_record.stack_identifier = STACK_LOGGING_OFFSET(target_64_index[i].offset_and_flags); - pass_record.type_flags = STACK_LOGGING_FLAGS(target_64_index[i].offset_and_flags); - enumerator(pass_record, context); - } - } - } else { - for (i = 0; i < read_count; i++) { - if (reading_all_addresses || target_32_index[i].address == target_addr_32) { - pass_record.address = STACK_LOGGING_DISGUISE(target_32_index[i].address); - pass_record.argument = target_32_index[i].argument; - pass_record.stack_identifier = STACK_LOGGING_OFFSET(target_32_index[i].offset_and_flags); - pass_record.type_flags = STACK_LOGGING_FLAGS(target_32_index[i].offset_and_flags); - enumerator(pass_record, context); - } - } - } - } while (read_count); - - release_file_streams_for_task(task); - return err; -} - - -kern_return_t -__mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count) -{ - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL); - if (remote_fd == NULL) return KERN_FAILURE; - - __unwind_stack_from_table_index(&remote_fd->cache->uniquing_table, stack_identifier, stack_frames_buffer, count, max_stack_frames); - - release_file_streams_for_task(task); - - if (*count) return KERN_SUCCESS; - else return KERN_FAILURE; -} - - -#ifdef TEST_DISK_STACK_LOGGING - -// cc -o stack_logging_disk stack_logging_disk.c -DTEST_DISK_STACK_LOGGING - -#include - -int -main() -{ - int status; - int i; - size_t total_globals = 0ul; - - fprintf(stderr, "master test process is %d\n", getpid()); - fprintf(stderr, "sizeof pre_write_buffers: %lu\n", sizeof(pre_write_buffers)); total_globals += sizeof(pre_write_buffers); - fprintf(stderr, "sizeof stack_buffer: %lu\n", sizeof(stack_buffer)); total_globals += sizeof(stack_buffer); - fprintf(stderr, "sizeof last_logged_malloc_address: %lu\n", sizeof(last_logged_malloc_address)); total_globals += sizeof(last_logged_malloc_address); - fprintf(stderr, "sizeof stack_log_file_base_name: %lu\n", sizeof(stack_log_file_base_name)); total_globals += sizeof(stack_log_file_base_name); - fprintf(stderr, "sizeof stack_log_file_suffix: %lu\n", sizeof(stack_log_file_suffix)); total_globals += sizeof(stack_log_file_suffix); - fprintf(stderr, "sizeof stack_log_link_suffix: %lu\n", sizeof(stack_log_link_suffix)); total_globals += sizeof(stack_log_link_suffix); - fprintf(stderr, "sizeof stack_log_location: %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX; - fprintf(stderr, "sizeof stack_log_reference_file: %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX; - fprintf(stderr, "sizeof __stack_log_file_path__ (index_file_path): %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX; - fprintf(stderr, "sizeof index_file_descriptor: %lu\n", sizeof(index_file_descriptor)); total_globals += sizeof(index_file_descriptor); - fprintf(stderr, "sizeof remote_fds: %lu\n", sizeof(remote_fds)); total_globals += sizeof(remote_fds); - fprintf(stderr, "sizeof next_remote_task_fd: %lu\n", sizeof(next_remote_task_fd)); total_globals += sizeof(next_remote_task_fd); - fprintf(stderr, "sizeof remote_task_fd_count: %lu\n", sizeof(remote_task_fd_count)); total_globals += sizeof(remote_task_fd_count); - fprintf(stderr, "sizeof remote_fd_list_lock: %lu\n", sizeof(remote_fd_list_lock)); total_globals += sizeof(remote_fd_list_lock); - fprintf(stderr, "sizeof logging_use_compaction: %lu\n", sizeof(logging_use_compaction)); total_globals += sizeof(logging_use_compaction); - - fprintf(stderr, "size of all global data: %lu\n", total_globals); - - create_log_file(); - - // create a few child processes and exit them cleanly so their logs should get cleaned up - fprintf(stderr, "\ncreating child processes and exiting cleanly\n"); - for (i = 0; i < 3; i++) { - if (fork() == 0) { - fprintf(stderr, "\nin child processes %d\n", getpid()); - create_log_file(); - fprintf(stderr, "exiting child processes %d\n", getpid()); - exit(1); - } - wait(&status); - } - - // create a few child processes and abruptly _exit them, leaving their logs around - fprintf(stderr, "\ncreating child processes and exiting abruptly, leaving logs around\n"); - for (i = 0; i < 3; i++) { - if (fork() == 0) { - fprintf(stderr, "\nin child processes %d\n", getpid()); - create_log_file(); - fprintf(stderr, "exiting child processes %d\n", getpid()); - _exit(1); - } - wait(&status); - } - - // this should reap any remaining logs - fprintf(stderr, "\nexiting master test process %d\n", getpid()); - delete_log_files(); - return 0; -} - -#endif diff --git a/src/libc/gen/strtofflags.c b/src/libc/gen/strtofflags.c index 098bf6a57..e6b98dfe2 100644 --- a/src/libc/gen/strtofflags.c +++ b/src/libc/gen/strtofflags.c @@ -68,6 +68,7 @@ static const char rcsid[] = #include #include #include +#include static struct { char *name; @@ -82,6 +83,9 @@ static struct { { "noschg", SF_IMMUTABLE, 0 }, { "noschange", SF_IMMUTABLE, 0 }, { "nosimmutable", SF_IMMUTABLE, 0 }, + { "norestricted", SF_RESTRICTED, 0 }, + { "nosunlnk", SF_NOUNLINK, 0 }, + { "nosunlink", SF_NOUNLINK, 0 }, { "nouappnd", UF_APPEND, 0 }, { "nouappend", UF_APPEND, 0 }, { "nouchg", UF_IMMUTABLE, 0 }, diff --git a/src/libc/gen/syslog.3 b/src/libc/gen/syslog.3 deleted file mode 100644 index bdce9476b..000000000 --- a/src/libc/gen/syslog.3 +++ /dev/null @@ -1,323 +0,0 @@ -.\" Copyright (c) 1985, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)syslog.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/gen/syslog.3,v 1.22 2001/10/01 16:08:51 ru Exp $ -.\" -.Dd June 4, 1993 -.Dt SYSLOG 3 -.Os -.Sh NAME -.Nm closelog , -.Nm openlog , -.Nm setlogmask , -.Nm syslog , -.Nm vsyslog -.Nd control system log -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In syslog.h -.Ft void -.Fo closelog -.Fa void -.Fc -.Ft void -.Fo openlog -.Fa "const char *ident" -.Fa "int logopt" -.Fa "int facility" -.Fc -.Ft int -.Fo setlogmask -.Fa "int maskpri" -.Fc -.Ft void -.Fo syslog -.Fa "int priority" -.Fa "const char *message" -.Fa "..." -.Fc -.In syslog.h -.In stdarg.h -.Ft void -.Fo vsyslog -.Fa "int priority" -.Fa "const char *message" -.Fa "va_list args" -.Fc -.Sh DESCRIPTION -The -.Fn syslog -function -writes -.Fa message -to the system message logger. -The message is then written to the system console, log files, -logged-in users, or forwarded to other machines as appropriate. -(See -.Xr syslogd 8 . ) -.Pp -The message is identical to a -.Xr printf 3 -format string, except that -.Ql %m -is replaced by the current error -message. -(As denoted by the global variable -.Va errno ; -see -.Xr strerror 3 . ) -A trailing newline is added if none is present. -.Pp -Newlines and other non-printable characters embedded in the message string are printed in an alternate format. -This prevents someone from using non-printable characters to construct misleading log messages in an output file. -Newlines are printed as "\\n", -tabs are printed as "\\t". -Other control characters are printed using a caret ("^") representation, for example "^M" for carriage return. -.Pp -The -.Fn vsyslog -function -is an alternate form in which the arguments have already been captured -using the variable-length argument facilities of -.Xr stdarg 3 . -.Pp -The message is tagged with -.Fa priority . -Priorities are encoded as a -.Fa facility -and a -.Em level . -The facility describes the part of the system -generating the message. -The level is selected from the following -.Em ordered -(high to low) list: -.Bl -tag -width LOG_AUTHPRIV -.It Dv LOG_EMERG -A panic condition. -This is normally broadcast to all users. -.It Dv LOG_ALERT -A condition that should be corrected immediately, such as a corrupted -system database. -.It Dv LOG_CRIT -Critical conditions, e.g., hard device errors. -.It Dv LOG_ERR -Errors. -.It Dv LOG_WARNING -Warning messages. -.It Dv LOG_NOTICE -Conditions that are not error conditions, -but should possibly be handled specially. -.It Dv LOG_INFO -Informational messages. -.It Dv LOG_DEBUG -Messages that contain information -normally of use only when debugging a program. -.El -.Pp -The -.Fn openlog -function -provides for more specialized processing of the messages sent -by -.Fn syslog -and -.Fn vsyslog . -The parameter -.Fa ident -is a string that will be prepended to every message. -The -.Fa logopt -argument -is a bit field specifying logging options, which is formed by -.Tn OR Ns 'ing -one or more of the following values: -.Bl -tag -width LOG_AUTHPRIV -.It Dv LOG_CONS -If -.Fn syslog -cannot pass the message to -.Xr syslogd 8 -it will attempt to write the message to the console -.Pq Dq Pa /dev/console . -.It Dv LOG_NDELAY -Open the connection to -.Xr syslogd 8 -immediately. -Normally the open is delayed until the first message is logged. -Useful for programs that need to manage the order in which file -descriptors are allocated. -.It Dv LOG_PERROR -Write the message to standard error output as well to the system log. -.It Dv LOG_PID -Log the process id with each message: useful for identifying -instantiations of daemons. -.El -.Pp -The -.Fa facility -parameter encodes a default facility to be assigned to all messages -that do not have an explicit facility encoded: -.Bl -tag -width LOG_AUTHPRIV -.It Dv LOG_AUTH -The authorization system: -.Xr login 1 , -.Xr su 1 , -.Xr getty 8 , -etc. -.It Dv LOG_AUTHPRIV -The same as -.Dv LOG_AUTH , -but logged to a file readable only by -selected individuals. -.It Dv LOG_CRON -The cron daemon: -.Xr cron 8 . -.It Dv LOG_DAEMON -System daemons, such as -.Xr routed 8 , -that are not provided for explicitly by other facilities. -.It Dv LOG_FTP -The file transfer protocol daemons: -.Xr ftpd 8 , -.Xr tftpd 8 . -.It Dv LOG_KERN -Messages generated by the kernel. -These cannot be generated by any user processes. -.It Dv LOG_LPR -The line printer spooling system: -.Xr cups-lpd 8 , -.Xr cupsd 8 , -etc. -.It Dv LOG_MAIL -The mail system. -.It Dv LOG_NEWS -The network news system. -.It Dv LOG_SECURITY -Security subsystems, such as -.Xr ipfw 4 . -.It Dv LOG_SYSLOG -Messages generated internally by -.Xr syslogd 8 . -.It Dv LOG_USER -Messages generated by random user processes. -This is the default facility identifier if none is specified. -.It Dv LOG_UUCP -The uucp system. -.It Dv LOG_LOCAL0 -Reserved for local use. -Similarly for -.Dv LOG_LOCAL1 -through -.Dv LOG_LOCAL7 . -.El -.Pp -The -.Fn closelog -function -can be used to close the log file. -.Pp -The -.Fn setlogmask -function -sets the log priority mask to -.Fa maskpri -and returns the previous mask. -Calls to -.Fn syslog -with a priority not set in -.Fa maskpri -are rejected. -The mask for an individual priority -.Fa pri -is calculated by the macro -.Fn LOG_MASK pri ; -the mask for all priorities up to and including -.Fa toppri -is given by the macro -.Fn LOG_UPTO toppri ; . -The default allows all priorities to be logged. -.Sh RETURN VALUES -The routines -.Fn closelog , -.Fn openlog , -.Fn syslog , -and -.Fn vsyslog -return no value. -.Pp -The routine -.Fn setlogmask -always returns the previous log mask level. -.Sh EXAMPLES -.Bd -literal -offset indent -compact -syslog(LOG_ALERT, "who: internal error 23"); - -openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); - -setlogmask(LOG_UPTO(LOG_ERR)); - -syslog(LOG_INFO, "Connection from host %d", CallingHost); - -syslog(LOG_INFO|LOG_LOCAL2, "foobar error: %m"); -.Ed -.Sh LEGACY SYNOPSIS -.Fd #include -.Fd #include -.Pp -These include files are necessary for all functions. -.Sh SEE ALSO -.Xr asl 3 , -.Xr logger 1 , -.Xr compat 5 , -.Xr syslogd 8 -.Sh HISTORY -These -functions appeared in -.Bx 4.2 . -.Sh BUGS -Never pass a string with user-supplied data as a format without using -.Ql %s . -An attacker can put format specifiers in the string to mangle your stack, -leading to a possible security hole. -This holds true even if the string was built using a function like -.Fn snprintf , -as the resulting string may still contain user-supplied conversion specifiers -for later interpolation by -.Fn syslog . -.Pp -Always use the proper secure idiom: -.Pp -.Bd -literal -offset indent -compact -syslog(LOG_ERR, "%s", string); -.Ed diff --git a/src/libc/gen/syslog.c b/src/libc/gen/syslog.c deleted file mode 100644 index d63e50986..000000000 --- a/src/libc/gen/syslog.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 1999-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include "asl_private.h" - -#ifdef __STDC__ -#include -#else -#include -#endif - -#define LOG_NO_NOTIFY 0x1000 -extern const char *asl_syslog_faciliy_num_to_name(int n); - -#ifdef BUILDING_VARIANT -__private_extern__ pthread_mutex_t _sl_lock; -__private_extern__ aslclient _sl_asl; -__private_extern__ char *_sl_ident; -__private_extern__ int _sl_fac; -__private_extern__ int _sl_opts; -__private_extern__ int _sl_mask; -#else /* !BUILDING_VARIANT */ -__private_extern__ pthread_mutex_t _sl_lock = PTHREAD_MUTEX_INITIALIZER; -__private_extern__ aslclient _sl_asl = NULL; -__private_extern__ char *_sl_ident = NULL; -__private_extern__ int _sl_fac = 0; -__private_extern__ int _sl_opts = 0; -__private_extern__ int _sl_mask = 0; -#endif /* BUILDING_VARIANT */ - -/* - * syslog, vsyslog -- - * print message on log file; output is intended for syslogd(8). - */ -void -#ifdef __STDC__ -syslog(int pri, const char *fmt, ...) -#else -syslog(pri, fmt, va_alist) - int pri; - char *fmt; - va_dcl -#endif -{ - va_list ap; - -#ifdef __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - vsyslog(pri, fmt, ap); - va_end(ap); -} - -void -vsyslog(int pri, const char *fmt, va_list ap) -{ - int fac; - aslmsg facmsg; - const char *facility; - - facmsg = NULL; - fac = pri & LOG_FACMASK; - if (fac != 0) - { - facility = asl_syslog_faciliy_num_to_name(fac); - if (facility != NULL) - { - facmsg = asl_new(ASL_TYPE_MSG); - asl_set(facmsg, ASL_KEY_FACILITY, facility); - } - } - - asl_vlog(_sl_asl, facmsg, LOG_PRI(pri), fmt, ap); - if (facmsg != NULL) asl_free(facmsg); -} - -#ifndef BUILDING_VARIANT - -void -openlog(const char *ident, int opts, int logfac) -{ - const char *facility; - uint32_t asl_opts; - - pthread_mutex_lock(&_sl_lock); - - /* close existing aslclient */ - if (_sl_asl != NULL) asl_close(_sl_asl); - _sl_asl = NULL; - - if (_sl_ident != NULL) free(_sl_ident); - _sl_ident = NULL; - - /* open with specified parameters */ - - if (ident != NULL) _sl_ident = strdup(ident); - /* NB we allow the strdup to fail silently */ - - _sl_fac = logfac; - facility = asl_syslog_faciliy_num_to_name(_sl_fac); - - _sl_opts = opts; - asl_opts = ASL_OPT_SYSLOG_LEGACY; - - if (_sl_opts & LOG_NO_NOTIFY) asl_opts |= ASL_OPT_NO_REMOTE; - if (_sl_opts & LOG_PERROR) asl_opts |= ASL_OPT_STDERR; - - _sl_mask = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG); - - _sl_asl = asl_open(_sl_ident, facility, asl_opts); - asl_set_filter(_sl_asl, _sl_mask); - - pthread_mutex_unlock(&_sl_lock); -} - -void -closelog() -{ - pthread_mutex_lock(&_sl_lock); - - if (_sl_asl != NULL) asl_close(_sl_asl); - _sl_asl = NULL; - - if (_sl_ident != NULL) free(_sl_ident); - _sl_ident = NULL; - - pthread_mutex_unlock(&_sl_lock); -} - -/* setlogmask -- set the log mask level */ -int -setlogmask(int mask) -{ - int oldmask; - - pthread_mutex_lock(&_sl_lock); - - _sl_mask = mask; - oldmask = asl_set_filter(_sl_asl, mask); - - pthread_mutex_unlock(&_sl_lock); - - return oldmask; -} - -#endif /* !BUILDING_VARIANT */ diff --git a/src/libc/gen/tcsetattr.3 b/src/libc/gen/tcsetattr.3 index b4b77b362..0edbad1a8 100644 --- a/src/libc/gen/tcsetattr.3 +++ b/src/libc/gen/tcsetattr.3 @@ -205,7 +205,7 @@ with the particular file descriptor. .Pp The .Fn cfmakeraw -function sets the flags stored in the termios structure to a state disabling +function modifies the flags stored in the termios structure to a state disabling all input and output processing, giving a .Dq raw I/O path . It should be noted that there is no function to reverse this effect. diff --git a/src/libc/gen/thread_stack_pcs.c b/src/libc/gen/thread_stack_pcs.c index a14583100..107606543 100644 --- a/src/libc/gen/thread_stack_pcs.c +++ b/src/libc/gen/thread_stack_pcs.c @@ -27,6 +27,7 @@ #include #include #include +#include "stack_logging.h" #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) #define FP_LINK_OFFSET 1 diff --git a/src/libc/gen/tzset.3 b/src/libc/gen/tzset.3 index 3476572c0..18f980bb2 100644 --- a/src/libc/gen/tzset.3 +++ b/src/libc/gen/tzset.3 @@ -298,27 +298,32 @@ may be used to separate the .Em rule from the rest of the specification. .Sh FILES -.Bl -tag -width /usr/share/zoneinfo/posixrules -compact +#ifdef UNIFDEF_TZDIR_SYMLINK +.ds zi /var/db/timezone/zoneinfo +#else /* !UNIFDEF_TZDIR_SYMLINK */ +.ds zi /usr/share/zoneinfo +#endif /* UNIFDEF_TZDIR_SYMLINK */ +.Bl -tag -width \*(zi/posixrules -compact .It Pa /etc/localtime local time zone file -.It Pa /usr/share/zoneinfo +.It Pa \*(zi time zone directory -.It Pa /usr/share/zoneinfo/posixrules +.It Pa \*(zi/posixrules rules for .Tn POSIX Ns -style .Tn TZ Ns 's -.It Pa /usr/share/zoneinfo/GMT +.It Pa \*(zi/GMT for .Tn UTC leap seconds .El .Pp If the file -.Pa /usr/share/zoneinfo/GMT +.Pa \*(zi/GMT does not exist, .Tn UTC leap seconds are loaded from -.Pa /usr/share/zoneinfo/posixrules . +.Pa \*(zi/posixrules . .Sh SEE ALSO .Xr date 1 , .Xr gettimeofday 2 , diff --git a/src/libc/gen/uname.c b/src/libc/gen/uname.c index c4ebb079c..8ed2924ca 100644 --- a/src/libc/gen/uname.c +++ b/src/libc/gen/uname.c @@ -72,12 +72,13 @@ uname(name) rval = -1; else for (p = name->version; len--; ++p) - if (*p == '\n' || *p == '\t') - if (len > 1) + if (*p == '\n' || *p == '\t') { + if (len > 1) { *p = ' '; - else + } else { *p = '\0'; - + } + } mib[0] = CTL_HW; mib[1] = HW_MACHINE; len = sizeof(name->machine); diff --git a/src/libc/gen/utmpx-darwin.c b/src/libc/gen/utmpx-darwin.c index d8b034069..485fa5dd1 100644 --- a/src/libc/gen/utmpx-darwin.c +++ b/src/libc/gen/utmpx-darwin.c @@ -41,8 +41,6 @@ #include #include #include -#include -#include #include #include @@ -52,21 +50,31 @@ #include #include #include -//#include #ifdef UTMP_COMPAT #include #endif /* UTMP_COMPAT */ +#if ASL_API_VERSION < 20131108 +#include +#include +#endif + __private_extern__ const char __utx_magic__[UTMPX_MAGIC] = __UTX_MAGIC__; extern const char _utmpx_vers[]; /* in utmpx.c */ +#if ASL_API_VERSION < 20131108 static void msg2lastlogx(const aslmsg, struct lastlogx *); static void msg2utmpx(const aslmsg, struct utmpx *); static void utmpx2msg(const struct utmpx *, aslmsg); +#else +static void msg2lastlogx(asl_object_t, struct lastlogx *); +static void msg2utmpx(asl_object_t, struct utmpx *); +static void utmpx2msg(const struct utmpx *, asl_object_t); +#endif -static int pw_size = 0; +static size_t pw_size = 0; #define FACILITY "Facility" #define WTMP_COUNT 32 @@ -141,51 +149,86 @@ getlastlogx(uid_t uid, struct lastlogx *lx) struct lastlogx * getlastlogxbyname(const char *user, struct lastlogx *lx) { +#if ASL_API_VERSION < 20131108 aslmsg m; asl_msg_t *qm[1]; asl_search_result_t query, *res; uint32_t status; + asl_store_t *store = NULL; uint64_t cmax; +#else + asl_object_t m, query, res; + size_t cmax; +#endif struct lastlogx *result = NULL; - asl_store_t *store; if (!user || !*user) return NULL; - store = NULL; +#if ASL_API_VERSION < 20131108 status = asl_store_open_read(NULL, &store); if (status != 0) return NULL; if (store == NULL) return NULL; +#endif /* * We search for the last LASTLOG_FACILITY entry that has the * ut_user entry matching the user's name. */ - if ((m = asl_new(ASL_TYPE_QUERY)) == NULL) + m = asl_new(ASL_TYPE_QUERY); + if (m == NULL) { +#if ASL_API_VERSION < 20131108 asl_store_close(store); +#endif return NULL; } asl_set_query(m, FACILITY, LASTLOG_FACILITY, ASL_QUERY_OP_EQUAL); asl_set_query(m, "ut_user", user, ASL_QUERY_OP_EQUAL); + +#if ASL_API_VERSION < 20131108 qm[0] = (asl_msg_t *)m; query.count = 1; query.msg = qm; +#else + query = asl_new(ASL_TYPE_LIST); + if (query == NULL) + { + asl_release(m); + return NULL; + } + + asl_append(query, m); + asl_release(m); +#endif res = NULL; cmax = 0; +#if ASL_API_VERSION < 20131108 asl_store_match_timeout(store, &query, &res, &cmax, -1, 1, -1, ASL_QUERY_TIMEOUT); asl_store_close(store); asl_free(m); +#else + res = asl_match(NULL, query, &cmax, -1, 1, ASL_QUERY_TIMEOUT, ASL_MATCH_DIRECTION_REVERSE); + asl_release(query); +#endif - if (status != 0) return NULL; if (res == NULL) return NULL; +#if ASL_API_VERSION < 20131108 m = aslresponse_next(res); +#else + m = asl_next(res); +#endif + if (m == NULL) { +#if ASL_API_VERSION < 20131108 aslresponse_free(res); +#else + asl_release(res); +#endif return NULL; } @@ -193,13 +236,21 @@ getlastlogxbyname(const char *user, struct lastlogx *lx) { if ((lx = (struct lastlogx *)malloc(sizeof(*lx))) == NULL) { +#if ASL_API_VERSION < 20131108 aslresponse_free(res); +#else + asl_release(res); +#endif return NULL; } } msg2lastlogx(m, lx); +#if ASL_API_VERSION < 20131108 aslresponse_free(res); +#else + asl_release(res); +#endif result = lx; return result; @@ -211,9 +262,13 @@ getlastlogxbyname(const char *user, struct lastlogx *lx) #define SGET(e,p) if ((cp = asl_get(m, __STRING(ut_##e))) != NULL) \ strncpy(u->p##_##e, cp, sizeof(u->p##_##e)) -/* fill in a struct lastlogx from a aslmsg */ +/* fill in a struct lastlogx from an ASL message */ static void +#if ASL_API_VERSION < 20131108 msg2lastlogx(const aslmsg m, struct lastlogx *u) +#else +msg2lastlogx(asl_object_t m, struct lastlogx *u) +#endif { const char *cp; @@ -224,9 +279,13 @@ msg2lastlogx(const aslmsg m, struct lastlogx *u) SGET(host, ll); } -/* fill in a struct utmpx from a aslmsg */ +/* fill in a struct utmpx from an ASL message */ static void -msg2utmpx(const aslmsg m, struct utmpx *u) +#if ASL_API_VERSION < 20131108 +msg2utmpx(aslmsg m, struct utmpx *u) +#else +msg2utmpx(asl_object_t m, struct utmpx *u) +#endif { const char *cp; @@ -241,9 +300,13 @@ msg2utmpx(const aslmsg m, struct utmpx *u) SGET(host, ut); } -/* fill in a aslmsg from a struct utmpx */ +/* fill in an ASL message from a struct utmpx */ static void +#if ASL_API_VERSION < 20131108 utmpx2msg(const struct utmpx *u, aslmsg m) +#else +utmpx2msg(const struct utmpx *u, asl_object_t m) +#endif { char buf[_UTX_HOSTSIZE + 1]; /* the largest string in struct utmpx */ const char *cp; @@ -292,18 +355,27 @@ static const char *utmpx_types[] = { "SHUTDOWN_TIME", /* 11 */ }; -/* send a struct utmpx record using asl */ +/* send a struct utmpx record using ASL */ __private_extern__ void _utmpx_asl(const struct utmpx *u) { +#if ASL_API_VERSION < 20131108 aslclient asl = asl_open(NULL, NULL, ASL_OPT_NO_REMOTE); /* could be NULL, but still works */ aslmsg m; +#else + asl_object_t asl = asl_open(NULL, NULL, ASL_OPT_NO_REMOTE); + asl_object_t m; +#endif char msg[64]; if (u->ut_type == EMPTY) return; if ((m = asl_new(ASL_TYPE_MSG)) == NULL) { +#if ASL_API_VERSION < 20131108 asl_close(asl); +#else + asl_release(asl); +#endif return; } /* @@ -344,9 +416,13 @@ _utmpx_asl(const struct utmpx *u) } asl_set(m, ASL_KEY_MSG, msg); asl_send(asl, m); +#if ASL_API_VERSION < 20131108 asl_free(m); - if (asl) - asl_close(asl); + asl_close(asl); +#else + asl_release(m); + asl_release(asl); +#endif } #define UT_USER (1 << 0) @@ -480,10 +556,15 @@ static struct { get_asl, set_asl }; + static struct { uint64_t start; int dir; +#if ASL_API_VERSION < 20131108 asl_search_result_t *res; +#else + asl_object_t res; +#endif char *str; uint32_t len; char inited; @@ -576,7 +657,11 @@ end_asl(void) { if (wtmp_asl.res != NULL) { +#if ASL_API_VERSION < 20131108 aslresponse_free(wtmp_asl.res); +#else + asl_release(wtmp_asl.res); +#endif wtmp_asl.res = NULL; } @@ -600,16 +685,28 @@ end_file(void) static struct utmpx * get_asl(void) { +#if ASL_API_VERSION < 20131108 aslmsg m; +#else + asl_object_t m; +#endif static struct utmpx utx; if (wtmp_asl.inited == 0) set_asl(-1); if (wtmp_asl.done != 0) return NULL; +#if ASL_API_VERSION < 20131108 m = aslresponse_next(wtmp_asl.res); +#else + m = asl_next(wtmp_asl.res); +#endif if (m == NULL) { +#if ASL_API_VERSION < 20131108 aslresponse_free(wtmp_asl.res); +#else + asl_release(wtmp_asl.res); +#endif wtmp_asl.res = NULL; wtmp_asl.done = 1; return NULL; @@ -714,12 +811,17 @@ _set_dir(int forward) static void set_asl(int forward) { +#if ASL_API_VERSION < 20131108 aslmsg q0, q1; asl_msg_t *m[2]; asl_search_result_t query; - uint64_t cmax; - asl_store_t *store; + asl_store_t *store = NULL; uint32_t status; + uint64_t cmax; +#else + asl_object_t q0, q1, query; + size_t cmax; +#endif _set_dir(forward); @@ -728,46 +830,75 @@ set_asl(int forward) if (wtmp_asl.res != NULL) { +#if ASL_API_VERSION < 20131108 aslresponse_free(wtmp_asl.res); +#else + asl_release(wtmp_asl.res); +#endif wtmp_asl.res = NULL; } - store = NULL; +#if ASL_API_VERSION < 20131108 status = asl_store_open_read(NULL, &store); if (status != 0) return; if (store == NULL) return; +#endif /* * Create a search query that matches either UTMPX_FACILITY * or LASTLOG_FACILITY. */ q0 = asl_new(ASL_TYPE_QUERY); - q1 = asl_new(ASL_TYPE_QUERY); + if (q0 == NULL) return; - if ((q0 == NULL) || (q1 == NULL)) + asl_set_query(q0, FACILITY, UTMPX_FACILITY, ASL_QUERY_OP_EQUAL); + + q1 = asl_new(ASL_TYPE_QUERY); + if (q1 == NULL) { - asl_store_close(store); - if (q0 != NULL) free(q0); - if (q1 != NULL) free(q1); +#if ASL_API_VERSION < 20131108 + asl_free(q0); +#else + asl_release(q0); +#endif return; } - asl_set_query(q0, FACILITY, UTMPX_FACILITY, ASL_QUERY_OP_EQUAL); asl_set_query(q1, FACILITY, LASTLOG_FACILITY, ASL_QUERY_OP_EQUAL); +#if ASL_API_VERSION < 20131108 m[0] = (asl_msg_t *)q0; m[1] = (asl_msg_t *)q1; query.count = 2; query.msg = m; +#else + query = asl_new(ASL_TYPE_LIST); + if (query == NULL) + { + asl_release(q0); + asl_release(q1); + return; + } + + asl_append(query, q0); + asl_append(query, q1); + + asl_release(q0); + asl_release(q1); +#endif cmax = 0; +#if ASL_API_VERSION < 20131108 asl_store_match_timeout(store, &query, &(wtmp_asl.res), &cmax, wtmp_asl.start, 0, wtmp_asl.dir, ASL_QUERY_TIMEOUT); asl_store_close(store); - - asl_free(q1); asl_free(q0); - + asl_free(q1); +#else + wtmp_asl.res = asl_match(NULL, query, &cmax, wtmp_asl.start, 0, ASL_QUERY_TIMEOUT, wtmp_asl.dir); + asl_release(query); +#endif + if (wtmp_asl.res == NULL) return; wtmp_asl.inited = 1; diff --git a/src/libc/gen/utmpx-darwin.h b/src/libc/gen/utmpx-darwin.h index 3b9d28dad..ae4733cc4 100644 --- a/src/libc/gen/utmpx-darwin.h +++ b/src/libc/gen/utmpx-darwin.h @@ -26,7 +26,6 @@ #include #include #include -#include #ifdef UTMP_COMPAT #define UTMP_COMPAT_UTMP0 0x01 @@ -38,8 +37,8 @@ #define LASTLOG_FACILITY "com.apple.system.lastlog" #define UTMPX_FACILITY "com.apple.system.utmpx" -#define UTMPX_LOCK(x) if (__is_threaded) pthread_mutex_lock(&(x)->utmpx_mutex) -#define UTMPX_UNLOCK(x) if (__is_threaded) pthread_mutex_unlock(&(x)->utmpx_mutex) +#define UTMPX_LOCK(x) pthread_mutex_lock(&(x)->utmpx_mutex) +#define UTMPX_UNLOCK(x) pthread_mutex_unlock(&(x)->utmpx_mutex) #define UTMPX_MAGIC 8 #define __UTX_MAGIC__ { 'u', 't', 'x', 0, 'v', 1, 0, 0 } @@ -50,8 +49,6 @@ LIBC_ABORT("%s: magic mismatch", (x)); \ } -extern int __is_threaded; - struct _utmpx { char magic[UTMPX_MAGIC]; struct utmpx ut; @@ -61,12 +58,11 @@ struct _utmpx { unsigned int utfile_system :1; /* are we using _PATH_UTMPX? */ unsigned int readonly :1; }; -extern struct _utmpx __utx__; /* the default struct _utmpx */ extern const char __utx_magic__[]; /* size of UTMPX_MAGIC */ #ifdef __LP64__ -#define __need_struct_timeval32 -#include <_structs.h> +#include +#include /* * these structures assume natural alignment so they are the same size @@ -99,6 +95,8 @@ struct utmpx32 { }; #endif /* __LP64__ */ +struct _utmpx *__default_utx(void); + void __endutxent(struct _utmpx *); struct utmpx *__getutxent(struct _utmpx *); void __setutxent(struct _utmpx *); diff --git a/src/libc/gen/wordexp.3 b/src/libc/gen/wordexp.3 deleted file mode 100644 index d2a40c5c0..000000000 --- a/src/libc/gen/wordexp.3 +++ /dev/null @@ -1,183 +0,0 @@ -.\" -.\" Copyright (c) 2002 Tim J. Robbins -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc/gen/wordexp.3,v 1.6 2003/09/08 19:57:14 ru Exp $ -.\" -.Dd December 27, 2002 -.Dt WORDEXP 3 -.Os -.Sh NAME -.Nm wordexp -.Nd "perform shell-style word expansions" -.Sh SYNOPSIS -.In wordexp.h -.Ft int -.Fo wordexp -.Fa "const char *restrict words" -.Fa "wordexp_t *restrict pwordexp" -.Fa "int flags" -.Fc -.Ft void -.Fo wordfree -.Fa "wordexp_t *pwordexp" -.Fc -.Sh DESCRIPTION -The -.Fn wordexp -function performs shell-style word expansion on -.Fa words . -It places the list of words into the -.Va we_wordv -member of -.Fa pwordexp -and the number of words into -.Va we_wordc . -.Pp -The -.Fa flags -argument (see -.Sx BUGS ) -is the bitwise inclusive OR of any of the following constants: -.Bl -tag -width ".Dv WRDE_SHOWERR" -.It Dv WRDE_APPEND -Append the words to those generated by a previous call to -.Fn wordexp . -.It Dv WRDE_DOOFS -As many -.Dv NULL -pointers as are specified by the -.Va we_offs -member of -.Fa pwordexp -are added to the front of -.Va we_wordv . -.It Dv WRDE_NOCMD -Disallow command substitution in -.Fa words . -See the note in -.Sx BUGS -before using this. -.It Dv WRDE_REUSE -The -.Fa pwordexp -argument was passed to a previous successful call to -.Fn wordexp -but has not been passed to -.Fn wordfree . -The implementation may reuse the space allocated to it. -.It Dv WRDE_SHOWERR -Do not redirect shell error messages to -.Pa /dev/null . -.It Dv WRDE_UNDEF -Report error on an attempt to expand an undefined shell variable. -.El -.Pp -The -.Vt wordexp_t -structure is defined in -.In wordexp.h -as: -.Bd -literal -offset indent -typedef struct { - size_t we_wordc; /* count of words matched */ - char **we_wordv; /* pointer to list of words */ - size_t we_offs; /* slots to reserve in we_wordv */ -} wordexp_t; -.Ed -.Pp -The -.Fn wordfree -function frees the memory allocated by -.Fn wordexp . -.Sh RETURN VALUES -The -.Fn wordexp -function returns zero if successful, otherwise it returns one of the following -error codes: -.Bl -tag -width ".Dv WRDE_NOSPACE" -.It Dv WRDE_BADCHAR -The -.Fa words -argument contains one of the following unquoted characters: -.Aq newline , -.Ql | , -.Ql & , -.Ql \&; , -.Ql < , -.Ql > , -.Ql \&( , -.Ql \&) , -.Ql { , -.Ql } . -.It Dv WRDE_BADVAL -An attempt was made to expand an undefined shell variable and -.Dv WRDE_UNDEF -is set in -.Fa flags . -.It Dv WRDE_CMDSUB -An attempt was made to use command substitution and -.Dv WRDE_NOCMD -is set in -.Fa flags . -.It Dv WRDE_NOSPACE -Not enough memory to store the result. -.It Dv WRDE_SYNTAX -Shell syntax error in -.Fa words . -.El -.Pp -The -.Fn wordfree -function returns no value. -.Sh EXAMPLES -Invoke the editor on all -.Pa .c -files in the current directory -and -.Pa /etc/motd -(error checking omitted): -.Bd -literal -offset indent -wordexp_t pwordexp; - -wordexp("${EDITOR:-vi} *.c /etc/motd", &pwordexp, 0); -execvp(pwordexp->we_wordv[0], pwordexp->we_wordv); -.Ed -.Sh SEE ALSO -.Xr sh 1 , -.Xr fnmatch 3 , -.Xr glob 3 , -.Xr popen 3 , -.Xr system 3 -.Sh BUGS -This version of -.Fn wordexp -ignores the value of the -.Fa flags -argument. -.Sh COPYRIGHT -Copyright 1995-2002 University Corporation for Atmospheric Research/Unidata -.Pp -Portions of this software were developed by the Unidata Program at the -University Corporation for Atmospheric Research. diff --git a/src/libc/gen/wordexp.c b/src/libc/gen/wordexp.c deleted file mode 100644 index 467603d26..000000000 --- a/src/libc/gen/wordexp.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright (c) 2005, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// For _NSGetEnviron() -- which gives us a pointer to environ -#include - -extern size_t malloc_good_size(size_t size); -extern int errno; - -pthread_once_t re_init_c = PTHREAD_ONCE_INIT; -static regex_t re_cmd, re_goodchars, re_subcmd_syntax_err_kludge, re_quoted_string; - -/* Similar to popen, but captures stderr for you. Doesn't interoperate - with pclose. Call wait4 on your own */ -static pid_t popen_oe(char *cmd, FILE **out, FILE **err) { - int out_pipe[2], err_pipe[2]; - char *argv[4]; - pid_t pid; - posix_spawn_file_actions_t file_actions; - int errrtn; - - if ((errrtn = posix_spawn_file_actions_init(&file_actions)) != 0) { - errno = errrtn; - return 0; - } - if (pipe(out_pipe) < 0) { - posix_spawn_file_actions_destroy(&file_actions); - return 0; - } - if (pipe(err_pipe) < 0) { - posix_spawn_file_actions_destroy(&file_actions); - close(out_pipe[0]); - close(out_pipe[1]); - return 0; - } - - if (out_pipe[1] != STDOUT_FILENO) { - posix_spawn_file_actions_adddup2(&file_actions, out_pipe[1], STDOUT_FILENO); - posix_spawn_file_actions_addclose(&file_actions, out_pipe[1]); - } - posix_spawn_file_actions_addclose(&file_actions, out_pipe[0]); - if (err_pipe[1] != STDERR_FILENO) { - posix_spawn_file_actions_adddup2(&file_actions, err_pipe[1], STDERR_FILENO); - posix_spawn_file_actions_addclose(&file_actions, err_pipe[1]); - } - posix_spawn_file_actions_addclose(&file_actions, err_pipe[0]); - - argv[0] = "sh"; - argv[1] = "-c"; - argv[2] = cmd; - argv[3] = NULL; - - errrtn = posix_spawn(&pid, _PATH_BSHELL, &file_actions, NULL, argv, *_NSGetEnviron()); - posix_spawn_file_actions_destroy(&file_actions); - - if (errrtn != 0) { - close(out_pipe[0]); - close(out_pipe[1]); - close(err_pipe[0]); - close(err_pipe[1]); - errno = errrtn; - return 0; - } - - *out = fdopen(out_pipe[0], "r"); - assert(*out); - close(out_pipe[1]); - *err = fdopen(err_pipe[0], "r"); - assert(*err); - close(err_pipe[1]); - - return pid; -} - -static void re_init(void) { - int rc = regcomp(&re_cmd, "(^|[^\\])(`|\\$\\([^(])", REG_EXTENDED|REG_NOSUB); - /* XXX I'm not sure the { } stuff is correct, - it may be overly restrictave */ - char *rx = "^([^\\\"'|&;<>(){}\n]" - "|\\\\." - "|'(\\\\\\\\|\\\\'|[^'])*'" - "|\"(\\\\\\\\|\\\\\"|[^\"])*\"" - "|`(\\\\\\\\|\\\\`|[^`])*`" - "|\\$\\(\\(([^)]|\\\\)*\\)\\)" /* can't do nesting in a regex */ - "|\\$\\(([^)]|\\\\)*\\)" /* can't do nesting in a regex */ - "|\\$\\{[^}]*\\}" - /* XXX: { } ? */ - ")*$"; - rc = regcomp(&re_goodchars, rx, - REG_EXTENDED|REG_NOSUB); - - rc = regcomp(&re_subcmd_syntax_err_kludge, - "command substitution.*syntax error", REG_EXTENDED|REG_NOSUB); - - rc = regcomp(&re_quoted_string, - "(^|[^\\])'(\\\\\\\\|\\\\'|[^'])*'", REG_EXTENDED|REG_NOSUB); -} - -/* Returns zero if it can't realloc */ -static int word_alloc(size_t want, wordexp_t *__restrict__ pwe, size_t *have) { - if (want < *have) { - return 1; - } - size_t bytes = malloc_good_size(sizeof(char *) * want * 2); - pwe->we_wordv = reallocf(pwe->we_wordv, bytes); - if (pwe->we_wordv) { - *have = bytes / sizeof(char *); - return 1; - } - return 0; -} - -static int -cmd_search(const char *str) { - regoff_t first = 0; - regoff_t last = strlen(str); - regmatch_t m = {first, last}; - int flags; - - if (last == 0) return REG_NOMATCH; /* empty string */ - - flags = REG_STARTEND; - while(regexec(&re_quoted_string, str, 1, &m, flags) == 0) { - /* - * We have matched a single quoted string, from m.rm_so to m.rm_eo. - * So the (non-quote string) from first to m.rm_so needs to be - * checked for command substitution. Then we use REG_STARTEND to - * look for any other single quote strings after this one. - */ - regmatch_t head = {first, m.rm_so}; - if (regexec(&re_cmd, str, 1, &head, flags) == 0) { - return 0; /* found a command substitution */ - } - flags = REG_NOTBOL | REG_STARTEND; - m.rm_so = first = m.rm_eo; - m.rm_eo = last; - } - /* Check the remaining string */ - flags = REG_STARTEND; - if (m.rm_so > 0) flags |= REG_NOTBOL; - return regexec(&re_cmd, str, 1, &m, flags); -} - -/* XXX this is _not_ designed to be fast */ -/* wordexp is also rife with security "challenges", unless you pass it - WRDE_NOCMD it *must* support subshell expansion, and even if you - don't beause it has to support so much of the standard shell (all - the odd little variable expansion options for example) it is hard - to do without a subshell). It is probbably just plan a Bad Idea - to call in anything setuid, or executing remotely. */ - -int wordexp(const char *__restrict__ words, - wordexp_t *__restrict__ pwe, int flags) { - /* cbuf_l's inital value needs to be big enough for 'cmd' plus - about 20 chars */ - size_t cbuf_l = 1024; - char *cbuf = NULL; - /* Put a NUL byte between each word, and at the end */ - char *cmd = "/usr/bin/perl -e 'print join(chr(0), @ARGV), chr(0)' -- "; - size_t wordv_l = 0, wordv_i = 0; - int rc; - wordexp_t save; - - /* Some errors require us to leave pwe unchanged, so we save it here */ - save = *pwe; - pthread_once(&re_init_c, re_init); - - if (flags & WRDE_NOCMD) { - /* This attempts to match any backticks or $(...)'s, but there may be - other ways to do subshell expansion that the standard doesn't - cover, but I don't know of any -- failures here are a potential - security risk */ - rc = cmd_search(words); - if (rc != REG_NOMATCH) { - /* Technically ==0 is WRDE_CMDSUB, and != REG_NOMATCH is - "some internal error", but failing to catch those here - could allow a subshell */ - return WRDE_CMDSUB; - } - } - rc = regexec(&re_goodchars, words, 0, NULL, 0); - if (rc != 0) { - /* Technically ==REG_NOMATCH is WRDE_BADCHAR, and != is - some internal error", but again failure to notice the - internal error could allow unexpected shell commands - (allowing an unexcaped ;), or file clobbering (unescaped - >) */ - return WRDE_BADCHAR; - } - - if (flags & WRDE_APPEND) { - wordv_i = wordv_l = pwe->we_wordc; - if (flags & WRDE_DOOFFS) { - wordv_l = wordv_i += pwe->we_offs; - } - } else { - if (flags & WRDE_REUSE) { - wordfree(pwe); - } - pwe->we_wordc = 0; - pwe->we_wordv = NULL; - - if (flags & WRDE_DOOFFS) { - size_t wend = wordv_i + pwe->we_offs; - word_alloc(wend, pwe, &wordv_l); - if (!pwe->we_wordv) { - return WRDE_NOSPACE; - } - bzero(pwe->we_wordv + wordv_i, pwe->we_offs * sizeof(char *)); - wordv_i = wend; - } else { - pwe->we_offs = 0; - } - } - - size_t need = 0; - while(!cbuf || need > cbuf_l) { - if (need > cbuf_l) { - cbuf_l = malloc_good_size(need +1); - } - cbuf = reallocf(cbuf, cbuf_l); - if (cbuf == NULL) { - wordfree(pwe); - return WRDE_NOSPACE; - } - cbuf[0] = '\0'; - if (flags & WRDE_UNDEF) { - strlcat(cbuf, "set -u; ", cbuf_l); - } - /* This kludge is needed because /bin/sh seems to set IFS to the - defualt even if you have set it; We also can't just ignore it - because it is hard/unplesent to code around or even a potential - security problem because the test suiete explicitly checks - to make sure setting IFS "works" */ - if (getenv("IFS")) { - setenv("_IFS", getenv("IFS"), 1); - strlcat(cbuf, "export IFS=${_IFS}; ", cbuf_l); - } - strlcat(cbuf, cmd, cbuf_l); - need = strlcat(cbuf, words, cbuf_l); - } - - FILE *out, *err; - pid_t pid = popen_oe(cbuf, &out, &err); - if (pid == 0) { - wordfree(pwe); - return WRDE_NOSPACE; - } - - char *word = NULL; - int word_l = 0; - int word_i = 0; - int ch; - - while(EOF != (ch = fgetc(out))) { - if (word_l <= word_i) { - word_l = malloc_good_size(word_l * 2 + 1); - word = reallocf(word, word_l); - if (!word) { - fclose(err); - fclose(out); - wordfree(pwe); - return WRDE_NOSPACE; - } - } - word[word_i++] = ch; - - if (ch == '\0') { - word_alloc(wordv_i + 1, pwe, &wordv_l); - char *tmp = strdup(word); - if (pwe->we_wordv == NULL || tmp == NULL) { - fclose(err); - fclose(out); - wordfree(pwe); - free(word); - free(tmp); - int status; - wait4(pid, &status, 0, NULL); - return WRDE_NOSPACE; - } - pwe->we_wordv[wordv_i++] = tmp; - pwe->we_wordc++; - word_i = 0; - } - } - - assert(word_i == 0); - free(word); - - char err_buf[1024]; - size_t err_sz = fread(err_buf, 1, sizeof(err_buf) -1, err); - err_buf[(err_sz >= 0) ? err_sz : 0] = '\0'; - if (flags & WRDE_SHOWERR) { - fputs(err_buf, stderr); - } - - pid_t got_pid = 0; - int status; - do { - pid = wait4(pid, &status, 0, NULL); - } while(got_pid == -1 && errno == EINTR); - - fclose(out); - fclose(err); - - /* the exit status isn't set for some command syntax errors */ - if (regexec(&re_subcmd_syntax_err_kludge, err_buf, 0, NULL, 0) == 0 - || got_pid == -1 || (WIFEXITED(status) && WEXITSTATUS(status))) { - if (!(flags & (WRDE_APPEND|WRDE_REUSE))) { - /* Restore pwe if possiable, can't really do it in the append - case, and isn't easy in the reuse case */ - *pwe = save; - } - if (strstr(err_buf, " unbound variable")) { - return WRDE_BADVAL; - } - return WRDE_SYNTAX; - } - - if (!word_alloc(wordv_i + 1, pwe, &wordv_l)) { - return WRDE_NOSPACE; - } - pwe->we_wordv[wordv_i] = NULL; - - return 0; -} - -void wordfree(wordexp_t *pwe) { - if (pwe == NULL || pwe->we_wordv == NULL) { - return; - } - - int i = 0, e = pwe->we_wordc + pwe->we_offs; - for(i = pwe->we_offs; i < e; i++) { - free(pwe->we_wordv[i]); - } - free(pwe->we_wordv); - pwe->we_wordv = NULL; -} diff --git a/src/libc/gmon/gmon.c b/src/libc/gmon/gmon.c index ff2f4edc4..1ba417166 100644 --- a/src/libc/gmon/gmon.c +++ b/src/libc/gmon/gmon.c @@ -137,28 +137,6 @@ extern void monreset( extern void monoutput( const char *filename); -static char profiling = -1; /* tas (test and set) location for NeXT */ -static char init = 0; /* set while moninit() is being serviced */ - -static unsigned long order = 0; /* call order */ - -typedef struct { - /* the address range and size this mon struct refers to */ - char *lowpc; - char *highpc; - unsigned long textsize; - /* the data structures to support the arc's and their counts */ - unsigned short *froms; /* froms is unsigned shorts indexing into tos */ - tostruct_t *tos; - long tolimit; - /* the pc-sample buffer, it's size and scale */ - char *sbuf; - long ssiz; /* includes the gmonhdr_t */ - long scale; -} mon_t; -static mon_t *mon = NULL; -static unsigned long nmon = 0; - void moninit( void) diff --git a/src/libc/i386/CMakeLists.txt b/src/libc/i386/CMakeLists.txt index ca68d0d5a..a8179b3e4 100644 --- a/src/libc/i386/CMakeLists.txt +++ b/src/libc/i386/CMakeLists.txt @@ -8,63 +8,14 @@ enable_language(C ASM) add_definitions(-DPRIVATE) set(i386_sources - gen/getmcontext.c - gen/makecontext.c - gen/setcontext.c - gen/setjmperr.c - gen/swapcontext.c - gen/cpu_number.S - gen/icacheinval.S gen/mcount.S - gen/_ctx_start.S - gen/getcontext.S - gen/_setcontext.S - - # sys/i386_gettimeofday_asm.S - # sys/mach_absolute_time_asm.S - sys/atomic.c - sys/spinlocks.c - sys/OSAtomic.S - sys/_setjmp.S - sys/setjmp.S - sys/_sigtramp.S - sys/spinlocks_asm.S - - string/bcopy_scalar.S - string/bcopy_sse2.S - string/bcopy_sse3x.S - string/bcopy_sse42.S - string/__bzero.S - string/bzero_scalar.S - string/bzero_sse2.S - string/bzero_sse42.S - string/ffs.S - string/longcopy_sse3x.S - string/memcmp.S - string/memset_pattern_sse2.S - string/memset.S - string/strcmp.S string/strcpy.S string/strlcat.S string/strlcpy.S string/strlen.S - string/strncmp.S string/strncpy.S - string/bcopy.c - string/bzero.c - string/memcpy.c - string/memmove.c - - pthreads/preempt.S - pthreads/pthread_getspecific.S - pthreads/pthread_mutex_lock.S - pthreads/pthread_self.S - #pthreads/pthread_set_self.S - pthreads/start_wqthread.S - pthreads/thread_start.S - pthreads/init_cpu_capabilities.c ) -add_library(libc-hwplat OBJECT ${i386_sources}) +add_library(libc-i386 OBJECT ${i386_sources}) diff --git a/src/libc/i386/gen/_ctx_start.S b/src/libc/i386/gen/_ctx_start.S deleted file mode 100644 index f6f8556e0..000000000 --- a/src/libc/i386/gen/_ctx_start.S +++ /dev/null @@ -1,82 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Copyright (c) 2001 Daniel Eischen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(__i386__) - -#include - -#ifdef DARLING -# define __ctx_start _ctx_start -# define __ctx_done _ctx_done -#endif - -/* - * _ctx_start((void *func)(int arg1, ..., argn), - * int arg1, ..., argn, ucontext_t *ucp) - * - * 0(%esp) - func - * 4(%esp) - arg1 - * 8(%esp) - arg2 - * ... - * (4*n)(%esp) - argn - * (4*(n + 1))(%esp) - ucp, %ebp setup to point here (base of stack) - */ -TEXT -LABEL(__ctx_start) - popl %eax /* get start function */ - call *%eax /* call start function */ - movl %esi, %esp /* - * setup stack for completion routine; - * ucp is now at top of stack - */ - CALL_EXTERN(__ctx_done) /* should never return */ - int $5 /* trap */ - -#endif /* __i386__ */ diff --git a/src/libc/i386/gen/_setcontext.S b/src/libc/i386/gen/_setcontext.S deleted file mode 100644 index d9466a134..000000000 --- a/src/libc/i386/gen/_setcontext.S +++ /dev/null @@ -1,54 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined(__i386__) - -#include - -#ifdef DARLING -# define __setcontext _setcontext -# define _sigsetmask sigsetmask -#endif - -TEXT -LABEL(__setcontext) - subl $28, %esp - movl 32(%esp), %eax - movl 4(%eax), %eax - movl %eax, (%esp) /* load up signal mask */ - CALL_EXTERN(_sigsetmask) /* set signal mask */ - addl $28, %esp - movl 4(%esp), %ecx - movl 28(%ecx), %ecx - movl 16(%ecx), %ebx - movl 28(%ecx), %edi - movl 32(%ecx), %esi - movl 36(%ecx), %ebp - movl 40(%ecx), %esp - pushl 48(%ecx) - popfl - movl 12(%ecx), %eax - jmp *52(%ecx) - -#endif /* __i386__ */ diff --git a/src/libc/i386/gen/cpu_number.S b/src/libc/i386/gen/cpu_number.S deleted file mode 100644 index 71344c753..000000000 --- a/src/libc/i386/gen/cpu_number.S +++ /dev/null @@ -1,68 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2008 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -/* - * These platfunc routines provide fast access to the logical cpu number - * of the calling processor assuming no pre-emption occurs. This number - * is encoded in the bottom 12-bits of the limit field of the IDTR (the - * Interrupt Descriptor Table Register). The SIDT instruction is used in - * userspace to read this register and thus to gain access to the cpu number. - * The IDTR is loaded by the kernel for each processor at startup - see - * osfmk/i386/mp_desc.c. - */ - -/* return logical cpu number in %eax */ - -#ifdef DARLING -#define _cpu_number cpu_number -#endif - - .align 4 -#ifdef DARLING - .hidden _cpu_number - .globl _cpu_number -#else - .private_extern _cpu_number -#endif -_cpu_number: - push %ebp - mov %esp,%ebp - sub $8, %esp // space to read IDTR - - sidt (%esp) // store limit:base on stack - movw (%esp), %ax // get limit - and $0xfff, %eax // mask off lower 12 bits to return - - mov %ebp,%esp - pop %ebp - ret diff --git a/src/libc/i386/gen/getcontext.S b/src/libc/i386/gen/getcontext.S deleted file mode 100644 index ae37c1120..000000000 --- a/src/libc/i386/gen/getcontext.S +++ /dev/null @@ -1,59 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined(__i386__) - -#include - -#ifdef DARLING -# define _getcontext getcontext -# define _getmcontext getmcontext -#endif - -TEXT -LABEL(_getcontext) - subl $28, %esp - movl 32(%esp), %eax - movl %eax, (%esp) - movl %esp, 4(%esp) - CALL_EXTERN(_getmcontext) - movl %eax, %ecx - addl $28, %esp - movl %ebx, 16(%ecx) - movl %edi, 28(%ecx) - movl %esi, 32(%ecx) - movl %ebp, 36(%ecx) - movl (%esp), %eax - movl %eax, 52(%ecx) - movl %esp, %eax - addl $4, %eax - movl %eax, 40(%ecx) - pushf - popl %eax - movl %eax, 48(%ecx) - xorl %eax, %eax - movl %eax, 12(%ecx) - ret - -#endif /* __i386__ */ diff --git a/src/libc/i386/gen/getmcontext.c b/src/libc/i386/gen/getmcontext.c deleted file mode 100644 index a64da4cfb..000000000 --- a/src/libc/i386/gen/getmcontext.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined(__i386__) - -#define _XOPEN_SOURCE 600L - -#include -#include -#include -#include -#include -#include - -extern size_t pthread_get_stacksize_np(pthread_t); -extern void *pthread_get_stackaddr_np(pthread_t); -#ifdef __DYNAMIC__ -extern int __in_sigtramp; -#endif /* __DYNAMIC_ */ - -__private_extern__ mcontext_t -getmcontext(ucontext_t *uctx, void *sp) -{ - pthread_t self = pthread_self(); - mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; - size_t stacksize = pthread_get_stacksize_np(self); - stack_t stack; - - uctx->uc_stack.ss_sp = sp; - uctx->uc_stack.ss_flags = 0; - - if (0 == sigaltstack(NULL, &stack)) { - if (stack.ss_flags & SS_ONSTACK) { - uctx->uc_stack = stack; - stacksize = stack.ss_size; - } - } - - if (stacksize == 0) { /* main thread doesn't have pthread stack size */ - struct rlimit rlim; - if (0 == getrlimit(RLIMIT_STACK, &rlim)) - stacksize = rlim.rlim_cur; - } - - uctx->uc_stack.ss_size = stacksize; - - if (uctx->uc_mcontext != mctx) { - uctx->uc_mcontext = mctx; - -#ifdef __DYNAMIC__ - uctx->uc_link = (ucontext_t*)__in_sigtramp; /* non-zero if in signal handler */ -#else /* !__DYNAMIC__ */ - uctx->uc_link = 0; -#endif /* __DYNAMIC__ */ - - } - - sigprocmask(0, NULL, &uctx->uc_sigmask); - return mctx; -} - -#endif /* __i386__ */ diff --git a/src/libc/i386/gen/icacheinval.S b/src/libc/i386/gen/icacheinval.S deleted file mode 100644 index 9b1870f6d..000000000 --- a/src/libc/i386/gen/icacheinval.S +++ /dev/null @@ -1,64 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - - #include - - - .text - .align 4, 0x00 - -#ifdef DARLING -# define _sys_icache_invalidate sys_icache_invalidate -# define _sys_dcache_flush sys_dcache_flush -#endif - -/* void sys_icache_invalidate(addr_t start, int length) */ - - .globl _sys_icache_invalidate -_sys_icache_invalidate: - // This is a NOP on intel processors, since the intent of the API - // is to make data executable, and Intel L1Is are coherent with L1D. - ret - - -/* void sys_dcache_flush(addr_t start, int length) */ - - .globl _sys_dcache_flush -_sys_dcache_flush: - movl 8(%esp),%ecx // get length - movl 4(%esp),%edx // get ptr - testl %ecx,%ecx // length 0? - jz 2f // yes - mfence // ensure previous stores make it to memory - clflush -1(%edx,%ecx) // make sure last line is flushed -1: - clflush (%edx) // flush a line - addl $64,%edx - subl $64,%ecx - ja 1b - mfence // make sure memory is updated before we return -2: - ret diff --git a/src/libc/i386/gen/makecontext.c b/src/libc/i386/gen/makecontext.c deleted file mode 100644 index 5d1a3caec..000000000 --- a/src/libc/i386/gen/makecontext.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2007, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Copyright (c) 2001 Daniel M. Eischen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(__i386__) - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -/* Prototypes */ -extern void _ctx_start(ucontext_t *, int argc, ...); - -void -_ctx_done (ucontext_t *ucp) -{ - if (ucp->uc_link == NULL) - exit(0); - else { - /* - * Since this context has finished, don't allow it - * to be restarted without being reinitialized (via - * setcontext or swapcontext). - */ - ucp->uc_mcsize = 0; - - /* Set context to next one in link */ - /* XXX - what to do for error, abort? */ - setcontext((const ucontext_t *)ucp->uc_link); - LIBC_ABORT("setcontext failed"); /* should never get here */ - } -} - -void -makecontext(ucontext_t *ucp, void (*start)(), int argc, ...) -{ - va_list ap; - char *stack_top; - intptr_t *argp; - int i; - - if (ucp == NULL) - return; - else if ((ucp->uc_stack.ss_sp == NULL) || - (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { - /* - * This should really return -1 with errno set to ENOMEM - * or something, but the spec says that makecontext is - * a void function. At least make sure that the context - * isn't valid so it can't be used without an error. - */ - ucp->uc_mcsize = 0; - } - /* XXX - Do we want to sanity check argc? */ - else if ((argc < 0) || (argc > NCARGS)) { - ucp->uc_mcsize = 0; - } - /* Make sure the context is valid. */ - else { - /* - * Arrange the stack as follows: - * - * _ctx_start() - context start wrapper - * start() - user start routine - * arg1 - first argument, aligned(16) - * ... - * argn - * ucp - this context, %ebp points here - * - * When the context is started, control will return to - * the context start wrapper which will pop the user - * start routine from the top of the stack. After that, - * the top of the stack will be setup with all arguments - * necessary for calling the start routine. When the - * start routine returns, the context wrapper then sets - * the stack pointer to %ebp which was setup to point to - * the base of the stack (and where ucp is stored). It - * will then call _ctx_done() to swap in the next context - * (uc_link != 0) or exit the program (uc_link == 0). - */ - mcontext_t mc; - - stack_top = (char *)(ucp->uc_stack.ss_sp + - ucp->uc_stack.ss_size - sizeof(intptr_t)); - - /* - * Adjust top of stack to allow for 3 pointers (return - * address, _ctx_start, and ucp) and argc arguments. - * We allow the arguments to be pointers also. The first - * argument to the user function must be properly aligned. - */ - stack_top = stack_top - (sizeof(intptr_t) * (1 + argc)); - stack_top = (char *)((unsigned)stack_top & ~15); - stack_top = stack_top - (2 * sizeof(intptr_t)); - argp = (intptr_t *)stack_top; - - /* - * Setup the top of the stack with the user start routine - * followed by all of its aguments and the pointer to the - * ucontext. We need to leave a spare spot at the top of - * the stack because setcontext will move eip to the top - * of the stack before returning. - */ - *argp = (intptr_t)_ctx_start; /* overwritten with same value */ - argp++; - *argp = (intptr_t)start; - argp++; - - /* Add all the arguments: */ - va_start(ap, argc); - for (i = 0; i < argc; i++) { - *argp = va_arg(ap, intptr_t); - argp++; - } - va_end(ap); - - /* The ucontext is placed at the bottom of the stack. */ - *argp = (intptr_t)ucp; - - /* - * Set the machine context to point to the top of the - * stack and the program counter to the context start - * wrapper. Note that setcontext() pushes the return - * address onto the top of the stack, so allow for this - * by adjusting the stack downward 1 slot. Also set - * %esi to point to the base of the stack where ucp - * is stored. - */ - mc = ucp->uc_mcontext; - - mc->__ss.__esi = (int)argp; - mc->__ss.__ebp = 0; - mc->__ss.__esp = (int)stack_top + sizeof(caddr_t); - mc->__ss.__eip = (int)_ctx_start; - } -} - -#endif /* __i386__ */ diff --git a/src/libc/i386/gen/mcount.S b/src/libc/i386/gen/mcount.S index f3a1bc550..bb0e7d39b 100644 --- a/src/libc/i386/gen/mcount.S +++ b/src/libc/i386/gen/mcount.S @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. * @@ -23,10 +22,6 @@ */ #import -#ifdef DARLING -# define _moncount moncount -#endif - .text .globl mcount mcount: diff --git a/src/libc/i386/gen/setcontext.c b/src/libc/i386/gen/setcontext.c deleted file mode 100644 index 022a74ad9..000000000 --- a/src/libc/i386/gen/setcontext.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined(__i386__) - -#define _XOPEN_SOURCE 600L - -#include - -extern int _setcontext(const ucontext_t *); - -int -setcontext(const ucontext_t *uctx) -{ - mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; - ucontext_t *_uctx = (ucontext_t *)uctx; - if (mctx != _uctx->uc_mcontext) - _uctx->uc_mcontext = mctx; - return _setcontext(uctx); -} - -#endif /* __i386__ */ diff --git a/src/libc/i386/gen/setjmperr.c b/src/libc/i386/gen/setjmperr.c deleted file mode 100644 index bf065952f..000000000 --- a/src/libc/i386/gen/setjmperr.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1980 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)setjmperr.c 5.4 (Berkeley) 6/27/88"; -#endif /* LIBC_SCCS and not lint */ - -#include - -/* - * This routine is called from longjmp() when an error occurs. - * Programs that wish to exit gracefully from this error may - * write their own versions. - * If this routine returns, the program is aborted. - */ - -void -longjmperror() -{ -#define ERRMSG "longjmp botch\n" - write(2, ERRMSG, sizeof(ERRMSG) - 1); -} diff --git a/src/libc/i386/gen/swapcontext.c b/src/libc/i386/gen/swapcontext.c deleted file mode 100644 index 2c8145c70..000000000 --- a/src/libc/i386/gen/swapcontext.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Copyright (c) 2001 Daniel M. Eischen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(__i386__) - -#include -#include -#include -#include - -#include -#include - -#define uc_flags uc_onstack -#define UCF_SWAPPED 0x80000000 - -int -swapcontext(ucontext_t *oucp, const ucontext_t *ucp) -{ - int ret; - - if ((oucp == NULL) || (ucp == NULL)) { - errno = EINVAL; - return (-1); - } - oucp->uc_flags &= ~UCF_SWAPPED; - ret = getcontext(oucp); - if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) { - oucp->uc_flags |= UCF_SWAPPED; - ret = setcontext(ucp); - } - return (ret); -} - -#endif /* __i386__ */ diff --git a/src/libc/i386/pthreads/init_cpu_capabilities.c b/src/libc/i386/pthreads/init_cpu_capabilities.c deleted file mode 100644 index 51448d78b..000000000 --- a/src/libc/i386/pthreads/init_cpu_capabilities.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* Initialize the "_cpu_capabilities" vector on x86 processors. */ - -#define _APPLE_API_PRIVATE -#include -#undef _APPLE_API_PRIVATE - -int _cpu_has_altivec = 0; // DEPRECATED -int _cpu_capabilities = 0; - -__private_extern__ void -_init_cpu_capabilities( void ) -{ - _cpu_capabilities = _get_cpu_capabilities(); -} diff --git a/src/libc/i386/pthreads/preempt.S b/src/libc/i386/pthreads/preempt.S deleted file mode 100644 index e1ad46634..000000000 --- a/src/libc/i386/pthreads/preempt.S +++ /dev/null @@ -1,83 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -#ifdef DARLING -# define _preempt preempt -# define _backoff backoff -#endif - -/* Subroutine to make a preempt syscall. Called when we notice %ebx is - * nonzero after returning from a PFZ subroutine. - * When we enter kernel: - * %edx = return address - * %ecx = stack ptr - * Destroys %eax, %ecx, and %edx. - */ - .align 4 -#ifndef DARLING - .private_extern _preempt -#else - .globl _preempt - .hidden _preempt -#endif -_preempt: - popl %edx // get return address - movl %esp,%ecx // save stack ptr here - movl $(-58),%eax /* 58 = pfz_exit */ - xorl %ebx,%ebx // clear "preemption pending" flag - sysenter - - -/* Subroutine to back off if we cannot get the spinlock. Called - * after a few attempts inline in the PFZ subroutines. This code is - * not in the PFZ. - * %edi = ptr to queue head structure - * %ebx = preemption flag (nonzero if preemption pending) - * Destroys %eax. - */ - - .align 4 -#ifndef DARLING - .private_extern _backoff -#else - .globl _backoff - .hidden _backoff -#endif -_backoff: - testl %ebx,%ebx // does kernel want to preempt us? - jz 1f // no - xorl %ebx,%ebx // yes, clear flag - pushl %edx // preserve regs used by preempt syscall - pushl %ecx - call _preempt - popl %ecx - popl %edx -1: - pause // SMT-friendly backoff - cmpl $0,8(%edi) // sniff the lockword - jnz 1b // loop if still taken - ret // lockword is free, so reenter PFZ diff --git a/src/libc/i386/pthreads/pthread_getspecific.S b/src/libc/i386/pthreads/pthread_getspecific.S deleted file mode 100644 index 96dd1b7cc..000000000 --- a/src/libc/i386/pthreads/pthread_getspecific.S +++ /dev/null @@ -1,37 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "pthread_machdep.h" - -#ifdef DARLING -# define _pthread_getspecific pthread_getspecific -#endif - -.text -.align (1<<2), 0x90 -.globl _pthread_getspecific -_pthread_getspecific: - movl 4(%esp),%eax - movl %fs:(,%eax,4),%eax - ret diff --git a/src/libc/i386/pthreads/pthread_mutex_lock.S b/src/libc/i386/pthreads/pthread_mutex_lock.S deleted file mode 100644 index ed34a76d7..000000000 --- a/src/libc/i386/pthreads/pthread_mutex_lock.S +++ /dev/null @@ -1,68 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -#ifdef DARLING -# define _preempt preempt -# define _commpage_pfz_base commpage_pfz_base -#endif - - .text - .align (1<<2) - .globl __commpage_pthread_mutex_lock -__commpage_pthread_mutex_lock: - pushl %ebp // set up frame for backtrace - movl %esp,%ebp - pushl %esi - pushl %edi - pushl %ebx - xorl %ebx,%ebx // clear "preemption pending" flag - movl 20(%esp),%edi // %edi == ptr to LVAL/UVAL structure - lea 20(%esp),%esi // %esi == ptr to argument list - movl _COMM_PAGE_SPIN_COUNT, %edx - movl 16(%esi),%ecx // get mask (ie, PTHRW_EBIT etc) -1: - testl 0(%edi),%ecx // is mutex available? - jz 2f // yes, it is available - pause - decl %edx // decrement max spin count - jnz 1b // keep spinning -2: - EXTERN_TO_REG(_commpage_pfz_base, %ecx) - movl (%ecx), %ecx - addl $(_COMM_TEXT_PFZ_MUTEX_LOCK_OFFSET), %ecx - call *%ecx - testl %ebx,%ebx // pending preemption? - jz 3f - pushl %eax // save return value across sysenter - call _preempt - popl %eax -3: - popl %ebx - popl %edi - popl %esi - popl %ebp - ret diff --git a/src/libc/i386/pthreads/pthread_self.S b/src/libc/i386/pthreads/pthread_self.S deleted file mode 100644 index b471959df..000000000 --- a/src/libc/i386/pthreads/pthread_self.S +++ /dev/null @@ -1,36 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "pthread_machdep.h" - -#ifdef DARLING -# define _pthread_self pthread_self -#endif - -.text -.align (1<<2), 0x90 -.globl _pthread_self -_pthread_self: - movl %fs:0,%eax - ret diff --git a/src/libc/i386/pthreads/pthread_set_self.S b/src/libc/i386/pthreads/pthread_set_self.S deleted file mode 100644 index aa76eb1b8..000000000 --- a/src/libc/i386/pthreads/pthread_set_self.S +++ /dev/null @@ -1,42 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#ifdef DARLING -# define ___pthread_set_self __pthread_set_self -#endif - -.text -.align 2, 0x90 -.globl ___pthread_set_self -___pthread_set_self: -#ifndef DARLING - pushl 4(%esp) - pushl $0 - movl $3,%eax - MACHDEP_SYSCALL_TRAP - addl $8,%esp -#endif - ret diff --git a/src/libc/i386/pthreads/start_wqthread.S b/src/libc/i386/pthreads/start_wqthread.S deleted file mode 100644 index c01e08877..000000000 --- a/src/libc/i386/pthreads/start_wqthread.S +++ /dev/null @@ -1,48 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "pthread_machdep.h" - -#ifdef DARLING -# define _start_wqthread start_wqthread -# define __pthread_wqthread _pthread_wqthread@PLT -#endif - -.text -.align 2, 0x90 -.globl _start_wqthread -_start_wqthread: -// This routine is never called directly by user code, jumped from kernel - push %ebp - mov %esp,%ebp - sub $28,%esp // align the stack - mov %edi,16(%esp) //arg5 - mov %edx,12(%esp) //arg4 - mov %ecx,8(%esp) //arg3 - mov %ebx,4(%esp) //arg2 - mov %eax,(%esp) //arg1 - call __pthread_wqthread - leave - ret - diff --git a/src/libc/i386/pthreads/thread_start.S b/src/libc/i386/pthreads/thread_start.S deleted file mode 100644 index d07b135c3..000000000 --- a/src/libc/i386/pthreads/thread_start.S +++ /dev/null @@ -1,49 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "pthread_machdep.h" - -#ifdef DARLING -# define _thread_start thread_start -# define __pthread_start _pthread_start -#endif - -.text -.align (1<<2), 0x90 -.globl _thread_start -_thread_start: -// This routine is never called directly by user code, jumped from kernel - push %ebp - mov %esp,%ebp - sub $28,%esp // align the stack - mov %esi,20(%esp) //arg6 - mov %edi,16(%esp) //arg5 - mov %edx,12(%esp) //arg4 - mov %ecx,8(%esp) //arg3 - mov %ebx,4(%esp) //arg2 - mov %eax,(%esp) //arg1 - call __pthread_start - leave - ret - diff --git a/src/libc/i386/string/__bzero.S b/src/libc/i386/string/__bzero.S deleted file mode 100644 index 58b483b05..000000000 --- a/src/libc/i386/string/__bzero.S +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef DARLING -# define ___bzero __bzero -# define _bzero bzero -#endif - - .globl ___bzero -___bzero: - jmp _bzero@PLT diff --git a/src/libc/i386/string/bcopy.c b/src/libc/i386/string/bcopy.c deleted file mode 100644 index 314b6838b..000000000 --- a/src/libc/i386/string/bcopy.c +++ /dev/null @@ -1,48 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse42); -PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse3x); -PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse2); -PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, scalar); - -static const platfunc_descriptor *bcopy_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse42), - PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse3x), - PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse2), - PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, scalar), - 0 -}; - -void *bcopy_chooser(void *, const void *, size_t) __asm__("bcopy"); -void *bcopy_chooser(void *src, const void *dest, size_t n) { - //__asm__(".desc _bcopy, 0x100"); - void *(*impl)(void *, const void *, size_t); - impl = find_platform_function((const platfunc_descriptor **) bcopy_platfunc_descriptors); - return impl(src, dest, n); -} diff --git a/src/libc/i386/string/bcopy_scalar.S b/src/libc/i386/string/bcopy_scalar.S deleted file mode 100644 index fc63dbbc0..000000000 --- a/src/libc/i386/string/bcopy_scalar.S +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from locore.s. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -//#include - - /* - * (ov)bcopy (src,dst,cnt) - * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800 - */ - -PLATFUNC_FUNCTION_START_GENERIC(bcopy, scalar, 32, 5) - pushl %ebp /* set up a frame for backtraces */ - movl %esp,%ebp - pushl %esi - pushl %edi - movl 8(%ebp),%esi - movl 12(%ebp),%edi - jmp 1f - -PLATFUNC_FUNCTION_START_GENERIC(memcpy, scalar, 32, 0) -PLATFUNC_FUNCTION_START_GENERIC(memmove, scalar, 32, 0) - pushl %ebp /* set up a frame for backtraces */ - movl %esp,%ebp - pushl %esi - pushl %edi - movl 8(%ebp),%edi - movl 12(%ebp),%esi - movl %edi,%eax -1: - movl 16(%ebp),%ecx - movl %edi,%edx - subl %esi,%edx - cmpl %ecx,%edx /* overlapping? */ - jb 2f - cld /* nope, copy forwards. */ - movl %ecx,%edx - shrl $2,%ecx /* copy by words */ - rep - movsl - movl %edx,%ecx - andl $3,%ecx /* any bytes left? */ - rep - movsb - popl %edi - popl %esi - popl %ebp - ret -2: - addl %ecx,%edi /* copy backwards. */ - addl %ecx,%esi - std - movl %ecx,%edx - andl $3,%ecx /* any fractional bytes? */ - decl %edi - decl %esi - rep - movsb - movl %edx,%ecx /* copy remainder by words */ - shrl $2,%ecx - subl $3,%esi - subl $3,%edi - rep - movsl - popl %edi - popl %esi - popl %ebp - cld - ret - -PLATFUNC_DESCRIPTOR(bcopy,scalar,0,0) -PLATFUNC_DESCRIPTOR(memcpy,scalar,0,0) -PLATFUNC_DESCRIPTOR(memmove,scalar,0,0) diff --git a/src/libc/i386/string/bcopy_sse2.S b/src/libc/i386/string/bcopy_sse2.S deleted file mode 100644 index 4987c5e46..000000000 --- a/src/libc/i386/string/bcopy_sse2.S +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include - -/* - * The bcopy/memcpy loops, tuned for Pentium-M class processors with SSE2 - * and 64-byte cache lines, such as Core and Core 2. - * - * The following #defines are tightly coupled to the u-architecture: - */ - -#define kShort 80 // too short to bother with SSE (must be >=80) -#define kVeryLong (500*1024) // large enough for non-temporal stores (must be >= 8192) -#define kBigChunk (256*1024) // outer loop chunk size for kVeryLong sized operands -#define kFastUCode (16*1024) // cutoff for microcode fastpath for "rep/movsl" - - -// void bcopy(const void *src, void *dst, size_t len); - -PLATFUNC_FUNCTION_START(bcopy, sse2, 32, 5) - pushl %ebp // set up a frame for backtraces - movl %esp,%ebp - pushl %esi - pushl %edi - movl 8(%ebp),%esi // get source ptr - movl 12(%ebp),%edi // get dest ptr - jmp Ljoin - -// -// void *memcpy(void *dst, const void *src, size_t len); -// void *memmove(void *dst, const void *src, size_t len); -// - -PLATFUNC_FUNCTION_START(memcpy, sse2, 32, 0) // void *memcpy(void *dst, const void *src, size_t len) -PLATFUNC_FUNCTION_START(memmove, sse2, 32, 0) // void *memmove(void *dst, const void *src, size_t len) -Lmemcpy_sse2: - pushl %ebp // set up a frame for backtraces - movl %esp,%ebp - pushl %esi - pushl %edi - movl 8(%ebp),%edi // get dest ptr - movl 12(%ebp),%esi // get source ptr - -Ljoin: // here from bcopy() with esi and edi loaded - movl 16(%ebp),%ecx // get length - movl %edi,%edx - subl %esi,%edx // (dest - source) - cmpl %ecx,%edx // must move in reverse if (dest - source) < length - jb LReverseIsland -Lrejoin: // here from very-long-operand copies - cmpl $(kShort),%ecx // long enough to bother with SSE? - ja LNotShort // yes - -// Handle short forward copies. As the most common case, this is the fall-through path. -// ecx = length (<= kShort) -// esi = source ptr -// edi = dest ptr - -Lshort: - movl %ecx,%edx // copy length - shrl $2,%ecx // get #doublewords - jz LLeftovers -2: // loop copying doublewords - movl (%esi),%eax - addl $4,%esi - movl %eax,(%edi) - addl $4,%edi - dec %ecx - jnz 2b -LLeftovers: // handle leftover bytes (0..3) in last word - andl $3,%edx // any leftover bytes? - jz 5f -4: // loop copying bytes - movb (%esi),%al - inc %esi -movb %al,(%edi) - inc %edi - dec %edx - jnz 4b -5: - movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove - popl %edi - popl %esi - popl %ebp - ret - - -LReverseIsland: // keep the "jb" above a short branch... - jmp LReverse // ...because reverse moves are uncommon - - -// Handle forward moves that are long enough to justify use of SSE3. -// First, 16-byte align the destination. -// ecx = length (> kShort) -// esi = source ptr -// edi = dest ptr - -LNotShort: - cmpl $(kVeryLong),%ecx // long enough to justify heavyweight loops? - movl %edi,%edx // copy destination - jae LVeryLong // use very-long-operand path - negl %edx - andl $15,%edx // get #bytes to align destination - jz LDestAligned // already aligned - subl %edx,%ecx // decrement length -1: // loop copying 1..15 bytes - movb (%esi),%al - inc %esi - movb %al,(%edi) - inc %edi - dec %edx - jnz 1b - -// Destination is now aligned. Prepare for forward loops over 64-byte chunks. -// Since kShort>=80 and we've moved at most 15 bytes already, there is at least one chunk. - -LDestAligned: - movl %ecx,%edx // copy length - movl %ecx,%eax // twice - andl $63,%ecx // get remaining bytes for Lshort - andl $-64,%edx // get number of bytes we will copy in inner loop - addl %edx,%esi // point to 1st byte not copied - addl %edx,%edi - negl %edx // now generate offset to 1st byte to be copied - testl $15,%esi // is source aligned too? - jnz LUnalignedLoop // no - - cmpl $(kFastUCode),%eax // long enough for the fastpath in microcode? - jb LAlignedLoop // no, use SSE - cld // we'll move forward - movl %eax,%ecx // copy length again - shrl $2,%ecx // compute #words to move - addl %edx,%esi // restore ptrs to 1st byte of source and dest - addl %edx,%edi - rep // the u-code will optimize this - movsl - movl %eax,%edx // original length - jmp LLeftovers // handle 0..3 leftover bytes - - -// Forward aligned loop for medium length operands (kShort < n < kVeryLong). - - .align 4,0x90 // 16-byte align inner loops -LAlignedLoop: // loop over 64-byte chunks - movdqa (%esi,%edx),%xmm0 - movdqa 16(%esi,%edx),%xmm1 - movdqa 32(%esi,%edx),%xmm2 - movdqa 48(%esi,%edx),%xmm3 - - movdqa %xmm0,(%edi,%edx) - movdqa %xmm1,16(%edi,%edx) - movdqa %xmm2,32(%edi,%edx) - movdqa %xmm3,48(%edi,%edx) - - addl $64,%edx - jnz LAlignedLoop - - jmp Lshort // copy remaining 0..15 bytes and done - - -// Forward unaligned loop for medium length operands (kShort < n < kVeryLong). -// Note that LDDQU==MOVDQU on these machines, ie we don't care when we cross -// source cache lines. - - .align 4,0x90 // 16-byte align inner loops -LUnalignedLoop: // loop over 64-byte chunks - movdqu (%esi,%edx),%xmm0 // the loads are unaligned - movdqu 16(%esi,%edx),%xmm1 - movdqu 32(%esi,%edx),%xmm2 - movdqu 48(%esi,%edx),%xmm3 - - movdqa %xmm0,(%edi,%edx) // we can use aligned stores - movdqa %xmm1,16(%edi,%edx) - movdqa %xmm2,32(%edi,%edx) - movdqa %xmm3,48(%edi,%edx) - - addl $64,%edx - jnz LUnalignedLoop - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Very long forward moves. These are at least several pages, so we loop over big -// chunks of memory (kBigChunk in size.) We first prefetch the chunk, and then copy -// it using non-temporal stores. Hopefully all the reads occur in the prefetch loop, -// so the copy loop reads from L2 and writes directly to memory (with write combining.) -// This minimizes bus turnaround and maintains good DRAM page locality. -// Note that for this scheme to work, kVeryLong must be a large fraction of L2 cache -// size. Otherwise, it is counter-productive to bypass L2 on the stores. -// ecx = length (>= kVeryLong bytes) -// edi = dest (aligned) -// esi = source - -LVeryLong: - pushl %ebx // we'll need to use this - movl %edi,%ebx // copy dest ptr - negl %ebx - andl $63,%ebx // get #bytes to cache line align destination - jz LBigChunkLoop // already aligned - -// Cache line align destination, so temporal stores in copy loops work right. - - pushl %ecx // save total length remaining - pushl %ebx // arg3 - #bytes to align destination (1..63) - pushl %esi // arg2 - source - pushl %edi // arg1 - dest - call Lmemcpy_sse2 // align the destination - movl 12(%esp),%ecx // recover total length - addl $16,%esp - addl %ebx,%esi // adjust ptrs and lengths past copy - addl %ebx,%edi - subl %ebx,%ecx - -// Loop over big chunks. -// ecx = length remaining (>= 4096) -// edi = dest (64-byte aligned) -// esi = source (may be unaligned) - -LBigChunkLoop: - movl $(kBigChunk),%edx // assume we can do a full chunk - cmpl %edx,%ecx // do we have a full chunk left to do? - cmovbl %ecx,%edx // if not, only move what we have left - andl $-4096,%edx // we work in page multiples - xor %eax,%eax // initialize chunk offset - jmp LTouchLoop - -// Because the source may be unaligned, we use byte loads to touch. -// ecx = length remaining (including this chunk) -// edi = ptr to start of dest chunk -// esi = ptr to start of source chunk -// edx = chunk length (multiples of pages) -// ebx = scratch reg used to read a byte of each cache line -// eax = chunk offset - - .align 4,0x90 // 16-byte align inner loops -LTouchLoop: - movzb (%esi,%eax),%ebx // touch line 0, 2, 4, or 6 of page - movzb 1*64(%esi,%eax),%ebx // touch line 1, 3, 5, or 7 - movzb 8*64(%esi,%eax),%ebx // touch line 8, 10, 12, or 14 - movzb 9*64(%esi,%eax),%ebx // etc - - movzb 16*64(%esi,%eax),%ebx - movzb 17*64(%esi,%eax),%ebx - movzb 24*64(%esi,%eax),%ebx - movzb 25*64(%esi,%eax),%ebx - - movzb 32*64(%esi,%eax),%ebx - movzb 33*64(%esi,%eax),%ebx - movzb 40*64(%esi,%eax),%ebx - movzb 41*64(%esi,%eax),%ebx - - movzb 48*64(%esi,%eax),%ebx - movzb 49*64(%esi,%eax),%ebx - movzb 56*64(%esi,%eax),%ebx - movzb 57*64(%esi,%eax),%ebx - - subl $-128,%eax // next slice of page (adding 128 w 8-bit immediate) - testl $512,%eax // done with this page? - jz LTouchLoop // no, next of four slices - addl $(4096-512),%eax // move on to next page - cmpl %eax,%edx // done with this chunk? - jnz LTouchLoop // no, do next page - -// The chunk has been pre-fetched, now copy it using non-temporal stores. -// There are two copy loops, depending on whether the source is 16-byte aligned -// or not. - - addl %edx,%esi // increment ptrs by chunk length - addl %edx,%edi - subl %edx,%ecx // adjust remaining length - negl %edx // prepare loop index (counts up to 0) - testl $15,%esi // is source 16-byte aligned? - jnz LVeryLongUnaligned // source is not aligned - jmp LVeryLongAligned - - .align 4,0x90 // 16-byte align inner loops -LVeryLongAligned: // aligned loop over 128-bytes - movdqa (%esi,%edx),%xmm0 - movdqa 16(%esi,%edx),%xmm1 - movdqa 32(%esi,%edx),%xmm2 - movdqa 48(%esi,%edx),%xmm3 - movdqa 64(%esi,%edx),%xmm4 - movdqa 80(%esi,%edx),%xmm5 - movdqa 96(%esi,%edx),%xmm6 - movdqa 112(%esi,%edx),%xmm7 - - movntdq %xmm0,(%edi,%edx) - movntdq %xmm1,16(%edi,%edx) - movntdq %xmm2,32(%edi,%edx) - movntdq %xmm3,48(%edi,%edx) - movntdq %xmm4,64(%edi,%edx) - movntdq %xmm5,80(%edi,%edx) - movntdq %xmm6,96(%edi,%edx) - movntdq %xmm7,112(%edi,%edx) - - subl $-128,%edx // add 128 with an 8-bit immediate - jnz LVeryLongAligned - jmp LVeryLongChunkEnd - - .align 4,0x90 // 16-byte align inner loops -LVeryLongUnaligned: // unaligned loop over 128-bytes - movdqu (%esi,%edx),%xmm0 - movdqu 16(%esi,%edx),%xmm1 - movdqu 32(%esi,%edx),%xmm2 - movdqu 48(%esi,%edx),%xmm3 - movdqu 64(%esi,%edx),%xmm4 - movdqu 80(%esi,%edx),%xmm5 - movdqu 96(%esi,%edx),%xmm6 - movdqu 112(%esi,%edx),%xmm7 - - movntdq %xmm0,(%edi,%edx) - movntdq %xmm1,16(%edi,%edx) - movntdq %xmm2,32(%edi,%edx) - movntdq %xmm3,48(%edi,%edx) - movntdq %xmm4,64(%edi,%edx) - movntdq %xmm5,80(%edi,%edx) - movntdq %xmm6,96(%edi,%edx) - movntdq %xmm7,112(%edi,%edx) - - subl $-128,%edx // add 128 with an 8-bit immediate - jnz LVeryLongUnaligned - -LVeryLongChunkEnd: - cmpl $4096,%ecx // at least another page to go? - jae LBigChunkLoop // yes - - sfence // required by non-temporal stores - popl %ebx - jmp Lrejoin // handle remaining (0..4095) bytes - - -// Reverse moves. -// ecx = length -// esi = source ptr -// edi = dest ptr - -LReverse: - addl %ecx,%esi // point to end of strings - addl %ecx,%edi - cmpl $(kShort),%ecx // long enough to bother with SSE? - ja LReverseNotShort // yes - -// Handle reverse short copies. -// ecx = length -// esi = one byte past end of source -// edi = one byte past end of dest - -LReverseShort: - movl %ecx,%edx // copy length - shrl $2,%ecx // #words - jz 3f -1: - subl $4,%esi - movl (%esi),%eax - subl $4,%edi - movl %eax,(%edi) - dec %ecx - jnz 1b -3: - andl $3,%edx // bytes? - jz 5f -4: - dec %esi - movb (%esi),%al - dec %edi - movb %al,(%edi) - dec %edx - jnz 4b -5: - movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove - popl %edi - popl %esi - popl %ebp - ret - -// Handle a reverse move long enough to justify using SSE. -// ecx = length -// esi = one byte past end of source -// edi = one byte past end of dest - -LReverseNotShort: - movl %edi,%edx // copy destination - andl $15,%edx // get #bytes to align destination - je LReverseDestAligned // already aligned - subl %edx,%ecx // adjust length -1: // loop copying 1..15 bytes - dec %esi - movb (%esi),%al - dec %edi - movb %al,(%edi) - dec %edx - jnz 1b - -// Destination is now aligned. Prepare for reverse loops. - -LReverseDestAligned: - movl %ecx,%edx // copy length - andl $63,%ecx // get remaining bytes for Lshort - andl $-64,%edx // get number of bytes we will copy in inner loop - subl %edx,%esi // point to endpoint of copy - subl %edx,%edi - testl $15,%esi // is source aligned too? - jnz LReverseUnalignedLoop // no - jmp LReverseAlignedLoop // use aligned loop - - .align 4,0x90 // 16-byte align inner loops -LReverseAlignedLoop: // loop over 64-byte chunks - movdqa -16(%esi,%edx),%xmm0 - movdqa -32(%esi,%edx),%xmm1 - movdqa -48(%esi,%edx),%xmm2 - movdqa -64(%esi,%edx),%xmm3 - - movdqa %xmm0,-16(%edi,%edx) - movdqa %xmm1,-32(%edi,%edx) - movdqa %xmm2,-48(%edi,%edx) - movdqa %xmm3,-64(%edi,%edx) - - subl $64,%edx - jne LReverseAlignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - - -// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. - - .align 4,0x90 // 16-byte align inner loops -LReverseUnalignedLoop: // loop over 64-byte chunks - movdqu -16(%esi,%edx),%xmm0 - movdqu -32(%esi,%edx),%xmm1 - movdqu -48(%esi,%edx),%xmm2 - movdqu -64(%esi,%edx),%xmm3 - - movdqa %xmm0,-16(%edi,%edx) - movdqa %xmm1,-32(%edi,%edx) - movdqa %xmm2,-48(%edi,%edx) - movdqa %xmm3,-64(%edi,%edx) - - subl $64,%edx - jne LReverseUnalignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - -PLATFUNC_DESCRIPTOR(bcopy,sse2,kHasSSE2|kCache64,kHasSupplementalSSE3) -PLATFUNC_DESCRIPTOR(memcpy,sse2,kHasSSE2|kCache64,kHasSupplementalSSE3) -PLATFUNC_DESCRIPTOR(memmove,sse2,kHasSSE2|kCache64,kHasSupplementalSSE3) diff --git a/src/libc/i386/string/bcopy_sse3x.S b/src/libc/i386/string/bcopy_sse3x.S deleted file mode 100644 index 4f20988dd..000000000 --- a/src/libc/i386/string/bcopy_sse3x.S +++ /dev/null @@ -1,811 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include - -#ifdef DARLING -# define _longcopy longcopy -#endif - -/* - * The bcopy/memcpy loops, tuned for Pentium-M class processors with - * Supplemental SSE3 and 64-byte cache lines. - * - * The following #defines are tightly coupled to the u-architecture: - */ - -#define kShort 80 // too short to bother with SSE (must be >=80) -#define kVeryLong (500*1024) // large enough for non-temporal stores (must be >= 8192) -#define kFastUCode ((16*1024)-15) // cutoff for microcode fastpath for "rep/movsl" - -// void bcopy(const void *src, void *dst, size_t len); - -PLATFUNC_FUNCTION_START(bcopy, sse3x, 32, 5) - pushl %ebp // set up a frame for backtraces - movl %esp,%ebp - pushl %esi - pushl %edi - pushl %ebx - movl 8(%ebp),%esi // get source ptr - movl 12(%ebp),%edi // get dest ptr - movl 16(%ebp),%ecx // get length - movl %edi,%edx - subl %esi,%edx // (dest - source) - cmpl %ecx,%edx // must move in reverse if (dest - source) < length - jb LReverseIsland - cmpl $(kShort),%ecx // long enough to bother with SSE? - jbe Lshort // no - jmp LNotShort - -// -// void *memcpy(void *dst, const void *src, size_t len); -// void *memmove(void *dst, const void *src, size_t len); -// - -PLATFUNC_FUNCTION_START(memcpy, sse3x, 32, 0) // void *memcpy(void *dst, const void *src, size_t len) -PLATFUNC_FUNCTION_START(memmove, sse3x, 32, 0) // void *memmove(void *dst, const void *src, size_t len) - pushl %ebp // set up a frame for backtraces - movl %esp,%ebp - pushl %esi - pushl %edi - pushl %ebx - movl 8(%ebp),%edi // get dest ptr - movl 12(%ebp),%esi // get source ptr - movl 16(%ebp),%ecx // get length - movl %edi,%edx - subl %esi,%edx // (dest - source) - cmpl %ecx,%edx // must move in reverse if (dest - source) < length - jb LReverseIsland - cmpl $(kShort),%ecx // long enough to bother with SSE? - ja LNotShort // yes - -// Handle short forward copies. As the most common case, this is the fall-through path. -// ecx = length (<= kShort) -// esi = source ptr -// edi = dest ptr - -Lshort: - movl %ecx,%edx // copy length - shrl $2,%ecx // get #doublewords - jz LLeftovers -2: // loop copying doublewords - movl (%esi),%eax - addl $4,%esi - movl %eax,(%edi) - addl $4,%edi - dec %ecx - jnz 2b -LLeftovers: // handle leftover bytes (0..3) in last word - andl $3,%edx // any leftover bytes? - jz Lexit -4: // loop copying bytes - movb (%esi),%al - inc %esi - movb %al,(%edi) - inc %edi - dec %edx - jnz 4b -Lexit: - movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove - popl %ebx - popl %edi - popl %esi - popl %ebp - ret - - -LReverseIsland: // keep the "jb" above a short branch... - jmp LReverse // ...because reverse moves are uncommon - - -// Handle forward moves that are long enough to justify use of SSE3. -// First, 16-byte align the destination. -// ecx = length (> kShort) -// esi = source ptr -// edi = dest ptr - -LNotShort: - cmpl $(kVeryLong),%ecx // long enough to justify heavyweight loops? - movl %edi,%edx // copy destination - jae LVeryLong // use very-long-operand path - negl %edx - andl $15,%edx // get #bytes to align destination - jz LDestAligned // already aligned - subl %edx,%ecx // decrement length -1: // loop copying 1..15 bytes - movb (%esi),%al - inc %esi - movb %al,(%edi) - inc %edi - dec %edx - jnz 1b - -// Destination is now aligned. Dispatch to one of sixteen loops over 64-byte chunks, -// based on the alignment of the source. All vector loads and stores are aligned. -// Even though this means we have to shift and repack vectors, doing so is much faster -// than unaligned loads. Since kShort>=80 and we've moved at most 15 bytes already, -// there is at least one chunk. When we enter the copy loops, the following registers -// are set up: -// ecx = residual length (0..63) -// edx = -(length to move), a multiple of 64 -// esi = ptr to 1st source byte not to move (unaligned) -// edi = ptr to 1st dest byte not to move (aligned) - -LDestAligned: - movl %ecx,%edx // copy length - movl %esi,%eax // copy source address - andl $63,%ecx // get remaining bytes for Lshort - andl $-64,%edx // get number of bytes we will copy in inner loop - andl $15,%eax // mask to low 4 bits of source address - addl %edx,%esi // point to 1st byte not copied - addl %edx,%edi - negl %edx // now generate offset to 1st byte to be copied - call 1f -1: - popl %ebx - movl (LTable-1b)(%ebx,%eax,4), %eax // load jump table entry address, relative to LZero - leal (LTable-1b)(%ebx,%eax,1), %eax - jmp *%eax - - .align 2 -LTable: // table of copy loop addresses - .long LMod0 -LTable - .long LMod1 -LTable - .long LMod2 -LTable - .long LMod3 -LTable - .long LMod4 -LTable - .long LMod5 -LTable - .long LMod6 -LTable - .long LMod7 -LTable - .long LMod8 -LTable - .long LMod9 -LTable - .long LMod10 -LTable - .long LMod11 -LTable - .long LMod12 -LTable - .long LMod13 -LTable - .long LMod14 -LTable - .long LMod15 -LTable - - -// Very long forward moves. These are at least several pages. They are special cased -// and aggressively optimized, not so much because they are common or useful, but -// because they are subject to benchmark. There isn't enough room for them in the -// area reserved on the platfunc for bcopy, so we put them elsewhere. We call -// the longcopy routine using the normal ABI. - -LVeryLong: - pushl %ecx // length (>= kVeryLong) - pushl %esi // source ptr - pushl %edi // dest ptr - call _longcopy - addl $12,%esp // pop off our parameters - jmp Lexit - - -// On Pentium-M, the microcode for "rep/movsl" is faster than SSE for 8-byte -// aligned operands from about 32KB up to kVeryLong for the hot cache case, and from -// about 256 bytes up to kVeryLong for cold caches. This is because the microcode -// avoids having to read destination cache lines that will be completely overwritten. -// The cutoff we use (ie, kFastUCode) must somehow balance the two cases, since -// we do not know if the destination is in cache or not. - -Lfastpath: - addl %edx,%esi // restore ptrs to 1st byte of source and dest - addl %edx,%edi - negl %edx // make length positive - orl %edx,%ecx // restore total #bytes remaining to move - cld // we'll move forward - movl %ecx,%edx // copy total length to move - shrl $2,%ecx // compute #words to move - rep // the u-code will optimize this - movsl - jmp LLeftovers // handle 0..3 leftover bytes - - -// Forward loop for medium length operands in which low four bits of %esi == 0000 - -LMod0: - cmpl $(-kFastUCode),%edx // %edx == -length, where (length < kVeryLong) - jle Lfastpath // long enough for fastpath in microcode - jmp 1f - .align 4,0x90 // 16-byte align inner loops -1: // loop over 64-byte chunks - movdqa (%esi,%edx),%xmm0 - movdqa 16(%esi,%edx),%xmm1 - movdqa 32(%esi,%edx),%xmm2 - movdqa 48(%esi,%edx),%xmm3 - - movdqa %xmm0,(%edi,%edx) - movdqa %xmm1,16(%edi,%edx) - movdqa %xmm2,32(%edi,%edx) - movdqa %xmm3,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 0001 - -LMod1: - movdqa -1(%esi,%edx),%xmm0 // prime the loop by loading 1st quadword -1: // loop over 64-byte chunks - movdqa 15(%esi,%edx),%xmm1 - movdqa 31(%esi,%edx),%xmm2 - movdqa 47(%esi,%edx),%xmm3 - movdqa 63(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $1,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $1,%xmm2,%xmm3 - palignr $1,%xmm1,%xmm2 - palignr $1,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 0010 - -LMod2: - movdqa -2(%esi,%edx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 14(%esi,%edx),%xmm1 - movdqa 30(%esi,%edx),%xmm2 - movdqa 46(%esi,%edx),%xmm3 - movdqa 62(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $2,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $2,%xmm2,%xmm3 - palignr $2,%xmm1,%xmm2 - palignr $2,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 0011 - -LMod3: - movdqa -3(%esi,%edx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 13(%esi,%edx),%xmm1 - movdqa 29(%esi,%edx),%xmm2 - movdqa 45(%esi,%edx),%xmm3 - movdqa 61(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $3,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $3,%xmm2,%xmm3 - palignr $3,%xmm1,%xmm2 - palignr $3,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 0100 -// We use the float single data type in order to use "movss" to merge vectors. - -LMod4: - movaps -4(%esi,%edx),%xmm0 // 4-byte aligned: prime the loop - jmp 1f - .align 4,0x90 -1: // loop over 64-byte chunks - movaps 12(%esi,%edx),%xmm1 - movaps 28(%esi,%edx),%xmm2 - movss %xmm1,%xmm0 // copy low 4 bytes of source into destination - pshufd $(0x39),%xmm0,%xmm0 // rotate right 4 bytes (mask -- 00 11 10 01) - movaps 44(%esi,%edx),%xmm3 - movss %xmm2,%xmm1 - pshufd $(0x39),%xmm1,%xmm1 - movaps 60(%esi,%edx),%xmm4 - movss %xmm3,%xmm2 - pshufd $(0x39),%xmm2,%xmm2 - - movaps %xmm0,(%edi,%edx) - movss %xmm4,%xmm3 - pshufd $(0x39),%xmm3,%xmm3 - movaps %xmm1,16(%edi,%edx) - movaps %xmm2,32(%edi,%edx) - movaps %xmm4,%xmm0 - movaps %xmm3,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 0101 - -LMod5: - movdqa -5(%esi,%edx),%xmm0// prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 11(%esi,%edx),%xmm1 - movdqa 27(%esi,%edx),%xmm2 - movdqa 43(%esi,%edx),%xmm3 - movdqa 59(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $5,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $5,%xmm2,%xmm3 - palignr $5,%xmm1,%xmm2 - palignr $5,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 0110 - -LMod6: - movdqa -6(%esi,%edx),%xmm0// prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 10(%esi,%edx),%xmm1 - movdqa 26(%esi,%edx),%xmm2 - movdqa 42(%esi,%edx),%xmm3 - movdqa 58(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $6,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $6,%xmm2,%xmm3 - palignr $6,%xmm1,%xmm2 - palignr $6,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 0111 - -LMod7: - movdqa -7(%esi,%edx),%xmm0// prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 9(%esi,%edx),%xmm1 - movdqa 25(%esi,%edx),%xmm2 - movdqa 41(%esi,%edx),%xmm3 - movdqa 57(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $7,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $7,%xmm2,%xmm3 - palignr $7,%xmm1,%xmm2 - palignr $7,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 1000 -// We use the float double data type in order to use "shufpd" to shift by 8 bytes. - -LMod8: - cmpl $(-kFastUCode),%edx// %edx == -length, where (length < kVeryLong) - jle Lfastpath // long enough for fastpath in microcode - movapd -8(%esi,%edx),%xmm0// 8-byte aligned: prime the loop - jmp 1f - .align 4,0x90 -1: // loop over 64-byte chunks - movapd 8(%esi,%edx),%xmm1 - movapd 24(%esi,%edx),%xmm2 - shufpd $01,%xmm1,%xmm0 // %xmm0 <- shr( %xmm0 || %xmm1, 8 bytes) - movapd 40(%esi,%edx),%xmm3 - shufpd $01,%xmm2,%xmm1 - movapd 56(%esi,%edx),%xmm4 - shufpd $01,%xmm3,%xmm2 - - movapd %xmm0,(%edi,%edx) - shufpd $01,%xmm4,%xmm3 - movapd %xmm1,16(%edi,%edx) - movapd %xmm2,32(%edi,%edx) - movapd %xmm4,%xmm0 - movapd %xmm3,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 1001 - -LMod9: - movdqa -9(%esi,%edx),%xmm0// prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 7(%esi,%edx),%xmm1 - movdqa 23(%esi,%edx),%xmm2 - movdqa 39(%esi,%edx),%xmm3 - movdqa 55(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $9,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $9,%xmm2,%xmm3 - palignr $9,%xmm1,%xmm2 - palignr $9,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 1010 - -LMod10: - movdqa -10(%esi,%edx),%xmm0// prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 6(%esi,%edx),%xmm1 - movdqa 22(%esi,%edx),%xmm2 - movdqa 38(%esi,%edx),%xmm3 - movdqa 54(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $10,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $10,%xmm2,%xmm3 - palignr $10,%xmm1,%xmm2 - palignr $10,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 1011 - -LMod11: - movdqa -11(%esi,%edx),%xmm0// prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 5(%esi,%edx),%xmm1 - movdqa 21(%esi,%edx),%xmm2 - movdqa 37(%esi,%edx),%xmm3 - movdqa 53(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $11,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $11,%xmm2,%xmm3 - palignr $11,%xmm1,%xmm2 - palignr $11,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 1100 -// We use the float single data type in order to use "movss" to merge vectors. - -LMod12: - movss (%esi,%edx),%xmm0// prefetch 1st four bytes of source, right justified - jmp 1f - .align 4,0x90 -1: // loop over 64-byte chunks - pshufd $(0x93),4(%esi,%edx),%xmm1 // load and rotate right 12 bytes (mask -- 10 01 00 11) - pshufd $(0x93),20(%esi,%edx),%xmm2 - pshufd $(0x93),36(%esi,%edx),%xmm3 - pshufd $(0x93),52(%esi,%edx),%xmm4 - - movaps %xmm4,%xmm5 - movss %xmm3,%xmm4 // copy low 4 bytes of source into destination - movss %xmm2,%xmm3 - movss %xmm1,%xmm2 - movss %xmm0,%xmm1 - - movaps %xmm1,(%edi,%edx) - movaps %xmm2,16(%edi,%edx) - movaps %xmm5,%xmm0 - movaps %xmm3,32(%edi,%edx) - movaps %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 1101 - -LMod13: - movdqa -13(%esi,%edx),%xmm0// prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 3(%esi,%edx),%xmm1 - movdqa 19(%esi,%edx),%xmm2 - movdqa 35(%esi,%edx),%xmm3 - movdqa 51(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $13,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $13,%xmm2,%xmm3 - palignr $13,%xmm1,%xmm2 - palignr $13,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 1110 - -LMod14: - movdqa -14(%esi,%edx),%xmm0// prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 2(%esi,%edx),%xmm1 - movdqa 18(%esi,%edx),%xmm2 - movdqa 34(%esi,%edx),%xmm3 - movdqa 50(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $14,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $14,%xmm2,%xmm3 - palignr $14,%xmm1,%xmm2 - palignr $14,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %esi == 1111 - -LMod15: - movdqa -15(%esi,%edx),%xmm0// prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 1(%esi,%edx),%xmm1 - movdqa 17(%esi,%edx),%xmm2 - movdqa 33(%esi,%edx),%xmm3 - movdqa 49(%esi,%edx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $15,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $15,%xmm2,%xmm3 - palignr $15,%xmm1,%xmm2 - palignr $15,%xmm5,%xmm1 - - movdqa %xmm1,(%edi,%edx) - movdqa %xmm2,16(%edi,%edx) - movdqa %xmm3,32(%edi,%edx) - movdqa %xmm4,48(%edi,%edx) - - addl $64,%edx - jnz 1b - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Reverse moves. These are not optimized as aggressively as their forward -// counterparts, as they are only used with destructive overlap. -// ecx = length -// esi = source ptr -// edi = dest ptr - -LReverse: - addl %ecx,%esi // point to end of strings - addl %ecx,%edi - cmpl $(kShort),%ecx // long enough to bother with SSE? - ja LReverseNotShort // yes - -// Handle reverse short copies. -// ecx = length -// esi = one byte past end of source -// edi = one byte past end of dest - -LReverseShort: - movl %ecx,%edx // copy length - shrl $2,%ecx // #words - jz 3f -1: - subl $4,%esi - movl (%esi),%eax - subl $4,%edi - movl %eax,(%edi) - dec %ecx - jnz 1b -3: - andl $3,%edx // bytes? - jz 5f -4: - dec %esi - movb (%esi),%al - dec %edi - movb %al,(%edi) - dec %edx - jnz 4b -5: - movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove - popl %ebx - popl %edi - popl %esi - popl %ebp - ret - -// Handle a reverse move long enough to justify using SSE. -// ecx = length -// esi = one byte past end of source -// edi = one byte past end of dest - -LReverseNotShort: - movl %edi,%edx // copy destination - andl $15,%edx // get #bytes to align destination - je LReverseDestAligned // already aligned - subl %edx,%ecx // adjust length -1: // loop copying 1..15 bytes - dec %esi - movb (%esi),%al - dec %edi - movb %al,(%edi) - dec %edx - jnz 1b - -// Destination is now aligned. Prepare for reverse loops. - -LReverseDestAligned: - movl %ecx,%edx // copy length - andl $63,%ecx // get remaining bytes for Lshort - andl $-64,%edx // get number of bytes we will copy in inner loop - subl %edx,%esi // point to endpoint of copy - subl %edx,%edi - testl $15,%esi // is source aligned too? - jnz LReverseUnalignedLoop // no - -LReverseAlignedLoop: // loop over 64-byte chunks - movdqa -16(%esi,%edx),%xmm0 - movdqa -32(%esi,%edx),%xmm1 - movdqa -48(%esi,%edx),%xmm2 - movdqa -64(%esi,%edx),%xmm3 - - movdqa %xmm0,-16(%edi,%edx) - movdqa %xmm1,-32(%edi,%edx) - movdqa %xmm2,-48(%edi,%edx) - movdqa %xmm3,-64(%edi,%edx) - - subl $64,%edx - jne LReverseAlignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - - -// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. - -LReverseUnalignedLoop: // loop over 64-byte chunks - movdqu -16(%esi,%edx),%xmm0 - movdqu -32(%esi,%edx),%xmm1 - movdqu -48(%esi,%edx),%xmm2 - movdqu -64(%esi,%edx),%xmm3 - - movdqa %xmm0,-16(%edi,%edx) - movdqa %xmm1,-32(%edi,%edx) - movdqa %xmm2,-48(%edi,%edx) - movdqa %xmm3,-64(%edi,%edx) - - subl $64,%edx - jne LReverseUnalignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - -PLATFUNC_DESCRIPTOR(bcopy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) -PLATFUNC_DESCRIPTOR(memcpy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) -PLATFUNC_DESCRIPTOR(memmove,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) diff --git a/src/libc/i386/string/bcopy_sse42.S b/src/libc/i386/string/bcopy_sse42.S deleted file mode 100644 index 14146eeb7..000000000 --- a/src/libc/i386/string/bcopy_sse42.S +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include - -/* - * The bcopy/memcpy loops, tuned for Nehalem. - * - * The following #defines are tightly coupled to the u-architecture: - */ - -#define kShort 80 // too short to bother with SSE (must be >=80) - - -// void bcopy(const void *src, void *dst, size_t len); - -PLATFUNC_FUNCTION_START(bcopy, sse42, 32, 5) - pushl %ebp // set up a frame for backtraces - movl %esp,%ebp - pushl %esi - pushl %edi - movl 8(%ebp),%esi // get source ptr - movl 12(%ebp),%edi // get dest ptr - movl 16(%ebp),%ecx // get length - movl %edi,%edx - subl %esi,%edx // (dest - source) - cmpl %ecx,%edx // must move in reverse if (dest - source) < length - jb LReverseIsland - cmpl $(kShort),%ecx // long enough to bother with SSE? - jbe Lshort // no - jmp LNotShort - -// -// void *memcpy(void *dst, const void *src, size_t len); -// void *memmove(void *dst, const void *src, size_t len); -// - -PLATFUNC_FUNCTION_START(memcpy, sse42, 32, 0) // void *memcpy(void *dst, const void *src, size_t len) -PLATFUNC_FUNCTION_START(memmove, sse42, 32, 0) // void *memmove(void *dst, const void *src, size_t len) - pushl %ebp // set up a frame for backtraces - movl %esp,%ebp - pushl %esi - pushl %edi - movl 8(%ebp),%edi // get dest ptr - movl 12(%ebp),%esi // get source ptr - movl 16(%ebp),%ecx // get length - movl %edi,%edx - subl %esi,%edx // (dest - source) - cmpl %ecx,%edx // must move in reverse if (dest - source) < length - jb LReverseIsland - cmpl $(kShort),%ecx // long enough to bother with SSE? - ja LNotShort // yes - -// Handle short forward copies. As the most common case, this is the fall-through path. -// ecx = length (<= kShort) -// esi = source ptr -// edi = dest ptr - -Lshort: - movl %ecx,%edx // copy length - shrl $2,%ecx // get #doublewords - jz 3f -2: // loop copying doublewords - movl (%esi),%eax - addl $4,%esi - movl %eax,(%edi) - addl $4,%edi - dec %ecx - jnz 2b -3: // handle leftover bytes (0..3) in last word - andl $3,%edx // any leftover bytes? - jz Lexit -4: // loop copying bytes - movb (%esi),%al - inc %esi - movb %al,(%edi) - inc %edi - dec %edx - jnz 4b -Lexit: - movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove - popl %edi - popl %esi - popl %ebp - ret - - -LReverseIsland: // keep the "jb" above a short branch... - jmp LReverse // ...because reverse moves are uncommon - - -// Handle forward moves that are long enough to justify use of SSE. -// First, 16-byte align the destination. -// ecx = length (> kShort) -// esi = source ptr -// edi = dest ptr - -LNotShort: - movl %edi,%edx // copy destination - negl %edx - andl $15,%edx // get #bytes to align destination - jz LDestAligned // already aligned - subl %edx,%ecx // decrement length -1: // loop copying 1..15 bytes - movb (%esi),%al - inc %esi - movb %al,(%edi) - inc %edi - dec %edx - jnz 1b - -// Destination is now aligned. Nehalem does a great job with unaligned SSE loads, -// so we use MOVDQU rather than aligned loads and shifts. Since kShort>=80, we -// know there is at least one 64-byte chunk to move. -// When we enter the copy loops, the following registers are set up: -// ecx = residual length (0..63) -// edx = -(length to move), a multiple of 64 -// esi = ptr to 1st source byte not to move (unaligned) -// edi = ptr to 1st dest byte not to move (aligned) - -LDestAligned: - movl %ecx,%edx // copy length - andl $63,%ecx // get remaining bytes for Lshort - andl $-64,%edx // get number of bytes we will copy in inner loop - addl %edx,%esi // point to 1st byte not copied - addl %edx,%edi - negl %edx // now generate offset to 1st byte to be copied - testl $15,%esi // source also aligned? - jnz LUnalignedLoop - jmp LAlignedLoop - - -// Forward loop for aligned operands. - - .align 4,0x90 // 16-byte align inner loops -LAlignedLoop: // loop over 64-byte chunks - movdqa (%esi,%edx),%xmm0 - movdqa 16(%esi,%edx),%xmm1 - movdqa 32(%esi,%edx),%xmm2 - movdqa 48(%esi,%edx),%xmm3 - - movdqa %xmm0,(%edi,%edx) - movdqa %xmm1,16(%edi,%edx) - movdqa %xmm2,32(%edi,%edx) - movdqa %xmm3,48(%edi,%edx) - - addl $64,%edx - jnz LAlignedLoop - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Forward loop for unaligned operands. - - .align 4,0x90 // 16-byte align inner loops -LUnalignedLoop: // loop over 64-byte chunks - movdqu (%esi,%edx),%xmm0 - movdqu 16(%esi,%edx),%xmm1 - movdqu 32(%esi,%edx),%xmm2 - movdqu 48(%esi,%edx),%xmm3 - - movdqa %xmm0,(%edi,%edx) - movdqa %xmm1,16(%edi,%edx) - movdqa %xmm2,32(%edi,%edx) - movdqa %xmm3,48(%edi,%edx) - - addl $64,%edx - jnz LUnalignedLoop - - jmp Lshort // copy remaining 0..63 bytes and done - - -// Reverse moves. They are only used with destructive overlap. -// ecx = length -// esi = source ptr -// edi = dest ptr - -LReverse: - addl %ecx,%esi // point to end of strings - addl %ecx,%edi - cmpl $(kShort),%ecx // long enough to bother with SSE? - ja LReverseNotShort // yes - -// Handle reverse short copies. -// ecx = length -// esi = one byte past end of source -// edi = one byte past end of dest - -LReverseShort: - movl %ecx,%edx // copy length - shrl $2,%ecx // #words - jz 3f -1: - subl $4,%esi - movl (%esi),%eax - subl $4,%edi - movl %eax,(%edi) - dec %ecx - jnz 1b -3: - andl $3,%edx // bytes? - jz 5f -4: - dec %esi - movb (%esi),%al - dec %edi - movb %al,(%edi) - dec %edx - jnz 4b -5: - movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove - popl %edi - popl %esi - popl %ebp - ret - -// Handle a reverse move long enough to justify using SSE. -// ecx = length -// esi = one byte past end of source -// edi = one byte past end of dest - -LReverseNotShort: - movl %edi,%edx // copy destination - andl $15,%edx // get #bytes to align destination - je LReverseDestAligned // already aligned - subl %edx,%ecx // adjust length -1: // loop copying 1..15 bytes - dec %esi - movb (%esi),%al - dec %edi - movb %al,(%edi) - dec %edx - jnz 1b - -// Destination is now aligned. Prepare for reverse loops. - -LReverseDestAligned: - movl %ecx,%edx // copy length - andl $63,%ecx // get remaining bytes for Lshort - andl $-64,%edx // get number of bytes we will copy in inner loop - subl %edx,%esi // point to endpoint of copy - subl %edx,%edi - testl $15,%esi // is source aligned too? - jnz LReverseUnalignedLoop // no - -LReverseAlignedLoop: // loop over 64-byte chunks - movdqa -16(%esi,%edx),%xmm0 - movdqa -32(%esi,%edx),%xmm1 - movdqa -48(%esi,%edx),%xmm2 - movdqa -64(%esi,%edx),%xmm3 - - movdqa %xmm0,-16(%edi,%edx) - movdqa %xmm1,-32(%edi,%edx) - movdqa %xmm2,-48(%edi,%edx) - movdqa %xmm3,-64(%edi,%edx) - - subl $64,%edx - jne LReverseAlignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - - -// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. - -LReverseUnalignedLoop: // loop over 64-byte chunks - movdqu -16(%esi,%edx),%xmm0 - movdqu -32(%esi,%edx),%xmm1 - movdqu -48(%esi,%edx),%xmm2 - movdqu -64(%esi,%edx),%xmm3 - - movdqa %xmm0,-16(%edi,%edx) - movdqa %xmm1,-32(%edi,%edx) - movdqa %xmm2,-48(%edi,%edx) - movdqa %xmm3,-64(%edi,%edx) - - subl $64,%edx - jne LReverseUnalignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - - -PLATFUNC_DESCRIPTOR(bcopy,sse42,kHasSSE4_2,0) -PLATFUNC_DESCRIPTOR(memcpy,sse42,kHasSSE4_2,0) -PLATFUNC_DESCRIPTOR(memmove,sse42,kHasSSE4_2,0) diff --git a/src/libc/i386/string/bzero.c b/src/libc/i386/string/bzero.c deleted file mode 100644 index a90962303..000000000 --- a/src/libc/i386/string/bzero.c +++ /dev/null @@ -1,46 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse42) -PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse2) -PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, scalar) - -static const platfunc_descriptor *bzero_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse42), - PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse2), - PLATFUNC_DESCRIPTOR_REFERENCE(bzero, scalar), - 0 -}; - -void *bzero_chooser(void *, size_t) __asm__("bzero"); -void *bzero_chooser(void *s, size_t n) { - //__asm__(".desc _bzero, 0x100"); - void *(*impl)(void *, size_t); - impl = find_platform_function((const platfunc_descriptor **) bzero_platfunc_descriptors); - return impl(s, n); -} diff --git a/src/libc/i386/string/bzero_scalar.S b/src/libc/i386/string/bzero_scalar.S deleted file mode 100644 index 74adf99e3..000000000 --- a/src/libc/i386/string/bzero_scalar.S +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1993 Winning Strategies, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Winning Strategies, Inc. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include - -/* - * bzero (void *b, size_t len) - * write len zero bytes to the string b. - * - * Written by: - * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc. - */ - -PLATFUNC_FUNCTION_START_GENERIC(bzero, scalar, 32, 4) - pushl %ebp /* set up a frame for backtraces */ - movl %esp,%ebp - pushl %edi - pushl %ebx - movl 8(%ebp),%edi - movl 12(%ebp),%ecx - - cld /* set fill direction forward */ - xorl %eax,%eax /* set fill data to 0 */ - - /* - * if the string is too short, it's really not worth the overhead - * of aligning to word boundries, etc. So we jump to a plain - * unaligned set. - */ - cmpl $0x0f,%ecx - jbe L1 - - movl %edi,%edx /* compute misalignment */ - negl %edx - andl $3,%edx - movl %ecx,%ebx - subl %edx,%ebx - - movl %edx,%ecx /* zero until word aligned */ - rep - stosb - - movl %ebx,%ecx /* zero by words */ - shrl $2,%ecx - rep - stosl - - movl %ebx,%ecx - andl $3,%ecx /* zero remainder by bytes */ -L1: rep - stosb - - popl %ebx - popl %edi - popl %ebp - ret - -PLATFUNC_DESCRIPTOR(bzero,scalar,0,0) diff --git a/src/libc/i386/string/bzero_sse2.S b/src/libc/i386/string/bzero_sse2.S deleted file mode 100644 index 6d0301925..000000000 --- a/src/libc/i386/string/bzero_sse2.S +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include - -/* - * Bzero, tuned for Pentium-M class processors with SSE2 - * and 64-byte cache lines. - * - * This routine is also used for memset(p,0,n), which is a common case - * since gcc sometimes silently maps bzero() into memset(). As a result, - * we always load the original ptr into %eax before returning. - */ - -#define kShort 80 // too short to bother with SSE (must be >=80) -#define kVeryLong (1024*1024) - -// void bzero(void *b, size_t len); - -PLATFUNC_FUNCTION_START(bzero, sse2, 32, 5) - pushl %ebp // set up a frame for backtraces - movl %esp,%ebp - pushl %edi - movl 8(%ebp),%edi // get ptr - movl 12(%ebp),%edx // get length - - xorl %eax,%eax // set fill data to 0 - cmpl $(kShort),%edx // long enough for SSE? - jg LNotShort // yes - -// Here for short operands or the end of long ones. -// %edx = length -// %edi = ptr -// %eax = zero - -Lshort: - cmpl $16,%edx // long enough to word align? - jge 3f // yes - test %edx,%edx // length==0? - jz 6f -1: - movb %al,(%edi) // zero a byte - inc %edi - dec %edx - jnz 1b - jmp 6f -2: - movb %al,(%edi) // zero a byte - inc %edi - dec %edx -3: - test $3,%edi // is ptr doubleword aligned? - jnz 2b // no - movl %edx,%ecx // copy length - shrl $2,%edx // #doublewords to store -4: - movl %eax,(%edi) // zero an aligned doubleword - addl $4,%edi - dec %edx - jnz 4b - andl $3,%ecx // mask down to #bytes at end (0..3) - jz 6f // none -5: - movb %al,(%edi) // zero a byte - inc %edi - dec %ecx - jnz 5b -6: - movl 8(%ebp),%eax // get return value in case this was a call of memset() - popl %edi - popl %ebp - ret - - -// We will be using SSE, so align ptr. - -LNotShort: - movl %edi,%ecx - negl %ecx - andl $15,%ecx // mask down to #bytes to 16-byte align - jz LDestAligned // already aligned - subl %ecx,%edx // decrement length -0: // loop storing bytes to align the ptr - movb %al,(%edi) // pack in a byte - inc %edi - dec %ecx - jnz 0b - -// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks. -// %edx = length -// %edi = ptr -// %eax = zero - -LDestAligned: - movl %edx,%ecx - andl $63,%edx // mask down to residual length (0..63) - andl $-64,%ecx // get #bytes we will zero in this loop - pxor %xmm0,%xmm0 // zero an SSE register - addl %ecx,%edi // increment ptr by length to move - cmpl $(kVeryLong),%ecx // long enough to justify non-temporal stores? - jae LVeryLong // yes - negl %ecx // negate length to move - jmp 1f - -// Loop over 64-byte chunks, storing into cache. - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movdqa %xmm0,(%edi,%ecx) - movdqa %xmm0,16(%edi,%ecx) - movdqa %xmm0,32(%edi,%ecx) - movdqa %xmm0,48(%edi,%ecx) - addl $64,%ecx - jne 1b - - jmp Lshort - -// Very long operands: use non-temporal stores to bypass cache. - -LVeryLong: - negl %ecx // negate length to move - jmp 1f - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movntdq %xmm0,(%edi,%ecx) - movntdq %xmm0,16(%edi,%ecx) - movntdq %xmm0,32(%edi,%ecx) - movntdq %xmm0,48(%edi,%ecx) - addl $64,%ecx - jne 1b - - sfence // required by non-temporal stores - jmp Lshort - -PLATFUNC_DESCRIPTOR(bzero,sse2,kHasSSE2,kHasSSE4_2) diff --git a/src/libc/i386/string/bzero_sse42.S b/src/libc/i386/string/bzero_sse42.S deleted file mode 100644 index 24073c432..000000000 --- a/src/libc/i386/string/bzero_sse42.S +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include - -/* - * Bzero, tuned for processors with SSE4.2 and 64-byte cache lines, ie Nehalem. - * We don't actually use SSE4.2, but rather use it to identify Nehalem. - * - * We do not use nontemporal operations, but use MOVDQA in preference to REP/STOS. - * - * This routine is also used for memset(p,0,n), which is a common case - * since gcc sometimes silently maps bzero() into memset(). As a result, - * we always load the original ptr into %eax before returning. - */ - -#define kShort 80 // too short to bother with SSE (must be >=80) - - -PLATFUNC_FUNCTION_START(bzero, sse42, 32, 5) - pushl %ebp // set up a frame for backtraces - movl %esp,%ebp - pushl %edi - movl 8(%ebp),%edi // get ptr - movl 12(%ebp),%edx // get length - - xorl %eax,%eax // set fill data to 0 - cmpl $(kShort),%edx // long enough for SSE? - jg LNotShort // yes - -// Here for short operands or the end of long ones. -// %edx = length -// %edi = ptr -// %eax = zero - -Lshort: - cmpl $12,%edx // long enough to word align? - jge 3f // yes - test %edx,%edx // length==0? - jz 6f -1: - movb %al,(%edi) // zero a byte - inc %edi - dec %edx - jnz 1b - jmp 6f -2: - movb %al,(%edi) // zero a byte - inc %edi - dec %edx -3: - test $3,%edi // is ptr doubleword aligned? - jnz 2b // no - movl %edx,%ecx // copy length - shrl $2,%edx // #doublewords to store -4: - movl %eax,(%edi) // zero an aligned doubleword - addl $4,%edi - dec %edx - jnz 4b - andl $3,%ecx // mask down to #bytes at end (0..3) - jz 6f // none -5: - movb %al,(%edi) // zero a byte - inc %edi - dec %ecx - jnz 5b -6: - movl 8(%ebp),%eax // get return value in case this was a call of memset() - popl %edi - popl %ebp - ret - - -// We will be using SSE, so align ptr. -// %edx = length -// %edi = ptr -// %eax = zero - -LNotShort: - testl $3,%edi // 4-byte aligned? - jz 2f // yes - movb %al,(%edi) // zero another byte - incl %edi - decl %edx - jmp LNotShort -1: // zero doublewords until 16-byte aligned - movl %eax,(%edi) - addl $4,%edi - subl $4,%edx -2: - testl $15,%edi // 16-byte aligned? - jnz 1b // no - - -// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks. -// %edx = length -// %edi = ptr -// %eax = zero - -LDestAligned: - movl %edx,%ecx - andl $63,%edx // mask down to residual length (0..63) - andl $-64,%ecx // get #bytes we will zero in this loop - pxor %xmm0,%xmm0 // zero an SSE register - addl %ecx,%edi // increment ptr by length to move - negl %ecx // negate length to move - jmp 1f - -// Loop over 64-byte chunks, storing into cache. - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movdqa %xmm0,(%edi,%ecx) - movdqa %xmm0,16(%edi,%ecx) - movdqa %xmm0,32(%edi,%ecx) - movdqa %xmm0,48(%edi,%ecx) - addl $64,%ecx - jne 1b - - jmp Lshort - - - -PLATFUNC_DESCRIPTOR(bzero,sse42,kHasSSE4_2,0) diff --git a/src/libc/i386/string/ffs.S b/src/libc/i386/string/ffs.S deleted file mode 100644 index 2513489bf..000000000 --- a/src/libc/i386/string/ffs.S +++ /dev/null @@ -1,56 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -#ifdef DARLING -# define _ffs ffs -# define _ffsl ffsl -# define _fls fls -# define _flsl flsl -#endif - - .text - - .align (1<<2) - .globl _ffs -_ffs: - .globl _ffsl -_ffsl: - movl $(-1), %edx - bsfl 4(%esp), %eax - cmovel %edx, %eax - incl %eax - ret - - - .align (1<<2) - .globl _fls -_fls: - .globl _flsl -_flsl: - movl $(-1), %edx - bsrl 4(%esp), %eax - cmovel %edx, %eax - incl %eax - ret diff --git a/src/libc/i386/string/longcopy_sse3x.S b/src/libc/i386/string/longcopy_sse3x.S deleted file mode 100644 index 11d8076d1..000000000 --- a/src/libc/i386/string/longcopy_sse3x.S +++ /dev/null @@ -1,230 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include - - -/* - * The bcopy/memcpy loops for very long operands, tuned for Pentium-M - * class processors with Supplemental SSE3 and 64-byte cache lines. - * - * The following #defines are tightly coupled to the u-architecture: - */ - -#define kBigChunk (256*1024) // outer loop chunk size for kVeryLong sized operands - -#ifdef DARLING -#define _longcopy longcopy -#define _memcpy memcpy -#endif - -// Very long forward moves. These are at least several pages, so we loop over big -// chunks of memory (kBigChunk in size.) We first prefetch the chunk, and then copy -// it using non-temporal stores. Hopefully all the reads occur in the prefetch loop, -// so the copy loop reads from L2 and writes directly to memory (with write combining.) -// This minimizes bus turnaround and maintains good DRAM page locality. -// Note that for this scheme to work, kVeryLong must be a large fraction of L2 cache -// size. Otherwise, it is counter-productive to bypass L2 on the stores. -// -// We are called from the platfunc bcopy loops when they encounter very long -// operands, with the standard ABI. -// -// void longcopy(const void *dest, void *sou, size_t len) - -// void longcopy(const void *dest, void *sou, size_t len) - - .text -#ifndef DARLING - .private_extern _longcopy -#else - .globl _longcopy - .hidden _longcopy -#endif - - .align (1<<5) -_longcopy: - pushl %ebp // set up a frame for backtraces - movl %esp,%ebp - pushl %esi - pushl %edi - pushl %ebx // we'll need to use this too - movl 8(%ebp),%edi // get dest ptr - movl 12(%ebp),%esi // get source ptr - movl 16(%ebp),%ecx // get length - movl %edi,%ebx // copy dest ptr - negl %ebx - andl $63,%ebx // get #bytes to cache line align destination - jz LBigChunkLoop // already aligned - -// Cache line align destination, so temporal stores in copy loops work right. - - pushl %ebx // arg3 - #bytes to align destination (1..63) - pushl %esi // arg2 - source - pushl %edi // arg1 - dest - call _memcpy // align the destination - addl $12,%esp - movl 8(%ebp),%edi // recover dest ptr - movl 12(%ebp),%esi // recover source ptr - movl 16(%ebp),%ecx // recover length - addl %ebx,%esi // adjust ptrs and lengths past copy - addl %ebx,%edi - subl %ebx,%ecx - -// Loop over big chunks. -// ecx = length remaining (>= 4096) -// edi = dest (64-byte aligned) -// esi = source (may be unaligned) - -LBigChunkLoop: - movl $(kBigChunk),%edx // assume we can do a full chunk - cmpl %edx,%ecx // do we have a full chunk left to do? - cmovbl %ecx,%edx // if not, only move what we have left - andl $-4096,%edx // we work in page multiples - xor %eax,%eax // initialize chunk offset - jmp LTouchLoop - -// Touch in the next chunk. We try to keep the prefetch unit in "kick-start" mode, -// by touching two adjacent cache lines every 8 lines of each page, in four slices. -// Because the source may be unaligned, we use byte loads to touch. -// ecx = length remaining (including this chunk) -// edi = ptr to start of dest chunk -// esi = ptr to start of source chunk -// edx = chunk length (multiples of pages) -// ebx = scratch reg used to read a byte of each cache line -// eax = chunk offset - - .align 4,0x90 // 16-byte align inner loops -LTouchLoop: - movzb (%esi,%eax),%ebx // touch line 0, 2, 4, or 6 of page - movzb 1*64(%esi,%eax),%ebx // touch line 1, 3, 5, or 7 - movzb 8*64(%esi,%eax),%ebx // touch line 8, 10, 12, or 14 - movzb 9*64(%esi,%eax),%ebx // etc - - movzb 16*64(%esi,%eax),%ebx - movzb 17*64(%esi,%eax),%ebx - movzb 24*64(%esi,%eax),%ebx - movzb 25*64(%esi,%eax),%ebx - - movzb 32*64(%esi,%eax),%ebx - movzb 33*64(%esi,%eax),%ebx - movzb 40*64(%esi,%eax),%ebx - movzb 41*64(%esi,%eax),%ebx - - movzb 48*64(%esi,%eax),%ebx - movzb 49*64(%esi,%eax),%ebx - movzb 56*64(%esi,%eax),%ebx - movzb 57*64(%esi,%eax),%ebx - - subl $-128,%eax // next slice of page (adding 128 w 8-bit immediate) - testl $512,%eax // done with this page? - jz LTouchLoop // no, next of four slices - addl $(4096-512),%eax // move on to next page - cmpl %eax,%edx // done with this chunk? - jnz LTouchLoop // no, do next page - -// The chunk has been pre-fetched, now copy it using non-temporal stores. -// There are two copy loops, depending on whether the source is 16-byte aligned -// or not. - - addl %edx,%esi // increment ptrs by chunk length - addl %edx,%edi - subl %edx,%ecx // adjust remaining length - negl %edx // prepare loop index (counts up to 0) - testl $15,%esi // is source 16-byte aligned? - jnz LVeryLongUnaligned // source is not aligned - jmp LVeryLongAligned - - .align 4,0x90 // 16-byte align inner loops -LVeryLongAligned: // aligned loop over 128-bytes - movdqa (%esi,%edx),%xmm0 - movdqa 16(%esi,%edx),%xmm1 - movdqa 32(%esi,%edx),%xmm2 - movdqa 48(%esi,%edx),%xmm3 - movdqa 64(%esi,%edx),%xmm4 - movdqa 80(%esi,%edx),%xmm5 - movdqa 96(%esi,%edx),%xmm6 - movdqa 112(%esi,%edx),%xmm7 - - movntdq %xmm0,(%edi,%edx) - movntdq %xmm1,16(%edi,%edx) - movntdq %xmm2,32(%edi,%edx) - movntdq %xmm3,48(%edi,%edx) - movntdq %xmm4,64(%edi,%edx) - movntdq %xmm5,80(%edi,%edx) - movntdq %xmm6,96(%edi,%edx) - movntdq %xmm7,112(%edi,%edx) - - subl $-128,%edx // add 128 with an 8-bit immediate - jnz LVeryLongAligned - jmp LVeryLongChunkEnd - - .align 4,0x90 // 16-byte align inner loops -LVeryLongUnaligned: // unaligned loop over 128-bytes - movdqu (%esi,%edx),%xmm0 - movdqu 16(%esi,%edx),%xmm1 - movdqu 32(%esi,%edx),%xmm2 - movdqu 48(%esi,%edx),%xmm3 - movdqu 64(%esi,%edx),%xmm4 - movdqu 80(%esi,%edx),%xmm5 - movdqu 96(%esi,%edx),%xmm6 - movdqu 112(%esi,%edx),%xmm7 - - movntdq %xmm0,(%edi,%edx) - movntdq %xmm1,16(%edi,%edx) - movntdq %xmm2,32(%edi,%edx) - movntdq %xmm3,48(%edi,%edx) - movntdq %xmm4,64(%edi,%edx) - movntdq %xmm5,80(%edi,%edx) - movntdq %xmm6,96(%edi,%edx) - movntdq %xmm7,112(%edi,%edx) - - subl $-128,%edx // add 128 with an 8-bit immediate - jnz LVeryLongUnaligned - -LVeryLongChunkEnd: - cmpl $4096,%ecx // at least another page to go? - jae LBigChunkLoop // yes - -// Done. Call memcpy() again to handle the 0-4095 bytes at the end. - - sfence // required by non-temporal stores - testl %ecx,%ecx // anything left to copy? - jz 1f - pushl %ecx // arg3 - #bytes to align destination (1..63) - pushl %esi // arg2 - source - pushl %edi // arg1 - dest - call _memcpy // align the destination - addl $12,%esp // pop off arguments -1: - popl %ebx - popl %edi - popl %esi - popl %ebp - ret diff --git a/src/libc/i386/string/memcmp.S b/src/libc/i386/string/memcmp.S deleted file mode 100644 index 59bf4105b..000000000 --- a/src/libc/i386/string/memcmp.S +++ /dev/null @@ -1,190 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifdef DARLING -# define _memcmp memcmp -# define _bcmp bcmp -#endif - -// *************** *********** -// * M E M C M P * and * B C M P * -// *************** *********** -// -// int memcmp(const char *s1, const char *s2, size_t len); -// int bcmp(const char *s1, const char *s2, size_t len); -// -// Bcmp returns (+,0,-), whereas memcmp returns the true difference -// between the first differing bytes, but we treat them identically. -// -// We optimize the compare by doing it with SSE. This introduces -// a complication: if we blindly did vector loads from both sides until -// finding a difference, we might get a spurious page fault by -// reading bytes past the difference. To avoid this, we never do a load -// that crosses a page boundary. - -#define kShort 18 // too short for vectors (must be >16) - - .text - .align (1<<4) - - .globl _memcmp - .globl _bcmp - -_memcmp: // int memcmp(const char *s1,const char *s2,size_t len); -_bcmp: // int bcmp(const char *s1,const char *s2,size_t len); - pushl %esi - pushl %edi - movl 20(%esp),%ecx // get length - movl 12(%esp),%esi // get LHS ptr - movl 16(%esp),%edi // get RHS ptr - cmpl $(kShort),%ecx // worth accelerating? - ja LNotShort // yes - - -// Too short to bother with parallel compares. Loop over bytes. -// %esi = LHS ptr -// %edi = RHS ptr -// %ecx = length (<= kShort) - -LShort: - testl %ecx,%ecx // 0-length? - jnz LShortLoop // no - xorl %eax,%eax // return 0 - jmp LExit - .align (1<<4),0x90 // align inner loops to optimize I-fetch -LShortLoop: // loop over bytes - movzb (%esi),%eax // get LHS byte - movzb (%edi),%edx // get RHS byte - incl %esi - incl %edi - subl %edx,%eax // compare them - jnz LExit // done if not equal - decl %ecx // decrement length - jnz LShortLoop -LExit: // return value is in %eax - popl %edi - popl %esi - ret - -LNotEqual: // here from LLoopOverBytes with LHS in eax - movzb (%edi),%edx // get RHS byte - subl %edx,%eax // generate return value (nonzero) - popl %edi - popl %esi - ret - - -// Loop over bytes until we reach end of a page. -// %esi = LHS ptr -// %edi = RHS ptr -// %ecx = length remaining after end of loop (ie, already adjusted) -// %edx = #bytes until next page (1..15) - - .align (1<<4),0x90 // align inner loops to optimize I-fetch -LLoopOverBytes: - movzb (%esi),%eax // get LHS byte - inc %esi - cmpb (%edi),%al // compare to RHS byte - jnz LNotEqual // done if not equal - inc %edi - dec %edx // more to go? - jnz LLoopOverBytes - - -// Long enough to justify overhead of setting up vector compares. In order to -// avoid spurious page faults, we loop over: -// -// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4 -// -// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte -// comparison until reaching the next page, then resume the vector comparison. -// %esi = LHS ptr -// %edi = RHS ptr -// %ecx = length (> kShort) - -LNotShort: - movl %esi,%eax // copy ptrs - movl %edi,%edx - andl $4095,%eax // mask down to page offsets - andl $4095,%edx - cmpl %eax,%edx // which is bigger? - cmova %edx,%eax // %eax = max(LHS offset, RHS offset); - movl $4096,%edx - subl %eax,%edx // get #bytes to next page crossing - cmpl %ecx,%edx // will operand run out first? - cmova %ecx,%edx // get min(length remaining, bytes to page end) - movl %edx,%eax - shrl $4,%edx // get #chunks till end of operand or page - jnz LLoopOverChunks // enter vector loop - -// Too near page end for vectors. - - subl %eax,%ecx // adjust length remaining - movl %eax,%edx // %edx <- #bytes to page end - cmpl $(kShort),%ecx // will there be enough after we cross page for vectors? - ja LLoopOverBytes // yes - addl %eax,%ecx // no, restore total length remaining - jmp LShortLoop // compare rest byte-by-byte (%ecx != 0) - - -// Loop over 16-byte chunks. -// %esi = LHS ptr -// %edi = RHS ptr -// %ecx = length remaining -// %edx = chunk count - - .align (1<<4),0x90 // align inner loops to optimize I-fetch -LLoopOverChunks: - movdqu (%esi),%xmm0 // get LHS - movdqu (%edi),%xmm1 // get RHS - addl $16,%esi - pcmpeqb %xmm1,%xmm0 // compare LHS to RHS - addl $16,%edi - pmovmskb %xmm0,%eax // collect comparison result bits (1 if equal) - subl $16,%ecx // adjust length remaining - xorl $0xFFFF,%eax // all equal? - jne LDifferent // no, we found differing bytes - dec %edx // more to go? - jnz LLoopOverChunks - - cmpl $(kShort),%ecx // a lot more to compare? - jbe LShort // no - jmp LNotShort // compute distance to next page crossing etc - - -// Found a difference. -// %esi = LHS ptr, already advanced by 16 -// %edi = RHS ptr, already advanced by 16 -// %eax = complemented compare vector (ie, 0 == equal) - -LDifferent: - bsf %eax,%edx // which byte differed? - subl $16,%esi // point to byte 0 while we wait for bit scan - subl $16,%edi - movzb (%esi,%edx),%eax // get LHS byte - movzb (%edi,%edx),%ecx // get RHS byte - subl %ecx,%eax // compute difference (ie, return value) - popl %edi - popl %esi - ret diff --git a/src/libc/i386/string/memcpy.c b/src/libc/i386/string/memcpy.c deleted file mode 100644 index 6b4e9cf5c..000000000 --- a/src/libc/i386/string/memcpy.c +++ /dev/null @@ -1,48 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse42) -PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse3x) -PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse2) -PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, scalar) - -static const platfunc_descriptor *memcpy_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse42), - PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse3x), - PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse2), - PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, scalar), - 0 -}; - -void *memcpy_chooser(void *dest, const void *src, size_t n) __asm__("memcpy"); -void *memcpy_chooser(void *dest, const void *src, size_t n) { - //__asm__(".desc _memcpy, 0x100"); - void *(*impl)(void *, const void *, size_t); - impl = find_platform_function((const platfunc_descriptor **) memcpy_platfunc_descriptors); - return impl(dest, src, n); -} diff --git a/src/libc/i386/string/memmove.c b/src/libc/i386/string/memmove.c deleted file mode 100644 index 459e6af3c..000000000 --- a/src/libc/i386/string/memmove.c +++ /dev/null @@ -1,48 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse42) -PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse3x) -PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse2) -PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, scalar) - -static const platfunc_descriptor *memmove_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse42), - PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse3x), - PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse2), - PLATFUNC_DESCRIPTOR_REFERENCE(memmove, scalar), - 0 -}; - -void *memmove_chooser(void *dest, const void *src, size_t n) __asm__("memmove"); -void *memmove_chooser(void *dest, const void *src, size_t n) { - //__asm__(".desc _memmove, 0x100"); - void *(*impl)(void *, const void *, size_t); - impl = find_platform_function((const platfunc_descriptor **) memmove_platfunc_descriptors); - return impl(dest, src, n); -} diff --git a/src/libc/i386/string/memset.S b/src/libc/i386/string/memset.S deleted file mode 100644 index 392dc3884..000000000 --- a/src/libc/i386/string/memset.S +++ /dev/null @@ -1,247 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - - -/* This file contains the following functions: - * - * void *memset(void *b, int c, size_t len); - * void memset_pattern4(void *b, const void *c4, size_t len); - * void memset_pattern8(void *b, const void *c8, size_t len); - * void memset_pattern16(void *b, const void *c16, size_t len); - * - * Calls of memset() with c==0 are routed to the bzero() routine. Most of the - * others go to _memset_pattern, which is entered as follows: - * %edi = ptr to memory to set (aligned) - * %edx = length (which can be short, though we bias in favor of long operands) - * %xmm0 = the pattern to store - * Return conditions: - * %eax, %edi, %esi, %ecx, and %edx all trashed - * - * NB: we avoid "stos" family of instructions (stosl, stosb), as they are very slow - * on P4s and probably other processors. - */ - - #define kShort 255 // for nonzero memset(), too short for commpage - -#ifdef DARLING -# define _memset memset -# define _memset_pattern memset_pattern -# define _memset_pattern4 memset_pattern4 -# define _memset_pattern8 memset_pattern8 -# define _memset_pattern16 memset_pattern16 -# define _bzero bzero -#endif - - .text - .globl _memset - .align (1<<2) -_memset: // void *memset(void *b, int c, size_t len); - movl 8(%esp),%eax // get 1-byte pattern - movl 12(%esp),%edx // get length - andl $0xFF,%eax // (c==0) ? - jnz LNonzero // not a bzero - - movl %edx,8(%esp) // put count where bzero() expects it - jmp _bzero // enter _bzero - - - // Handle memset of a nonzero value. - -LNonzero: - pushl %edi // save a few nonvolatiles - pushl %esi - movl %eax,%esi // replicate byte in %al into all four bytes - movl 12(%esp),%edi // point to operand - shll $8,%esi - orl %esi,%eax - movl %eax,%esi - shll $16,%esi - orl %esi,%eax // now %eax has "c" in all 4 bytes - cmpl $(kShort),%edx // is operand too short for SSE? - ja LCallCommpage // no - -// Nonzero memset() too short to call commpage. -// %eax = replicated 4-byte pattern -// %edi = ptr -// %edx = length (<= kShort) - - cmpl $16,%edx // long enough to word align? - jge 3f // yes - test %edx,%edx // length==0? - jz 6f -1: - movb %al,(%edi) // pack in a byte - inc %edi - dec %edx - jnz 1b - jmp 6f -2: - movb %al,(%edi) // pack in a byte - inc %edi - dec %edx -3: - test $3,%edi // is ptr doubleword aligned? - jnz 2b // no - movl %edx,%ecx // copy length - shrl $2,%edx // #doublewords to store -4: - movl %eax,(%edi) // store aligned doubleword - addl $4,%edi - dec %edx - jnz 4b - andl $3,%ecx // any leftover bytes? - jz 6f // no -5: - movb %al,(%edi) // pack in a byte - inc %edi - dec %ecx - jnz 5b -6: - movl 12(%esp),%eax // get return value (ie, original ptr) - popl %esi - popl %edi - ret - -// Nonzero memset() is long enough to call commpage. -// %eax = replicated 4-byte pattern -// %edi = ptr -// %edx = length (> kShort) - -LCallCommpage: - movd %eax,%xmm0 // move %eax to low 4 bytes of %xmm0 - pshufd $(0x00),%xmm0,%xmm0 // replicate across the vector - movl %edi,%ecx // copy dest ptr - negl %ecx - andl $15,%ecx // get #bytes to align ptr - jz 2f // skip if already aligned - subl %ecx,%edx // decrement length -1: - movb %al,(%edi) // pack in a byte - inc %edi - dec %ecx - jnz 1b -2: // ptr aligned, length long enough to justify - call _memset_pattern // call commpage to do the heavy lifting - movl 12(%esp),%eax // get return value (ie, original ptr) - popl %esi - popl %edi - ret - - -// Handle memset of a 16-byte pattern. - - .globl _memset_pattern16 - .align 2, 0x90 -_memset_pattern16: // void memset_pattern16(void *b, const void *c16, size_t len); - pushl %edi - pushl %esi - movl 20(%esp),%edx // get length - movl 16(%esp),%esi // get ptr to 16-byte pattern - movl 12(%esp),%edi // point to operand - movdqu (%esi),%xmm0 // load the pattern - jmp LAlignPtr - - -// Handle memset of an 8-byte pattern. - - .globl _memset_pattern8 - .align 2, 0x90 -_memset_pattern8: // void memset_pattern8(void *b, const void *c8, size_t len); - pushl %edi - pushl %esi - movl 20(%esp),%edx // get length - movl 16(%esp),%esi // get ptr to 8-byte pattern - movl 12(%esp),%edi // point to operand - movq (%esi),%xmm0 // load pattern into low 8 bytes - punpcklqdq %xmm0,%xmm0 // replicate into all 16 - jmp LAlignPtr - -// Handle memset of a 4-byte pattern. - - .globl _memset_pattern4 - .align 2, 0x90 -_memset_pattern4: // void memset_pattern4(void *b, const void *c4, size_t len); - pushl %edi - pushl %esi - movl 20(%esp),%edx // get length - movl 16(%esp),%esi // get ptr to 4-byte pattern - movl 12(%esp),%edi // point to operand - movd (%esi),%xmm0 // load pattern into low 4 bytes - pshufd $(0x00),%xmm0,%xmm0 // replicate the 4 bytes across the vector - - -// Align ptr if necessary. We must rotate the pattern right for each byte we -// store while aligning the ptr. Since there is no rotate instruction in SSE3, -// we have to synthesize the rotates. -// %edi = ptr -// %edx = length -// %xmm0 = pattern - -LAlignPtr: // NB: can drop down to here! - cmpl $100,%edx // long enough to bother aligning ptr? - movl %edi,%ecx // copy ptr - jb LReady // not long enough - negl %ecx - andl $15,%ecx // get #bytes to align ptr - jz LReady // already aligned - subl %ecx,%edx // adjust length - - test $1,%cl // 1-byte store required? - movd %xmm0,%eax // get 4 low bytes in %eax - jz 2f // no - movdqa %xmm0,%xmm1 // copy pattern so we can shift in both directions - movb %al,(%edi) // pack in the low-order byte - psrldq $1,%xmm0 // shift pattern right 1 byte - inc %edi - pslldq $15,%xmm1 // shift pattern left 15 bytes - shrl $8,%eax // in case 2-byte store is required - por %xmm1,%xmm0 // complete right rotate of pattern by 1 byte -2: - test $2,%cl // 2-byte store required? - jz 4f // no - psrldq $2,%xmm0 // shift pattern down 2 bytes - movw %ax,(%edi) // pack in next two bytes - pinsrw $7,%eax,%xmm0 // insert low word of %eax into high word of %xmm0 - addl $2,%edi // adjust ptr -4: - test $4,%cl // 4-byte store required? - jz 8f // no - movd %xmm0,(%edi) // store low 4 bytes of %xmm0 - pshufd $(0x39),%xmm0,%xmm0 // rotate %xmm0 right 4 bytes (mask == 00 11 10 01) - addl $4,%edi // adjust ptr -8: - test $8,%cl // 8-byte store required? - jz LReady // no - movq %xmm0,(%edi) // store low 8 bytes of %xmm0 - pshufd $(0x4e),%xmm0,%xmm0 // rotate %xmm0 right 8 bytes (mask == 01 00 11 10) - addl $8,%edi // adjust ptr - -// Ptr is aligned if practical, we're ready to call commpage to do the heavy lifting. - -LReady: - call _memset_pattern // call commpage to do the heavy lifting - popl %esi - popl %edi - ret diff --git a/src/libc/i386/string/memset_pattern_sse2.S b/src/libc/i386/string/memset_pattern_sse2.S deleted file mode 100644 index 51f9c865f..000000000 --- a/src/libc/i386/string/memset_pattern_sse2.S +++ /dev/null @@ -1,193 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include - -/* The common path for nonzero memset and the memset_pattern routines, - * tuned for Pentium-M class processors with SSE2 and 64-byte cache lines. - * This is used by the following functions: - * - * void *memset(void *b, int c, size_t len); // when c!=0 - * void memset_pattern4(void *b, const void *c4, size_t len); - * void memset_pattern8(void *b, const void *c8, size_t len); - * void memset_pattern16(void *b, const void *c16, size_t len); - * - * Note bzero() and memset() of 0 are handled separately. - */ - -#define kShort 63 -#define kVeryLong (1024*1024) - -#ifdef DARLING -# define _memset_pattern memset_pattern -#endif - -// Initial entry from Libc with parameters passed in registers. Although we -// correctly handle misaligned ptrs and short operands, they are inefficient. -// Therefore our caller should filter out short operands and exploit local -// knowledge (ie, original pattern length) to align the ptr if possible. -// When called, we expect: -// %edi = ptr to memory to set (not necessarily aligned) -// %edx = length (may be short or even 0) -// %xmm0 = the pattern to store -// Return conditions: -// %eax, %edi, %esi, %ecx, and %edx all trashed - - .align (1<<5) -#ifndef DARLING - .private_extern _memset_pattern -#else - .globl _memset_pattern - .hidden _memset_pattern -#endif -_memset_pattern: - cmpl $(kShort),%edx // long enough to bother aligning? - ja LNotShort // yes - jmp LShort // no - -// Here for short operands or the end of long ones. -// %edx = length -// %edi = ptr (may not be not aligned) -// %xmm0 = pattern - -LUnalignedStore16: - movdqu %xmm0,(%edi) // stuff in another 16 bytes - subl $16,%edx - addl $16,%edi -LShort: - cmpl $16,%edx // room for another vector? - jge LUnalignedStore16 // yes -LLessThan16: // here at end of copy with < 16 bytes remaining - test $8,%dl // 8-byte store required? - jz 2f // no - movq %xmm0,(%edi) // pack in 8 low bytes - psrldq $8,%xmm0 // then shift vector down 8 bytes - addl $8,%edi -2: - test $4,%dl // 4-byte store required? - jz 3f // no - movd %xmm0,(%edi) // pack in 4 low bytes - psrldq $4,%xmm0 // then shift vector down 4 bytes - addl $4,%edi -3: - andl $3,%edx // more to go? - jz 5f // no - movd %xmm0,%eax // move remainders out into %eax -4: // loop on up to three bytes - movb %al,(%edi) // pack in next byte - shrl $8,%eax // shift next byte into position - inc %edi - dec %edx - jnz 4b -5: ret - -// Long enough to justify aligning ptr. Note that we have to rotate the -// pattern to account for any alignment. We do this by doing two unaligned -// stores, and then an aligned load from the middle of the two stores. -// This will stall on store forwarding alignment mismatch, and the unaligned -// stores can be pretty slow too, but the alternatives aren't any better. -// Fortunately, in most cases our caller has already aligned the ptr. -// %edx = length (> kShort) -// %edi = ptr (may not be aligned) -// %xmm0 = pattern - -LNotShort: - movl %edi,%ecx // copy dest ptr - negl %ecx - andl $15,%ecx // mask down to #bytes to 16-byte align - jz LAligned // skip if already aligned - movdqu %xmm0,(%edi) // store 16 unaligned bytes - movdqu %xmm0,16(%edi) // and 16 more, to be sure we have an aligned chunk - addl %ecx,%edi // now point to the aligned chunk - subl %ecx,%edx // adjust remaining count - movdqa (%edi),%xmm0 // get the rotated pattern (probably stalling) - addl $16,%edi // skip past the aligned chunk - subl $16,%edx - -// Set up for 64-byte loops. -// %edx = length remaining -// %edi = ptr (aligned) -// %xmm0 = rotated pattern - -LAligned: - movl %edx,%ecx // copy length remaining - andl $63,%edx // mask down to residual length (0..63) - andl $-64,%ecx // %ecx <- #bytes we will zero in by-64 loop - jz LNoMoreChunks // no 64-byte chunks - addl %ecx,%edi // increment ptr by length to move - cmpl $(kVeryLong),%ecx // long enough to justify non-temporal stores? - jge LVeryLong // yes - negl %ecx // negate length to move - jmp 1f - -// Loop over 64-byte chunks, storing into cache. - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movdqa %xmm0,(%edi,%ecx) - movdqa %xmm0,16(%edi,%ecx) - movdqa %xmm0,32(%edi,%ecx) - movdqa %xmm0,48(%edi,%ecx) - addl $64,%ecx - jne 1b - - jmp LNoMoreChunks - -// Very long operands: use non-temporal stores to bypass cache. - -LVeryLong: - negl %ecx // negate length to move - jmp 1f - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movntdq %xmm0,(%edi,%ecx) - movntdq %xmm0,16(%edi,%ecx) - movntdq %xmm0,32(%edi,%ecx) - movntdq %xmm0,48(%edi,%ecx) - addl $64,%ecx - jne 1b - - sfence // required by non-temporal stores - jmp LNoMoreChunks - -// Handle leftovers: loop by 16. -// %edx = length remaining (<64) -// %edi = ptr (aligned) -// %xmm0 = rotated pattern - -LLoopBy16: - movdqa %xmm0,(%edi) // pack in 16 more bytes - subl $16,%edx // decrement count - addl $16,%edi // increment ptr -LNoMoreChunks: - cmpl $16,%edx // more to go? - jge LLoopBy16 // yes - jmp LLessThan16 // handle up to 15 remaining bytes diff --git a/src/libc/i386/string/strcmp.S b/src/libc/i386/string/strcmp.S deleted file mode 100644 index a932b74be..000000000 --- a/src/libc/i386/string/strcmp.S +++ /dev/null @@ -1,149 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifdef DARLING -# define _strcmp strcmp -#endif - -// *************** -// * S T R C M P * -// *************** -// -// int strcmp(const char *s1, const char *s2); -// -// We optimize the compare by doing it in parallel, using SSE. This introduces -// a complication: if we blindly did vector loads from both sides until -// finding a difference (or 0), we might get a spurious page fault by -// reading bytes past the difference. To avoid this, we never do a load -// that crosses a page boundary. - - .text - .globl _strcmp - - .align (1<<4) -_strcmp: // int strcmp(const char *s1,const char *s2); - pushl %esi - pushl %edi - movl 12(%esp),%esi // get LHS ptr - movl 16(%esp),%edi // get RHS ptr - - -// In order to avoid spurious page faults, we loop over: -// -// min( bytes_in_LHS_page, bytes_in_RHS_page) >> 4 -// -// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte -// comparison until reaching the next page, then resume the vector comparison. -// %esi = LHS ptr -// %edi = RHS ptr - -LNextChunk: - movl %esi,%eax // copy ptrs - movl %edi,%edx - andl $4095,%eax // mask down to page offsets - andl $4095,%edx - cmpl %eax,%edx // which is bigger? - cmova %edx,%eax // %eax = max(LHS offset, RHS offset); - movl $4096,%edx - subl %eax,%edx // get #bytes to next page crossing - movl %edx,%eax - shrl $4,%edx // get #chunks till end of operand or page - jnz LLoopOverChunks // enter vector loop - movl %eax,%edx // no chunks... - jmp LLoopOverBytes // ...so loop over bytes until page end - - -// Loop over bytes. -// %esi = LHS ptr -// %edi = RHS ptr -// %edx = byte count - - .align (1<<4),0x90 // align inner loops to optimize I-fetch -LLoopOverBytes: - movzb (%esi),%eax // get LHS byte - movzb (%edi),%ecx // get RHS byte - inc %esi - inc %edi - testl %eax,%eax // 0? - jz LExit0 // yes, we're done - subl %ecx,%eax // compare them - jnz LExit // done if not equal - dec %edx // more to go? - jnz LLoopOverBytes - - jmp LNextChunk // we've come to end of page - - -// Loop over 16-byte chunks. -// %esi = LHS ptr -// %edi = RHS ptr -// %edx = chunk count - - .align (1<<4),0x90 // align inner loops to optimize I-fetch -LLoopOverChunks: - movdqu (%esi),%xmm1 // get LHS - movdqu (%edi),%xmm2 // get RHS - pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads - addl $16,%esi - pcmpeqb %xmm1,%xmm2 // compare LHS to RHS - pcmpeqb %xmm1,%xmm0 // compare LHS to 0s - addl $16,%edi - pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS - pmovmskb %xmm0,%ecx // get result mask for 0 check - xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal" - orl %ecx,%eax // combine the masks and check for 1-bits - jnz LFoundDiffOr0 // we found differing bytes or a 0-byte - dec %edx // more to go? - jnz LLoopOverChunks - - jmp LNextChunk // compare up to next page boundary - - -// Found a zero and/or a difference in vector compare. -// %esi = LHS ptr, already advanced by 16 -// %edi = RHS ptr, already advanced by 16 -// %eax = bit n set if bytes n differed or were 0 - -LFoundDiffOr0: - bsf %eax,%edx // which byte differed or was 0? - subl $16,%esi // point to start of vectors while we wait for bit scan - subl $16,%edi - movzb (%esi,%edx),%eax // get LHS byte - movzb (%edi,%edx),%ecx // get RHS byte - subl %ecx,%eax // compute difference (ie, return value) - popl %edi - popl %esi - ret - - -// Found a zero and/or difference in byte loop. -// %eax = LHS byte -// %ecx = RHS byte - -LExit0: - subl %ecx,%eax // compute difference (ie, return value) -LExit: // here with difference already in %eax - popl %edi - popl %esi - ret diff --git a/src/libc/i386/string/strcpy.S b/src/libc/i386/string/strcpy.S index 51df54518..771eec47c 100644 --- a/src/libc/i386/string/strcpy.S +++ b/src/libc/i386/string/strcpy.S @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * @@ -22,9 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ -#ifdef DARLING -# define _strcpy strcpy -#endif // *************** // * S T R C P Y * @@ -43,7 +39,7 @@ .text .globl _strcpy - .align (1<<4) + .align 4 _strcpy: // char *strcpy(const char *dst, const char *src); pushl %edi movl 8(%esp),%edi // get dest ptr @@ -76,7 +72,7 @@ LNextChunk: // %edi = dest ptr // %edx = byte count - .align (1<<4),0x90 // align inner loops to optimize I-fetch + .align 4,0x90 // align inner loops to optimize I-fetch LLoopOverBytes: movzb (%ecx),%eax // get source byte inc %ecx @@ -95,7 +91,7 @@ LLoopOverBytes: // %edi = dest ptr (aligned) // %edx = chunk count - .align (1<<4),0x90 // align inner loops to optimize I-fetch + .align 4,0x90 // align inner loops to optimize I-fetch LLoopOverChunks: movdqu (%ecx),%xmm1 // get source pxor %xmm0,%xmm0 // get some 0s diff --git a/src/libc/i386/string/strlcat.S b/src/libc/i386/string/strlcat.S index dda8d7f3d..d165cfca9 100644 --- a/src/libc/i386/string/strlcat.S +++ b/src/libc/i386/string/strlcat.S @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2007 Apple Inc. All rights reserved. * @@ -22,9 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ -#ifdef DARLING -# define _strlcat strlcat -#endif // ***************** // * S T R L C A T * @@ -57,7 +53,7 @@ .text .globl _strlcat - .align (1<<4) + .align 4 _strlcat: // size_t *strlcat(char *dst, const char *src, size_t size); pushl %edi pushl %esi diff --git a/src/libc/i386/string/strlcpy.S b/src/libc/i386/string/strlcpy.S index 4a33acf23..21a366cbf 100644 --- a/src/libc/i386/string/strlcpy.S +++ b/src/libc/i386/string/strlcpy.S @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2007 Apple Inc. All rights reserved. * @@ -22,9 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ -#ifdef DARLING -# define _strlcpy strlcpy -#endif // ***************** // * S T R L C P Y * @@ -55,7 +51,7 @@ .text .globl _strlcpy - .align (1<<4) + .align 4 _strlcpy: // size_t *strlcpy(char *dst, const char *src, size_t size); pushl %edi pushl %esi diff --git a/src/libc/i386/string/strlen.S b/src/libc/i386/string/strlen.S index e37434648..b21bee553 100644 --- a/src/libc/i386/string/strlen.S +++ b/src/libc/i386/string/strlen.S @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * @@ -20,10 +19,6 @@ * * @APPLE_LICENSE_HEADER_END@ */ - -#ifdef DARLING -# define _strlen strlen -#endif /* * Strlen, for processors with SSE3. @@ -38,7 +33,7 @@ .text .globl _strlen - .align (1<<4), 0x90 + .align 4, 0x90 _strlen: // size_t strlen(char *b); movl 4(%esp),%edx // get ptr to string pxor %xmm0,%xmm0 // zero %xmm0 diff --git a/src/libc/i386/string/strncmp.S b/src/libc/i386/string/strncmp.S deleted file mode 100644 index 444fb1df2..000000000 --- a/src/libc/i386/string/strncmp.S +++ /dev/null @@ -1,196 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -#ifdef DARLING -# define _strncmp strncmp -#endif - -// ***************** -// * S T R N C M P * -// ***************** -// -// int strncmp(const char *s1, const char *s2, size_t len); -// -// We optimize the compare by doing it vector parallel. This introduces -// a complication: if we blindly did vector loads from both sides until -// finding a difference (or 0), we might get a spurious page fault by -// reading bytes past the difference. To avoid this, we never do a load -// that crosses a page boundary. - -#define kShort 20 // too short for vectors (must be >16) - - .text - .globl _strncmp - - .align (1<<4) -_strncmp: // int strncmp(const char *s1, const char *s2, size_t len); - pushl %esi - pushl %edi - movl 20(%esp),%ecx // get length - movl 12(%esp),%esi // get LHS ptr - movl 16(%esp),%edi // get RHS ptr - push %ebx - cmpl $(kShort),%ecx // worth accelerating? - ja LNotShort // yes - - -// Too short to bother with parallel compares. Loop over bytes. -// %esi = LHS ptr -// %edi = RHS ptr -// %ecx = length (<= kShort) - -LShort: - testl %ecx,%ecx // 0-length? - jnz LShortLoop // no - jmp LReturn0 // yes, return 0 - .align 4,0x90 // align inner loops to optimize I-fetch -LShortLoop: // loop over bytes - movzb (%esi),%eax // get LHS byte - movzb (%edi),%ebx // get RHS byte - incl %esi - incl %edi - testl %eax,%eax // LHS==0 ? - jz LNotEqual // yes, this terminates comparison - subl %ebx,%eax // compare them - jnz LExit // done if not equal - decl %ecx // decrement length - jnz LShortLoop -LReturn0: - xorl %eax,%eax // all bytes equal, so return 0 -LExit: // return value is in %eax - popl %ebx - popl %edi - popl %esi - ret - -LNotEqual: // LHS in eax, RHS in ebx - subl %ebx,%eax // generate return value (nonzero) - popl %ebx - popl %edi - popl %esi - ret - - -// Loop over bytes until we reach end of a page. -// %esi = LHS ptr -// %edi = RHS ptr -// %ecx = length remaining after end of loop (ie, already adjusted) -// %edx = #bytes until next page (1..15) - - .align (1<<4),0x90 // align inner loops to optimize I-fetch -LLoopOverBytes: - movzb (%esi),%eax // get LHS byte - movzb (%edi),%ebx // get RHS byte - inc %esi - inc %edi - testl %eax,%eax // LHS==0 ? - jz LNotEqual // yes, this terminates comparison - subl %ebx,%eax // compare them - jnz LExit // done if not equal - dec %edx // more to go? - jnz LLoopOverBytes - - -// Long enough to justify overhead of setting up vector compares. In order to -// avoid spurious page faults, we loop over: -// -// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4 -// -// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte -// comparison until reaching the next page, then resume the vector comparison. -// %esi = LHS ptr -// %edi = RHS ptr -// %ecx = length (> kShort) - -LNotShort: - movl %esi,%eax // copy ptrs - movl %edi,%edx - andl $4095,%eax // mask down to page offsets - andl $4095,%edx - cmpl %eax,%edx // which is bigger? - cmova %edx,%eax // %eax = max(LHS offset, RHS offset); - movl $4096,%edx - subl %eax,%edx // get #bytes to next page crossing - cmpl %ecx,%edx // will operand run out first? - cmova %ecx,%edx // get min(length remaining, bytes to page end) - movl %edx,%eax - shrl $4,%edx // get #chunks till end of operand or page - jnz LLoopOverChunks // enter vector loop - -// Too near page end for vectors. - - subl %eax,%ecx // adjust length remaining - movl %eax,%edx // %edx <- #bytes to page end - cmpl $(kShort),%ecx // will there be enough after we cross page for vectors? - ja LLoopOverBytes // yes - addl %eax,%ecx // no, restore total length remaining - jmp LShortLoop // compare rest byte-by-byte (%ecx != 0) - - -// Loop over 16-byte chunks. -// %esi = LHS ptr -// %edi = RHS ptr -// %ecx = length remaining -// %edx = chunk count - - .align 4,0x90 // align inner loops to optimize I-fetch -LLoopOverChunks: - movdqu (%esi),%xmm1 // get LHS - movdqu (%edi),%xmm2 // get RHS - pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads - addl $16,%esi - pcmpeqb %xmm1,%xmm2 // compare LHS to RHS - pcmpeqb %xmm1,%xmm0 // compare LHS to 0s - addl $16,%edi - pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS - pmovmskb %xmm0,%ebx // get result mask for 0 check - subl $16,%ecx // decrement length remaining - xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal" - orl %ebx,%eax // combine the masks and check for 1-bits - jnz LFoundDiffOr0 // we found differing bytes or a 0-byte - dec %edx // more to go? - jnz LLoopOverChunks // yes - - cmpl $(kShort),%ecx // a lot more to compare? - jbe LShort // no - jmp LNotShort // compute distance to next page crossing etc - - -// Found a zero and/or a difference in vector compare. -// %esi = LHS ptr, already advanced by 16 -// %edi = RHS ptr, already advanced by 16 -// %eax = bit n set if bytes n differed or were 0 - -LFoundDiffOr0: - bsf %eax,%edx // which byte differed or was 0? - subl $16,%esi // point to start of vectors while we wait for bit scan - subl $16,%edi - movzb (%esi,%edx),%eax // get LHS byte - movzb (%edi,%edx),%ecx // get RHS byte - popl %ebx - popl %edi - subl %ecx,%eax // compute difference (ie, return value) - popl %esi - ret diff --git a/src/libc/i386/string/strncpy.S b/src/libc/i386/string/strncpy.S index bf62dc381..9b1799db6 100644 --- a/src/libc/i386/string/strncpy.S +++ b/src/libc/i386/string/strncpy.S @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * @@ -25,11 +24,6 @@ #include -#ifdef DARLING -#define _strncpy strncpy -#define _bzero bzero -#endif - // ***************** // * S T R N C P Y * // ***************** @@ -53,7 +47,7 @@ .text .globl _strncpy - .align (1<<4) + .align 4 _strncpy: // char *strncpy(const char *dst, const char *src, size_t n); pushl %edi pushl %esi @@ -125,7 +119,7 @@ LLoopOverBytes: // %ecx = buffer length remaining // %edx = chunk count - .align (1<<4),0x90 // align inner loops to optimize I-fetch + .align 4,0x90 // align inner loops to optimize I-fetch LLoopOverChunks: movdqu (%esi),%xmm1 // get source pxor %xmm0,%xmm0 // get some 0s @@ -183,10 +177,15 @@ LFound0: // %ecx = buffer length remaining LZeroBuffer: - pushl %ecx // remaining buffer size - pushl %edi // ptr to 1st unstored byte +// The stack currently is aligned to 4 mod 16 (it was 0 mod 16 at the time of +// the call, and the return address, edi, and esi have been pushed). It needs +// to aligned 0 mod 16 when we call bzero, so we subtract 20 from esp (not 4 +// because we need to have 8 bytes for the arguments to bzero). + subl $20,%esp + movl %ecx,4(%esp) // remaining buffer size + movl %edi, (%esp) // pointer to first unstored byte call _bzero - addl $8,%esp // pop off the arguments + addl $20,%esp LDone: movl 12(%esp),%eax // original dest ptr is return value diff --git a/src/libc/i386/sys/OSAtomic.S b/src/libc/i386/sys/OSAtomic.S deleted file mode 100644 index aafba3205..000000000 --- a/src/libc/i386/sys/OSAtomic.S +++ /dev/null @@ -1,460 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -#define ATOMIC_UP 0 -#define ATOMIC_MP 1 -#define ATOMIC_RET_ORIG 0 -#define ATOMIC_RET_NEW 1 - -#ifdef DARLING -# define _OSAtomicFifoEnqueue OSAtomicFifoEnqueue -# define _OSAtomicFifoDequeue OSAtomicFifoDequeue -# define _preempt preempt -# define _commpage_pfz_base commpage_pfz_base -#endif - -#ifndef DARLING -// compare and exchange 32-bit -// xchg32 -.macro xchg32 - .if $2 == ATOMIC_MP - lock - .endif - cmpxchgl $0, ($1) -.endm - -// compare and exchange 64-bit -// xchg64 -.macro xchg64 - .if $1 == ATOMIC_MP - lock - .endif - cmpxchg8b ($0) -.endm -#else -// compare and exchange 32-bit -// xchg32 -#define xchg32(a, b, c) \ - lock \ - cmpxchgl a, (b) - -// compare and exchange 64-bit -// xchg64 -#define xchg64(a, b) \ - lock \ - cmpxchg8b (a) -#endif - -// int32_t OSAtomicAdd32(int32_t theAmount, volatile int32_t *theValue); -#define ATOMIC_ARITHMETIC(instr, orig, mp) \ - movl 8(%esp), %ecx /* load 2nd arg ptr into ecx */ ;\ - movl (%ecx), %eax /* load contents of ecx into eax */ ;\ -1: movl 4(%esp), %edx /* load 1st arg into edx */ ;\ - instr %eax, %edx /* do the operation */ ;\ - xchg32 (%edx, %ecx, mp) /* old in %eax, new in %edx, exchange into %ecx */ ;\ - jnz 1b /* go back if we failed to exchange */ ;\ - .if orig == ATOMIC_RET_NEW ;\ - movl %edx, %eax /* return new value */ ;\ - .endif - -// bool OSAtomicTestAndSet(uint32_t n, volatile void *theAddress); -#define ATOMIC_BIT_OP(instr, mp) \ - movl 4(%esp), %eax ;\ - movl 8(%esp), %edx ;\ - shldl $3,%edx,%ecx /* save top 3 bits of address in %ecx */ ;\ - shll $3,%edx ;\ - xorl $7,%eax /* bit position is numbered big endian so convert to little endian */ ;\ - addl %eax,%edx /* generate bit address */ ;\ - adcl $0,%ecx /* handle carry out of lower half of address */ ;\ - movl %edx,%eax /* copy lower half of bit address */ ;\ - andl $31,%eax /* keep bit offset in range 0..31 */ ;\ - xorl %eax,%edx /* 4-byte align address */ ;\ - shrdl $3,%ecx,%edx /* restore 32-bit byte address in %edx */ ;\ - //.if mp == ATOMIC_MP ;\ - lock ;\ - //.endif ;\ - instr %eax, (%edx) ;\ - setc %al ;\ - movzbl %al,%eax // widen in case caller assumes we return an int - -// int64_t OSAtomicAdd64(int64_t theAmount, volatile int64_t *theValue); -#define ATOMIC_ADD64(mp) \ - pushl %ebx ;\ - pushl %esi ;\ - movl 20(%esp), %esi ;\ - movl 0(%esi), %eax ;\ - movl 4(%esi), %edx ;\ -1: movl 12(%esp), %ebx ;\ - movl 16(%esp), %ecx ;\ - addl %eax, %ebx ;\ - adcl %edx, %ecx ;\ - xchg64 (%esi, mp) ;\ - jnz 1b ;\ - movl %ebx, %eax ;\ - movl %ecx, %edx ;\ - popl %esi ;\ - popl %ebx - - .text - -PLATFUNC_FUNCTION_START(OSAtomicAnd32, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicAnd32Barrier, up, 32, 2) - ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Barrier, mp, 32, 2) - ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_MP) - ret - -PLATFUNC_FUNCTION_START(OSAtomicOr32, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicOr32Barrier, up, 32, 2) - ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Barrier, mp, 32, 2) - ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_MP) - ret - -PLATFUNC_FUNCTION_START(OSAtomicXor32, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicXor32Barrier, up, 32, 2) - ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Barrier, mp, 32, 2) - ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_MP) - ret - -PLATFUNC_FUNCTION_START(OSAtomicAnd32Orig, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicAnd32OrigBarrier, up, 32, 2) - ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Orig, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32OrigBarrier, mp, 32, 2) - ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_MP) - ret - -PLATFUNC_FUNCTION_START(OSAtomicOr32Orig, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicOr32OrigBarrier, up, 32, 2) - ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Orig, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32OrigBarrier, mp, 32, 2) - ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_MP) - ret - -PLATFUNC_FUNCTION_START(OSAtomicXor32Orig, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicXor32OrigBarrier, up, 32, 2) - ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Orig, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32OrigBarrier, mp, 32, 2) - ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_MP) - ret - -// bool OSAtomicCompareAndSwapInt(int oldValue, int newValue, volatile int *theValue); -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtr, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtrBarrier, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapInt, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapIntBarrier, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLong, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLongBarrier, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32Barrier, up, 32, 2) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp), %ecx - xchg32 (%edx, %ecx, ATOMIC_UP) - sete %al - movzbl %al,%eax // widen in case caller assumes we return an int - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtr, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtrBarrier, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapInt, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapIntBarrier, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLong, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLongBarrier, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32Barrier, mp, 32, 2) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp), %ecx - xchg32 (%edx, %ecx, ATOMIC_MP) - sete %al - movzbl %al,%eax // widen in case caller assumes we return an int - ret - -// bool OSAtomicCompareAndSwap64(int64_t oldValue, int64_t newValue, volatile int64_t *theValue); -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64Barrier, up, 32, 2) - pushl %ebx // push out spare stuff for space - pushl %esi - movl 12(%esp), %eax // load in 1st 64-bit parameter - movl 16(%esp), %edx - movl 20(%esp), %ebx // load in 2nd 64-bit parameter - movl 24(%esp), %ecx - movl 28(%esp), %esi // laod in destination address - xchg64 (%esi, ATOMIC_UP) // compare and swap 64-bit - sete %al - movzbl %al,%eax // widen in case caller assumes we return an int - popl %esi - popl %ebx - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64Barrier, mp, 32, 2) - pushl %ebx // push out spare stuff for space - pushl %esi - movl 12(%esp), %eax // load in 1st 64-bit parameter - movl 16(%esp), %edx - movl 20(%esp), %ebx // load in 2nd 64-bit parameter - movl 24(%esp), %ecx - movl 28(%esp), %esi // laod in destination address - xchg64 (%esi, ATOMIC_MP) // compare and swap 64-bit - sete %al - movzbl %al,%eax // widen in case caller assumes we return an int - popl %esi - popl %ebx - ret - -PLATFUNC_FUNCTION_START(OSAtomicAdd32, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicAdd32Barrier, up, 32, 2) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl %eax, %ecx - xaddl %eax, (%edx) - addl %ecx, %eax - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32Barrier, mp, 32, 2) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl %eax, %ecx - lock - xaddl %eax, (%edx) - addl %ecx, %eax - ret - -PLATFUNC_FUNCTION_START(OSAtomicAdd64, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicAdd64Barrier, up, 32, 2) - ATOMIC_ADD64(ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64Barrier, mp, 32, 2) - ATOMIC_ADD64(ATOMIC_MP) - ret - -PLATFUNC_FUNCTION_START(OSAtomicTestAndSet, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicTestAndSetBarrier, up, 32, 2) - ATOMIC_BIT_OP(btsl, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSet, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSetBarrier, mp, 32, 2) - ATOMIC_BIT_OP(btsl, ATOMIC_MP) - ret - -PLATFUNC_FUNCTION_START(OSAtomicTestAndClear, up, 32, 2) -PLATFUNC_FUNCTION_START(OSAtomicTestAndClearBarrier, up, 32, 2) - ATOMIC_BIT_OP(btrl, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClear, mp, 32, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClearBarrier, mp, 32, 2) - ATOMIC_BIT_OP(btrl, ATOMIC_MP) - ret - -// OSMemoryBarrier() -// These are used both in 32 and 64-bit mode. We use a fence even on UP -// machines, so this function can be used with nontemporal stores. - -PLATFUNC_FUNCTION_START_GENERIC(OSMemoryBarrier, all, 32, 4) - lock - addl $0,(%esp) - ret -PLATFUNC_DESCRIPTOR(OSMemoryBarrier,all,0,kHasSSE2); - -PLATFUNC_FUNCTION_START(OSMemoryBarrier, sse2, 32, 4) - mfence - ret -PLATFUNC_DESCRIPTOR(OSMemoryBarrier,sse2,kHasSSE2,0); - - /* - * typedef volatile struct { - * void *opaque1; <-- ptr to 1st queue element or null - * long opaque2; <-- generation count - * } OSQueueHead; - * - * void OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset); - */ -PLATFUNC_FUNCTION_START(OSAtomicEnqueue, up, 32, 2) - pushl %edi - pushl %esi - pushl %ebx - movl 16(%esp),%edi // %edi == ptr to list head - movl 20(%esp),%ebx // %ebx == new - movl 24(%esp),%esi // %esi == offset - movl (%edi),%eax // %eax == ptr to 1st element in Q - movl 4(%edi),%edx // %edx == current generation count -1: movl %eax,(%ebx,%esi)// link to old list head from new element - movl %edx,%ecx - incl %ecx // increment generation count - xchg64 (%edi, ATOMIC_UP) // ...push on new element - jnz 1b - popl %ebx - popl %esi - popl %edi - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicEnqueue, mp, 32, 2) - pushl %edi - pushl %esi - pushl %ebx - movl 16(%esp),%edi // %edi == ptr to list head - movl 20(%esp),%ebx // %ebx == new - movl 24(%esp),%esi // %esi == offset - movl (%edi),%eax // %eax == ptr to 1st element in Q - movl 4(%edi),%edx // %edx == current generation count -1: movl %eax,(%ebx,%esi)// link to old list head from new element - movl %edx,%ecx - incl %ecx // increment generation count - xchg64 (%edi, ATOMIC_MP) // ...push on new element - jnz 1b - popl %ebx - popl %esi - popl %edi - ret - -/* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ -PLATFUNC_FUNCTION_START(OSAtomicDequeue, up, 32, 2) - pushl %edi - pushl %esi - pushl %ebx - movl 16(%esp),%edi // %edi == ptr to list head - movl 20(%esp),%esi // %esi == offset - movl (%edi),%eax // %eax == ptr to 1st element in Q - movl 4(%edi),%edx // %edx == current generation count -1: testl %eax,%eax // list empty? - jz 2f // yes - movl (%eax,%esi),%ebx // point to 2nd in Q - movl %edx,%ecx - incl %ecx // increment generation count - xchg64 (%edi, ATOMIC_UP) // ...pop off 1st element - jnz 1b -2: popl %ebx - popl %esi - popl %edi - ret // ptr to 1st element in Q still in %eax - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicDequeue, mp, 32, 2) - pushl %edi - pushl %esi - pushl %ebx - movl 16(%esp),%edi // %edi == ptr to list head - movl 20(%esp),%esi // %esi == offset - movl (%edi),%eax // %eax == ptr to 1st element in Q - movl 4(%edi),%edx // %edx == current generation count -1: testl %eax,%eax // list empty? - jz 2f // yes - movl (%eax,%esi),%ebx // point to 2nd in Q - movl %edx,%ecx - incl %ecx // increment generation count - xchg64 (%edi, ATOMIC_MP) // ...pop off 1st element - jnz 1b -2: popl %ebx - popl %esi - popl %edi - ret // ptr to 1st element in Q still in %eax - -/* - * typedef volatile struct { - * void *opaque1; <-- ptr to first queue element or null - * void *opaque2; <-- ptr to last queue element or null - * int opaque3; <-- spinlock - * } OSFifoQueueHead; - * - * void OSAtomicFifoEnqueue( OSFifoQueueHead *list, void *new, size_t offset); - */ - .align (1<<2) - .globl _OSAtomicFifoEnqueue -_OSAtomicFifoEnqueue: - pushl %edi - pushl %esi - pushl %ebx - xorl %ebx,%ebx // clear "preemption pending" flag - movl 16(%esp),%edi // %edi == ptr to list head - movl 20(%esp),%esi // %esi == new - EXTERN_TO_REG(_commpage_pfz_base,%ecx) - movl (%ecx), %ecx - addl $(_COMM_TEXT_PFZ_ENQUEUE_OFFSET), %ecx - movl 24(%esp),%edx // %edx == offset - call *%ecx - testl %ebx,%ebx // pending preemption? - jz 1f - call _preempt -1: popl %ebx - popl %esi - popl %edi - ret - -/* void* OSAtomicFifoDequeue( OSFifoQueueHead *list, size_t offset); */ - .align (1<<2) - .globl _OSAtomicFifoDequeue -_OSAtomicFifoDequeue: - pushl %edi - pushl %esi - pushl %ebx - xorl %ebx,%ebx // clear "preemption pending" flag - movl 16(%esp),%edi // %edi == ptr to list head - PICIFY(_commpage_pfz_base) - movl (%edx),%ecx - movl 20(%esp),%edx // %edx == offset - addl $(_COMM_TEXT_PFZ_DEQUEUE_OFFSET), %ecx - call *%ecx - testl %ebx,%ebx // pending preemption? - jz 1f - pushl %eax // save return value across sysenter - call _preempt - popl %eax -1: popl %ebx - popl %esi - popl %edi - ret // ptr to 1st element in Q still in %eax - -// Local Variables: -// tab-width: 8 -// End: diff --git a/src/libc/i386/sys/_sigtramp.S b/src/libc/i386/sys/_sigtramp.S deleted file mode 100644 index 35cf0c06e..000000000 --- a/src/libc/i386/sys/_sigtramp.S +++ /dev/null @@ -1,256 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007, 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#ifdef DARLING -# define ___in_sigtramp __in_sigtramp -# define __sigtramp _sigtramp -#endif - -#if defined(__DYNAMIC__) - .globl ___in_sigtramp - .data - .align 2 -___in_sigtramp: - .space 4 -#endif - -#define UC_TRAD 1 -#define UC_FLAVOR 30 - -/* Structure fields for ucontext and mcontext. */ -#define UCONTEXT_UC_MCONTEXT 28 - -#define MCONTEXT_ES_EXCEPTION 0 -#define MCONTEXT_SS_EAX 12 -#define MCONTEXT_SS_EBX 16 -#define MCONTEXT_SS_ECX 20 -#define MCONTEXT_SS_EDX 24 -#define MCONTEXT_SS_EDI 28 -#define MCONTEXT_SS_ESI 32 -#define MCONTEXT_SS_EBP 36 -#define MCONTEXT_SS_ESP 40 -#define MCONTEXT_SS_EFLAGS 48 -#define MCONTEXT_SS_EIP 52 - -/* register use: - %ebp frame pointer - %ebx Address of "L00000000001$pb" - %esi uctx - -void -_sigtramp( - union __sigaction_u __sigaction_u, - int sigstyle, - int sig, - siginfo_t *sinfo, - ucontext_t *uctx -) -*/ - - .globl __sigtramp - .text - .align 4,0x90 -__sigtramp: -Lstart: - /* Although this routine does not need any stack frame, various parts - of the OS can't analyse the stack without them. */ - pushl %ebp - movl %esp, %ebp - subl $24, %esp - movl 8(%ebp), %ecx # get '__sigaction_u' -#if defined(__DYNAMIC__) - call 0f -"L00000000001$pb": -0: - popl %ebx - incl ___in_sigtramp-"L00000000001$pb"(%ebx) -#endif - movl 16(%ebp), %edx # get 'sig' - movl 20(%ebp), %eax # get 'sinfo' - movl 24(%ebp), %esi # get 'uctx' - /* Call the signal handler. - Some variants are not supposed to get the last two parameters, - but the test to prevent this is more expensive than just passing - them. */ - movl %esi, 8(%esp) - movl %eax, 4(%esp) - movl %edx, (%esp) - call *%ecx -#if defined(__DYNAMIC__) - decl ___in_sigtramp-"L00000000001$pb"(%ebx) -#endif - movl %esi, 4(%esp) - movl $ UC_FLAVOR, 8(%esp) - movl $ SYS_sigreturn, %eax - int $0x80 -Lend: - -/* DWARF unwind table #defines. */ -#define DW_CFA_advance_loc_4 0x44 -#define DW_CFA_def_cfa 0x0c -#define DW_CFA_def_cfa_expression 0x0F -#define DW_CFA_expression 0x10 -#define DW_CFA_val_expression 0x16 -#define DW_CFA_offset(column) 0x80+(column) - -/* DWARF expression #defines. */ -#define DW_OP_deref 0x06 -#define DW_OP_const1u 0x08 -#define DW_OP_dup 0x12 -#define DW_OP_drop 0x13 -#define DW_OP_over 0x14 -#define DW_OP_pick 0x15 -#define DW_OP_swap 0x16 -#define DW_OP_rot 0x17 -#define DW_OP_abs 0x19 -#define DW_OP_and 0x1a -#define DW_OP_div 0x1b -#define DW_OP_minus 0x1c -#define DW_OP_mod 0x1d -#define DW_OP_mul 0x1e -#define DW_OP_neg 0x1f -#define DW_OP_not 0x20 -#define DW_OP_or 0x21 -#define DW_OP_plus 0x22 -#define DW_OP_plus_uconst 0x23 -#define DW_OP_shl 0x24 -#define DW_OP_shr 0x25 -#define DW_OP_shra 0x26 -#define DW_OP_xor 0x27 -#define DW_OP_skip 0x2f -#define DW_OP_bra 0x28 -#define DW_OP_eq 0x29 -#define DW_OP_ge 0x2A -#define DW_OP_gt 0x2B -#define DW_OP_le 0x2C -#define DW_OP_lt 0x2D -#define DW_OP_ne 0x2E -#define DW_OP_lit(n) 0x30+(n) -#define DW_OP_breg(n) 0x70+(n) -#define DW_OP_deref_size 0x94 - -/* The location expression we'll use. */ - -#define loc_expr_for_reg(regno, offs) \ - .byte DW_CFA_expression, regno, 5 /* block length */, \ - DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \ - DW_OP_plus_uconst, offs - -#ifndef DARLING - /* Unwind tables. */ - .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 # Length of Common Information Entry -LSCIE1: - .long 0 # CIE Identifier Tag - .byte 0x1 # CIE Version - .ascii "zRS\0" # CIE Augmentation - .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor - .byte 0x7c # sleb128 -4; CIE Data Alignment Factor - .byte 0x8 # CIE RA Column - .byte 0x1 # uleb128 0x1; Augmentation size - .byte 0x10 # FDE Encoding (pcrel) - .byte DW_CFA_def_cfa - .byte 0x5 # uleb128 0x5 - .byte 0x4 # uleb128 0x4 - .byte DW_CFA_offset(8) - .byte 0x1 # uleb128 0x1 - .byte DW_CFA_offset(8) // double DW_CFA_offset (eip, -4) tells linker to not make compact unwind - .byte 0x1 # uleb128 0x1 - .align 2 -LECIE1: - .globl _sigtramp.eh -_sigtramp.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 # FDE Length -LASFDE1: - .long LASFDE1-EH_frame1 # FDE CIE offset - .long Lstart-. # FDE initial location - .set L$set$2,Lend-Lstart - .long L$set$2 # FDE address range - .byte 0x0 # uleb128 0x0; Augmentation size - - /* Now for the expressions, which all compute - uctx->uc_mcontext->register - for each register. - - Describe even the registers that are not call-saved because they - might be being used in the prologue to save other registers. - Only integer registers are described at present. */ - - loc_expr_for_reg (0, MCONTEXT_SS_EAX) - loc_expr_for_reg (1, MCONTEXT_SS_ECX) - loc_expr_for_reg (2, MCONTEXT_SS_EDX) - loc_expr_for_reg (3, MCONTEXT_SS_EBX) - loc_expr_for_reg (4, MCONTEXT_SS_EBP) # note that GCC switches - loc_expr_for_reg (5, MCONTEXT_SS_ESP) # DWARF registers 4 & 5 - loc_expr_for_reg (6, MCONTEXT_SS_ESI) - loc_expr_for_reg (7, MCONTEXT_SS_EDI) - loc_expr_for_reg (9, MCONTEXT_SS_EFLAGS) - - /* The Intel architecture classifies exceptions into three categories, - 'faults' which put the address of the faulting instruction - in EIP, 'traps' which put the following instruction in EIP, - and 'aborts' which don't typically report the instruction - causing the exception. - - The traps are #BP and #OF. */ - - .byte DW_CFA_val_expression, 8 - .set L$set$3,Lpc_end-Lpc_start - .byte L$set$3 -Lpc_start: - /* Push the mcontext address twice. */ - .byte DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref, DW_OP_dup - /* Find the value of EIP. */ - .byte DW_OP_plus_uconst, MCONTEXT_SS_EIP, DW_OP_deref, DW_OP_swap - /* Determine the exception type. */ - .byte DW_OP_plus_uconst, MCONTEXT_ES_EXCEPTION, DW_OP_deref - /* Check whether it is #BP (3) or #OF (4). */ - .byte DW_OP_dup, DW_OP_lit(3), DW_OP_ne - .byte DW_OP_swap, DW_OP_lit(4), DW_OP_ne, DW_OP_and - /* If it is, then add 1 to the instruction address, so as to point - within or past the faulting instruction. */ - .byte DW_OP_plus -Lpc_end: - - /* The CFA will have been saved as the value of ESP (it is not - ESP+4). */ - .byte DW_CFA_def_cfa_expression - .set L$set$4,Lcfa_end-Lcfa_start - .byte L$set$4 -Lcfa_start: - .byte DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref - .byte DW_OP_plus_uconst, MCONTEXT_SS_ESP, DW_OP_deref -Lcfa_end: - - .align 2 -LEFDE1: - - .subsections_via_symbols -#endif diff --git a/src/libc/i386/sys/atomic.c b/src/libc/i386/sys/atomic.c deleted file mode 100644 index 4149cc630..000000000 --- a/src/libc/i386/sys/atomic.c +++ /dev/null @@ -1,100 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -#ifndef DARLING__DISABLED -#define RESOLVER_UP_MP(symbol) \ - PLATFUNC_DESCRIPTOR(symbol, up, kUP, 0); \ - PLATFUNC_DESCRIPTOR(symbol, mp, 0, kUP); \ - static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \ - PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \ - PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \ - 0 \ - }; \ - void* symbol ## _chooser() __asm__("_" #symbol); \ - void* symbol ## _chooser() { \ - __asm__(".symbol_resolver _" #symbol); \ - return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \ - } -#else // ELF doesn't support symbol resolvers -#define RESOLVER_UP_MP(symbol) __asm__(".globl " #symbol); __asm__(#symbol ": jmp " #symbol "$VARIANT$mp"); -#endif - -RESOLVER_UP_MP(OSAtomicAnd32) -RESOLVER_UP_MP(OSAtomicAnd32Barrier) -RESOLVER_UP_MP(OSAtomicOr32) -RESOLVER_UP_MP(OSAtomicOr32Barrier) -RESOLVER_UP_MP(OSAtomicXor32) -RESOLVER_UP_MP(OSAtomicXor32Barrier) -RESOLVER_UP_MP(OSAtomicAnd32Orig) -RESOLVER_UP_MP(OSAtomicAnd32OrigBarrier) -RESOLVER_UP_MP(OSAtomicOr32Orig) -RESOLVER_UP_MP(OSAtomicOr32OrigBarrier) -RESOLVER_UP_MP(OSAtomicXor32Orig) -RESOLVER_UP_MP(OSAtomicXor32OrigBarrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwapPtr) -RESOLVER_UP_MP(OSAtomicCompareAndSwapPtrBarrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwapInt) -RESOLVER_UP_MP(OSAtomicCompareAndSwapIntBarrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwapLong) -RESOLVER_UP_MP(OSAtomicCompareAndSwapLongBarrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwap32) -RESOLVER_UP_MP(OSAtomicCompareAndSwap32Barrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwap64) -RESOLVER_UP_MP(OSAtomicCompareAndSwap64Barrier) -RESOLVER_UP_MP(OSAtomicAdd32) -RESOLVER_UP_MP(OSAtomicAdd32Barrier) -RESOLVER_UP_MP(OSAtomicAdd64) -RESOLVER_UP_MP(OSAtomicAdd64Barrier) -RESOLVER_UP_MP(OSAtomicTestAndSet) -RESOLVER_UP_MP(OSAtomicTestAndSetBarrier) -RESOLVER_UP_MP(OSAtomicTestAndClear) -RESOLVER_UP_MP(OSAtomicTestAndClearBarrier) -RESOLVER_UP_MP(OSAtomicEnqueue) -RESOLVER_UP_MP(OSAtomicDequeue) - -#ifndef DARLING__DISABLED -PLATFUNC_DESCRIPTOR_PROTOTYPE(OSMemoryBarrier, all) -PLATFUNC_DESCRIPTOR_PROTOTYPE(OSMemoryBarrier, sse2) - -static const platfunc_descriptor *OSMemoryBarrier_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(OSMemoryBarrier, sse2), - PLATFUNC_DESCRIPTOR_REFERENCE(OSMemoryBarrier, all), - 0 -}; - -void *OSMemoryBarrier_chooser() __asm__("_OSMemoryBarrier"); -void *OSMemoryBarrier_chooser() { - __asm__(".symbol_resolver _OSMemoryBarrier"); - return find_platform_function((const platfunc_descriptor **) OSMemoryBarrier_platfunc_descriptors); -} -#else -extern void OSMemoryBarrierImpl(void) asm("OSMemoryBarrier$VARIANT$sse2"); -void OSMemoryBarrier(void) -{ - OSMemoryBarrierImpl(); -} -#endif diff --git a/src/libc/i386/sys/i386_gettimeofday_asm.S b/src/libc/i386/sys/i386_gettimeofday_asm.S deleted file mode 100644 index 589df7f86..000000000 --- a/src/libc/i386/sys/i386_gettimeofday_asm.S +++ /dev/null @@ -1,80 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2003-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -#define NSEC_PER_SEC 1000*1000*1000 -#define NSEC_PER_USEC 1000 - - .align 4 - .private_extern ___commpage_gettimeofday -___commpage_gettimeofday: - push %ebp - mov %esp,%ebp - push %esi - push %ebx - -0: - movl _COMM_PAGE_GTOD_GENERATION,%esi /* get generation (0 if disabled) */ - testl %esi,%esi /* disabled? */ - jz 4f - - call _mach_absolute_time_direct - - sub _COMM_PAGE_GTOD_NS_BASE,%eax - sbb _COMM_PAGE_GTOD_NS_BASE+4,%edx - mov _COMM_PAGE_GTOD_SEC_BASE,%ebx /* load all the data before checking generation */ - mov $ NSEC_PER_SEC,%ecx - - cmpl _COMM_PAGE_GTOD_GENERATION,%esi /* has time data changed out from under us? */ - jne 0b - - div %ecx - add %eax,%ebx - - mov $ NSEC_PER_USEC,%ecx - mov %edx,%eax - xor %edx,%edx - div %ecx - - mov 8(%ebp),%ecx - mov %ebx,(%ecx) - mov %eax,4(%ecx) - xor %eax,%eax - -3: - pop %ebx - pop %esi - pop %ebp - ret -4: /* fail */ - movl $1,%eax - jmp 3b diff --git a/src/libc/i386/sys/mach_absolute_time.c b/src/libc/i386/sys/mach_absolute_time.c deleted file mode 100644 index d78ebf95e..000000000 --- a/src/libc/i386/sys/mach_absolute_time.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -PLATFUNC_DESCRIPTOR_PROTOTYPE(mach_absolute_time,fast) -PLATFUNC_DESCRIPTOR_PROTOTYPE(mach_absolute_time,slow) - -static const platfunc_descriptor *mach_absolute_time_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(mach_absolute_time,fast), - PLATFUNC_DESCRIPTOR_REFERENCE(mach_absolute_time,slow), - 0 -}; - -void *mach_absolute_time_chooser() __asm__("_mach_absolute_time"); -void *mach_absolute_time_chooser() { - __asm__(".desc _mach_absolute_time, 0x100"); - return find_platform_function((const platfunc_descriptor **) mach_absolute_time_platfunc_descriptors); -} diff --git a/src/libc/i386/sys/mach_absolute_time_asm.S b/src/libc/i386/sys/mach_absolute_time_asm.S deleted file mode 100644 index 4d3bc2507..000000000 --- a/src/libc/i386/sys/mach_absolute_time_asm.S +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2003-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include -#include - -#if defined(VARIANT_DYLD) -/* For dyld, we need to decide upon call whether to jump to fast or slow */ - .globl _mach_absolute_time - .align 2, 0x90 -_mach_absolute_time: - movl _COMM_PAGE_CPU_CAPABILITIES, %eax - andl $(kSlow), %eax - jnz PLATFUNC_VARIANT_NAME(mach_absolute_time, slow) - jmp PLATFUNC_VARIANT_NAME(mach_absolute_time, fast) -#endif - -/* return mach_absolute_time in %edx:%eax */ - -PLATFUNC_FUNCTION_START(mach_absolute_time, fast, 32, 4) - .private_extern _mach_absolute_time_direct -_mach_absolute_time_direct: - pushl %ebp - movl %esp,%ebp - pushl %esi - pushl %ebx - -0: - movl _COMM_PAGE_NT_GENERATION,%esi /* get generation (0 if being changed) */ - testl %esi,%esi /* if being updated, loop until stable */ - jz 0b - - lfence - rdtsc /* get TSC in %edx:%eax */ - lfence - - subl _COMM_PAGE_NT_TSC_BASE,%eax - sbbl _COMM_PAGE_NT_TSC_BASE+4,%edx - - movl _COMM_PAGE_NT_SCALE,%ecx - - movl %edx,%ebx - mull %ecx - movl %ebx,%eax - movl %edx,%ebx - mull %ecx - addl %ebx,%eax - adcl $0,%edx - - addl _COMM_PAGE_NT_NS_BASE,%eax - adcl _COMM_PAGE_NT_NS_BASE+4,%edx - - cmpl _COMM_PAGE_NT_GENERATION,%esi /* have the parameters changed? */ - jne 0b /* yes, loop until stable */ - - popl %ebx - popl %esi - popl %ebp - ret -PLATFUNC_DESCRIPTOR(mach_absolute_time,fast,0,kSlow) - - -/* mach_absolute_time routine for machines slower than ~1Gz (SLOW_TSC_THRESHOLD) */ -PLATFUNC_FUNCTION_START(mach_absolute_time, slow, 32, 4) - push %ebp - mov %esp,%ebp - push %esi - push %edi - push %ebx - -0: - movl _COMM_PAGE_NT_GENERATION,%esi - testl %esi,%esi /* if generation is 0, data being changed */ - jz 0b /* so loop until stable */ - - lfence - rdtsc /* get TSC in %edx:%eax */ - lfence - subl _COMM_PAGE_NT_TSC_BASE,%eax - sbbl _COMM_PAGE_NT_TSC_BASE+4,%edx - - pushl %esi /* save generation */ - /* - * Do the math to convert tsc ticks to nanoseconds. We first - * do long multiply of 1 billion times the tsc. Then we do - * long division by the tsc frequency - */ - mov $1000000000, %ecx /* number of nanoseconds in a second */ - mov %edx, %ebx - mul %ecx - mov %edx, %edi - mov %eax, %esi - mov %ebx, %eax - mul %ecx - add %edi, %eax - adc $0, %edx /* result in edx:eax:esi */ - mov %eax, %edi - mov _COMM_PAGE_NT_SHIFT,%ecx /* overloaded as the low 32 tscFreq */ - xor %eax, %eax - xchg %edx, %eax - div %ecx - xor %eax, %eax - mov %edi, %eax - div %ecx - mov %eax, %ebx - mov %esi, %eax - div %ecx - mov %ebx, %edx /* result in edx:eax */ - popl %esi /* recover generation */ - - add _COMM_PAGE_NT_NS_BASE,%eax - adc _COMM_PAGE_NT_NS_BASE+4,%edx - - cmpl _COMM_PAGE_NT_GENERATION,%esi /* have the parameters changed? */ - jne 0b /* yes, loop until stable */ - - pop %ebx - pop %edi - pop %esi - pop %ebp - ret /* result in edx:eax */ -PLATFUNC_DESCRIPTOR(mach_absolute_time,slow,kSlow,0) diff --git a/src/libc/i386/sys/setjmp.S b/src/libc/i386/sys/setjmp.S deleted file mode 100644 index b5deda101..000000000 --- a/src/libc/i386/sys/setjmp.S +++ /dev/null @@ -1,147 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -/* - * NeXT 386 setjmp/longjmp - * - * Written by Bruce Martin, NeXT Inc. 4/9/92 - */ - -#ifdef DARLING -# define _sigprocmask sigprocmask -# define _sigsetjmp sigsetjmp -# define _sigaltstack sigaltstack -# define x__setjmp _setjmp -# define x_setjmp setjmp -# define _siglongjmp siglongjmp -# define x_longjmp longjmp -# define x__longjmp _longjmp -# define __sigunaltstack _sigunaltstack -#else -# define x_longjmp _longjmp -# define x__longjmp __longjmp -# define x__setjmp __setjmp -# define x_setjmp _setjmp -#endif - -/* - * C library -- setjmp, longjmp - * - * longjmp(a,v) - * will generate a "return(v)" from - * the last call to - * setjmp(a) - * by restoring registers from the stack, - * The previous value of the signal mask is - * restored. - * - */ - -#include - -// The FP control word is actually two bytes, but there's no harm in -// using four bytes for it and keeping the struct aligned. -#define JB_FPCW 0 -#define JB_MASK 4 -#define JB_MXCSR 8 -#define JB_EBX 12 -#define JB_ONSTACK 16 -#define JB_EDX 20 -#define JB_EDI 24 -#define JB_ESI 28 -#define JB_EBP 32 -#define JB_ESP 36 -#define JB_SS 40 -#define JB_EFLAGS 44 -#define JB_EIP 48 -#define JB_CS 52 -#define JB_DS 56 -#define JB_ES 60 -#define JB_FS 64 -#define JB_GS 68 -#define JB_SAVEMASK 72 // sigsetjmp/siglongjmp only - -LEAF(_sigsetjmp, 0) - movl 4(%esp), %eax // sigjmp_buf * jmpbuf; - movl 8(%esp), %ecx // int savemask; - movl %ecx, JB_SAVEMASK(%eax) // jmpbuf[_JBLEN] = savemask; - cmpl $0, %ecx // if savemask != 0 - jne _setjmp // setjmp(jmpbuf); - jmp L_do__setjmp // else _setjmp(jmpbuf); - -LEAF(x_setjmp, 0) - subl $16, %esp // make space for return from sigprocmask - // + 12 to align stack - pushl %esp // oset - pushl $0 // set = NULL - pushl $1 // how = SIG_BLOCK - CALL_EXTERN(_sigprocmask) - movl 12(%esp),%eax // save the mask - addl $28, %esp // restore original esp - movl 4(%esp), %ecx // jmp_buf (struct sigcontext *) - movl %eax, JB_MASK(%ecx) - - subl $20, %esp // temporary struct sigaltstack + 8 to - // align stack - pushl %esp // oss - pushl $0 // ss == NULL - CALL_EXTERN(_sigaltstack) // get alternate signal stack info - movl 16(%esp), %eax // oss->ss_flags - addl $28, %esp // Restore %esp - movl %eax, JB_ONSTACK(%ecx) - -L_do__setjmp: - BRANCH_EXTERN(x__setjmp) - -LEAF(x_siglongjmp, 0) - movl 4(%esp), %eax // sigjmp_buf * jmpbuf; - cmpl $0, JB_SAVEMASK(%eax) // if jmpbuf[_JBLEN] != 0 - jne x_longjmp // longjmp(jmpbuf, var); - jmp L_do__longjmp // else _longjmp(jmpbuf, var); - -LEAF(x_longjmp, 0) - movl 4(%esp), %ecx // address of jmp_buf (saved context) - movl JB_MASK(%ecx),%eax // get the mask - subl $12, %esp // Make sure the stack is 16-byte - // aligned when we call sigprocmask - pushl %eax // store the mask - movl %esp, %edx // save the address where we stored the mask - pushl $0 // oset = NULL - pushl %edx // set - pushl $3 // how = SIG_SETMASK - CALL_EXTERN_AGAIN(_sigprocmask) - addl $28, %esp // restore original esp - - movl 4(%esp), %ecx // address of jmp_buf - movl JB_ONSTACK(%ecx), %eax // ss_flags - subl $8, %esp - pushl %eax - CALL_EXTERN(__sigunaltstack) - addl $12, %esp - -L_do__longjmp: - BRANCH_EXTERN(x__longjmp) // else -END(x_longjmp) diff --git a/src/libc/i386/sys/spinlocks.c b/src/libc/i386/sys/spinlocks.c deleted file mode 100644 index a201d1a1d..000000000 --- a/src/libc/i386/sys/spinlocks.c +++ /dev/null @@ -1,50 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -#ifndef DARLING -#define RESOLVER_UP_MP(symbol) \ - PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, up); \ - PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, mp); \ - static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \ - PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \ - PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \ - 0 \ - }; \ - void* symbol ## _chooser() __asm__("_" #symbol); \ - void* symbol ## _chooser() { \ - __asm__(".symbol_resolver _" #symbol); \ - return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \ - } -#else // ELF doesn't support symbol resolvers -#define RESOLVER_UP_MP(symbol) __asm__(".globl " #symbol); __asm__(#symbol ": jmp " #symbol "$VARIANT$mp"); -#endif - -RESOLVER_UP_MP(OSSpinLockTry) -RESOLVER_UP_MP(_spin_lock_try) -RESOLVER_UP_MP(OSSpinLockLock) -RESOLVER_UP_MP(_spin_lock) -RESOLVER_UP_MP(spin_lock) diff --git a/src/libc/i386/sys/spinlocks_asm.S b/src/libc/i386/sys/spinlocks_asm.S deleted file mode 100644 index 7a12c6c0b..000000000 --- a/src/libc/i386/sys/spinlocks_asm.S +++ /dev/null @@ -1,130 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2003-2009 Apple, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include - - -PLATFUNC_FUNCTION_START(OSSpinLockTry, up, 32, 4) -PLATFUNC_FUNCTION_START(_spin_lock_try, up, 32, 4) - movl 4(%esp), %ecx - xorl %eax, %eax - orl $-1, %edx - cmpxchgl %edx, (%ecx) - setz %dl - movzbl %dl, %eax - ret -PLATFUNC_DESCRIPTOR(OSSpinLockTry,up,kUP,0) -PLATFUNC_DESCRIPTOR(_spin_lock_try,up,kUP,0) - -PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockTry, mp, 32, 4) -PLATFUNC_FUNCTION_START_GENERIC(_spin_lock_try, mp, 32, 4) - movl 4(%esp), %ecx - xorl %eax, %eax - orl $-1, %edx - lock - cmpxchgl %edx, (%ecx) - setz %dl - movzbl %dl, %eax - ret -PLATFUNC_DESCRIPTOR(OSSpinLockTry,mp,0,kUP) -PLATFUNC_DESCRIPTOR(_spin_lock_try,mp,0,kUP) - - -PLATFUNC_FUNCTION_START(spin_lock, up, 32, 4) -PLATFUNC_FUNCTION_START(OSSpinLockLock, up, 32, 4) -PLATFUNC_FUNCTION_START(_spin_lock, up, 32, 4) -Lspin_lock_up: - movl 4(%esp), %ecx - xorl %eax, %eax - orl $-1, %edx - cmpxchgl %edx, (%ecx) - jnz 1f - ret -1: - /* failed to get lock so relinquish the processor immediately on UP */ - pushl $1 /* 1 ms */ - pushl $1 /* SWITCH_OPTION_DEPRESS */ - pushl $0 /* THREAD_NULL */ - pushl $0 /* push dummy stack ret addr */ - movl $-61,%eax /* SYSCALL_THREAD_SWITCH */ - int $(MACH_INT) - addl $16, %esp /* adjust stack*/ - jmp Lspin_lock_up -PLATFUNC_DESCRIPTOR(spin_lock,up,kUP,0) -PLATFUNC_DESCRIPTOR(OSSpinLockLock,up,kUP,0) -PLATFUNC_DESCRIPTOR(_spin_lock,up,kUP,0) - -PLATFUNC_FUNCTION_START_GENERIC(spin_lock, mp, 32, 4) -PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockLock, mp, 32, 4) -PLATFUNC_FUNCTION_START_GENERIC(_spin_lock, mp, 32, 4) -Lspin_lock_mp: - movl 4(%esp), %ecx - xorl %eax, %eax -0: - orl $-1, %edx - lock - cmpxchgl %edx, (%ecx) - jnz 1f - ret -1: - xorl %eax, %eax - movl $(MP_SPIN_TRIES), %edx -2: - pause - cmpl %eax, (%ecx) - jz 0b /* favor success and slow down spin loop */ - decl %edx - jnz 2b - /* failed to get lock after spinning so relinquish */ - pushl $1 /* 1 ms */ - pushl $1 /* SWITCH_OPTION_DEPRESS */ - pushl $0 /* THREAD_NULL */ - pushl $0 /* push dummy stack ret addr */ - movl $-61,%eax /* SYSCALL_THREAD_SWITCH */ - int $(MACH_INT) - addl $16, %esp /* adjust stack*/ - jmp Lspin_lock_mp -PLATFUNC_DESCRIPTOR(spin_lock,mp,0,kUP) -PLATFUNC_DESCRIPTOR(OSSpinLockLock,mp,0,kUP) -PLATFUNC_DESCRIPTOR(_spin_lock,mp,0,kUP) - - .align 2, 0x90 - .globl _OSSpinLockUnlock - .globl _spin_unlock - .globl __spin_unlock -_OSSpinLockUnlock: -_spin_unlock: -__spin_unlock: - movl 4(%esp), %eax - movl $0, (%eax) - ret - diff --git a/src/libc/include/CrashReporterClient.h b/src/libc/include/CrashReporterClient.h deleted file mode 100644 index 68593aee7..000000000 --- a/src/libc/include/CrashReporterClient.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/*********************************************************************** - * Not to be installed in /usr/local/include - ***********************************************************************/ - -#ifndef _LIBC_CRASHREPORTERCLIENT_H -#define _LIBC_CRASHREPORTERCLIENT_H - -#ifdef LIBC_NO_LIBCRASHREPORTERCLIENT - -/* Fake the CrashReporterClient API */ -#define CRGetCrashLogMessage() 0 -#define CRSetCrashLogMessage(x) /* nothing */ - -#else /* !LIBC_NO_LIBCRASHREPORTERCLIENT */ - -/* Include the real CrashReporterClient.h */ -#include_next - -#endif /* !LIBC_NO_LIBCRASHREPORTERCLIENT */ - -#endif /* _LIBC_CRASHREPORTERCLIENT_H */ diff --git a/src/libc/include/FreeBSD/nl_types.h b/src/libc/include/FreeBSD/nl_types.h index db74be935..72d0da254 100644 --- a/src/libc/include/FreeBSD/nl_types.h +++ b/src/libc/include/FreeBSD/nl_types.h @@ -91,10 +91,7 @@ typedef struct __nl_cat_d { int __size; } *nl_catd; -#ifndef _NL_ITEM -typedef __darwin_nl_item nl_item; -#define _NL_ITEM -#endif +#include <_types/_nl_item.h> __BEGIN_DECLS nl_catd catopen(const char *, int); diff --git a/src/libc/include/NSSystemDirectories.h b/src/libc/include/NSSystemDirectories.h deleted file mode 100644 index b6781069d..000000000 --- a/src/libc/include/NSSystemDirectories.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 1999-2000, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - This API returns the various standard system directories where apps, resources, etc get installed. - Because queries can return multiple directories, the API is in the form of an enumeration. - The directories are returned in search path order; that is, the first place to look is returned first. - This API may return directories that do not exist yet. - If NSUserDomain is included in a query, then the results will contain "~" to refer to the user's directory. - NEXT_ROOT is prepended as necessary to the returned values. - Some calls might return no directories! - The buffer that is passed in will be filled with a null-terminated string, possibly containing as many as PATH_MAX-1 characters. - - Typical usage: - - #include - #include - - char path[PATH_MAX]; - NSSearchPathEnumerationState state = NSStartSearchPathEnumeration(dir, domainMask); - while (state = NSGetNextSearchPathEnumeration(state, path)) { - // Handle path - } - - -*/ - -#ifndef __NS_SYSTEM_DIRECTORIES_H__ -#define __NS_SYSTEM_DIRECTORIES_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -// Directories - -typedef enum { - NSApplicationDirectory = 1, // supported applications (Applications) - NSDemoApplicationDirectory = 2, // unsupported applications, demonstration versions (Applications/GrabBag) - NSDeveloperApplicationDirectory = 3, // developer applications (Developer/Applications) - NSAdminApplicationDirectory = 4, // system and network administration applications (Applications/Utilities) - NSLibraryDirectory = 5, // various user-visible documentation, support, and configuration files, resources (Library) - NSDeveloperDirectory = 6, // developer resources (Developer) - NSUserDirectory = 7, // user home directories (Users) - NSDocumentationDirectory = 8, // documentation (Library/Documentation) - NSDocumentDirectory = 9, // documents (Documents) - NSCoreServiceDirectory = 10, // location of core services (System/Library/CoreServices) - NSAutosavedInformationDirectory = 11, // location of user's directory for use with autosaving (Library/Autosave Information) - NSDesktopDirectory = 12, // location of user's Desktop (Desktop) - NSCachesDirectory = 13, // location of discardable cache files (Library/Caches) - NSApplicationSupportDirectory = 14, // location of application support files (plug-ins, etc) (Library/Application Support) - NSDownloadsDirectory = 15, // location of user's Downloads directory (Downloads) - NSInputMethodsDirectory = 16, // input methods (Library/Input Methods) - NSMoviesDirectory = 17, // location of user's Movies directory (~/Movies) - NSMusicDirectory = 18, // location of user's Music directory (~/Music) - NSPicturesDirectory = 19, // location of user's Pictures directory (~/Pictures) - NSPrinterDescriptionDirectory = 20, // location of system's PPDs directory (Library/Printers/PPDs) - NSSharedPublicDirectory = 21, // location of user's Public sharing directory (~/Public) - NSPreferencePanesDirectory = 22, // location of the PreferencePanes directory for use with System Preferences (Library/PreferencePanes) - NSAllApplicationsDirectory = 100, // all directories where applications can occur (Applications, Applications/Utilities, Developer/Applications, ...) - NSAllLibrariesDirectory = 101 // all directories where resources can occur (Library, Developer) -} NSSearchPathDirectory; - -// Domains - -typedef enum { - NSUserDomainMask = 1, // user's home directory --- place to install user's personal items (~) - NSLocalDomainMask = 2, // local to the current machine --- place to install items available to everyone on this machine - NSNetworkDomainMask = 4, // publically available location in the local area network --- place to install items available on the network (/Network) - NSSystemDomainMask = 8, // provided by Apple - NSAllDomainsMask = 0x0ffff // all domains: all of the above and more, future items -} NSSearchPathDomainMask; - -typedef unsigned int NSSearchPathEnumerationState; - -/* Enumeration - Call NSStartSearchPathEnumeration() once, then call NSGetNextSearchPathEnumeration() one or more times with the returned state. - The return value of NSGetNextSearchPathEnumeration() should be used as the state next time around. - When NSGetNextSearchPathEnumeration() returns 0, you're done. -*/ - -extern NSSearchPathEnumerationState NSStartSearchPathEnumeration(NSSearchPathDirectory dir, NSSearchPathDomainMask domainMask); - -extern NSSearchPathEnumerationState NSGetNextSearchPathEnumeration(NSSearchPathEnumerationState state, char *path); - -#ifdef __cplusplus -} -#endif - -#endif /* __NS_SYSTEM_DIRECTORIES_H__ */ diff --git a/src/libc/include/NetBSD/utmpx.h b/src/libc/include/NetBSD/utmpx.h index 616b4c031..d14f17ce1 100644 --- a/src/libc/include/NetBSD/utmpx.h +++ b/src/libc/include/NetBSD/utmpx.h @@ -64,17 +64,10 @@ #include #include #include - -#ifndef _PID_T -#define _PID_T -typedef __darwin_pid_t pid_t; -#endif +#include #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#ifndef _UID_T -#define _UID_T -typedef __darwin_uid_t uid_t; -#endif +#include #endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ #define _PATH_UTMPX "/var/run/utmpx" @@ -153,8 +146,8 @@ struct lastlogx * getlastlogxbyname(const char*, struct lastlogx *)__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); #ifdef UNIFDEF_LEGACY_UTMP_APIS struct utmp; /* forward reference */ -void getutmp(const struct utmpx *, struct utmp *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -void getutmpx(const struct utmp *, struct utmpx *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +void getutmp(const struct utmpx *, struct utmp *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_9, __IPHONE_2_0, __IPHONE_7_0) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +void getutmpx(const struct utmp *, struct utmpx *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_9, __IPHONE_2_0, __IPHONE_7_0) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; #endif /* UNIFDEF_LEGACY_UTMP_APIS */ #endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ diff --git a/src/libc/include/_locale.h b/src/libc/include/_locale.h index 9f890ef70..b87458ddf 100644 --- a/src/libc/include/_locale.h +++ b/src/libc/include/_locale.h @@ -67,9 +67,7 @@ struct lconv { char int_n_sign_posn; }; -#ifndef NULL -#define NULL __DARWIN_NULL -#endif /* ! NULL */ +#include __BEGIN_DECLS struct lconv *localeconv(void); diff --git a/src/libc/include/_structs.h b/src/libc/include/_structs.h deleted file mode 100644 index 44443b2d7..000000000 --- a/src/libc/include/_structs.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - diff --git a/src/libc/include/_types/_intmax_t.h b/src/libc/include/_types/_intmax_t.h new file mode 100644 index 000000000..abb585e65 --- /dev/null +++ b/src/libc/include/_types/_intmax_t.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _INTMAX_T +#define _INTMAX_T +#ifdef __INTMAX_TYPE__ +typedef __INTMAX_TYPE__ intmax_t; +#else +#ifdef __LP64__ +typedef long int intmax_t; +#else +typedef long long int intmax_t; +#endif /* __LP64__ */ +#endif /* __INTMAX_TYPE__ */ +#endif /* _INTMAX_T */ diff --git a/src/libc/include/_types/_nl_item.h b/src/libc/include/_types/_nl_item.h new file mode 100644 index 000000000..ca4531eaf --- /dev/null +++ b/src/libc/include/_types/_nl_item.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _NL_ITEM +#define _NL_ITEM +typedef __darwin_nl_item nl_item; +#endif /* _NL_ITEM */ \ No newline at end of file diff --git a/src/libc/include/_types/_uint16_t.h b/src/libc/include/_types/_uint16_t.h new file mode 100644 index 000000000..9ce997601 --- /dev/null +++ b/src/libc/include/_types/_uint16_t.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _UINT16_T +#define _UINT16_T +typedef unsigned short uint16_t; +#endif /* _UINT16_T */ diff --git a/src/libc/include/_types/_uint32_t.h b/src/libc/include/_types/_uint32_t.h new file mode 100644 index 000000000..8c9c92e31 --- /dev/null +++ b/src/libc/include/_types/_uint32_t.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _UINT32_T +#define _UINT32_T +typedef unsigned int uint32_t; +#endif /* _UINT32_T */ diff --git a/src/libc/include/_types/_uint64_t.h b/src/libc/include/_types/_uint64_t.h new file mode 100644 index 000000000..37866cfe0 --- /dev/null +++ b/src/libc/include/_types/_uint64_t.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _UINT64_T +#define _UINT64_T +typedef unsigned long long uint64_t; +#endif /* _UINT64_T */ diff --git a/src/libc/include/_types/_uint8_t.h b/src/libc/include/_types/_uint8_t.h new file mode 100644 index 000000000..9fb2a8e51 --- /dev/null +++ b/src/libc/include/_types/_uint8_t.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _UINT8_T +#define _UINT8_T +typedef unsigned char uint8_t; +#endif /* _UINT8_T */ diff --git a/src/libc/include/_types/_uintmax_t.h b/src/libc/include/_types/_uintmax_t.h new file mode 100644 index 000000000..ee5275577 --- /dev/null +++ b/src/libc/include/_types/_uintmax_t.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _UINTMAX_T +#define _UINTMAX_T +#ifdef __UINTMAX_TYPE__ +typedef __UINTMAX_TYPE__ uintmax_t; +#else +#ifdef __LP64__ +typedef long unsigned int uintmax_t; +#else +typedef long long unsigned int uintmax_t; +#endif /* __LP64__ */ +#endif /* __UINTMAX_TYPE__ */ +#endif /* _UINTMAX_T */ diff --git a/src/libc/include/_types/_wctrans_t.h b/src/libc/include/_types/_wctrans_t.h new file mode 100644 index 000000000..1d3df0b2f --- /dev/null +++ b/src/libc/include/_types/_wctrans_t.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _WCTRANS_T +#define _WCTRANS_T +typedef __darwin_wctrans_t wctrans_t; +#endif /* _WCTRANS_T */ \ No newline at end of file diff --git a/src/libc/include/_types/_wctype_t.h b/src/libc/include/_types/_wctype_t.h new file mode 100644 index 000000000..650ebc4ac --- /dev/null +++ b/src/libc/include/_types/_wctype_t.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _WCTYPE_T +#define _WCTYPE_T +typedef __darwin_wctype_t wctype_t; +#endif /* _WCTYPE_T */ \ No newline at end of file diff --git a/src/libc/include/_wctype.h b/src/libc/include/_wctype.h index 626b53128..63487792e 100644 --- a/src/libc/include/_wctype.h +++ b/src/libc/include/_wctype.h @@ -30,7 +30,7 @@ * * Contains everything required by wctype.h except: * - * typedef __darwin_wctrans_t wctrans_t; + * #include <_types/_wctrans_t.h> * int iswblank(wint_t); * wint_t towctrans(wint_t, wctrans_t); * wctrans_t wctrans(const char *); @@ -42,22 +42,16 @@ #include #include <_types.h> -#ifndef _WINT_T -#define _WINT_T -typedef __darwin_wint_t wint_t; -#endif - -#ifndef _WCTYPE_T -#define _WCTYPE_T -typedef __darwin_wctype_t wctype_t; -#endif +#include +#include +#include <_types/_wctype_t.h> #ifndef WEOF #define WEOF __DARWIN_WEOF #endif -#ifndef __DARWIN_WCTYPE_TOP_static_inline -#define __DARWIN_WCTYPE_TOP_static_inline static __inline +#ifndef __DARWIN_WCTYPE_TOP_inline +#define __DARWIN_WCTYPE_TOP_inline __header_inline #endif #include @@ -68,85 +62,85 @@ typedef __darwin_wctype_t wctype_t; #if !defined(_DONT_USE_CTYPE_INLINE_) && \ (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswalnum(wint_t _wc) { return (__istype(_wc, _CTYPE_A|_CTYPE_D)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswalpha(wint_t _wc) { return (__istype(_wc, _CTYPE_A)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswcntrl(wint_t _wc) { return (__istype(_wc, _CTYPE_C)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswctype(wint_t _wc, wctype_t _charclass) { return (__istype(_wc, _charclass)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswdigit(wint_t _wc) { return (__isctype(_wc, _CTYPE_D)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswgraph(wint_t _wc) { return (__istype(_wc, _CTYPE_G)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswlower(wint_t _wc) { return (__istype(_wc, _CTYPE_L)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswprint(wint_t _wc) { return (__istype(_wc, _CTYPE_R)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswpunct(wint_t _wc) { return (__istype(_wc, _CTYPE_P)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswspace(wint_t _wc) { return (__istype(_wc, _CTYPE_S)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswupper(wint_t _wc) { return (__istype(_wc, _CTYPE_U)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswxdigit(wint_t _wc) { return (__isctype(_wc, _CTYPE_X)); } -__DARWIN_WCTYPE_TOP_static_inline wint_t +__DARWIN_WCTYPE_TOP_inline wint_t towlower(wint_t _wc) { return (__tolower(_wc)); } -__DARWIN_WCTYPE_TOP_static_inline wint_t +__DARWIN_WCTYPE_TOP_inline wint_t towupper(wint_t _wc) { return (__toupper(_wc)); diff --git a/src/libc/include/alloca.h b/src/libc/include/alloca.h index e6a8fc7bf..0264ae680 100644 --- a/src/libc/include/alloca.h +++ b/src/libc/include/alloca.h @@ -26,11 +26,7 @@ #include #include <_types.h> - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif +#include __BEGIN_DECLS void *alloca(size_t); /* built-in for gcc */ diff --git a/src/libc/include/arpa/inet.h b/src/libc/include/arpa/inet.h new file mode 100644 index 000000000..46f44e1a8 --- /dev/null +++ b/src/libc/include/arpa/inet.h @@ -0,0 +1,97 @@ +/* + * ++Copyright++ 1983, 1993 + * - + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +/* + * @(#)inet.h 8.1 (Berkeley) 6/2/93 + * $Id: inet.h,v 1.10 2006/02/01 18:09:47 majka Exp $ + */ + +#ifndef _ARPA_INET_H_ +#define _ARPA_INET_H_ + +/* External definitions for functions in inet(3), addr2ascii(3) */ + +#include +#include +#include /* uint32_t uint16_t */ +#include /* htonl() and family if (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ +#include /* htonl() and family if (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ +#include /* in_addr */ + +__BEGIN_DECLS + +in_addr_t inet_addr(const char *); +char *inet_ntoa(struct in_addr); +const char *inet_ntop(int, const void *, char *, socklen_t); +int inet_pton(int, const char *, void *); + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +int ascii2addr(int, const char *, void *); +char *addr2ascii(int, const void *, int, char *); +int inet_aton(const char *, struct in_addr *); +in_addr_t inet_lnaof(struct in_addr); +struct in_addr inet_makeaddr(in_addr_t, in_addr_t); +in_addr_t inet_netof(struct in_addr); +in_addr_t inet_network(const char *); +char *inet_net_ntop(int, const void *, int, char *, __darwin_size_t); +int inet_net_pton(int, const char *, void *, __darwin_size_t); +char *inet_neta(in_addr_t, char *, __darwin_size_t); +unsigned int inet_nsap_addr(const char *, unsigned char *, int); +char *inet_nsap_ntoa(int, const unsigned char *, char *); +#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */ + +__END_DECLS + +#endif /* !_ARPA_INET_H_ */ diff --git a/src/libc/include/asl.h b/src/libc/include/asl.h deleted file mode 100644 index ec4799eff..000000000 --- a/src/libc/include/asl.h +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (c) 2004-2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __ASL_H__ -#define __ASL_H__ - -#include -#include -#include -#include - -typedef struct __aslclient *aslclient; -typedef struct __aslmsg *aslmsg; -typedef struct __aslresponse *aslresponse; - -/*! @header - * These routines provide an interface to the Apple System Log facility. - * The API allows client applications to create flexible, structured messages - * and send them to the syslogd server. Messages received by the server are - * saved in a data store, subject to input filtering constraints. - * This API also permits clients to create queries and search the message - * data store for matching messages. - */ - -/* - * NOTE FOR HeaderDoc - * - * These are added to allow headerdoc2html to process - * the prototypes of asl_log and asl_vlog correctly. - * The "-p" option to headerdoc2html is required. - */ -#ifndef __printflike -/*! @parseOnly */ -#define __printflike(a,b) -#endif - -/*! @defineblock Log Message Priority Levels - * Log levels of the message. - */ -#define ASL_LEVEL_EMERG 0 -#define ASL_LEVEL_ALERT 1 -#define ASL_LEVEL_CRIT 2 -#define ASL_LEVEL_ERR 3 -#define ASL_LEVEL_WARNING 4 -#define ASL_LEVEL_NOTICE 5 -#define ASL_LEVEL_INFO 6 -#define ASL_LEVEL_DEBUG 7 -/*! @/defineblock */ - -/*! @defineblock Log Message Priority Level Strings - * Strings corresponding to log levels. - */ -#define ASL_STRING_EMERG "Emergency" -#define ASL_STRING_ALERT "Alert" -#define ASL_STRING_CRIT "Critical" -#define ASL_STRING_ERR "Error" -#define ASL_STRING_WARNING "Warning" -#define ASL_STRING_NOTICE "Notice" -#define ASL_STRING_INFO "Info" -#define ASL_STRING_DEBUG "Debug" -/*! @/defineblock */ - -/*! @defineblock Attribute Matching - * Attribute value comparison operations. - */ -#define ASL_QUERY_OP_CASEFOLD 0x0010 -#define ASL_QUERY_OP_PREFIX 0x0020 -#define ASL_QUERY_OP_SUFFIX 0x0040 -#define ASL_QUERY_OP_SUBSTRING 0x0060 -#define ASL_QUERY_OP_NUMERIC 0x0080 -#define ASL_QUERY_OP_REGEX 0x0100 - -#define ASL_QUERY_OP_EQUAL 0x0001 -#define ASL_QUERY_OP_GREATER 0x0002 -#define ASL_QUERY_OP_GREATER_EQUAL 0x0003 -#define ASL_QUERY_OP_LESS 0x0004 -#define ASL_QUERY_OP_LESS_EQUAL 0x0005 -#define ASL_QUERY_OP_NOT_EQUAL 0x0006 -#define ASL_QUERY_OP_TRUE 0x0007 -/*! @/defineblock */ - -/*! @defineblock Message Attributes - * - * These attributes are known by ASL, and are generally - * associated with all log messages. - * Additional attributes may be added as desired. - */ -#define ASL_KEY_TIME "Time" /* Timestamp. Set automatically */ -#define ASL_KEY_TIME_NSEC "TimeNanoSec" /* Nanosecond time. */ -#define ASL_KEY_HOST "Host" /* Sender's address (set by the server). */ -#define ASL_KEY_SENDER "Sender" /* Sender's identification string. Default is process name. */ -#define ASL_KEY_FACILITY "Facility" /* Sender's facility. Default is "user". */ -#define ASL_KEY_PID "PID" /* Sending process ID encoded as a string. Set automatically. */ -#define ASL_KEY_UID "UID" /* UID that sent the log message (set by the server). */ -#define ASL_KEY_GID "GID" /* GID that sent the log message (set by the server). */ -#define ASL_KEY_LEVEL "Level" /* Log level number encoded as a string. See levels above. */ -#define ASL_KEY_MSG "Message" /* Message text. */ -#define ASL_KEY_READ_UID "ReadUID" /* User read access (-1 is any user). */ -#define ASL_KEY_READ_GID "ReadGID" /* Group read access (-1 is any group). */ -#define ASL_KEY_EXPIRE_TIME "ASLExpireTime" /* Expiration time for messages with long TTL. */ -#define ASL_KEY_MSG_ID "ASLMessageID" /* 64-bit message ID number (set by the server). */ -#define ASL_KEY_SESSION "Session" /* Session (set by the launchd). */ -#define ASL_KEY_REF_PID "RefPID" /* Reference PID for messages proxied by launchd */ -#define ASL_KEY_REF_PROC "RefProc" /* Reference process for messages proxied by launchd */ -#define ASL_KEY_AUX_TITLE "ASLAuxTitle" /* Auxiliary title string */ -#define ASL_KEY_AUX_UTI "ASLAuxUTI" /* Auxiliary Uniform Type ID */ -#define ASL_KEY_AUX_URL "ASLAuxURL" /* Auxiliary Uniform Resource Locator */ -#define ASL_KEY_AUX_DATA "ASLAuxData" /* Auxiliary in-line data */ -#define ASL_KEY_OPTION "ASLOption" /* Internal */ -#define ASL_KEY_SENDER_INSTANCE "SenderInstance" /* Sender instance UUID. */ -/*! @/defineblock */ - -/*! @defineblock aslmsg Types - * Message type argument passed to asl_new(). - */ -#define ASL_TYPE_MSG 0 -#define ASL_TYPE_QUERY 1 -/*! @/defineblock */ - -/*! @defineblock Filter Masks - * Used in client-side filtering, which determines which - * messages are sent by the client to the syslogd server. - */ -#define ASL_FILTER_MASK_EMERG 0x01 -#define ASL_FILTER_MASK_ALERT 0x02 -#define ASL_FILTER_MASK_CRIT 0x04 -#define ASL_FILTER_MASK_ERR 0x08 -#define ASL_FILTER_MASK_WARNING 0x10 -#define ASL_FILTER_MASK_NOTICE 0x20 -#define ASL_FILTER_MASK_INFO 0x40 -#define ASL_FILTER_MASK_DEBUG 0x80 -/*! @/defineblock */ - -/*! @defineblock Filter Mask Macros - * Macros to create bitmasks for filter settings - see asl_set_filter(). - */ -#define ASL_FILTER_MASK(level) (1 << (level)) -#define ASL_FILTER_MASK_UPTO(level) ((1 << ((level) + 1)) - 1) -/*! @/defineblock */ - -/*! @defineblock Client Creation Options - * Options for asl_open(). - */ -#define ASL_OPT_STDERR 0x00000001 -#define ASL_OPT_NO_DELAY 0x00000002 -#define ASL_OPT_NO_REMOTE 0x00000004 -/*! @/defineblock */ - -/*! @defineblock File Descriptor Types - * Instructions on how to treat the file descriptor in asl_log_descriptor(). - */ -#define ASL_LOG_DESCRIPTOR_READ 1 -#define ASL_LOG_DESCRIPTOR_WRITE 2 - -/*! - * ASL_PREFILTER_LOG is a macro similar to asl_log(), but it first checks - * if the message will simply be ignored due to local filter settings. - * This prevents the variable argument list from being evaluated. - * Note that the message may still be processed if it will be written - * to a file or stderr. - * - * @param asl - * (input) An ASL client handle - * @param msg - * (input) An aslmsg (default attributes will be supplied if msg is NULL) - * @param level - * (input) Log level (ASL_LEVEL_DEBUG to ASL_LEVEL_EMERG) - * @param format - * (input) A printf() - style format string followed by a list of arguments - */ -#define ASL_PREFILTER_LOG(asl, msg, level, format, ...) \ - do { \ - aslclient _asl = (asl); \ - aslmsg _msg = (msg); \ - uint32_t _asl_eval = _asl_evaluate_send(_asl, _msg, (level)); \ - if (_asl_eval != 0) _asl_lib_log(_asl, _asl_eval, _msg, (format), ## __VA_ARGS__); \ - } while (0) - -__BEGIN_DECLS - -/* ASL Library SPI - do not call directly */ -int _asl_lib_log(aslclient asl, uint32_t eval, aslmsg msg, const char *format, ...) __printflike(4, 5); - -uint32_t _asl_evaluate_send(aslclient asl, aslmsg msg, int level); - -/*! - * Initialize a connection to the ASL server. - * - * This call is optional in most cases. The library will perform any - * necessary initializations on the fly. A call to asl_open() is required - * if optional settings must be made before messages are sent to the server. - * These include setting the client filter and managing additional output - * file descriptors. Note that the default setting of the client filter is - * ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE), so ASL_LEVEL_DEBUG and ASL_LEVEL_INFO - * messages are not sent to the server by default. - * - * Options (defined above) may be set using the opts parameter. They are: - * - * ASL_OPT_STDERR - adds stderr as an output file descriptor - * - * ASL_OPT_NO_DELAY - connects to the server immediately - * - * ASL_OPT_NO_REMOTE - disables the remote-control mechanism for adjusting - * filter levers for processes using e.g. syslog -c ... - * - * @param ident - * (input) Sender name - * @param facility - * (input) Facility name - * @param opts - * (input) Options (see asl_open Options) - * @result Returns an ASL client handle - */ -aslclient asl_open(const char *ident, const char *facility, uint32_t opts); - -/*! - * Shuts down a connection to the server. - * - * @param asl - * (input) An ASL client handle - */ -void asl_close(aslclient asl); - -/*! - * Write log messages to the given file descriptor. - * - * Log messages will be written to this file as well as to the server. - * - * @param asl - * (input) An ASL client handle - * @param descriptor - * (input) A file descriptor - * @result Returns 0 on success, non-zero on failure -*/ -int asl_add_log_file(aslclient asl, int descriptor); - -/*! - * Stop writing log messages to the given file descriptor. - * The file descripter is not closed by this routine. - * - * @param asl - * (input) An ASL client handle - * @param descriptor - * (input) A file descriptor - * @result Returns 0 on success, non-zero on failure - */ -int asl_remove_log_file(aslclient asl, int descriptor); - -/*! - * Set a filter for messages being sent to the server. - * The filter is a bitmask representing priorities. The ASL_FILTER_MASK - * macro may be used to convert a priority level into a bitmask for that - * level. The ASL_FILTER_MASK_UPTO macro creates a bitmask for all - * priorities up to and including a given priority. - * Messages with priority levels that do not have a corresponding bit - * set in the filter are not sent to the server, although they will be - * sent to any file descripters added with asl_add_log_file(). - * The default setting is ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE). - * Returns the previous filter value. - * - * @param asl - * (input) An ASL client handle - * @param f - * (input) A filter value - * @result Returns the previous filter value - */ -int asl_set_filter(aslclient asl, int f); - -/* - * Examine attribute keys. - * - * @param msg - * (input) An ASL message - * @param n - * (input) An index value - * @result Returns the key of the nth attribute in a message (beginning at zero), - * or NULL if n is greater than the largest message index. - */ -const char *asl_key(aslmsg msg, uint32_t n); - -/*! - * Create a new log message or query message. - * - * @param type - * (input) Message type (see aslmsg Types) - * @result Returns a newly allocated asmsg of the specified type - */ -aslmsg asl_new(uint32_t type); - -/*! - * Set or re-set a message attribute. - * - * @param msg - * (input) An aslmsg - * @param key - * (input) Attribute key - * @param value - * (input) Attribute value - * @result returns 0 for success, non-zero for failure - */ -int asl_set(aslmsg msg, const char *key, const char *value); - -/*! - * Remove a message attribute. - * - * @param msg - * (input) An aslmsg - * @param key - * (input) Attribute key - * returns 0 for success, non-zero for failure - */ -int asl_unset(aslmsg msg, const char *key); - -/*! - * Get the value of a message attribute. - * - * @param msg - * (input) An aslmsg - * @param key - * (input) Attribute key - * @result Returns the attribute value, or NULL if the message does not contain the key - */ -const char *asl_get(aslmsg msg, const char *key); - -/*! - * Log a message with a particular log level. - * - * @param asl - * (input) An ASL client handle - * @param msg - * (input) An aslmsg (default attributes will be supplied if msg is NULL) - * @param level - * (input) Log level (ASL_LEVEL_DEBUG to ASL_LEVEL_EMERG) - * @param format - * (input) A printf() - style format string followed by a list of arguments - * @result Returns 0 for success, non-zero for failure - */ -int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __printflike(4, 5); - -/*! - * Log a message with a particular log level. - * Similar to asl_log, but takes a va_list argument. - * - * @param asl - * (input) An ASL client handle - * @param msg - * (input) An aslmsg (default attributes will be supplied if msg is NULL) - * @param level - * (input) Log level (ASL_LEVEL_DEBUG to ASL_LEVEL_EMERG) - * @param format - * (input) A printf() - style format string followed by a list of arguments - * @param ap - * (input) A va_list containing the values for the format string - * @result Returns 0 for success, non-zero for failure - */ -int asl_vlog(aslclient asl, aslmsg msg, int level, const char *format, va_list ap) __printflike(4, 0); - -/*! - * Log a message. - * - * This routine may be used instead of asl_log() or asl_vlog() if asl_set() - * has been used to set all of a message's attributes. - * - * @param asl - * (input) An ASL client handle - * @param msg - * (input) An aslmsg - * @result Returns 0 for success, non-zero for failure - */ -int asl_send(aslclient asl, aslmsg msg); - -/*! - * Free a message. Frees all the attribute keys and values. - * - * @param msg - * (input) An aslmsg to free - */ -void asl_free(aslmsg msg); - -/*! - * Set arbitrary parameters of a query. - * This is similar to asl_set, but allows richer query operations. - * See ASL_QUERY_OP_* above. - * - * @param msg - * (input) An aslmsg - * @param key - * (input) Attribute key - * @param value - * (input) Attribute value - * @param op - * (input) An operation (ASL_QUERY_OP_*) - * @result Returns 0 for success, non-zero for failure - */ -int asl_set_query(aslmsg msg, const char *key, const char *value, uint32_t op); - -/*! - * Search for messages matching the criteria described by the aslmsg. - * The caller should set the attributes to match using asl_set_query() or asl_set(). - * The operatoin ASL_QUERY_OP_EQUAL is used for attributes set with asl_set(). - * - * @param msg - * (input) An aslmsg to match - * @result Returns a set of messages accessable using aslresponse_next(), - */ -aslresponse asl_search(aslclient asl, aslmsg msg); - -/*! - * Iterate over responses returned from asl_search(). - * - * @param r - * (input) An aslresponse returned by asl_search() - * @result Returns the next message (an aslmsg) in the response, or NULL when there are no more messages - */ -aslmsg aslresponse_next(aslresponse r); - -/*! - * Free a response returned from asl_search(). - * @param r - * (input) An aslresponse returned by asl_search() - */ -void aslresponse_free(aslresponse r); - -/*! - * Creates an auxiliary file that may be used to save arbitrary data. The ASL message msg - * will be saved at the time that the auxiliary file is closed with asl_close_auxiliary_file(). - * The log entry will include any keys and values found in msg, and it will include the title - * and Uniform Type Identifier specified. If NULL is supplied as a value for the uti parameter, - * the type "public.data" is used. Console.app will display a hyperlink to the file. - * Output parameter out_descriptor will contain a readable and writable file descriptor for the new - * auxiliary file. - * - * By default, the file will be world-readable. If the message contains a ReadUID and/or a - * ReadGID key, then the values for those keys will determine read access to the file. - * - * The file will be deleted at the same time that the message expires from the ASL data store. - * The aslmanager utility manages message expiry. If msg contains a value for ASLExpireTime, - * then the message and the file will not be deleted before that time. The value may be in - * seconds after the Epoch, or it may be ctime() format, e.g "Thu Jun 24 18:22:48 2010". - * - * @param msg - * (input) An aslmsg - * @param tite - * (input) A title string for the file - * @param uti - * (input) Uniform Type Identifier for the file - * @param out_descriptor - * (output) A writable file descriptor - * @result Returns 0 for success, non-zero for failure - */ -int asl_create_auxiliary_file(aslmsg msg, const char *title, const char *uti, int *out_descriptor) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0); - -/*! - * Close an auxiliary file opened by asl_create_auxiliary_file() when writing is complete. - * syslogd will log the message provided to asl_create_auxiliary_file() when this routine - * is called. - * - * @param descriptor - * (input) The file descriptor - * @result Returns 0 for success, non-zero for failure - */ -int asl_close_auxiliary_file(int descriptor) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0); - -/*! - * Sends an ASL message to syslogd along with a title string, Uniform Resource Locator, - * and Uniform Type Identifier specified. Console.app will hyperlink the title string to - * the specified URL. If NULL is supplied as a value for the uti parameter, the default - * type "public.data" is used. - * - * @param msg - * (input) An aslmsg - * @param title - * (input) A title string for the file - * @param uti - * (input) Uniform Type Identifier for the file - * @param url - * (input) Uniform Type Locator - * @result Returns 0 for success, non-zero for failure - */ -int asl_log_auxiliary_location(aslmsg msg, const char *title, const char *uti, const char *url) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0); - -/*! - * Creates an aslclient for logging to a file descriptor. The file must be opened for read and - * write access. This routine may be used in conjunction with asl_create_auxiliary_file() to - * save ASL format log messages to an auxiliary file. - * - * The file will be truncated if it is not empty. When logging to the auxiliary file is complete, - * aslclient should be closed using asl_close(). The file should be closed using - * asl_close_auxiliary_file() if it was returned by asl_create_auxiliary_file(), or close() - * otherwise. - * - * The returned aslclient is thread-safe. - * - * Note that per-message read access controls (ReadUID and ReadGID) and message expire - * times (ASLExpireTime) keys have no effect for messages written to this file. - * - * @param descriptor - * (input) A file descriptor - * @param ident - * (input) Sender name - * @param facility - * (input) Facility name - * @result An aslclient - */ -aslclient asl_open_from_file(int descriptor, const char *ident, const char *facility) -__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0); - -/*! - * This API provides functionality to use file descriptors to send logging - * data to ASL. - * - * asl is retained by ASL and must still be closed by the caller by calling - * asl_close() if the caller loses reference to it. msg is copied by ASL and - * similarly must still be freed by the caller by calling asl_free() if the - * caller loses reference to it. Any changes made to it after calling - * asl_log_descriptor() are not applicable to the message used. descriptor - * is treated differentlty based on the value of fd_type. - * - * If fd_type is ASL_LOG_DESCRIPTOR_READ, the descriptor must be open for read - * access. ASL uses GCD to read from the descriptor as data becomes available. - * These data are line buffered and passed to asl_log. When EOF is read, the - * descriptor is closed. - * - * Example: - * asl_log_descriptor(c, m, ASL_LEVEL_NOTICE, STDIN_FILENO, ASL_LOG_DESCRIPTOR_READ); - * - * If fd_type is ASL_LOG_DESCRIPTOR_WRITE, the descriptor is closed and a new - * writable descriptor is created with the same fileno. Any data written to - * this new descriptor are line buffered and passed to asl_log. When EOF is - * sent, no further data are read. The caller is responsible for closing the - * new descriptor. One common use for this API is to redirect writes to stdout - * or stderr to ASL by passing STDOUT_FILENO or STDERR_FILENO as descriptor. - * - * Example: - * asl_log_descriptor(c, m, ASL_LEVEL_NOTICE, STDOUT_FILENO, ASL_LOG_DESCRIPTOR_WRITE); - * asl_log_descriptor(c, m, ASL_LEVEL_ERR, STDERR_FILENO, ASL_LOG_DESCRIPTOR_WRITE); - * - * @param asl - * (input) An ASL client handle - * @param msg - * (input) An aslmsg (default attributes will be supplied if msg is NULL) - * @param level - * (input) Log level (ASL_LEVEL_DEBUG to ASL_LEVEL_EMERG) - * @param descriptor - * (input) An open file descriptor to read from - * @param fd_type - * (input) Either ASL_LOG_DESCRIPTOR_READ or ASL_LOG_DESCRIPTOR_WRITE - * @result Returns 0 for success, non-zero for failure - */ -int asl_log_descriptor(aslclient asl, aslmsg msg, int level, int descriptor, uint32_t fd_type) -__OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_5_1); - -__END_DECLS - -#endif /* __ASL_H__ */ diff --git a/src/libc/include/assert.h b/src/libc/include/assert.h index a585ff1b0..67ae0fd6a 100644 --- a/src/libc/include/assert.h +++ b/src/libc/include/assert.h @@ -66,7 +66,7 @@ int printf(const char * __restrict, ...); __END_DECLS #define assert(e) \ - ((void) ((e) ? 0 : __assert (#e, __FILE__, __LINE__))) + ((void) ((e) ? ((void)0) : __assert (#e, __FILE__, __LINE__))) #define __assert(e, file, line) \ ((void)printf ("%s:%u: failed assertion `%s'\n", file, line, e), abort()) @@ -98,3 +98,14 @@ __END_DECLS #endif /* __GNUC__ */ #endif /* NDEBUG */ + +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#ifndef __cplusplus +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define static_assert _Static_assert +#endif /* __STDC_VERSION__ */ +#endif /* !__cplusplus */ + +#endif /* _ASSERT_H_ */ diff --git a/src/libc/include/bitstring.h b/src/libc/include/bitstring.h index 1e08cb5d6..660ccdf6c 100644 --- a/src/libc/include/bitstring.h +++ b/src/libc/include/bitstring.h @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)bitstring.h 8.1 (Berkeley) 7/19/93 + * $FreeBSD$ */ #ifndef _BITSTRING_H_ @@ -53,16 +53,15 @@ typedef unsigned char bitstr_t; /* external macros */ /* bytes in a bitstring of nbits bits */ #define bitstr_size(nbits) \ - ((((nbits) - 1) >> 3) + 1) + (((nbits) + 7) >> 3) /* allocate a bitstring */ #define bit_alloc(nbits) \ - (bitstr_t *)calloc(1, \ - (unsigned int)bitstr_size(nbits) * sizeof(bitstr_t)) + (bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t)) /* allocate a bitstring on the stack */ #define bit_decl(name, nbits) \ - (name)[bitstr_size(nbits)] + ((name)[bitstr_size(nbits)]) /* is bit N of bitstring name set? */ #define bit_test(name, bit) \ @@ -70,18 +69,18 @@ typedef unsigned char bitstr_t; /* set bit N of bitstring name */ #define bit_set(name, bit) \ - (name)[_bit_byte(bit)] |= _bit_mask(bit) + ((name)[_bit_byte(bit)] |= _bit_mask(bit)) /* clear bit N of bitstring name */ #define bit_clear(name, bit) \ - (name)[_bit_byte(bit)] &= ~_bit_mask(bit) + ((name)[_bit_byte(bit)] &= ~_bit_mask(bit)) /* clear bits start ... stop in bitstring */ -#define bit_nclear(name, start, stop) { \ - register bitstr_t *_name = name; \ - register int _start = start, _stop = stop; \ - register int _startbyte = _bit_byte(_start); \ - register int _stopbyte = _bit_byte(_stop); \ +#define bit_nclear(name, start, stop) do { \ + bitstr_t *_name = (name); \ + int _start = (start), _stop = (stop); \ + int _startbyte = _bit_byte(_start); \ + int _stopbyte = _bit_byte(_stop); \ if (_startbyte == _stopbyte) { \ _name[_startbyte] &= ((0xff >> (8 - (_start&0x7))) | \ (0xff << ((_stop&0x7) + 1))); \ @@ -91,14 +90,14 @@ typedef unsigned char bitstr_t; _name[_startbyte] = 0; \ _name[_stopbyte] &= 0xff << ((_stop&0x7) + 1); \ } \ -} +} while (0) /* set bits start ... stop in bitstring */ -#define bit_nset(name, start, stop) { \ - register bitstr_t *_name = name; \ - register int _start = start, _stop = stop; \ - register int _startbyte = _bit_byte(_start); \ - register int _stopbyte = _bit_byte(_stop); \ +#define bit_nset(name, start, stop) do { \ + bitstr_t *_name = (name); \ + int _start = (start), _stop = (stop); \ + int _startbyte = _bit_byte(_start); \ + int _stopbyte = _bit_byte(_stop); \ if (_startbyte == _stopbyte) { \ _name[_startbyte] |= ((0xff << (_start&0x7)) & \ (0xff >> (7 - (_stop&0x7)))); \ @@ -108,36 +107,44 @@ typedef unsigned char bitstr_t; _name[_startbyte] = 0xff; \ _name[_stopbyte] |= 0xff >> (7 - (_stop&0x7)); \ } \ -} +} while (0) /* find first bit clear in name */ -#define bit_ffc(name, nbits, value) { \ - register bitstr_t *_name = name; \ - register int _byte, _nbits = nbits; \ - register int _stopbyte = _bit_byte(_nbits), _value = -1; \ - for (_byte = 0; _byte < _stopbyte; ++_byte) \ - if (_name[_byte] != 0xff) { \ - _value = _byte << 3; \ - for (_stopbyte = _name[_byte]; (_stopbyte&0x1); \ - ++_value, _stopbyte >>= 1); \ - break; \ - } \ +#define bit_ffc(name, nbits, value) do { \ + bitstr_t *_name = (name); \ + int _byte, _nbits = (nbits); \ + int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \ + if (_nbits > 0) \ + for (_byte = 0; _byte <= _stopbyte; ++_byte) \ + if (_name[_byte] != 0xff) { \ + bitstr_t _lb; \ + _value = _byte << 3; \ + for (_lb = _name[_byte]; (_lb&0x1); \ + ++_value, _lb >>= 1); \ + break; \ + } \ + if (_value >= nbits) \ + _value = -1; \ *(value) = _value; \ -} +} while (0) /* find first bit set in name */ -#define bit_ffs(name, nbits, value) { \ - register bitstr_t *_name = name; \ - register int _byte, _nbits = nbits; \ - register int _stopbyte = _bit_byte(_nbits), _value = -1; \ - for (_byte = 0; _byte < _stopbyte; ++_byte) \ - if (_name[_byte]) { \ - _value = _byte << 3; \ - for (_stopbyte = _name[_byte]; !(_stopbyte&0x1); \ - ++_value, _stopbyte >>= 1); \ - break; \ - } \ +#define bit_ffs(name, nbits, value) do { \ + bitstr_t *_name = (name); \ + int _byte, _nbits = (nbits); \ + int _stopbyte = _bit_byte(_nbits - 1), _value = -1; \ + if (_nbits > 0) \ + for (_byte = 0; _byte <= _stopbyte; ++_byte) \ + if (_name[_byte]) { \ + bitstr_t _lb; \ + _value = _byte << 3; \ + for (_lb = _name[_byte]; !(_lb&0x1); \ + ++_value, _lb >>= 1); \ + break; \ + } \ + if (_value >= nbits) \ + _value = -1; \ *(value) = _value; \ -} +} while (0) #endif /* !_BITSTRING_H_ */ diff --git a/src/libc/include/ctype.h b/src/libc/include/ctype.h index 798ec510d..3548bcd10 100644 --- a/src/libc/include/ctype.h +++ b/src/libc/include/ctype.h @@ -64,13 +64,12 @@ */ //Begin-Libc -#ifdef BUILDING_LIBC #include "xlocale_private.h" -#endif //End-Libc #ifndef _CTYPE_H_ #define _CTYPE_H_ +#include #include #define _CTYPE_A 0x00000100L /* Alpha */ @@ -118,27 +117,35 @@ #define _SW3 _CTYPE_SW3 /* 3 width character */ #endif /* _NONSTD_SOURCE */ +//Begin-Libc /* * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us * to generate code for extern versions of all intermediate inline functions. */ #ifdef _EXTERNALIZE_CTYPE_INLINES_ #define _USE_CTYPE_INLINE_ -#define __DARWIN_CTYPE_static_inline +#define __DARWIN_CTYPE_inline #else /* !_EXTERNALIZE_CTYPE_INLINES_ */ -#define __DARWIN_CTYPE_static_inline static __inline +//End-Libc +#define __DARWIN_CTYPE_inline __header_inline +//Begin-Libc #endif /* !_EXTERNALIZE_CTYPE_INLINES_ */ +//End-Libc +//Begin-Libc /* * _EXTERNALIZE_CTYPE_INLINES_TOP_ is defined in locale/isctype.c to tell us * to generate code for extern versions of all top-level inline functions. */ #ifdef _EXTERNALIZE_CTYPE_INLINES_TOP_ #define _USE_CTYPE_INLINE_ -#define __DARWIN_CTYPE_TOP_static_inline +#define __DARWIN_CTYPE_TOP_inline #else /* !_EXTERNALIZE_CTYPE_INLINES_TOP_ */ -#define __DARWIN_CTYPE_TOP_static_inline static __inline +//End-Libc +#define __DARWIN_CTYPE_TOP_inline __header_inline +//Begin-Libc #endif /* _EXTERNALIZE_CTYPE_INLINES_TOP_ */ +//End-Libc /* * Use inline functions if we are allowed to and the compiler supports them. @@ -153,34 +160,39 @@ __darwin_ct_rune_t ___tolower(__darwin_ct_rune_t); __darwin_ct_rune_t ___toupper(__darwin_ct_rune_t); __END_DECLS -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isascii(int _c) { return ((_c & ~0x7F) == 0); } #ifdef USE_ASCII -__DARWIN_CTYPE_static_inline int +__DARWIN_CTYPE_inline int __maskrune(__darwin_ct_rune_t _c, unsigned long _f) { - return _DefaultRuneLocale.__runetype[_c & 0xff] & _f; + return (int)_DefaultRuneLocale.__runetype[_c & 0xff] & (__uint32_t)_f; } //Begin-Libc #elif defined(__LIBC__) -__DARWIN_CTYPE_static_inline int +__DARWIN_CTYPE_inline int __maskrune(__darwin_ct_rune_t _c, unsigned long _f) { - return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) : - __current_locale()->__lc_ctype->_CurrentRuneLocale.__runetype[_c]) & _f; + /* _CurrentRuneLocale.__runetype[_c] is __uint32_t + * _f is unsigned long + * ___runetype(_c) is unsigned long + * retval is int + */ + return (int)((_c < 0 || _c >= _CACHED_RUNES) ? (__uint32_t)___runetype(_c) : + __current_locale()->__lc_ctype->_CurrentRuneLocale.__runetype[_c]) & (__uint32_t)_f; } //End-Libc #else /* !USE_ASCII */ __BEGIN_DECLS -int __maskrune(__darwin_ct_rune_t, unsigned long); +int __maskrune(__darwin_ct_rune_t, unsigned long); __END_DECLS #endif /* USE_ASCII */ -__DARWIN_CTYPE_static_inline int +__DARWIN_CTYPE_inline int __istype(__darwin_ct_rune_t _c, unsigned long _f) { #ifdef USE_ASCII @@ -191,7 +203,7 @@ __istype(__darwin_ct_rune_t _c, unsigned long _f) #endif /* USE_ASCII */ } -__DARWIN_CTYPE_static_inline __darwin_ct_rune_t +__DARWIN_CTYPE_inline __darwin_ct_rune_t __isctype(__darwin_ct_rune_t _c, unsigned long _f) { #ifdef USE_ASCII @@ -203,13 +215,13 @@ __isctype(__darwin_ct_rune_t _c, unsigned long _f) } #ifdef USE_ASCII -__DARWIN_CTYPE_static_inline __darwin_ct_rune_t +__DARWIN_CTYPE_inline __darwin_ct_rune_t __toupper(__darwin_ct_rune_t _c) { return _DefaultRuneLocale.__mapupper[_c & 0xff]; } -__DARWIN_CTYPE_static_inline __darwin_ct_rune_t +__DARWIN_CTYPE_inline __darwin_ct_rune_t __tolower(__darwin_ct_rune_t _c) { return _DefaultRuneLocale.__maplower[_c & 0xff]; @@ -222,14 +234,14 @@ __tolower(__darwin_ct_rune_t _c) * assume c >= _CACHED_RUNES. So we are stuck making __toupper() a routine * to hide the extended locale details, outside of Libc. */ -__DARWIN_CTYPE_static_inline __darwin_ct_rune_t +__DARWIN_CTYPE_inline __darwin_ct_rune_t __toupper(__darwin_ct_rune_t _c) { return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) : __current_locale()->__lc_ctype->_CurrentRuneLocale.__mapupper[_c]; } -__DARWIN_CTYPE_static_inline __darwin_ct_rune_t +__DARWIN_CTYPE_inline __darwin_ct_rune_t __tolower(__darwin_ct_rune_t _c) { return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) : @@ -243,7 +255,7 @@ __darwin_ct_rune_t __tolower(__darwin_ct_rune_t); __END_DECLS #endif /* USE_ASCII */ -__DARWIN_CTYPE_static_inline int +__DARWIN_CTYPE_inline int __wcwidth(__darwin_ct_rune_t _c) { unsigned int _x; @@ -261,136 +273,136 @@ __wcwidth(__darwin_ct_rune_t _c) #define _tolower(c) __tolower(c) #define _toupper(c) __toupper(c) -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isalnum(int _c) { return (__istype(_c, _CTYPE_A|_CTYPE_D)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isalpha(int _c) { return (__istype(_c, _CTYPE_A)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isblank(int _c) { return (__istype(_c, _CTYPE_B)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int iscntrl(int _c) { return (__istype(_c, _CTYPE_C)); } /* ANSI -- locale independent */ -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isdigit(int _c) { return (__isctype(_c, _CTYPE_D)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isgraph(int _c) { return (__istype(_c, _CTYPE_G)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int islower(int _c) { return (__istype(_c, _CTYPE_L)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isprint(int _c) { return (__istype(_c, _CTYPE_R)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int ispunct(int _c) { return (__istype(_c, _CTYPE_P)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isspace(int _c) { return (__istype(_c, _CTYPE_S)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isupper(int _c) { return (__istype(_c, _CTYPE_U)); } /* ANSI -- locale independent */ -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isxdigit(int _c) { return (__isctype(_c, _CTYPE_X)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int toascii(int _c) { return (_c & 0x7F); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int tolower(int _c) { return (__tolower(_c)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int toupper(int _c) { return (__toupper(_c)); } #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int digittoint(int _c) { return (__maskrune(_c, 0x0F)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int ishexnumber(int _c) { return (__istype(_c, _CTYPE_X)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isideogram(int _c) { return (__istype(_c, _CTYPE_I)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isnumber(int _c) { return (__istype(_c, _CTYPE_D)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isphonogram(int _c) { return (__istype(_c, _CTYPE_Q)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isrune(int _c) { return (__istype(_c, 0xFFFFFFF0L)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isspecial(int _c) { return (__istype(_c, _CTYPE_T)); diff --git a/src/libc/include/err.h b/src/libc/include/err.h index ee4eae99d..6a531763b 100644 --- a/src/libc/include/err.h +++ b/src/libc/include/err.h @@ -83,9 +83,9 @@ void vwarnc(int, const char *, __darwin_va_list) __printflike(2, 0); void warnx(const char *, ...) __printflike(1, 2); void vwarnx(const char *, __darwin_va_list) __printflike(1, 0); void err_set_file(void *); -void err_set_exit(void (*)(int)); +void err_set_exit(void (* _Nullable)(int)); #ifdef __BLOCKS__ -void err_set_exit_b(void (^)(int)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +void err_set_exit_b(void (^ _Nullable)(int)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ __END_DECLS diff --git a/src/libc/include/fts.h b/src/libc/include/fts.h index f04d5ff50..c91b09900 100644 --- a/src/libc/include/fts.h +++ b/src/libc/include/fts.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2003-2006, 2008 Apple Inc. All rights reserved. + * Copyright (c) 2000, 2003-2006, 2008, 2012 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -59,21 +59,11 @@ #define _FTS_H_ #include +#include +#include +#include -#ifndef _DEV_T -typedef __darwin_dev_t dev_t; /* device number */ -#define _DEV_T -#endif - -#ifndef _INO_T -typedef __darwin_ino_t ino_t; /* inode number */ -#define _INO_T -#endif - -#ifndef _NLINK_T -typedef __uint16_t nlink_t; /* link count */ -#define _NLINK_T -#endif +#include typedef struct { struct _ftsent *fts_cur; /* current node */ @@ -100,9 +90,14 @@ typedef struct { #define FTS_PHYSICAL 0x010 /* physical walk */ #define FTS_SEEDOT 0x020 /* return dot and dot-dot */ #define FTS_XDEV 0x040 /* don't cross devices */ -#define FTS_WHITEOUT 0x080 /* return whiteout information */ +#define FTS_WHITEOUT 0x080 /* (no longer supported) return whiteout information */ #define FTS_COMFOLLOWDIR 0x400 /* (non-std) follow command line symlinks for directories only */ +#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1090) || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 70000) #define FTS_OPTIONMASK 0x4ff /* valid user option mask */ +#else +#define FTS_NOSTAT_TYPE 0x800 /* (non-std) no stat, but use d_type in struct dirent when available */ +#define FTS_OPTIONMASK 0xcff /* valid user option mask */ +#endif #define FTS_NAMEONLY 0x100 /* (private) child names only */ #define FTS_STOP 0x200 /* (private) unrecoverable error */ @@ -131,6 +126,7 @@ typedef struct _ftsent { #define FTS_ROOTPARENTLEVEL -1 #define FTS_ROOTLEVEL 0 +#define FTS_MAXLEVEL 0x7fffffff short fts_level; /* depth (-1 to N) */ #define FTS_D 1 /* preorder directory */ diff --git a/src/libc/include/glob.h b/src/libc/include/glob.h index 878720b2a..06314af31 100644 --- a/src/libc/include/glob.h +++ b/src/libc/include/glob.h @@ -43,11 +43,7 @@ #include <_types.h> #include #include - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif +#include #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) struct dirent; diff --git a/src/libc/include/i386/libc-features.h b/src/libc/include/i386/libc-features.h deleted file mode 100644 index d62b55f71..000000000 --- a/src/libc/include/i386/libc-features.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _LIBC_FEATURES_H_ -#define _LIBC_FEATURES_H_ - -#if !defined(__i386__) -#error Mismatched libc-features.h architecture -#endif - -#define UNIFDEF_LEGACY_RUNE_APIS 1 -#define LEGACY_CRT1_ENVIRON 1 -#define UNIFDEF_LEGACY_UTMP_APIS 1 -/* #undef UNIFDEF_MOVE_LOCALTIME */ -#if __DARWIN_ONLY_VERS_1050 -# error Feature mismatch: __DARWIN_ONLY_VERS_1050 == 1 -#endif /* __DARWIN_ONLY_VERS_1050 */ -#if __DARWIN_ONLY_UNIX_CONFORMANCE -# error Feature mismatch: __DARWIN_ONLY_UNIX_CONFORMANCE == 1 -#endif /* __DARWIN_ONLY_UNIX_CONFORMANCE */ -#if __DARWIN_ONLY_64_BIT_INO_T -# error Feature mismatch: __DARWIN_ONLY_64_BIT_INO_T == 1 -#endif /* __DARWIN_ONLY_64_BIT_INO_T */ -#define __APPLE_PR3417676_HACK__ 1 -#define PR_5243343 1 -/* #define PLOCKSTAT 1 */ -/* #define NOTIFY_TZ 1 */ -/* #undef LIBC_NO_LIBCRASHREPORTERCLIENT */ -#define CONFIG_MEMORYSTATUS 1 -#endif // _LIBC_FEATURES_H_ diff --git a/src/libc/include/inttypes.h b/src/libc/include/inttypes.h index 1f9738c02..c29873da3 100644 --- a/src/libc/include/inttypes.h +++ b/src/libc/include/inttypes.h @@ -1,23 +1,23 @@ /* - * Copyright (c) 2000, 2001, 2002, 2003, 2004 Apple Computer, Inc. - * All rights reserved. + * Copyright (c) 2000-2004, 2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * * @APPLE_LICENSE_HEADER_END@ */ @@ -220,45 +220,56 @@ # define SCNuMAX __SCN_MAX_LENGTH_MODIFIER__ "u" # define SCNxMAX __SCN_MAX_LENGTH_MODIFIER__ "x" -#include /* For __BEGIN_DECLS and __END_DECLS */ -#include <_types.h> /* For __darwin_wchar_t */ -#include - -#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) - /* Translator is not ISO/IEC 9899:1999-compliant. */ -# if !defined(restrict) -# define restrict -# define __RESTRICT_KEYWORD_DEFINED__ -# endif -#endif - -__BEGIN_DECLS - - /* 7.8.2.1 */ - extern intmax_t imaxabs(intmax_t j); +#include +#include - /* 7.8.2.2 */ - typedef struct { - intmax_t quot; - intmax_t rem; - } imaxdiv_t; +#include <_types.h> +#include - extern imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); - - /* 7.8.2.3 */ - extern intmax_t strtoimax(const char * restrict nptr, char ** restrict endptr, int base); - extern uintmax_t strtoumax(const char * restrict nptr, char ** restrict endptr, int base); +#include -#ifndef __cplusplus /* wchar_t is a built-in type in C++ */ -# ifndef _WCHAR_T -# define _WCHAR_T - typedef __darwin_wchar_t wchar_t; -# endif /* _WCHAR_T */ -#endif /* __cplusplus */ +__BEGIN_DECLS - /* 7.8.2.4 */ - extern intmax_t wcstoimax(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base); - extern uintmax_t wcstoumax(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base); +/* 7.8.2.1 */ +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +extern intmax_t +imaxabs(intmax_t j); + +/* 7.8.2.2 */ +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +extern imaxdiv_t +imaxdiv(intmax_t __numer, intmax_t __denom); + +/* 7.8.2.3 */ +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +extern intmax_t +strtoimax(const char * __restrict __nptr, + char ** __restrict __endptr, + int __base); + +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +extern uintmax_t +strtoumax(const char * __restrict __nptr, + char ** __restrict __endptr, + int __base); + +/* 7.8.2.4 */ +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +extern intmax_t +wcstoimax(const wchar_t * __restrict __nptr, + wchar_t ** __restrict __endptr, + int __base); + +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +extern uintmax_t +wcstoumax(const wchar_t * __restrict __nptr, + wchar_t ** __restrict __endptr, + int __base); /* Poison the following routines if -fshort-wchar is set */ #if !defined(__cplusplus) && defined(__WCHAR_MAX__) && __WCHAR_MAX__ <= 0xffffU @@ -283,9 +294,4 @@ __END_DECLS not where it is #defined. */ -#if defined(__RESTRICT_KEYWORD_DEFINED__) -# undef restrict -# undef __RESTRICT_KEYWORD_DEFINED__ -#endif - #endif /* !_INTTYPES_H_ */ diff --git a/src/libc/include/langinfo.h b/src/libc/include/langinfo.h index 117402bea..a7a3b2b53 100644 --- a/src/libc/include/langinfo.h +++ b/src/libc/include/langinfo.h @@ -30,11 +30,7 @@ #define _LANGINFO_H_ #include <_types.h> - -#ifndef _NL_ITEM -typedef __darwin_nl_item nl_item; -#define _NL_ITEM -#endif +#include <_types/_nl_item.h> #define CODESET 0 /* codeset name */ #define D_T_FMT 1 /* string for formatting date and time */ diff --git a/src/libc/include/libc-features.h b/src/libc/include/libc-features.h deleted file mode 100644 index 0c232be33..000000000 --- a/src/libc/include/libc-features.h +++ /dev/null @@ -1,8 +0,0 @@ -#if defined(__x86_64__) -# include "x86-64/libc-features.h" -#elif defined(__i386__) -# include "i386/libc-features.h" -#else -# error Missing include -#endif - diff --git a/src/libc/include/libgen.h b/src/libc/include/libgen.h index 06184d81c..4200fc6c4 100644 --- a/src/libc/include/libgen.h +++ b/src/libc/include/libgen.h @@ -47,6 +47,17 @@ char *dirname(const char *); #endif /* __DARWIN_UNIX_03 */ +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#include +char *basename_r(const char *, char *) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); + +char *dirname_r(const char *, char *) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + __END_DECLS #endif /* _LIBGEN_H_ */ diff --git a/src/libc/include/libkern/OSAtomic.h b/src/libc/include/libkern/OSAtomic.h deleted file mode 100644 index 9bc4dbb23..000000000 --- a/src/libc/include/libkern/OSAtomic.h +++ /dev/null @@ -1,748 +0,0 @@ -/* - * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _OSATOMIC_H_ -#define _OSATOMIC_H_ - -#include -#include -#include -#include - -#include - -/*! @header - * These are the preferred versions of the atomic and synchronization operations. - * Their implementation is customized at boot time for the platform, including - * late-breaking errata fixes as necessary. They are thread safe. - * - * WARNING: all addresses passed to these functions must be "naturally aligned", - * i.e. * int32_t pointers must be 32-bit aligned (low 2 bits of - * address are zeroes), and int64_t pointers must be 64-bit aligned - * (low 3 bits of address are zeroes.) - * - * Note that some versions of the atomic functions incorporate memory barriers - * and some do not. Barriers strictly order memory access on weakly-ordered - * architectures such as PPC. All loads and stores that appear (in sequential - * program order) before the barrier are guaranteed to complete before any - * load or store that appears after the barrier. - * - * On a uniprocessor system, the barrier operation is typically a no-op. On a - * multiprocessor system, the barrier can be quite expensive on some platforms, - * such as PPC. - * - * Most code should use the barrier functions to ensure that memory shared between - * threads is properly synchronized. For example, if you want to initialize - * a shared data structure and then atomically increment a variable to indicate - * that the initialization is complete, you must use {@link OSAtomicIncrement32Barrier} - * to ensure that the stores to your data structure complete before the atomic - * increment. - * - * Likewise, the consumer of that data structure must use {@link OSAtomicDecrement32Barrier}, - * in order to ensure that their loads of the structure are not executed before - * the atomic decrement. On the other hand, if you are simply incrementing a global - * counter, then it is safe and potentially faster to use {@link OSAtomicIncrement32}. - * - * If you are unsure which version to use, prefer the barrier variants as they are - * safer. - * - * The spinlock and queue operations always incorporate a barrier. - * - * For the kernel-space version of this header, see - * {@link //apple_ref/doc/header/OSAtomic.h OSAtomic.h (Kernel Framework)} - * - * @apiuid //apple_ref/doc/header/user_space_OSAtomic.h - */ -__BEGIN_DECLS - - -/*! @group Arithmetic functions - All functions in this group return the new value. - */ - -/*! @abstract Atomically adds two 32-bit values. - @discussion - This function adds the value given by __theAmount to the - value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - @result Returns the new value. - */ -int32_t OSAtomicAdd32( int32_t __theAmount, volatile int32_t *__theValue ); - - -/*! @abstract Atomically adds two 32-bit values. - @discussion - This function adds the value given by __theAmount to the - value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - - This function is equivalent to {@link OSAtomicAdd32} - except that it also introduces a barrier. - @result Returns the new value. - */ -int32_t OSAtomicAdd32Barrier( int32_t __theAmount, volatile int32_t *__theValue ); - - -/*! @abstract Atomically increments a 32-bit value. - */ -int32_t OSAtomicIncrement32( volatile int32_t *__theValue ); - - -/*! @abstract Atomically increments a 32-bit value with a barrier. - @discussion - This function is equivalent to {@link OSAtomicIncrement32} - except that it also introduces a barrier. - @result Returns the new value. - */ -int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue ); - -/*! @abstract Atomically decrements a 32-bit value. */ -int32_t OSAtomicDecrement32( volatile int32_t *__theValue ); - -/*! @abstract Atomically increments a 32-bit value with a barrier. - @discussion - This function is equivalent to {@link OSAtomicDecrement32} - except that it also introduces a barrier. - @result Returns the new value. - */ -int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue ); - - -/*! @abstract Atomically adds two 64-bit values. - @discussion - This function adds the value given by __theAmount to the - value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - */ -int64_t OSAtomicAdd64( int64_t __theAmount, volatile int64_t *__theValue ); - - -/*! @abstract Atomically adds two 64-bit values with a barrier. - @discussion - This function adds the value given by __theAmount to the - value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - - This function is equivalent to {@link OSAtomicAdd64} - except that it also introduces a barrier. - @result Returns the new value. - */ -int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2); - - -/*! @abstract Atomically increments a 64-bit value. */ -__inline static -int64_t OSAtomicIncrement64( volatile int64_t *__theValue ); - -/*! @abstract Atomically increments a 64-bit value with a barrier. - @discussion - This function is equivalent to {@link OSAtomicIncrement64} - except that it also introduces a barrier. - @result Returns the new value. - */ -__inline static -int64_t OSAtomicIncrement64Barrier( volatile int64_t *__theValue ); - - -/*! @abstract Atomically decrements a 64-bit value. - @discussion - This function is equivalent to {@link OSAtomicIncrement64} - except that it also introduces a barrier. - @result Returns the new value. - */ -__inline static -int64_t OSAtomicDecrement64( volatile int64_t *__theValue ); - - -/*! @abstract Atomically decrements a 64-bit value with a barrier. - @discussion - This function is equivalent to {@link OSAtomicDecrement64} - except that it also introduces a barrier. - @result Returns the new value. - */ -__inline static -int64_t OSAtomicDecrement64Barrier( volatile int64_t *__theValue ); - - -/*! @group Boolean functions (AND, OR, XOR) - * - * @discussion Functions in this group come in four variants for each operation: - * with and without barriers, and functions that return the original value or - * the result value of the operation. - * - * The "Orig" versions return the original value, (before the operation); the non-Orig - * versions return the value after the operation. All are layered on top of - * {@link OSAtomicCompareAndSwap32} and similar. - */ - -/*! @abstract Atomic bitwise OR of two 32-bit values. - @discussion - This function performs the bitwise OR of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - @result Returns the new value. - */ -int32_t OSAtomicOr32( uint32_t __theMask, volatile uint32_t *__theValue ); - - -/*! @abstract Atomic bitwise OR of two 32-bit values with barrier. - @discussion - This function performs the bitwise OR of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - - This function is equivalent to {@link OSAtomicOr32} - except that it also introduces a barrier. - @result Returns the new value. - */ -int32_t OSAtomicOr32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); - - -/*! @abstract Atomic bitwise OR of two 32-bit values returning original. - @discussion - This function performs the bitwise OR of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - @result Returns the original value referenced by __theValue. - */ -int32_t OSAtomicOr32Orig( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); - - -/*! @abstract Atomic bitwise OR of two 32-bit values returning original with barrier. - @discussion - This function performs the bitwise OR of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - - This function is equivalent to {@link OSAtomicOr32Orig} - except that it also introduces a barrier. - @result Returns the original value referenced by __theValue. - */ -int32_t OSAtomicOr32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); - - - - -/*! @abstract Atomic bitwise AND of two 32-bit values. - @discussion - This function performs the bitwise AND of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - @result Returns the new value. - */ -int32_t OSAtomicAnd32( uint32_t __theMask, volatile uint32_t *__theValue ); - - -/*! @abstract Atomic bitwise AND of two 32-bit values with barrier. - @discussion - This function performs the bitwise AND of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - - This function is equivalent to {@link OSAtomicAnd32} - except that it also introduces a barrier. - @result Returns the new value. - */ -int32_t OSAtomicAnd32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); - - -/*! @abstract Atomic bitwise AND of two 32-bit values returning original. - @discussion - This function performs the bitwise AND of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - @result Returns the original value referenced by __theValue. - */ -int32_t OSAtomicAnd32Orig( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); - - -/*! @abstract Atomic bitwise AND of two 32-bit values returning original with barrier. - @discussion - This function performs the bitwise AND of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - - This function is equivalent to {@link OSAtomicAnd32Orig} - except that it also introduces a barrier. - @result Returns the original value referenced by __theValue. - */ -int32_t OSAtomicAnd32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); - - - - -/*! @abstract Atomic bitwise XOR of two 32-bit values. - @discussion - This function performs the bitwise XOR of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - @result Returns the new value. - */ -int32_t OSAtomicXor32( uint32_t __theMask, volatile uint32_t *__theValue ); - - -/*! @abstract Atomic bitwise XOR of two 32-bit values with barrier. - @discussion - This function performs the bitwise XOR of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - - This function is equivalent to {@link OSAtomicXor32} - except that it also introduces a barrier. - @result Returns the new value. - */ -int32_t OSAtomicXor32Barrier( uint32_t __theMask, volatile uint32_t *__theValue ); - - -/*! @abstract Atomic bitwise XOR of two 32-bit values returning original. - @discussion - This function performs the bitwise XOR of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - @result Returns the original value referenced by __theValue. - */ -int32_t OSAtomicXor32Orig( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); - - -/*! @abstract Atomic bitwise XOR of two 32-bit values returning original with barrier. - @discussion - This function performs the bitwise XOR of the value given by __theMask - with the value in the memory location referenced by __theValue, - storing the result back to that memory location atomically. - - This function is equivalent to {@link OSAtomicXor32Orig} - except that it also introduces a barrier. - @result Returns the original value referenced by __theValue. - */ -int32_t OSAtomicXor32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2); - - -/*! @group Compare and swap - * Functions in this group return true if the swap occured. There are several versions, - * depending on data type and on whether or not a barrier is used. - */ - - -/*! @abstract Compare and swap for 32-bit values. - @discussion - This function compares the value in __oldValue to the value - in the memory location referenced by __theValue. If the values - match, this function stores the value from __newValue into - that memory location atomically. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwap32( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); - - -/*! @abstract Compare and swap for 32-bit values with barrier. - @discussion - This function compares the value in __oldValue to the value - in the memory location referenced by __theValue. If the values - match, this function stores the value from __newValue into - that memory location atomically. - - This function is equivalent to {@link OSAtomicCompareAndSwap32} - except that it also introduces a barrier. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue ); - - -/*! @abstract Compare and swap pointers. - @discussion - This function compares the pointer stored in __oldValue to the pointer - in the memory location referenced by __theValue. If the pointers - match, this function stores the pointer from __newValue into - that memory location atomically. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - - -/*! @abstract Compare and swap pointers with barrier. - @discussion - This function compares the pointer stored in __oldValue to the pointer - in the memory location referenced by __theValue. If the pointers - match, this function stores the pointer from __newValue into - that memory location atomically. - - This function is equivalent to {@link OSAtomicCompareAndSwapPtr} - except that it also introduces a barrier. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - - -/*! @abstract Compare and swap for int values. - @discussion - This function compares the value in __oldValue to the value - in the memory location referenced by __theValue. If the values - match, this function stores the value from __newValue into - that memory location atomically. - - This function is equivalent to {@link OSAtomicCompareAndSwap32}. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwapInt( int __oldValue, int __newValue, volatile int *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - - -/*! @abstract Compare and swap for int values. - @discussion - This function compares the value in __oldValue to the value - in the memory location referenced by __theValue. If the values - match, this function stores the value from __newValue into - that memory location atomically. - - This function is equivalent to {@link OSAtomicCompareAndSwapInt} - except that it also introduces a barrier. - - This function is equivalent to {@link OSAtomicCompareAndSwap32Barrier}. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwapIntBarrier( int __oldValue, int __newValue, volatile int *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - - -/*! @abstract Compare and swap for long values. - @discussion - This function compares the value in __oldValue to the value - in the memory location referenced by __theValue. If the values - match, this function stores the value from __newValue into - that memory location atomically. - - This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures, - or {@link OSAtomicCompareAndSwap64} on 64-bit architectures. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwapLong( long __oldValue, long __newValue, volatile long *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - - -/*! @abstract Compare and swap for long values. - @discussion - This function compares the value in __oldValue to the value - in the memory location referenced by __theValue. If the values - match, this function stores the value from __newValue into - that memory location atomically. - - This function is equivalent to {@link OSAtomicCompareAndSwapLong} - except that it also introduces a barrier. - - This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures, - or {@link OSAtomicCompareAndSwap64} on 64-bit architectures. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwapLongBarrier( long __oldValue, long __newValue, volatile long *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - - -/*! @abstract Compare and swap for uint64_t values. - @discussion - This function compares the value in __oldValue to the value - in the memory location referenced by __theValue. If the values - match, this function stores the value from __newValue into - that memory location atomically. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwap64( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ); - - -/*! @abstract Compare and swap for uint64_t values. - @discussion - This function compares the value in __oldValue to the value - in the memory location referenced by __theValue. If the values - match, this function stores the value from __newValue into - that memory location atomically. - - This function is equivalent to {@link OSAtomicCompareAndSwap64} - except that it also introduces a barrier. - @result Returns TRUE on a match, FALSE otherwise. - */ -bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2); - - -/* Test and set. They return the original value of the bit, and operate on bit (0x80>>(n&7)) - * in byte ((char*)theAddress + (n>>3)). - */ -/*! @abstract Atomic test and set - @discussion - This function tests a bit in the value referenced by __theAddress - and if it is not set, sets it. The bit is chosen by the value of __n. - The bits are numbered in order beginning with bit 1 as the lowest order bit. - - For example, if __theAddress points to a 64-bit value, - to compare the value of the highest bit, you would specify 64 for - __n. - @result - Returns the original value of the bit being tested. - */ -bool OSAtomicTestAndSet( uint32_t __n, volatile void *__theAddress ); - - -/*! @abstract Atomic test and set with barrier - @discussion - This function tests a bit in the value referenced by __theAddress - and if it is not set, sets it. The bit is chosen by the value of __n. - The bits are numbered in order beginning with bit 1 as the lowest order bit. - - For example, if __theAddress points to a 64-bit value, - to compare the value of the highest bit, you would specify 64 for - __n. - - This function is equivalent to {@link OSAtomicTestAndSet} - except that it also introduces a barrier. - @result - Returns the original value of the bit being tested. - */ - -bool OSAtomicTestAndSetBarrier( uint32_t __n, volatile void *__theAddress ); - - - -/*! @abstract Atomic test and clear - @discussion - This function tests a bit in the value referenced by __theAddress - and if it is not cleared, clears it. The bit is chosen by the value of __n. - The bits are numbered in order beginning with bit 1 as the lowest order bit. - - For example, if __theAddress points to a 64-bit value, - to compare the value of the highest bit, you would specify 64 for - __n. - @result - Returns the original value of the bit being tested. - */ -bool OSAtomicTestAndClear( uint32_t __n, volatile void *__theAddress ); - - -/*! @abstract Atomic test and clear - @discussion - This function tests a bit in the value referenced by __theAddress - and if it is not cleared, clears it. The bit is chosen by the value of __n. - The bits are numbered in order beginning with bit 1 as the lowest order bit. - - For example, if __theAddress points to a 64-bit value, - to compare the value of the highest bit, you would specify 64 for - __n. - - This function is equivalent to {@link OSAtomicTestAndSet} - except that it also introduces a barrier. - @result - Returns the original value of the bit being tested. - */ -bool OSAtomicTestAndClearBarrier( uint32_t __n, volatile void *__theAddress ); - - -/*! @group Spinlocks - * These spinlocks use memory barriers as required to synchronize access to shared - * memory protected by the lock. - */ - -/*! @abstract The default value for an OSSpinLock. - @discussion - The convention is that unlocked is zero, locked is nonzero. - */ -#define OS_SPINLOCK_INIT 0 - - -/*! @abstract Data type for a spinlock. - @discussion - You should always initialize a spinlock to {@link OS_SPINLOCK_INIT} before - using it. - */ -typedef int32_t OSSpinLock; - - -/*! @abstract Locks a spinlock if it would not block - @result - Returns false if the lock was already held by another thread, - true if it took the lock successfully. - */ -bool OSSpinLockTry( volatile OSSpinLock *__lock ); - - -/*! @abstract Locks a spinlock - @discussion - Although the lock operation spins, it employs various strategies - to back off if the lock is held, making it immune to most priority-inversion - livelocks. - */ -void OSSpinLockLock( volatile OSSpinLock *__lock ); - - -/*! @abstract Unlocks a spinlock */ -void OSSpinLockUnlock( volatile OSSpinLock *__lock ); - - -/*! @group Lockless atomic enqueue and dequeue - * These routines manipulate singly-linked LIFO lists. - */ - -/*! @abstract The data structure for a queue head. - @discussion - You should always initialize a queue head structure with the - initialization vector {@link OS_ATOMIC_QUEUE_INIT} before use. - */ -#if defined(__x86_64__) - -typedef volatile struct { - void *opaque1; - long opaque2; -} __attribute__ ((aligned (16))) OSQueueHead; - -#else - -typedef volatile struct { - void *opaque1; - long opaque2; -} OSQueueHead; - -#endif - -/*! @abstract The initialization vector for a queue head. */ -#define OS_ATOMIC_QUEUE_INIT { NULL, 0 } - -/*! @abstract Enqueue an item onto a list. - @discussion - Memory barriers are incorporated as needed to permit thread-safe access - to the queue element. - @param __list - The list on which you want to enqueue the item. - @param __new - The item to add. - @param __offset - The "offset" parameter is the offset (in bytes) of the link field - from the beginning of the data structure being queued (__new). - The link field should be a pointer type. - The __offset value needs to be same for all enqueuing and - dequeuing operations on the same queue, even if different structure types - are enqueued on that queue. The use of offsetset(), defined in - stddef.h is the common way to specify the __offset - value. - */ -void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0); - - -/*! @abstract Dequeue an item from a list. - @discussion - Memory barriers are incorporated as needed to permit thread-safe access - to the queue element. - @param __list - The list on which you want to enqueue the item. - @param __offset - The "offset" parameter is the offset (in bytes) of the link field - from the beginning of the data structure being queued (__new). - The link field should be a pointer type. - The __offset value needs to be same for all enqueuing and - dequeuing operations on the same queue, even if different structure types - are enqueued on that queue. The use of offsetset(), defined in - stddef.h is the common way to specify the __offset - value. - @result - Returns the most recently enqueued element, or NULL if the - list is empty. - */ -void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0); - -#if defined(__x86_64__) || defined(__i386__) - -/*! @group Lockless atomic fifo enqueue and dequeue - * These routines manipulate singly-linked FIFO lists. - */ - -/*! @abstract The data structure for a fifo queue head. - @discussion - You should always initialize a fifo queue head structure with the - initialization vector {@link OS_ATOMIC_FIFO_QUEUE_INIT} before use. - */ -#if defined(__x86_64__) - -typedef volatile struct { - void *opaque1; - void *opaque2; - int opaque3; -} __attribute__ ((aligned (16))) OSFifoQueueHead; - -#else - -typedef volatile struct { - void *opaque1; - void *opaque2; - int opaque3; -} OSFifoQueueHead; - -#endif - -/*! @abstract The initialization vector for a fifo queue head. */ -#define OS_ATOMIC_FIFO_QUEUE_INIT { NULL, NULL, 0 } - -/*! @abstract Enqueue an item onto a list. - @discussion - Memory barriers are incorporated as needed to permit thread-safe access - to the queue element. - @param __list - The list on which you want to enqueue the item. - @param __new - The item to add. - @param __offset - The "offset" parameter is the offset (in bytes) of the link field - from the beginning of the data structure being queued (__new). - The link field should be a pointer type. - The __offset value needs to be same for all enqueuing and - dequeuing operations on the same queue, even if different structure types - are enqueued on that queue. The use of offsetset(), defined in - stddef.h is the common way to specify the __offset - value. - */ -void OSAtomicFifoEnqueue( OSFifoQueueHead *__list, void *__new, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); - -/*! @abstract Dequeue an item from a list. - @discussion - Memory barriers are incorporated as needed to permit thread-safe access - to the queue element. - @param __list - The list on which you want to enqueue the item. - @param __offset - The "offset" parameter is the offset (in bytes) of the link field - from the beginning of the data structure being queued (__new). - The link field should be a pointer type. - The __offset value needs to be same for all enqueuing and - dequeuing operations on the same queue, even if different structure types - are enqueued on that queue. The use of offsetset(), defined in - stddef.h is the common way to specify the __offset - value. - @result - Returns the oldest enqueued element, or NULL if the - list is empty. - */ -void* OSAtomicFifoDequeue( OSFifoQueueHead *__list, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); - -#endif /* __i386__ || __x86_64__ */ - -/*! @group Memory barriers */ - -/*! @abstract Memory barrier. - @discussion - This function serves as both a read and write barrier. - */ -void OSMemoryBarrier( void ); - -__END_DECLS - -#endif /* _OSATOMIC_H_ */ diff --git a/src/libc/include/libkern/OSMemoryNotification.h b/src/libc/include/libkern/OSMemoryNotification.h deleted file mode 100644 index d4e450bba..000000000 --- a/src/libc/include/libkern/OSMemoryNotification.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _OSMEMORYNOTIFICATION_H_ -#define _OSMEMORYNOTIFICATION_H_ - -#include -#include - -/* -** OSMemoryNotification.h -** -** Kernel-generated notification mechanism to alert registered tasks when physical memory -** pressure reaches certain thresholds. Notifications are triggered in both directions -** so clients can manage their memory usage more and less aggressively. -** -** All of these functions and data types are iOS-only and deprecated in iOS 5.0. Applications -** should listen to UIKit memory warnings (didReceiveMemoryWarning or -** UIApplicationDidReceiveMemoryWarningNotification) instead. -*/ - -__BEGIN_DECLS - -struct timeval; - -/* -** Opaque type for notification object -** -** DEPRECATED. Use UIKit memory notification system. -*/ - -typedef struct _OSMemoryNotification * OSMemoryNotificationRef; - -/* -** Threshold values for notifications -** -** DEPRECATED. Use UIKit memory notification system. -*/ - -typedef enum { - OSMemoryNotificationLevelAny = -1, - OSMemoryNotificationLevelNormal = 0, - OSMemoryNotificationLevelWarning = 1, - OSMemoryNotificationLevelUrgent = 2, - OSMemoryNotificationLevelCritical = 3 -} OSMemoryNotificationLevel; - -/* -** Creation routines. Returns the created OSMemoryNotificationRef in the note param. -** returns: 0 on success -** ENOMEM if insufficient memory or resources exists to create the notification object -** EINVAL if the threshold is not a valid notification level -** -** DEPRECATED. Use UIKit memory notification system. -*/ - -int OSMemoryNotificationCreate(OSMemoryNotificationRef *note) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_2_0, __IPHONE_5_0); - -/* -** returns: 0 on success -** EINVAL if the notification is not an initialized notification object - ** - ** DEPRECATED. Use UIKit memory notification system. -*/ - -int OSMemoryNotificationDestroy(OSMemoryNotificationRef note) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_2_0, __IPHONE_5_0); - -/* -** Block waiting for notification -** returns: 0 on success, with the level that triggered the notification in the level param -** EINVAL if the notification object is invalid -** ETIMEDOUT if abstime passes before notification occurs -** -** 'note' is now ignored. -** -** DEPRECATED. Use UIKit memory notification system. -*/ -int OSMemoryNotificationWait(OSMemoryNotificationRef note, OSMemoryNotificationLevel *level) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_2_0, __IPHONE_5_0); -int OSMemoryNotificationTimedWait(OSMemoryNotificationRef note, OSMemoryNotificationLevel *level, const struct timeval *abstime) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_2_0, __IPHONE_5_0); - -/* -** Simple polling interface to detect current memory pressure level -** -** DEPRECATED. This is not a reliable way to discover the system's memory condition and -** the level is not meaningful in iOS 5.0 and later. Use UIKit memory notification -** system instead, with no need to check the level. -*/ - -OSMemoryNotificationLevel OSMemoryNotificationCurrentLevel(void) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_2_0, __IPHONE_5_0); - -/* -** External notify(3) string for manual notification setup -** -** DEPRECATED. Use UIKit memory notification system. -*/ - -extern const char *kOSMemoryNotificationName __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_2_0, __IPHONE_5_0); - -__END_DECLS - -#endif /* _OSMEMORYNOTIFICATION_H_ */ diff --git a/src/libc/include/libkern/OSThermalNotification.h b/src/libc/include/libkern/OSThermalNotification.h index ad19e7e8f..02bf1f7f6 100644 --- a/src/libc/include/libkern/OSThermalNotification.h +++ b/src/libc/include/libkern/OSThermalNotification.h @@ -38,6 +38,25 @@ __BEGIN_DECLS +/* Define pressure levels usable by OSThermalPressureLevel */ +typedef enum { + kOSThermalPressureLevelNominal = 0, + kOSThermalPressureLevelModerate, + kOSThermalPressureLevelHeavy, + kOSThermalPressureLevelTrapping, + kOSThermalPressureLevelSleeping +} OSThermalPressureLevel; + +/* + ** External notify(3) string for thermal pressure level notification + */ +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_7_0) +extern const char * const kOSThermalNotificationPressureLevelName; + + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ + __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_2_0 + typedef enum { OSThermalNotificationLevelAny = -1, OSThermalNotificationLevelNormal = 0, @@ -79,14 +98,28 @@ enum { /* ** Simple polling interface to detect current thermal level */ - -extern OSThermalNotificationLevel OSThermalNotificationCurrentLevel(void) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_2_0); +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_2_0) +extern OSThermalNotificationLevel OSThermalNotificationCurrentLevel(void); /* ** External notify(3) string for manual notification setup */ +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_2_0) +extern const char * const kOSThermalNotificationName; + +/* +** External notify(3) string for alerting user of a thermal condition +*/ +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_6_0) +extern const char * const kOSThermalNotificationAlert; + +/* +** External notify(3) string for notifying system the options taken to resolve thermal condition +*/ +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_6_0) +extern const char * const kOSThermalNotificationDecision; -extern const char * const kOSThermalNotificationName __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_2_0); +#endif // __IPHONE_OS_VERSION_MIN_REQUIRED __END_DECLS diff --git a/src/libc/include/limits.h b/src/libc/include/limits.h index 2f9385d42..b7d202d27 100644 --- a/src/libc/include/limits.h +++ b/src/libc/include/limits.h @@ -100,6 +100,8 @@ #define _POSIX_SEM_VALUE_MAX 32767 #define _POSIX_SIGQUEUE_MAX 32 #define _POSIX_TIMER_MAX 32 + +#define _POSIX_CLOCKRES_MIN 20000000 #endif /* __DARWIN_C_LEVEL >= 199309L */ #if __DARWIN_C_LEVEL >= 199506L @@ -109,7 +111,11 @@ #define PTHREAD_DESTRUCTOR_ITERATIONS 4 #define PTHREAD_KEYS_MAX 512 +#if defined(__arm__) +#define PTHREAD_STACK_MIN 16384 +#else #define PTHREAD_STACK_MIN 8192 +#endif #endif /* __DARWIN_C_LEVEL >= 199506L */ #if __DARWIN_C_LEVEL >= 200112 diff --git a/src/libc/include/malloc/malloc.h b/src/libc/include/malloc/malloc.h deleted file mode 100644 index 53e555f2b..000000000 --- a/src/libc/include/malloc/malloc.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _MALLOC_MALLOC_H_ -#define _MALLOC_MALLOC_H_ - -#include -#include -#include -#include - -__BEGIN_DECLS -/********* Type definitions ************/ - -typedef struct _malloc_zone_t { - /* Only zone implementors should depend on the layout of this structure; - Regular callers should use the access functions below */ - void *reserved1; /* RESERVED FOR CFAllocator DO NOT USE */ - void *reserved2; /* RESERVED FOR CFAllocator DO NOT USE */ - size_t (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */ - void *(*malloc)(struct _malloc_zone_t *zone, size_t size); - void *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */ - void *(*valloc)(struct _malloc_zone_t *zone, size_t size); /* same as malloc, but block returned is set to zero and is guaranteed to be page aligned */ - void (*free)(struct _malloc_zone_t *zone, void *ptr); - void *(*realloc)(struct _malloc_zone_t *zone, void *ptr, size_t size); - void (*destroy)(struct _malloc_zone_t *zone); /* zone is destroyed and all memory reclaimed */ - const char *zone_name; - - /* Optional batch callbacks; these may be NULL */ - unsigned (*batch_malloc)(struct _malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); /* given a size, returns pointers capable of holding that size; returns the number of pointers allocated (maybe 0 or less than num_requested) */ - void (*batch_free)(struct _malloc_zone_t *zone, void **to_be_freed, unsigned num_to_be_freed); /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process */ - - struct malloc_introspection_t *introspect; - unsigned version; - - /* aligned memory allocation. The callback may be NULL. Present in version >= 5. */ - void *(*memalign)(struct _malloc_zone_t *zone, size_t alignment, size_t size); - - /* free a pointer known to be in zone and known to have the given size. The callback may be NULL. Present in version >= 6.*/ - void (*free_definite_size)(struct _malloc_zone_t *zone, void *ptr, size_t size); - - /* Empty out caches in the face of memory pressure. The callback may be NULL. Present in version >= 8. */ - size_t (*pressure_relief)(struct _malloc_zone_t *zone, size_t goal); -} malloc_zone_t; - -/********* Creation and destruction ************/ - -extern malloc_zone_t *malloc_default_zone(void); - /* The initial zone */ - -extern malloc_zone_t *malloc_create_zone(vm_size_t start_size, unsigned flags); - /* Creates a new zone with default behavior and registers it */ - -extern void malloc_destroy_zone(malloc_zone_t *zone); - /* Destroys zone and everything it allocated */ - -/********* Block creation and manipulation ************/ - -extern void *malloc_zone_malloc(malloc_zone_t *zone, size_t size); - /* Allocates a new pointer of size size; zone must be non-NULL */ - -extern void *malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size); - /* Allocates a new pointer of size num_items * size; block is cleared; zone must be non-NULL */ - -extern void *malloc_zone_valloc(malloc_zone_t *zone, size_t size); - /* Allocates a new pointer of size size; zone must be non-NULL; Pointer is guaranteed to be page-aligned and block is cleared */ - -extern void malloc_zone_free(malloc_zone_t *zone, void *ptr); - /* Frees pointer in zone; zone must be non-NULL */ - -extern void *malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size); - /* Enlarges block if necessary; zone must be non-NULL */ - -extern malloc_zone_t *malloc_zone_from_ptr(const void *ptr); - /* Returns the zone for a pointer, or NULL if not in any zone. - The ptr must have been returned from a malloc or realloc call. */ - -extern size_t malloc_size(const void *ptr); - /* Returns size of given ptr */ - -extern size_t malloc_good_size(size_t size); - /* Returns number of bytes greater than or equal to size that can be allocated without padding */ - -extern void *malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); - /* - * Allocates a new pointer of size size whose address is an exact multiple of alignment. - * alignment must be a power of two and at least as large as sizeof(void *). - * zone must be non-NULL. - */ - -/********* Batch methods ************/ - -extern unsigned malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); - /* Allocates num blocks of the same size; Returns the number truly allocated (may be 0) */ - -extern void malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num); - /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process; This function will always free even if the zone has no batch callback */ - -/********* Functions for libcache ************/ - -extern malloc_zone_t *malloc_default_purgeable_zone(void) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); - /* Returns a pointer to the default purgeable_zone. */ - -extern void malloc_make_purgeable(void *ptr) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); - /* Make an allocation from the purgeable zone purgeable if possible. */ - -extern int malloc_make_nonpurgeable(void *ptr) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); - /* Makes an allocation from the purgeable zone nonpurgeable. - * Returns zero if the contents were not purged since the last - * call to malloc_make_purgeable, else returns non-zero. */ - -/********* Functions for zone implementors ************/ - -extern void malloc_zone_register(malloc_zone_t *zone); - /* Registers a custom malloc zone; Should typically be called after a - * malloc_zone_t has been filled in with custom methods by a client. See - * malloc_create_zone for creating additional malloc zones with the - * default allocation and free behavior. */ - -extern void malloc_zone_unregister(malloc_zone_t *zone); - /* De-registers a zone - Should typically be called before calling the zone destruction routine */ - -extern void malloc_set_zone_name(malloc_zone_t *zone, const char *name); - /* Sets the name of a zone */ - -extern const char *malloc_get_zone_name(malloc_zone_t *zone); - /* Returns the name of a zone */ - -size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); - /* malloc_zone_pressure_relief() advises the malloc subsystem that the process is under memory pressure and - * that the subsystem should make its best effort towards releasing (i.e. munmap()-ing) "goal" bytes from "zone". - * If "goal" is passed as zero, the malloc subsystem will attempt to achieve maximal pressure relief in "zone". - * If "zone" is passed as NULL, all zones are examined for pressure relief opportunities. - * malloc_zone_pressure_relief() returns the number of bytes released. - */ - -typedef struct { - vm_address_t address; - vm_size_t size; -} vm_range_t; - -typedef struct malloc_statistics_t { - unsigned blocks_in_use; - size_t size_in_use; - size_t max_size_in_use; /* high water mark of touched memory */ - size_t size_allocated; /* reserved in memory */ -} malloc_statistics_t; - -typedef kern_return_t memory_reader_t(task_t remote_task, vm_address_t remote_address, vm_size_t size, void **local_memory); - /* given a task, "reads" the memory at the given address and size -local_memory: set to a contiguous chunk of memory; validity of local_memory is assumed to be limited (until next call) */ - -#define MALLOC_PTR_IN_USE_RANGE_TYPE 1 /* for allocated pointers */ -#define MALLOC_PTR_REGION_RANGE_TYPE 2 /* for region containing pointers */ -#define MALLOC_ADMIN_REGION_RANGE_TYPE 4 /* for region used internally */ -#define MALLOC_ZONE_SPECIFIC_FLAGS 0xff00 /* bits reserved for zone-specific purposes */ - -typedef void vm_range_recorder_t(task_t, void *, unsigned type, vm_range_t *, unsigned); - /* given a task and context, "records" the specified addresses */ - -typedef struct malloc_introspection_t { - kern_return_t (*enumerator)(task_t task, void *, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder); /* enumerates all the malloc pointers in use */ - size_t (*good_size)(malloc_zone_t *zone, size_t size); - boolean_t (*check)(malloc_zone_t *zone); /* Consistency checker */ - void (*print)(malloc_zone_t *zone, boolean_t verbose); /* Prints zone */ - void (*log)(malloc_zone_t *zone, void *address); /* Enables logging of activity */ - void (*force_lock)(malloc_zone_t *zone); /* Forces locking zone */ - void (*force_unlock)(malloc_zone_t *zone); /* Forces unlocking zone */ - void (*statistics)(malloc_zone_t *zone, malloc_statistics_t *stats); /* Fills statistics */ - boolean_t (*zone_locked)(malloc_zone_t *zone); /* Are any zone locks held */ - - /* Discharge checking. Present in version >= 7. */ - boolean_t (*enable_discharge_checking)(malloc_zone_t *zone); - void (*disable_discharge_checking)(malloc_zone_t *zone); - void (*discharge)(malloc_zone_t *zone, void *memory); -#ifdef __BLOCKS__ - void (*enumerate_discharged_pointers)(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)); -#else - void *enumerate_unavailable_without_blocks; -#endif /* __BLOCKS__ */ -} malloc_introspection_t; - -extern void malloc_printf(const char *format, ...); - /* Convenience for logging errors and warnings; - No allocation is performed during execution of this function; - Only understands usual %p %d %s formats, and %y that expresses a number of bytes (5b,10KB,1MB...) - */ - -/********* Functions for performance tools ************/ - -extern kern_return_t malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count); - /* Fills addresses and count with the addresses of the zones in task; - Note that the validity of the addresses returned correspond to the validity of the memory returned by reader */ - -/********* Debug helpers ************/ - -extern void malloc_zone_print_ptr_info(void *ptr); - /* print to stdout if this pointer is in the malloc heap, free status, and size */ - -extern boolean_t malloc_zone_check(malloc_zone_t *zone); - /* Checks zone is well formed; if !zone, checks all zones */ - -extern void malloc_zone_print(malloc_zone_t *zone, boolean_t verbose); - /* Prints summary on zone; if !zone, prints all zones */ - -extern void malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats); - /* Fills statistics for zone; if !zone, sums up all zones */ - -extern void malloc_zone_log(malloc_zone_t *zone, void *address); - /* Controls logging of all activity; if !zone, for all zones; - If address==0 nothing is logged; - If address==-1 all activity is logged; - Else only the activity regarding address is logged */ - -struct mstats { - size_t bytes_total; - size_t chunks_used; - size_t bytes_used; - size_t chunks_free; - size_t bytes_free; -}; - -extern struct mstats mstats(void); - -extern boolean_t malloc_zone_enable_discharge_checking(malloc_zone_t *zone) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -/* Increment the discharge checking enabled counter for a zone. Returns true if the zone supports checking, false if it does not. */ - -extern void malloc_zone_disable_discharge_checking(malloc_zone_t *zone) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -/* Decrement the discharge checking enabled counter for a zone. */ - -extern void malloc_zone_discharge(malloc_zone_t *zone, void *memory) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -/* Register memory that the programmer expects to be freed soon. - zone may be NULL in which case the zone is determined using malloc_zone_from_ptr(). - If discharge checking is off for the zone this function is a no-op. */ - -#ifdef __BLOCKS__ -extern void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -/* Calls report_discharged for each block that was registered using malloc_zone_discharge() but has not yet been freed. - info is used to provide zone defined information about the memory block. - If zone is NULL then the enumeration covers all zones. */ -#else -extern void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -#endif /* __BLOCKS__ */ - -__END_DECLS - -#endif /* _MALLOC_MALLOC_H_ */ diff --git a/src/libc/include/monetary.h b/src/libc/include/monetary.h index 44858d5a5..a32f404d0 100644 --- a/src/libc/include/monetary.h +++ b/src/libc/include/monetary.h @@ -31,16 +31,8 @@ #include #include <_types.h> - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __darwin_ssize_t ssize_t; -#endif +#include +#include __BEGIN_DECLS ssize_t strfmon(char *, size_t, const char *, ...); diff --git a/src/libc/include/monitor.h b/src/libc/include/monitor.h index 6903b141c..c4d0a2d2e 100644 --- a/src/libc/include/monitor.h +++ b/src/libc/include/monitor.h @@ -31,19 +31,34 @@ #define __MONITOR_HEADER__ #include +#include __BEGIN_DECLS + +__OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0,__MAC_10_11,__IPHONE_2_0,__IPHONE_9_0, "Monitor is no longer supported.") +__WATCHOS_PROHIBITED extern void monstartup (char *lowpc, char *highpc); +__OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0,__MAC_10_11,__IPHONE_2_0,__IPHONE_9_0, "Monitor is no longer supported.") +__WATCHOS_PROHIBITED extern void monitor (char *lowpc, char *highpc, char *buf, int bufsiz, int cntsiz); +__OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0,__MAC_10_11,__IPHONE_2_0,__IPHONE_9_0, "Monitor is no longer supported.") +__WATCHOS_PROHIBITED extern void moncontrol (int mode); +__OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0,__MAC_10_11,__IPHONE_2_0,__IPHONE_9_0, "Monitor is no longer supported.") +__WATCHOS_PROHIBITED extern void monoutput (const char *filename); +__OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0,__MAC_10_11,__IPHONE_2_0,__IPHONE_9_0, "Monitor is no longer supported.") +__WATCHOS_PROHIBITED extern void moninit (void); +__OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0,__MAC_10_11,__IPHONE_2_0,__IPHONE_9_0, "Monitor is no longer supported.") +__WATCHOS_PROHIBITED extern void monreset (void); + __END_DECLS #endif /* __MONITOR_HEADER__ */ diff --git a/src/libc/include/ndbm.h b/src/libc/include/ndbm.h index a3fb88c10..b400c6207 100644 --- a/src/libc/include/ndbm.h +++ b/src/libc/include/ndbm.h @@ -62,16 +62,8 @@ #define _NDBM_H_ #include <_types.h> - -#ifndef _MODE_T -typedef __darwin_mode_t mode_t; -#define _MODE_T -#endif - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif +#include +#include #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) /* Map dbm interface onto db(3). */ diff --git a/src/libc/include/paths.h b/src/libc/include/paths.h index 9317b99da..3edd2b880 100644 --- a/src/libc/include/paths.h +++ b/src/libc/include/paths.h @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * diff --git a/src/libc/include/printf.h b/src/libc/include/printf.h new file mode 100644 index 000000000..22eb9b7a1 --- /dev/null +++ b/src/libc/include/printf.h @@ -0,0 +1,284 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/include/printf.h,v 1.5 2011/03/06 17:45:37 pjd Exp $ + */ + +#ifndef _PRINTF_H_ +#define _PRINTF_H_ + +/**************************************************************************** + * This is the header file for extensible printf, a set of APIs that allow + * adding/modifying conversion specifier(s) for stdio formatted printing. + * It is based on the GLIBC API documented in: + * + * http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html + * + * Because that API affects printf behavior process-wide and so is unsafe, + * we adapt a modified form, based on the concept of printf domains in which + * changes to conversion specifiers can be made independent of one another + * and which don't affect the normal printf behavior. In addition, there + * is now a set of printf variants that take a printf domain as an argument. + * + * See xprintf(5) for more details. + ****************************************************************************/ + +#include +#include +#include +#include + +#ifdef __GNUC__ +#define __XPRINTF_ATTR(x) __attribute__(x) +#else /* !__GNUC__ */ +#define __XPRINTF_ATTR(x) /* nothing */ +#endif /* !__GNUC__ */ + +/* + * The API defined by GLIBC allows a renderer to take multiple arguments + * This is obviously usable for things like (ptr+len) pairs etc. + * The current limit is to deal with up to __PRINTFMAXARG arguments (any + * above this limit are ignored). + */ +#define __PRINTFMAXARG 2 + +struct printf_info { + /* Mac OS X extensions */ + void *context; /* User context pointer */ + locale_t loc; /* Extended locale */ + wchar_t vsep; /* Vector separator char */ + /* one of ,:;_ flag or X by default */ + + /* GLIBC compatible */ + int prec; /* precision */ + int width; /* Width */ + wchar_t spec; /* Format letter */ + wchar_t pad; /* Padding char */ + /* 0 if 0 flag set, otherwise space */ + + /* FreeBSD extensions */ + wchar_t signchar; /* Sign char */ + + /* GLIBC compatible flags */ + unsigned is_long_double :1; /* L or ll flag */ + unsigned is_char :1; /* hh flag */ + unsigned is_short :1; /* h flag */ + unsigned is_long :1; /* l flag */ + unsigned alt :1; /* # flag */ + unsigned space :1; /* Space flag */ + unsigned left :1; /* - flag */ + unsigned showsign :1; /* + flag */ + unsigned group :1; /* ' flag */ + unsigned extra :1; /* For special use (currently unused) */ + unsigned wide :1; /* Nonzero for wide character streams (currently unused) */ + + /* FreeBSD flags */ + unsigned is_quad :1; /* q flag */ + unsigned is_intmax :1; /* j flag */ + unsigned is_ptrdiff :1; /* t flag */ + unsigned is_size :1; /* z flag */ + + /* Mac OS X flags */ + unsigned is_vec :1; /* v flag */ + + /* private */ + int sofar; + unsigned get_width; + unsigned get_prec; + const char *begin; + const char *end; + void *arg[__PRINTFMAXARG]; +}; + +enum { + PA_INT = (1 << 0), /* int */ + PA_CHAR = (1 << 1), /* int, cast to char */ + PA_WCHAR = (1 << 2), /* wide char */ + PA_STRING = (1 << 3), /* const char * (with '\0') */ + PA_WSTRING = (1 << 4), /* const wchar_t * */ + PA_POINTER = (1 << 5), /* void * */ + PA_FLOAT = (1 << 6), /* float (Defined but unused; best to avoid.) */ + PA_DOUBLE = (1 << 7), /* double */ + PA_VECTOR = (1 << 8), /* vector */ +}; + +#define PA_FLAG_MASK 0xff0000 +#define PA_FLAG_LONG_LONG (1 << 16) +#define PA_FLAG_LONG (1 << 17) +#define PA_FLAG_SHORT (1 << 18) +#define PA_FLAG_PTR (1 << 19) +#define PA_FLAG_QUAD (1 << 20) +#define PA_FLAG_INTMAX (1 << 21) +#define PA_FLAG_SIZE (1 << 22) +#define PA_FLAG_PTRDIFF (1 << 23) +#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG + +/************************ Basic Extensible Printf APIs ************************/ + +typedef int printf_arginfo_function(const struct printf_info *__info, + size_t __n, int *__argtypes); +typedef int printf_function(FILE *__stream, + const struct printf_info *__info, const void *const *__args); + +/* + * We don't support the GLIBC register_printf_function() or FreeBSD + * register_printf_render_std(), because they affect printf globally + * and are unsafe. + */ + +/*************** Extensible Printf Domains APIs ****************/ + +struct _printf_domain; /* forward reference */ +typedef struct _printf_domain *printf_domain_t; + +__BEGIN_DECLS + +printf_domain_t copy_printf_domain(printf_domain_t __domain) + __XPRINTF_ATTR((__nonnull__(1))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +void free_printf_domain(printf_domain_t __domain) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +printf_domain_t new_printf_domain(void) + __XPRINTF_ATTR((__malloc__)) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int register_printf_domain_function(printf_domain_t __domain, + int __spec, printf_function *__render, + printf_arginfo_function *__arginfo, void *__context) + __XPRINTF_ATTR((__nonnull__(1))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int register_printf_domain_render_std(printf_domain_t __domain, + const char *__specs) + __XPRINTF_ATTR((__nonnull__(1))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); + +/**** All-in-one extensible printf variants ****/ +int asxprintf(char ** __restrict __ret, + printf_domain_t __restrict __domain, locale_t __restrict __loc, + const char * __restrict __format, ...) + __XPRINTF_ATTR((__nonnull__(1, 2, 4))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int dxprintf(int __fd, printf_domain_t __restrict __domain, + locale_t __restrict __loc, const char * __restrict __format, ...) + __XPRINTF_ATTR((__nonnull__(2, 4))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int fxprintf(FILE * __restrict __stream, + printf_domain_t __restrict __domain, locale_t __restrict __loc, + const char * __restrict __format, ...) + __XPRINTF_ATTR((__nonnull__(1, 2, 4))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int sxprintf(char * __restrict __str, size_t __size, + printf_domain_t __restrict __domain, locale_t __restrict __loc, + const char * __restrict __format, ...) + __XPRINTF_ATTR((__nonnull__(1, 3, 5))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int xprintf(printf_domain_t __restrict __domain, + locale_t __restrict __loc, const char * __restrict __format, ...) + __XPRINTF_ATTR((__nonnull__(1, 3))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); + +int vasxprintf(char ** __restrict __ret, + printf_domain_t __restrict __domain, locale_t __restrict __loc, + const char * __restrict __format, va_list __ap) + __XPRINTF_ATTR((__nonnull__(1, 2, 4))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int vdxprintf(int __fd, printf_domain_t __restrict __domain, + locale_t __restrict __loc, const char * __restrict __format, + va_list __ap) + __XPRINTF_ATTR((__nonnull__(2, 4))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int vfxprintf(FILE * __restrict __stream, + printf_domain_t __restrict __domain, locale_t __restrict __loc, + const char * __restrict __format, va_list __ap) + __XPRINTF_ATTR((__nonnull__(1, 2, 4))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int vsxprintf(char * __restrict __str, size_t __size, + printf_domain_t __restrict __domain, locale_t __restrict __loc, + const char * __restrict __format, va_list __ap) + __XPRINTF_ATTR((__nonnull__(1, 3, 5))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int vxprintf(printf_domain_t __restrict __domain, + locale_t __restrict __loc, const char * __restrict __format, + va_list __ap) + __XPRINTF_ATTR((__nonnull__(1, 3))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); + +__END_DECLS + +/******** Extensible Printf Compilation/Execution APIs *********/ +struct _printf_compiled; /* forward reference */ +typedef struct _printf_compiled *printf_comp_t; + +__BEGIN_DECLS + +void free_printf_comp(printf_comp_t __pc) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +printf_comp_t new_printf_comp(printf_domain_t __restrict __domain, + locale_t __restrict __loc, const char * __restrict __fmt) + __XPRINTF_ATTR((__nonnull__(1, 3))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); + +/**** Extensible printf execution ****/ +int asxprintf_exec(char ** __restrict __ret, + printf_comp_t __restrict __pc, ...) + __XPRINTF_ATTR((__nonnull__(1, 2))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int dxprintf_exec(int __fd, printf_comp_t __restrict __pc, ...) + __XPRINTF_ATTR((__nonnull__(2))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int fxprintf_exec(FILE * __restrict __stream, + printf_comp_t __restrict __pc, ...) + __XPRINTF_ATTR((__nonnull__(1, 2))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int sxprintf_exec(char * __restrict __str, size_t __size, + printf_comp_t __restrict __pc, ...) + __XPRINTF_ATTR((__nonnull__(1, 3))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int xprintf_exec(printf_comp_t __restrict __pc, ...) + __XPRINTF_ATTR((__nonnull__(1))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); + +int vasxprintf_exec(char ** __restrict __ret, + printf_comp_t __restrict __pc, va_list __ap) + __XPRINTF_ATTR((__nonnull__(1, 2))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int vdxprintf_exec(int __fd, printf_comp_t __restrict __pc, + va_list __ap) + __XPRINTF_ATTR((__nonnull__(2))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int vfxprintf_exec(FILE * __restrict __stream, + printf_comp_t __restrict __pc, va_list __ap) + __XPRINTF_ATTR((__nonnull__(1, 2))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int vsxprintf_exec(char * __restrict __str, size_t __size, + printf_comp_t __restrict __pc, va_list __ap) + __XPRINTF_ATTR((__nonnull__(1, 3))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +int vxprintf_exec(printf_comp_t __restrict __pc, va_list __ap) + __XPRINTF_ATTR((__nonnull__(1))) + __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); + +__END_DECLS + +#endif /* !_PRINTF_H */ diff --git a/src/libc/include/protocols/timed.h b/src/libc/include/protocols/timed.h index b628fc78e..6999dff4d 100644 --- a/src/libc/include/protocols/timed.h +++ b/src/libc/include/protocols/timed.h @@ -66,8 +66,8 @@ #define ANYADDR NULL #ifdef __LP64__ -#define __need_struct_timeval32 -#include +#include +#include #endif /* __LP64__ */ struct tsp { diff --git a/src/libc/include/pthread_spinlock.h b/src/libc/include/pthread_spinlock.h new file mode 120000 index 000000000..343916797 --- /dev/null +++ b/src/libc/include/pthread_spinlock.h @@ -0,0 +1 @@ +../../external/libpthread/private/spinlock_private.h \ No newline at end of file diff --git a/src/libc/include/readpassphrase.h b/src/libc/include/readpassphrase.h index c774fe522..76316cc2a 100644 --- a/src/libc/include/readpassphrase.h +++ b/src/libc/include/readpassphrase.h @@ -1,31 +1,21 @@ -/* $OpenBSD: /usr/local/www/cvsroot/OpenBSD/src/include/readpassphrase.h,v 1.2 2002/02/16 21:27:17 millert Exp $ */ -/* $FreeBSD: /repoman/r/ncvs/src/include/readpassphrase.h,v 1.2 2002/03/08 20:52:52 green Exp $ */ - /* - * Copyright (c) 2000 Todd C. Miller - * All rights reserved. + * Copyright (c) 2000, 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ #ifndef _READPASSPHRASE_H_ @@ -37,13 +27,10 @@ #define RPP_FORCELOWER 0x04 /* Force input to lower case. */ #define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ #define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ +#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ #include <_types.h> - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif +#include __BEGIN_DECLS char * readpassphrase(const char *, char *, size_t, int); diff --git a/src/libc/include/regex.h b/src/libc/include/regex.h index d362ab466..a73513276 100644 --- a/src/libc/include/regex.h +++ b/src/libc/include/regex.h @@ -91,26 +91,17 @@ #include <_types.h> #include +#include /*********/ /* types */ /*********/ #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL -#ifndef __cplusplus -#ifndef _WCHAR_T -#define _WCHAR_T -typedef __darwin_wchar_t wchar_t; -#endif /* _WCHAR_T */ -#endif /* __cplusplus */ +#include #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ typedef __darwin_off_t regoff_t; -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif - typedef struct { int re_magic; size_t re_nsub; /* number of parenthesized subexpressions */ diff --git a/src/libc/include/runetype.h b/src/libc/include/runetype.h index fd16b8276..b3dcce26f 100644 --- a/src/libc/include/runetype.h +++ b/src/libc/include/runetype.h @@ -43,32 +43,11 @@ #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif - -#ifndef _CT_RUNE_T -#define _CT_RUNE_T -typedef __darwin_ct_rune_t ct_rune_t; -#endif - -#ifndef _RUNE_T -#define _RUNE_T -typedef __darwin_rune_t rune_t; -#endif - -#ifndef __cplusplus -#ifndef _WCHAR_T -#define _WCHAR_T -typedef __darwin_wchar_t wchar_t; -#endif /* _WCHAR_T */ -#endif /* __cplusplus */ - -#ifndef _WINT_T -#define _WINT_T -typedef __darwin_wint_t wint_t; -#endif +#include +#include +#include +#include +#include #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ diff --git a/src/libc/include/search.h b/src/libc/include/search.h index df98dd48b..58d69e76b 100644 --- a/src/libc/include/search.h +++ b/src/libc/include/search.h @@ -11,11 +11,7 @@ #include #include <_types.h> - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif +#include typedef struct entry { char *key; diff --git a/src/libc/include/secure/_common.h b/src/libc/include/secure/_common.h index 53e1a0230..a7acfaa0d 100644 --- a/src/libc/include/secure/_common.h +++ b/src/libc/include/secure/_common.h @@ -36,6 +36,6 @@ #endif #define __darwin_obsz0(object) __builtin_object_size (object, 0) -#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1) +#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1 ? 1 : 0) #endif diff --git a/src/libc/include/secure/_stdio.h b/src/libc/include/secure/_stdio.h index 49caf72af..c4dc7b234 100644 --- a/src/libc/include/secure/_stdio.h +++ b/src/libc/include/secure/_stdio.h @@ -32,42 +32,55 @@ #if _USE_FORTIFY_LEVEL > 0 -#undef sprintf -#undef vsprintf - -#if __DARWIN_C_LEVEL >= 200112L -#undef snprintf -#undef vsnprintf +#ifndef __has_builtin +#define _undef__has_builtin +#define __has_builtin(x) 0 #endif /* sprintf, vsprintf, snprintf, vsnprintf */ - +#if __has_builtin(__builtin___sprintf_chk) || defined(__GNUC__) extern int __sprintf_chk (char * __restrict, int, size_t, const char * __restrict, ...); +#undef sprintf #define sprintf(str, ...) \ __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__) +#endif +#if __DARWIN_C_LEVEL >= 200112L +#if __has_builtin(__builtin___snprintf_chk) || defined(__GNUC__) extern int __snprintf_chk (char * __restrict, size_t, int, size_t, const char * __restrict, ...); -#if __DARWIN_C_LEVEL >= 200112L +#undef snprintf #define snprintf(str, len, ...) \ __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__) +#endif +#if __has_builtin(__builtin___vsprintf_chk) || defined(__GNUC__) extern int __vsprintf_chk (char * __restrict, int, size_t, const char * __restrict, va_list); +#undef vsprintf #define vsprintf(str, format, ap) \ __builtin___vsprintf_chk (str, 0, __darwin_obsz(str), format, ap) +#endif +#if __has_builtin(__builtin___vsnprintf_chk) || defined(__GNUC__) extern int __vsnprintf_chk (char * __restrict, size_t, int, size_t, const char * __restrict, va_list); +#undef vsnprintf #define vsnprintf(str, len, format, ap) \ __builtin___vsnprintf_chk (str, len, 0, __darwin_obsz(str), format, ap) #endif -#endif +#endif /* __DARWIN_C_LEVEL >= 200112L */ +#ifdef _undef__has_builtin +#undef _undef__has_builtin +#undef __has_builtin #endif + +#endif /* _USE_FORTIFY_LEVEL > 0 */ +#endif /* _SECURE__STDIO_H_ */ diff --git a/src/libc/include/secure/_string.h b/src/libc/include/secure/_string.h index cba7db475..c1ff94b10 100644 --- a/src/libc/include/secure/_string.h +++ b/src/libc/include/secure/_string.h @@ -28,133 +28,117 @@ #ifndef _SECURE__STRING_H_ #define _SECURE__STRING_H_ +#include #include #include #if _USE_FORTIFY_LEVEL > 0 -/* memcpy, mempcpy, memmove, memset, strcpy, stpcpy, strncpy, stpncpy, - strcat, and strncat */ +#ifndef __has_builtin +#define _undef__has_builtin +#define __has_builtin(x) 0 +#endif -#undef memcpy -#undef memmove -#undef memset -#undef strcpy -#if __DARWIN_C_LEVEL >= 200809L -#undef stpcpy -#undef stpncpy +/* */ +#if defined(__clang__) && \ + ((defined(__apple_build_version__) && __apple_build_version__ >= 4260006) || \ + (!defined(__apple_build_version__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 3)))) +#define __HAS_FIXED_CHK_PROTOTYPES 1 +#else +#define __HAS_FIXED_CHK_PROTOTYPES 0 +#endif + +/* memccpy, memcpy, mempcpy, memmove, memset, strcpy, strlcpy, stpcpy, + strncpy, stpncpy, strcat, strlcat, and strncat */ + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 +#if __has_builtin(__builtin___memccpy_chk) && __HAS_FIXED_CHK_PROTOTYPES +#undef memccpy +#define memccpy(dest, src, c, len) \ + __builtin___memccpy_chk (dest, src, c, len, __darwin_obsz0 (dest)) #endif -#undef strncpy -#undef strcat -#if ! (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 32000) -#undef strncat #endif +#if __has_builtin(__builtin___memcpy_chk) || defined(__GNUC__) +#undef memcpy #define memcpy(dest, src, len) \ - ((__darwin_obsz0 (dest) != (size_t) -1) \ - ? __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest)) \ - : __inline_memcpy_chk (dest, src, len)) - -static __inline void * -__inline_memcpy_chk (void *__dest, const void *__src, size_t __len) -{ - return __builtin___memcpy_chk (__dest, __src, __len, __darwin_obsz0(__dest)); -} + __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest)) +#endif +#if __has_builtin(__builtin___memmove_chk) || defined(__GNUC__) +#undef memmove #define memmove(dest, src, len) \ - ((__darwin_obsz0 (dest) != (size_t) -1) \ - ? __builtin___memmove_chk (dest, src, len, __darwin_obsz0 (dest)) \ - : __inline_memmove_chk (dest, src, len)) - -static __inline void * -__inline_memmove_chk (void *__dest, const void *__src, size_t __len) -{ - return __builtin___memmove_chk (__dest, __src, __len, __darwin_obsz0(__dest)); -} + __builtin___memmove_chk (dest, src, len, __darwin_obsz0 (dest)) +#endif +#if __has_builtin(__builtin___memset_chk) || defined(__GNUC__) +#undef memset #define memset(dest, val, len) \ - ((__darwin_obsz0 (dest) != (size_t) -1) \ - ? __builtin___memset_chk (dest, val, len, __darwin_obsz0 (dest)) \ - : __inline_memset_chk (dest, val, len)) - -static __inline void * -__inline_memset_chk (void *__dest, int __val, size_t __len) -{ - return __builtin___memset_chk (__dest, __val, __len, __darwin_obsz0(__dest)); -} + __builtin___memset_chk (dest, val, len, __darwin_obsz0 (dest)) +#endif +#if __has_builtin(__builtin___strcpy_chk) || defined(__GNUC__) +#undef strcpy #define strcpy(dest, src) \ - ((__darwin_obsz0 (dest) != (size_t) -1) \ - ? __builtin___strcpy_chk (dest, src, __darwin_obsz (dest)) \ - : __inline_strcpy_chk (dest, src)) - -static __inline char * -__inline_strcpy_chk (char *__restrict __dest, const char *__restrict __src) -{ - return __builtin___strcpy_chk (__dest, __src, __darwin_obsz(__dest)); -} + __builtin___strcpy_chk (dest, src, __darwin_obsz (dest)) +#endif #if __DARWIN_C_LEVEL >= 200809L +#if __has_builtin(__builtin___stpcpy_chk) || defined(__GNUC__) +#undef stpcpy #define stpcpy(dest, src) \ - ((__darwin_obsz0 (dest) != (size_t) -1) \ - ? __builtin___stpcpy_chk (dest, src, __darwin_obsz (dest)) \ - : __inline_stpcpy_chk (dest, src)) - -static __inline char * -__inline_stpcpy_chk (char *__dest, const char *__src) -{ - return __builtin___stpcpy_chk (__dest, __src, __darwin_obsz(__dest)); -} + __builtin___stpcpy_chk (dest, src, __darwin_obsz (dest)) +#endif +#if __has_builtin(__builtin___stpncpy_chk) || __APPLE_CC__ >= 5666 || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) +#undef stpncpy #define stpncpy(dest, src, len) \ - ((__darwin_obsz0 (dest) != (size_t) -1) \ - ? __builtin___stpncpy_chk (dest, src, len, __darwin_obsz (dest)) \ - : __inline_stpncpy_chk (dest, src, len)) + __builtin___stpncpy_chk (dest, src, len, __darwin_obsz (dest)) +#endif +#endif /* _DARWIN_C_LEVEL >= 200809L */ + +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 +#if __has_builtin(__builtin___strlcpy_chk) && __HAS_FIXED_CHK_PROTOTYPES +#undef strlcpy +#define strlcpy(dest, src, len) \ + __builtin___strlcpy_chk (dest, src, len, __darwin_obsz (dest)) +#endif -static __inline char * -__inline_stpncpy_chk (char *__restrict __dest, const char *__restrict __src, - size_t __len) -{ - return __builtin___stpncpy_chk (__dest, __src, __len, __darwin_obsz(__dest)); -} +#if __has_builtin(__builtin___strlcat_chk) && __HAS_FIXED_CHK_PROTOTYPES +#undef strlcat +#define strlcat(dest, src, len) \ + __builtin___strlcat_chk (dest, src, len, __darwin_obsz (dest)) #endif +#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 */ +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ +#if __has_builtin(__builtin___strncpy_chk) || defined(__GNUC__) +#undef strncpy #define strncpy(dest, src, len) \ - ((__darwin_obsz0 (dest) != (size_t) -1) \ - ? __builtin___strncpy_chk (dest, src, len, __darwin_obsz (dest)) \ - : __inline_strncpy_chk (dest, src, len)) - -static __inline char * -__inline_strncpy_chk (char *__restrict __dest, const char *__restrict __src, - size_t __len) -{ - return __builtin___strncpy_chk (__dest, __src, __len, __darwin_obsz(__dest)); -} + __builtin___strncpy_chk (dest, src, len, __darwin_obsz (dest)) +#endif +#if __has_builtin(__builtin___strcat_chk) || defined(__GNUC__) +#undef strcat #define strcat(dest, src) \ - ((__darwin_obsz0 (dest) != (size_t) -1) \ - ? __builtin___strcat_chk (dest, src, __darwin_obsz (dest)) \ - : __inline_strcat_chk (dest, src)) - -static __inline char * -__inline_strcat_chk (char *__restrict __dest, const char *__restrict __src) -{ - return __builtin___strcat_chk (__dest, __src, __darwin_obsz(__dest)); -} + __builtin___strcat_chk (dest, src, __darwin_obsz (dest)) +#endif #if ! (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 32000) +#if __has_builtin(__builtin___strncat_chk) || defined(__GNUC__) +#undef strncat #define strncat(dest, src, len) \ - ((__darwin_obsz0 (dest) != (size_t) -1) \ - ? __builtin___strncat_chk (dest, src, len, __darwin_obsz (dest)) \ - : __inline_strncat_chk (dest, src, len)) - -static __inline char * -__inline_strncat_chk (char *__restrict __dest, const char *__restrict __src, - size_t __len) -{ - return __builtin___strncat_chk (__dest, __src, __len, __darwin_obsz(__dest)); -} + __builtin___strncat_chk (dest, src, len, __darwin_obsz (dest)) #endif - #endif + +#ifdef _undef__has_builtin +#undef _undef__has_builtin +#undef __has_builtin #endif + +#undef __HAS_FIXED_CHK_PROTOTYPES + +#endif /* _USE_FORTIFY_LEVEL > 0 */ +#endif /* _SECURE__STRING_H_ */ diff --git a/src/libc/include/signal.h b/src/libc/include/signal.h index 08ad77ec1..f589ec520 100644 --- a/src/libc/include/signal.h +++ b/src/libc/include/signal.h @@ -62,10 +62,8 @@ #include <_types.h> #include -#ifndef _PTHREAD_T -typedef __darwin_pthread_t pthread_t; -#define _PTHREAD_T -#endif +#include +#include #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) extern __const char *__const sys_signame[NSIG]; @@ -78,7 +76,7 @@ __END_DECLS #ifndef _ANSI_SOURCE __BEGIN_DECLS -void (*bsd_signal(int, void (*)(int)))(int); +void (* _Nullable bsd_signal(int, void (* _Nullable)(int)))(int); //Begin-Libc #ifndef LIBC_ALIAS_KILL //End-Libc @@ -113,10 +111,10 @@ int sigaddset(sigset_t *, int); //Begin-Libc #ifndef LIBC_ALIAS_SIGALTSTACK //End-Libc -int sigaltstack(const stack_t * __restrict, stack_t * __restrict) __DARWIN_ALIAS(sigaltstack); +int sigaltstack(const stack_t * __restrict, stack_t * __restrict) __DARWIN_ALIAS(sigaltstack) ;//__WATCHOS_PROHIBITED __TVOS_PROHIBITED; //Begin-Libc #else /* LIBC_ALIAS_SIGALTSTACK */ -int sigaltstack(const stack_t * __restrict, stack_t * __restrict) LIBC_ALIAS(sigaltstack); +int sigaltstack(const stack_t * __restrict, stack_t * __restrict) LIBC_ALIAS(sigaltstack) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; #endif /* !LIBC_ALIAS_SIGALTSTACK */ //End-Libc int sigdelset(sigset_t *, int); @@ -138,7 +136,7 @@ int sigpause(int) LIBC_ALIAS_C(sigpause); int sigpending(sigset_t *); int sigprocmask(int, const sigset_t * __restrict, sigset_t * __restrict); int sigrelse(int); -void (*sigset(int, void (*)(int)))(int); +void (* _Nullable sigset(int, void (* _Nullable)(int)))(int); //Begin-Libc #ifndef LIBC_ALIAS_SIGSUSPEND //End-Libc @@ -168,7 +166,7 @@ __END_DECLS /* List definitions after function declarations, or Reiser cpp gets upset. */ #if defined(__i386__) || defined(__x86_64__) /* The left shift operator on intel is modulo 32 */ -static __inline int +__header_always_inline int __sigbits(int __signo) { return __signo > __DARWIN_NSIG ? 0 : (1 << (__signo - 1)); diff --git a/src/libc/include/spawn_private.h b/src/libc/include/spawn_private.h deleted file mode 100644 index 10a1b544c..000000000 --- a/src/libc/include/spawn_private.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2006, 2008 Apple,Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _SPAWN_PRIVATE_H_ -#define _SPAWN_PRIVATE_H_ - -#include -#include -#include -#include - -int posix_spawnattr_getpcontrol_np(const posix_spawnattr_t * __restrict, int * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); -int posix_spawnattr_setpcontrol_np(posix_spawnattr_t *, const int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); - -int posix_spawnattr_getprocesstype_np(const posix_spawnattr_t * __restrict, int * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); -int posix_spawnattr_setprocesstype_np(posix_spawnattr_t *, const int) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); - -int posix_spawnattr_setcpumonitor(posix_spawnattr_t * __restrict, uint64_t, uint64_t) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); -int posix_spawnattr_getcpumonitor(posix_spawnattr_t * __restrict, uint64_t *, uint64_t *) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); -int posix_spawnattr_setcpumonitor_default(posix_spawnattr_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0); - - -#define POSIX_SPAWN_IMPORTANCE_PORT_COUNT 32 -int posix_spawnattr_set_importancewatch_port_np(posix_spawnattr_t * __restrict attr, - int count, mach_port_t portarray[]) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0); - -#define POSIX_SPAWN_MACPOLICYINFO_WITHSIZE 1 -int posix_spawnattr_getmacpolicyinfo_np(const posix_spawnattr_t * __restrict, const char *, void **, size_t *) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); -int posix_spawnattr_setmacpolicyinfo_np(posix_spawnattr_t * __restrict, const char *, void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); - -int posix_spawnattr_setcoalition_np(const posix_spawnattr_t * __restrict, uint64_t) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); - -int posix_spawnattr_set_qos_clamp_np(const posix_spawnattr_t * __restrict, uint64_t) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); -int posix_spawnattr_get_qos_clamp_np(const posix_spawnattr_t * __restrict, uint64_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); - -#endif /* !defined _SPAWN_PRIVATE_H_*/ diff --git a/src/libc/include/stddef.h b/src/libc/include/stddef.h index 2559fe288..6832cf723 100644 --- a/src/libc/include/stddef.h +++ b/src/libc/include/stddef.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -58,73 +58,33 @@ * @(#)stddef.h 5.5 (Berkeley) 4/3/91 */ -#if !defined(__STDDEF_H__) - -#if !defined(__need_wchar_t) && !defined(__need_size_t) \ - && !defined(__need_ptrdiff_t) && !defined(__need_NULL) \ - && !defined(__need_wint_t) +#ifndef __STDDEF_H__ #define __STDDEF_H__ -#endif /* none of __need_* defined */ #include <_types.h> -#if defined(__STDDEF_H__) || defined(__need_ptrdiff_t) -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef __darwin_ptrdiff_t ptrdiff_t; -#endif /* _PTRDIFF_T */ -#endif /* __STDDEF_H__ || __need_ptrdiff_t */ +#include +#include +#include +#include + +#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 +#include +#endif /* __STDC_WANT_LIB_EXT1__ >= 1 */ -#if defined(__STDDEF_H__) || defined(__need_size_t) -#ifndef _SIZE_T -#define _SIZE_T /* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: * _GCC_SIZE_T */ -typedef __darwin_size_t size_t; -#endif /* _SIZE_T */ -#endif /* __STDDEF_H__ || __need_size_t */ - -#if defined(__STDDEF_H__) || defined(__need_wchar_t) -#ifndef __cplusplus -#ifndef _WCHAR_T -#define _WCHAR_T -typedef __darwin_wchar_t wchar_t; -#endif /* _WCHAR_T */ -#endif /* __cplusplus */ -#endif /* __STDDEF_H__ || __need_wchar_t */ +#include -#if (defined(__STDDEF_H__) && !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))) \ - || defined(__need_wint_t) -#ifndef _WINT_T -#define _WINT_T -typedef __darwin_wint_t wint_t; -#endif /* _WINT_T */ -#endif /* __STDDEF_H__ && !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) || __need_wchar_t */ +#include -#if defined(__STDDEF_H__) || defined(__need_NULL) -#ifndef NULL -#define NULL __DARWIN_NULL -#endif /* ! NULL */ -#endif /* __STDDEF_H__ || __need_NULL */ +#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) +#include +#endif /* !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ -#ifdef __STDDEF_H__ -#if defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 || __GNUC__ > 3) -#ifndef __offsetof /* Deprecated: for source compatibility only */ -#define __offsetof(type, field) __builtin_offsetof(type, field) +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) \ + || (defined(__cplusplus) && __cplusplus >= 201103L) +typedef long double max_align_t; #endif -#define offsetof(type, field) __builtin_offsetof(type, field) -#else /* ! (gcc >= 3.5) */ -#ifndef __offsetof /* Deprecated: for source compatibility only */ -#define __offsetof(type, field) ((size_t)(&((type *)0)->field)) -#endif -#define offsetof(type, field) ((size_t)(&((type *)0)->field)) -#endif /* (gcc >= 3.5) */ -#endif /* __STDDEF_H__ */ #endif /* __STDDEF_H__ */ - -#undef __need_ptrdiff_t -#undef __need_size_t -#undef __need_wchar_t -#undef __need_wint_t -#undef __need_NULL diff --git a/src/libc/include/stdint.h b/src/libc/include/stdint.h index a9e312d3b..c0e570a99 100644 --- a/src/libc/include/stdint.h +++ b/src/libc/include/stdint.h @@ -15,45 +15,15 @@ /* from ISO/IEC 988:1999 spec */ /* 7.18.1.1 Exact-width integer types */ -#ifndef _INT8_T -#define _INT8_T -typedef signed char int8_t; -#endif /*_INT8_T */ - -#ifndef _INT16_T -#define _INT16_T -typedef short int16_t; -#endif /* _INT16_T */ - -#ifndef _INT32_T -#define _INT32_T -typedef int int32_t; -#endif /* _INT32_T */ - -#ifndef _INT64_T -#define _INT64_T -typedef long long int64_t; -#endif /* _INT64_T */ - -#ifndef _UINT8_T -#define _UINT8_T -typedef unsigned char uint8_t; -#endif /*_UINT8_T */ - -#ifndef _UINT16_T -#define _UINT16_T -typedef unsigned short uint16_t; -#endif /* _UINT16_T */ - -#ifndef _UINT32_T -#define _UINT32_T -typedef unsigned int uint32_t; -#endif /* _UINT32_T */ - -#ifndef _UINT64_T -#define _UINT64_T -typedef unsigned long long uint64_t; -#endif /* _UINT64_T */ +#include +#include +#include +#include + +#include <_types/_uint8_t.h> +#include <_types/_uint16_t.h> +#include <_types/_uint32_t.h> +#include <_types/_uint64_t.h> /* 7.18.1.2 Minimum-width integer types */ typedef int8_t int_least8_t; @@ -79,35 +49,14 @@ typedef uint64_t uint_fast64_t; /* 7.18.1.4 Integer types capable of holding object pointers */ -#ifndef _INTPTR_T -#define _INTPTR_T -typedef long intptr_t; -#endif /* _INTPTR_T */ - -#ifndef _UINTPTR_T -#define _UINTPTR_T -typedef unsigned long uintptr_t; -#endif /* _UINTPTR_T */ +#include +#include +#include /* 7.18.1.5 Greatest-width integer types */ -#ifndef _INTMAX_T -#define _INTMAX_T -#ifdef __INTMAX_TYPE__ -typedef __INTMAX_TYPE__ intmax_t; -#else /* __INTMAX_TYPE__ */ -typedef long long intmax_t; -#endif /* __INTMAX_TYPE__ */ -#endif /* _INTMAX_T */ - -#ifndef _UINTMAX_T -#define _UINTMAX_T -#ifdef __UINTMAX_TYPE__ -typedef __UINTMAX_TYPE__ uintmax_t; -#else /* __UINTMAX_TYPE__ */ -typedef unsigned long long uintmax_t; -#endif /* __UINTMAX_TYPE__ */ -#endif /* _UINTMAX_T */ +#include <_types/_intmax_t.h> +#include <_types/_uintmax_t.h> /* 7.18.2 Limits of specified-width integer types: * These #defines specify the minimum and maximum limits @@ -200,16 +149,16 @@ typedef unsigned long long uintmax_t; #define PTRDIFF_MAX INT32_MAX #endif -/* We have no sig_atomic_t yet, so no SIG_ATOMIC_{MIN,MAX}. - Should end up being {-127,127} or {0,255} ... or bigger. - My bet would be on one of {U}INT32_{MIN,MAX}. */ - #if __WORDSIZE == 64 #define SIZE_MAX UINT64_MAX #else #define SIZE_MAX UINT32_MAX #endif +#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 +#define RSIZE_MAX (SIZE_MAX >> 1) +#endif + #ifndef WCHAR_MAX # ifdef __WCHAR_MAX__ # define WCHAR_MAX __WCHAR_MAX__ @@ -247,7 +196,12 @@ typedef unsigned long long uintmax_t; #define UINT32_C(v) (v ## U) #define UINT64_C(v) (v ## ULL) +#ifdef __LP64__ +#define INTMAX_C(v) (v ## L) +#define UINTMAX_C(v) (v ## UL) +#else #define INTMAX_C(v) (v ## LL) #define UINTMAX_C(v) (v ## ULL) +#endif #endif /* _STDINT_H_ */ diff --git a/src/libc/include/stdio.h b/src/libc/include/stdio.h index b2860ed6b..d0cf7a50c 100644 --- a/src/libc/include/stdio.h +++ b/src/libc/include/stdio.h @@ -66,21 +66,13 @@ #include <_types.h> -#ifndef _VA_LIST -#define _VA_LIST /* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: * __gnuc_va_list and include */ -typedef __darwin_va_list va_list; -#endif - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif +#include +#include +#include -#ifndef NULL -#define NULL __DARWIN_NULL -#endif /* ! NULL */ +#include typedef __darwin_off_t fpos_t; @@ -138,10 +130,10 @@ typedef struct __sFILE { /* operations */ void *_cookie; /* cookie passed to io functions */ - int (*_close)(void *); - int (*_read) (void *, char *, int); - fpos_t (*_seek) (void *, fpos_t, int); - int (*_write)(void *, const char *, int); + int (* _Nullable _close)(void *); + int (* _Nullable _read) (void *, char *, int); + fpos_t (* _Nullable _seek) (void *, fpos_t, int); + int (* _Nullable _write)(void *, const char *, int); /* separate buffer for long sequences of ungetc() */ struct __sbuf _ub; /* ungetc buffer */ @@ -245,15 +237,15 @@ int fgetc(FILE *); int fgetpos(FILE * __restrict, fpos_t *); char *fgets(char * __restrict, int, FILE *); #if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) -FILE *fopen(const char * __restrict, const char * __restrict) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fopen)); +FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(fopen)); #else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ //Begin-Libc #ifndef LIBC_ALIAS_FOPEN //End-Libc -FILE *fopen(const char * __restrict, const char * __restrict) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen)); +FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen)); //Begin-Libc #else /* LIBC_ALIAS_FOPEN */ -FILE *fopen(const char * __restrict, const char * __restrict) LIBC_ALIAS(fopen); +FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) LIBC_ALIAS(fopen); #endif /* !LIBC_ALIAS_FOPEN */ //End-Libc #endif /* (DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */ @@ -268,7 +260,7 @@ int fputs(const char * __restrict, FILE * __restrict) __DARWIN_ALIAS(fputs); int fputs(const char * __restrict, FILE * __restrict) LIBC_ALIAS(fputs); #endif /* !LIBC_ALIAS_FPUTS */ //End-Libc -size_t fread(void * __restrict, size_t, size_t, FILE * __restrict); +size_t fread(void * __restrict __ptr, size_t __size, size_t __nitems, FILE * __restrict __stream); //Begin-Libc #ifndef LIBC_ALIAS_FREOPEN //End-Libc @@ -287,10 +279,10 @@ long ftell(FILE *); //Begin-Libc #ifndef LIBC_ALIAS_FWRITE //End-Libc -size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict) __DARWIN_ALIAS(fwrite); +size_t fwrite(const void * __restrict __ptr, size_t __size, size_t __nitems, FILE * __restrict __stream) __DARWIN_ALIAS(fwrite); //Begin-Libc #else /* LIBC_ALIAS_FWRITE */ -size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict) LIBC_ALIAS(fwrite); +size_t fwrite(const void * __restrict __ptr, size_t __size, size_t __nitems, FILE * __restrict __stream) LIBC_ALIAS(fwrite); #endif /* !LIBC_ALIAS_FWRITE */ //End-Libc int getc(FILE *); @@ -302,19 +294,24 @@ int putc(int, FILE *); int putchar(int); int puts(const char *); int remove(const char *); -int rename (const char *, const char *); +int rename (const char *__old, const char *__new); void rewind(FILE *); int scanf(const char * __restrict, ...) __scanflike(1, 2); void setbuf(FILE * __restrict, char * __restrict); int setvbuf(FILE * __restrict, char * __restrict, int, size_t); -int sprintf(char * __restrict, const char * __restrict, ...) __printflike(2, 3); +int sprintf(char * __restrict, const char * __restrict, ...) __printflike(2, 3) __swift_unavailable("Use snprintf instead."); int sscanf(const char * __restrict, const char * __restrict, ...) __scanflike(2, 3); FILE *tmpfile(void); + +__swift_unavailable("Use mkstemp(3) instead.") +#if !defined(_POSIX_C_SOURCE) +__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tmpnam(3), it is highly recommended that you use mkstemp(3) instead.") +#endif char *tmpnam(char *); int ungetc(int, FILE *); int vfprintf(FILE * __restrict, const char * __restrict, va_list) __printflike(2, 0); int vprintf(const char * __restrict, va_list) __printflike(1, 0); -int vsprintf(char * __restrict, const char * __restrict, va_list) __printflike(2, 0); +int vsprintf(char * __restrict, const char * __restrict, va_list) __printflike(2, 0) __swift_unavailable("Use vsnprintf instead."); __END_DECLS @@ -354,17 +351,22 @@ __END_DECLS /* Additional functionality provided by: * POSIX.2-1992 C Language Binding Option */ +#if TARGET_OS_EMBEDDED +#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(ios_msg) +#else +#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(osx_msg) +#endif #if __DARWIN_C_LEVEL >= 199209L __BEGIN_DECLS -int pclose(FILE *); +int pclose(FILE *) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable."); #if defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE) -FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(popen)); +FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_3_2, __DARWIN_EXTSN(popen)) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable."); #else /* !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */ //Begin-Libc #ifndef LIBC_ALIAS_POPEN //End-Libc -FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(popen)); +FILE *popen(const char *, const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(popen)) __swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable."); //Begin-Libc #else /* LIBC_ALIAS_POPEN */ FILE *popen(const char *, const char *) LIBC_ALIAS(popen); @@ -374,8 +376,7 @@ FILE *popen(const char *, const char *) LIBC_ALIAS(popen); __END_DECLS #endif /* __DARWIN_C_LEVEL >= 199209L */ - - +#undef __swift_unavailable_on /* Additional functionality provided by: * POSIX.1c-1995, @@ -398,7 +399,7 @@ __END_DECLS */ #define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) #if defined(__GNUC__) && defined(__STDC__) -static __inline int __sputc(int _c, FILE *_p) { +__header_always_inline int __sputc(int _c, FILE *_p) { if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) return (*_p->_p++ = _c); else @@ -438,13 +439,17 @@ int getw(FILE *); int putw(int, FILE *); #endif +__swift_unavailable("Use mkstemp(3) instead.") +#if !defined(_POSIX_C_SOURCE) +__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead.") +#endif //Begin-Libc #ifndef LIBC_ALIAS_TEMPNAM //End-Libc -char *tempnam(const char *, const char *) __DARWIN_ALIAS(tempnam); +char *tempnam(const char *__dir, const char *__prefix) __DARWIN_ALIAS(tempnam); //Begin-Libc #else /* LIBC_ALIAS_TEMPNAM */ -char *tempnam(const char *, const char *) LIBC_ALIAS(tempnam); +char *tempnam(const char *__dir, const char *__prefix) LIBC_ALIAS(tempnam); #endif /* !LIBC_ALIAS_TEMPNAM */ //End-Libc __END_DECLS @@ -466,24 +471,21 @@ __END_DECLS */ #if __DARWIN_C_LEVEL >= 200112L -#ifndef _OFF_T -#define _OFF_T -typedef __darwin_off_t off_t; -#endif +#include __BEGIN_DECLS -int fseeko(FILE *, off_t, int); -off_t ftello(FILE *); +int fseeko(FILE * __stream, off_t __offset, int __whence); +off_t ftello(FILE * __stream); __END_DECLS #endif /* __DARWIN_C_LEVEL >= 200112L */ #if __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) __BEGIN_DECLS -int snprintf(char * __restrict, size_t, const char * __restrict, ...) __printflike(3, 4); -int vfscanf(FILE * __restrict, const char * __restrict, va_list) __scanflike(2, 0); -int vscanf(const char * __restrict, va_list) __scanflike(1, 0); -int vsnprintf(char * __restrict, size_t, const char * __restrict, va_list) __printflike(3, 0); -int vsscanf(const char * __restrict, const char * __restrict, va_list) __scanflike(2, 0); +int snprintf(char * __restrict __str, size_t __size, const char * __restrict __format, ...) __printflike(3, 4); +int vfscanf(FILE * __restrict __stream, const char * __restrict __format, va_list) __scanflike(2, 0); +int vscanf(const char * __restrict __format, va_list) __scanflike(1, 0); +int vsnprintf(char * __restrict __str, size_t __size, const char * __restrict __format, va_list) __printflike(3, 0); +int vsscanf(const char * __restrict __str, const char * __restrict __format, va_list) __scanflike(2, 0); __END_DECLS #endif /* __DARWIN_C_LEVEL >= 200112L || defined(_C99_SOURCE) || defined(__cplusplus) */ @@ -494,16 +496,13 @@ __END_DECLS */ #if __DARWIN_C_LEVEL >= 200809L -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __darwin_ssize_t ssize_t; -#endif +#include __BEGIN_DECLS int dprintf(int, const char * __restrict, ...) __printflike(2, 3) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); int vdprintf(int, const char * __restrict, va_list) __printflike(2, 0) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -ssize_t getdelim(char ** __restrict, size_t * __restrict, int, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +ssize_t getdelim(char ** __restrict __linep, size_t * __restrict __linecapp, int __delimiter, FILE * __restrict __stream) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +ssize_t getline(char ** __restrict __linep, size_t * __restrict __linecapp, FILE * __restrict __stream) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); __END_DECLS #endif /* __DARWIN_C_LEVEL >= 200809L */ @@ -516,14 +515,14 @@ __BEGIN_DECLS extern __const int sys_nerr; /* perror(3) external variables */ extern __const char *__const sys_errlist[]; -int asprintf(char **, const char *, ...) __printflike(2, 3); +int asprintf(char ** __restrict, const char * __restrict, ...) __printflike(2, 3); char *ctermid_r(char *); char *fgetln(FILE *, size_t *); __const char *fmtcheck(const char *, const char *); int fpurge(FILE *); void setbuffer(FILE *, char *, int); int setlinebuf(FILE *); -int vasprintf(char **, const char *, va_list) __printflike(2, 0); +int vasprintf(char ** __restrict, const char * __restrict, va_list) __printflike(2, 0); FILE *zopen(const char *, const char *, int); @@ -531,10 +530,10 @@ FILE *zopen(const char *, const char *, int); * Stdio function-access interface. */ FILE *funopen(const void *, - int (*)(void *, char *, int), - int (*)(void *, const char *, int), - fpos_t (*)(void *, fpos_t, int), - int (*)(void *)); + int (* _Nullable)(void *, char *, int), + int (* _Nullable)(void *, const char *, int), + fpos_t (* _Nullable)(void *, fpos_t, int), + int (* _Nullable)(void *)); __END_DECLS #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) diff --git a/src/libc/include/stdlib.h b/src/libc/include/stdlib.h index e4aa81b43..c04d3a7ed 100644 --- a/src/libc/include/stdlib.h +++ b/src/libc/include/stdlib.h @@ -68,31 +68,16 @@ #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #endif /* !_ANSI_SOURCE */ -#ifndef _SIZE_T -#define _SIZE_T /* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: * _GCC_SIZE_T */ -typedef __darwin_size_t size_t; -#endif +#include #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) -#ifndef _CT_RUNE_T -#define _CT_RUNE_T -typedef __darwin_ct_rune_t ct_rune_t; -#endif - -#ifndef _RUNE_T -#define _RUNE_T -typedef __darwin_rune_t rune_t; -#endif +#include +#include #endif /* !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ -#ifndef __cplusplus -#ifndef _WCHAR_T -#define _WCHAR_T -typedef __darwin_wchar_t wchar_t; -#endif /* _WCHAR_T */ -#endif /* __cplusplus */ +#include typedef struct { int quot; /* quotient */ @@ -111,9 +96,7 @@ typedef struct { } lldiv_t; #endif /* !__DARWIN_NO_LONG_LONG */ -#ifndef NULL -#define NULL __DARWIN_NULL -#endif /* ! NULL */ +#include #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 @@ -141,18 +124,15 @@ extern int __mb_cur_max; #define MB_CUR_MAX_L(x) (___mb_cur_max_l(x)) #endif //Begin-Libc +#include "libc_private.h" /* f must be a literal string */ #define LIBC_ABORT(f,...) abort_report_np("%s:%s:%u: " f, __FILE__, __func__, __LINE__, ## __VA_ARGS__) //End-Libc __BEGIN_DECLS void abort(void) __dead2; -//Begin-Libc -__private_extern__ -void abort_report_np(const char *, ...) __dead2 __printflike(1, 2); -//End-Libc int abs(int) __pure2; -int atexit(void (*)(void)); +int atexit(void (* _Nonnull)(void)); double atof(const char *); int atoi(const char *); long atol(const char *); @@ -160,9 +140,9 @@ long atol(const char *); long long atoll(const char *); #endif /* !__DARWIN_NO_LONG_LONG */ -void *bsearch(const void *, const void *, size_t, - size_t, int (*)(const void *, const void *)); -void *calloc(size_t, size_t); +void *bsearch(const void *__key, const void *__base, size_t __nel, + size_t __width, int (* _Nonnull __compar)(const void *, const void *)); +void *calloc(size_t __count, size_t __size) __result_use_check; div_t div(int, int) __pure2; void exit(int) __dead2; void free(void *); @@ -174,40 +154,53 @@ long long llabs(long long); lldiv_t lldiv(long long, long long); #endif /* !__DARWIN_NO_LONG_LONG */ -void *malloc(size_t); -int mblen(const char *, size_t); +void *malloc(size_t __size) __result_use_check; +int mblen(const char *__s, size_t __n); size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t); int mbtowc(wchar_t * __restrict, const char * __restrict, size_t); -int posix_memalign(void **, size_t, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); -void qsort(void *, size_t, size_t, - int (*)(const void *, const void *)); -int rand(void); -void *realloc(void *, size_t); -void srand(unsigned); +int posix_memalign(void **__memptr, size_t __alignment, size_t __size) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); +void qsort(void *__base, size_t __nel, size_t __width, + int (* _Nonnull __compar)(const void *, const void *)); +int rand(void) __swift_unavailable("Use arc4random instead."); +void *realloc(void *__ptr, size_t __size) __result_use_check; +void srand(unsigned) __swift_unavailable("Use arc4random instead."); double strtod(const char *, char **) __DARWIN_ALIAS(strtod); float strtof(const char *, char **) __DARWIN_ALIAS(strtof); -long strtol(const char *, char **, int); +long strtol(const char *__str, char **__endptr, int __base); long double strtold(const char *, char **); #if !__DARWIN_NO_LONG_LONG long long - strtoll(const char *, char **, int); + strtoll(const char *__str, char **__endptr, int __base); #endif /* !__DARWIN_NO_LONG_LONG */ unsigned long - strtoul(const char *, char **, int); + strtoul(const char *__str, char **__endptr, int __base); #if !__DARWIN_NO_LONG_LONG unsigned long long - strtoull(const char *, char **, int); + strtoull(const char *__str, char **__endptr, int __base); #endif /* !__DARWIN_NO_LONG_LONG */ //Begin-Libc #ifndef LIBC_ALIAS_SYSTEM //End-Libc + +#if TARGET_OS_EMBEDDED +#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(ios_msg) +#else +#define __swift_unavailable_on(osx_msg, ios_msg) __swift_unavailable(osx_msg) +#endif + +__swift_unavailable_on("Use posix_spawn APIs or NSTask instead.", "Process spawning is unavailable") +__OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0,__MAC_NA,__IPHONE_2_0,__IPHONE_8_0, "Use posix_spawn APIs instead.") +__WATCHOS_PROHIBITED __TVOS_PROHIBITED int system(const char *) __DARWIN_ALIAS_C(system); //Begin-Libc #else /* LIBC_ALIAS_SYSTEM */ int system(const char *) LIBC_ALIAS_C(system); #endif /* !LIBC_ALIAS_SYSTEM */ //End-Libc + +#undef __swift_unavailable_on + size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t); int wctomb(char *, wchar_t); @@ -216,7 +209,7 @@ void _Exit(int) __dead2; long a64l(const char *); double drand48(void); char *ecvt(double, int, int *__restrict, int *__restrict); /* LEGACY */ -double erand48(unsigned short[3]); +double erand48(unsigned short[3]); char *fcvt(double, int, int *__restrict, int *__restrict); /* LEGACY */ char *gcvt(double, int, char *); /* LEGACY */ int getsubopt(char **, char * const *, char **); @@ -226,14 +219,14 @@ char *initstate(unsigned, char *, size_t); /* no __DARWIN_ALIAS needed */ #else /* !__DARWIN_UNIX03 */ char *initstate(unsigned long, char *, long); #endif /* __DARWIN_UNIX03 */ -long jrand48(unsigned short[3]); +long jrand48(unsigned short[3]) __swift_unavailable("Use arc4random instead."); char *l64a(long); void lcong48(unsigned short[7]); -long lrand48(void); +long lrand48(void) __swift_unavailable("Use arc4random instead."); char *mktemp(char *); int mkstemp(char *); -long mrand48(void); -long nrand48(unsigned short[3]); +long mrand48(void) __swift_unavailable("Use arc4random instead."); +long nrand48(unsigned short[3]) __swift_unavailable("Use arc4random instead."); int posix_openpt(int); char *ptsname(int); //Begin-Libc @@ -245,8 +238,8 @@ int putenv(char *) __DARWIN_ALIAS(putenv); int putenv(char *) LIBC_ALIAS(putenv); #endif /* !LIBC_ALIAS_PUTENV */ //End-Libc -long random(void); -int rand_r(unsigned *); +long random(void) __swift_unavailable("Use arc4random instead."); +int rand_r(unsigned *) __swift_unavailable("Use arc4random instead."); //Begin-Libc #ifdef __LIBC__ #ifndef LIBC_ALIAS_REALPATH @@ -273,10 +266,10 @@ unsigned short //Begin-Libc #ifndef LIBC_ALIAS_SETENV //End-Libc -int setenv(const char *, const char *, int) __DARWIN_ALIAS(setenv); +int setenv(const char * __name, const char * __value, int __overwrite) __DARWIN_ALIAS(setenv); //Begin-Libc #else /* LIBC_ALIAS_SETENV */ -int setenv(const char *, const char *, int) LIBC_ALIAS(setenv); +int setenv(const char * __name, const char * __value, int __overwrite) LIBC_ALIAS(setenv); #endif /* !LIBC_ALIAS_SETENV */ //End-Libc #if __DARWIN_UNIX03 @@ -318,27 +311,24 @@ void unsetenv(const char *); #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #include -#ifndef _DEV_T -typedef __darwin_dev_t dev_t; -#define _DEV_T -#endif - -#ifndef _MODE_T -typedef __darwin_mode_t mode_t; -#define _MODE_T -#endif +#include +#include +#include <_types/_uint32_t.h> -u_int32_t - arc4random(void); -void arc4random_addrandom(unsigned char * /*dat*/, int /*datlen*/); -void arc4random_buf(void * /*buf*/, size_t /*nbytes*/) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +uint32_t arc4random(void); +void arc4random_addrandom(unsigned char * /*dat*/, int /*datlen*/) + __OSX_DEPRECATED(10.0, 10.12, "use arc4random_stir") + __IOS_DEPRECATED(2.0, 10.0, "use arc4random_stir") + __TVOS_DEPRECATED(2.0, 10.0, "use arc4random_stir") + __WATCHOS_DEPRECATED(1.0, 3.0, "use arc4random_stir"); +void arc4random_buf(void * __buf, size_t __nbytes) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); void arc4random_stir(void); -u_int32_t - arc4random_uniform(u_int32_t /*upper_bound*/) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +uint32_t + arc4random_uniform(uint32_t __upper_bound) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); #ifdef __BLOCKS__ -int atexit_b(void (^)(void)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); -void *bsearch_b(const void *, const void *, size_t, - size_t, int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +int atexit_b(void (^ _Nonnull)(void)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +void *bsearch_b(const void *__key, const void *__base, size_t __nel, + size_t __width, int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ /* getcap(3) functions */ @@ -353,7 +343,7 @@ int cgetset(const char *); int cgetstr(char *, const char *, char **); int cgetustr(char *, const char *, char **); -int daemon(int, int) __DARWIN_1050(daemon) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_5, __IPHONE_2_0, __IPHONE_2_0); +int daemon(int, int) __DARWIN_1050(daemon) __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_0, __MAC_10_5, __IPHONE_2_0, __IPHONE_2_0, "Use posix_spawn APIs instead.") __WATCHOS_PROHIBITED __TVOS_PROHIBITED; char *devname(dev_t, mode_t); char *devname_r(dev_t, mode_t, char *buf, int len); char *getbsize(int *, long *); @@ -361,45 +351,45 @@ int getloadavg(double [], int); const char *getprogname(void); -int heapsort(void *, size_t, size_t, - int (*)(const void *, const void *)); +int heapsort(void *__base, size_t __nel, size_t __width, + int (* _Nonnull __compar)(const void *, const void *)); #ifdef __BLOCKS__ -int heapsort_b(void *, size_t, size_t, - int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +int heapsort_b(void *__base, size_t __nel, size_t __width, + int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ -int mergesort(void *, size_t, size_t, - int (*)(const void *, const void *)); +int mergesort(void *__base, size_t __nel, size_t __width, + int (* _Nonnull __compar)(const void *, const void *)); #ifdef __BLOCKS__ -int mergesort_b(void *, size_t, size_t, - int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +int mergesort_b(void *__base, size_t __nel, size_t __width, + int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ -void psort(void *, size_t, size_t, - int (*)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +void psort(void *__base, size_t __nel, size_t __width, + int (* _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #ifdef __BLOCKS__ -void psort_b(void *, size_t, size_t, - int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +void psort_b(void *__base, size_t __nel, size_t __width, + int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ -void psort_r(void *, size_t, size_t, void *, - int (*)(void *, const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +void psort_r(void *__base, size_t __nel, size_t __width, void *, + int (* _Nonnull __compar)(void *, const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #ifdef __BLOCKS__ -void qsort_b(void *, size_t, size_t, - int (^)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); +void qsort_b(void *__base, size_t __nel, size_t __width, + int (^ _Nonnull __compar)(const void *, const void *)) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); #endif /* __BLOCKS__ */ -void qsort_r(void *, size_t, size_t, void *, - int (*)(void *, const void *, const void *)); -int radixsort(const unsigned char **, int, const unsigned char *, - unsigned); +void qsort_r(void *__base, size_t __nel, size_t __width, void *, + int (* _Nonnull __compar)(void *, const void *, const void *)); +int radixsort(const unsigned char **__base, int __nel, const unsigned char *__table, + unsigned __endbyte); void setprogname(const char *); -int sradixsort(const unsigned char **, int, const unsigned char *, - unsigned); +int sradixsort(const unsigned char **__base, int __nel, const unsigned char *__table, + unsigned __endbyte); void sranddev(void); void srandomdev(void); -void *reallocf(void *, size_t); +void *reallocf(void *__ptr, size_t __size); #if !__DARWIN_NO_LONG_LONG long long - strtoq(const char *, char **, int); + strtoq(const char *__str, char **__endptr, int __base); unsigned long long - strtouq(const char *, char **, int); + strtouq(const char *__str, char **__endptr, int __base); #endif /* !__DARWIN_NO_LONG_LONG */ extern char *suboptarg; /* getsubopt(3) external variable */ void *valloc(size_t); diff --git a/src/libc/include/string.h b/src/libc/include/string.h index f56f38215..93d545c04 100644 --- a/src/libc/include/string.h +++ b/src/libc/include/string.h @@ -59,54 +59,44 @@ #define _STRING_H_ #include <_types.h> - #include #include - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif - -#ifndef NULL -#define NULL __DARWIN_NULL -#endif /* ! NULL */ - - +#include +#include /* ANSI-C */ __BEGIN_DECLS -void *memchr(const void *, int, size_t); -int memcmp(const void *, const void *, size_t); -void *memcpy(void *, const void *, size_t); -void *memmove(void *, const void *, size_t); -void *memset(void *, int, size_t); -char *strcat(char *, const char *); -char *strchr(const char *, int); -int strcmp(const char *, const char *); -int strcoll(const char *, const char *); -char *strcpy(char *, const char *); -size_t strcspn(const char *, const char *); +void *memchr(const void *__s, int __c, size_t __n); +int memcmp(const void *__s1, const void *__s2, size_t __n); +void *memcpy(void *__dst, const void *__src, size_t __n); +void *memmove(void *__dst, const void *__src, size_t __len); +void *memset(void *__b, int __c, size_t __len); +char *strcat(char *__s1, const char *__s2); +char *strchr(const char *__s, int __c); +int strcmp(const char *__s1, const char *__s2); +int strcoll(const char *__s1, const char *__s2); +char *strcpy(char *__dst, const char *__src); +size_t strcspn(const char *__s, const char *__charset); //Begin-Libc #ifndef LIBC_ALIAS_STRERROR //End-Libc -char *strerror(int) __DARWIN_ALIAS(strerror); +char *strerror(int __errnum) __DARWIN_ALIAS(strerror); //Begin-Libc #else /* LIBC_ALIAS_STRERROR */ -char *strerror(int) LIBC_ALIAS(strerror); +char *strerror(int __errnum) LIBC_ALIAS(strerror); #endif /* !LIBC_ALIAS_STRERROR */ //End-Libc -size_t strlen(const char *); -char *strncat(char *, const char *, size_t); -int strncmp(const char *, const char *, size_t); -char *strncpy(char *, const char *, size_t); -char *strpbrk(const char *, const char *); -char *strrchr(const char *, int); -size_t strspn(const char *, const char *); -char *strstr(const char *, const char *); -char *strtok(char *, const char *); -size_t strxfrm(char *, const char *, size_t); +size_t strlen(const char *__s); +char *strncat(char *__s1, const char *__s2, size_t __n); +int strncmp(const char *__s1, const char *__s2, size_t __n); +char *strncpy(char *__dst, const char *__src, size_t __n); +char *strpbrk(const char *__s, const char *__charset); +char *strrchr(const char *__s, int __c); +size_t strspn(const char *__s, const char *__charset); +char *strstr(const char *__big, const char *__little); +char *strtok(char *__str, const char *__sep); +size_t strxfrm(char *__s1, const char *__s2, size_t __n); __END_DECLS @@ -119,7 +109,7 @@ __END_DECLS #if __DARWIN_C_LEVEL >= 199506L __BEGIN_DECLS -char *strtok_r(char *, const char *, char **); +char *strtok_r(char *__str, const char *__sep, char **__lasts); __END_DECLS #endif /* __DARWIN_C_LEVEL >= 199506L */ @@ -131,9 +121,9 @@ __END_DECLS #if __DARWIN_C_LEVEL >= 200112L __BEGIN_DECLS -int strerror_r(int, char *, size_t); -char *strdup(const char *); -void *memccpy(void *, const void *, int, size_t); +int strerror_r(int __errnum, char *__strerrbuf, size_t __buflen); +char *strdup(const char *__s1); +void *memccpy(void *__dst, const void *__src, int __c, size_t __n); __END_DECLS #endif /* __DARWIN_C_LEVEL >= 200112L */ @@ -145,39 +135,51 @@ __END_DECLS #if __DARWIN_C_LEVEL >= 200809L __BEGIN_DECLS -char *stpcpy(char *, const char *); -char *stpncpy(char *, const char *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -char *strndup(const char *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -size_t strnlen(const char *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -char *strsignal(int sig); +char *stpcpy(char *__dst, const char *__src); +char *stpncpy(char *__dst, const char *__src, size_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +char *strndup(const char *__s1, size_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +size_t strnlen(const char *__s1, size_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +char *strsignal(int __sig); __END_DECLS #endif /* __DARWIN_C_LEVEL >= 200809L */ +/* C11 Annex K */ +#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 +#include +#include + +__BEGIN_DECLS +errno_t memset_s(void *__s, rsize_t __smax, int __c, rsize_t __n) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); +__END_DECLS +#endif /* Darwin extensions */ #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __darwin_ssize_t ssize_t; -#endif +#include __BEGIN_DECLS -void *memmem(const void *, size_t, const void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -void memset_pattern4(void *, const void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); -void memset_pattern8(void *, const void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); -void memset_pattern16(void *, const void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); - -char *strcasestr(const char *, const char *); -char *strnstr(const char *, const char *, size_t); -size_t strlcat(char *, const char *, size_t); -size_t strlcpy(char *, const char *, size_t); -void strmode(int, char *); -char *strsep(char **, const char *); +void *memmem(const void *__big, size_t __big_len, const void *__little, size_t __little_len) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); +void memset_pattern4(void *__b, const void *__pattern4, size_t __len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); +void memset_pattern8(void *__b, const void *__pattern8, size_t __len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); +void memset_pattern16(void *__b, const void *__pattern16, size_t __len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_0); + +char *strcasestr(const char *__big, const char *__little); +char *strnstr(const char *__big, const char *__little, size_t __len); +size_t strlcat(char *__dst, const char *__source, size_t __size); +size_t strlcpy(char *__dst, const char *__source, size_t __size); +void strmode(int __mode, char *__bp); +char *strsep(char **__stringp, const char *__delim); /* SUS places swab() in unistd.h. It is listed here for source compatibility */ void swab(const void * __restrict, void * __restrict, ssize_t); + +#ifndef __CUDACC__ +__OSX_AVAILABLE(10.12.1) __IOS_AVAILABLE(10.1) +__TVOS_AVAILABLE(10.0.1) __WATCHOS_AVAILABLE(3.1) +#endif +int timingsafe_bcmp(const void *__b1, const void *__b2, size_t __len); __END_DECLS /* Some functions historically defined in string.h were placed in strings.h diff --git a/src/libc/include/strings.h b/src/libc/include/strings.h index 47308aebf..0c59530a2 100644 --- a/src/libc/include/strings.h +++ b/src/libc/include/strings.h @@ -62,11 +62,7 @@ #include #include - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif +#include __BEGIN_DECLS /* Removed in Issue 7 */ @@ -87,8 +83,10 @@ __END_DECLS #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL __BEGIN_DECLS int ffsl(long) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int ffsll(long long) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); int fls(int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); int flsl(long) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +int flsll(long long) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); __END_DECLS #include diff --git a/src/libc/include/sys/acl.h b/src/libc/include/sys/acl.h index f3b26f635..62240bfc8 100644 --- a/src/libc/include/sys/acl.h +++ b/src/libc/include/sys/acl.h @@ -43,6 +43,7 @@ #define __DARWIN_ACL_READ_SECURITY (1<<11) #define __DARWIN_ACL_WRITE_SECURITY (1<<12) #define __DARWIN_ACL_CHANGE_OWNER (1<<13) +#define __DARWIN_ACL_SYNCHRONIZE (1<<20) #define __DARWIN_ACL_EXTENDED_ALLOW 1 #define __DARWIN_ACL_EXTENDED_DENY 2 @@ -82,6 +83,7 @@ typedef enum { ACL_READ_SECURITY = __DARWIN_ACL_READ_SECURITY, ACL_WRITE_SECURITY = __DARWIN_ACL_WRITE_SECURITY, ACL_CHANGE_OWNER = __DARWIN_ACL_CHANGE_OWNER, + ACL_SYNCHRONIZE = __DARWIN_ACL_SYNCHRONIZE, } acl_perm_t; /* 23.2.5 ACL entry tag type bits - nonstandard */ diff --git a/src/libc/include/sys/cdefs.h b/src/libc/include/sys/cdefs.h index 50e370c19..cf18a9477 100644 --- a/src/libc/include/sys/cdefs.h +++ b/src/libc/include/sys/cdefs.h @@ -89,7 +89,6 @@ /* * symbol versioning macros */ -#ifndef DARLING__DISABLED #define LIBC_ALIAS(sym) __asm("_" __STRING(sym) LIBC_SUF_UNIX03) #define LIBC_ALIAS_C(sym) __asm("_" __STRING(sym) LIBC_SUF_NON_CANCELABLE LIBC_SUF_UNIX03) #define LIBC_ALIAS_I(sym) __asm("_" __STRING(sym) LIBC_SUF_64_BIT_INO_T LIBC_SUF_UNIX03) @@ -104,45 +103,25 @@ #define LIBC_EXTSN(sym) __asm("_" __STRING(sym) LIBC_SUF_EXTSN) #define LIBC_EXTSN_C(sym) __asm("_" __STRING(sym) LIBC_SUF_EXTSN LIBC_SUF_NON_CANCELABLE) -#else // DARLING - -#define LIBC_ALIAS(sym) __asm(__STRING(sym) LIBC_SUF_UNIX03) -#define LIBC_ALIAS_C(sym) __asm(__STRING(sym) LIBC_SUF_NON_CANCELABLE LIBC_SUF_UNIX03) -#define LIBC_ALIAS_I(sym) __asm(__STRING(sym) LIBC_SUF_64_BIT_INO_T LIBC_SUF_UNIX03) -#define LIBC_INODE64(sym) __asm(__STRING(sym) LIBC_SUF_64_BIT_INO_T) - -#define LIBC_1050(sym) __asm(__STRING(sym) LIBC_SUF_1050) -#define LIBC_1050ALIAS(sym) __asm(__STRING(sym) LIBC_SUF_1050 LIBC_SUF_UNIX03) -#define LIBC_1050ALIAS_C(sym) __asm(__STRING(sym) LIBC_SUF_1050 LIBC_SUF_NON_CANCELABLE LIBC_SUF_UNIX03) -#define LIBC_1050ALIAS_I(sym) __asm(__STRING(sym) LIBC_SUF_1050 LIBC_SUF_64_BIT_INO_T LIBC_SUF_UNIX03) -#define LIBC_1050INODE64(sym) __asm(__STRING(sym) LIBC_SUF_1050 LIBC_SUF_64_BIT_INO_T) - -#define LIBC_EXTSN(sym) __asm(__STRING(sym) LIBC_SUF_EXTSN) -#define LIBC_EXTSN_C(sym) __asm(__STRING(sym) LIBC_SUF_EXTSN LIBC_SUF_NON_CANCELABLE) - -#endif // DARLING - -#ifdef __cplusplus -extern "C" { -#endif - -extern int __pthread_tsd_first; extern int pthread_key_init_np(int, void (*)(void *)); -#ifdef __cplusplus -} +#include +#if TARGET_IPHONE_SIMULATOR +/* Simulator keys are offset by 200 */ +#define __LIBC_PTHREAD_KEY(x) (210 + (x)) +#else +#define __LIBC_PTHREAD_KEY(x) (10 + (x)) #endif -#define __LIBC_PTHREAD_KEY(x) (__pthread_tsd_first + (x)) - /* * Libc pthread key assignments */ #define __LIBC_PTHREAD_KEY_XLOCALE __LIBC_PTHREAD_KEY(0) -#define __LIBC_PTHREAD_KEY_TTYNAME __LIBC_PTHREAD_KEY(1) +//#define __LIBC_PTHREAD_KEY_RESERVED_WIN64 __LIBC_PTHREAD_KEY(1) #define __LIBC_PTHREAD_KEY_LOCALTIME __LIBC_PTHREAD_KEY(2) #define __LIBC_PTHREAD_KEY_GMTIME __LIBC_PTHREAD_KEY(3) #define __LIBC_PTHREAD_KEY_GDTOA_BIGINT __LIBC_PTHREAD_KEY(4) #define __LIBC_PTHREAD_KEY_PARSEFLOAT __LIBC_PTHREAD_KEY(5) +#define __LIBC_PTHREAD_KEY_TTYNAME __LIBC_PTHREAD_KEY(6) #endif /* _LIBC_SYS_CDEFS_H_ */ diff --git a/src/libc/include/sys/rbtree.h b/src/libc/include/sys/rbtree.h new file mode 100644 index 000000000..e74b017a4 --- /dev/null +++ b/src/libc/include/sys/rbtree.h @@ -0,0 +1,106 @@ +/* $NetBSD: rbtree.h,v 1.2 2012/02/17 08:20:55 yamt Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Portions Copyright (c) 2012 Apple Inc. All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_RBTREE_H_ +#define _SYS_RBTREE_H_ + +#include + +#include +#include +#include +#include + +__BEGIN_DECLS + + +#define RB_DIR_LEFT 0 +#define RB_DIR_RIGHT 1 + +#define RB_TREE_MIN(T) rb_tree_iterate((T), NULL, RB_DIR_RIGHT) +#define RB_TREE_MAX(T) rb_tree_iterate((T), NULL, RB_DIR_LEFT) +#define RB_TREE_FOREACH(N, T) \ + for ((N) = RB_TREE_MIN(T); (N); \ + (N) = rb_tree_iterate((T), (N), RB_DIR_RIGHT)) +#define RB_TREE_FOREACH_REVERSE(N, T) \ + for ((N) = RB_TREE_MAX(T); (N); \ + (N) = rb_tree_iterate((T), (N), RB_DIR_LEFT)) + +/* + * rbto_compare_nodes_fn: + * return a positive value if the first node > the second node. + * return a negative value if the first node < the second node. + * return 0 if they are considered same. + * + * rbto_compare_key_fn: + * return a positive value if the node > the key. + * return a negative value if the node < the key. + * return 0 if they are considered same. + */ + +typedef signed int (*rbto_compare_nodes_fn)(void *, const void *, const void *); +typedef signed int (*rbto_compare_key_fn)(void *, const void *, const void *); + +typedef struct { + rbto_compare_nodes_fn rbto_compare_nodes; + rbto_compare_key_fn rbto_compare_key; + size_t rbto_node_offset; + void *rbto_context; +} rb_tree_ops_t; + +//Begin-Libc +#ifdef _RBTREE_NO_OPAQUE_STRUCTS_ +typedef struct rb_node rb_node_t; +typedef struct rb_tree rb_tree_t; +#else +//End-Libc +typedef struct rb_node { void * opaque[3]; } rb_node_t; +typedef struct rb_tree { void *opaque[8]; } rb_tree_t; +//Begin-Libc +#endif +//End-Libc + +#define _rb_availability __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); +void rb_tree_init(rb_tree_t *, const rb_tree_ops_t *) _rb_availability; +void * rb_tree_insert_node(rb_tree_t *, void *) _rb_availability; +void * rb_tree_find_node(rb_tree_t *, const void *) _rb_availability; +void * rb_tree_find_node_geq(rb_tree_t *, const void *) _rb_availability; +void * rb_tree_find_node_leq(rb_tree_t *, const void *) _rb_availability; +void rb_tree_remove_node(rb_tree_t *, void *) _rb_availability; +void * rb_tree_iterate(rb_tree_t *, void *, const unsigned int) _rb_availability; +size_t rb_tree_count(rb_tree_t *) _rb_availability; +#undef _rb_availability + +__END_DECLS + +#endif /* _SYS_RBTREE_H_*/ diff --git a/src/libc/include/sys/statvfs.h b/src/libc/include/sys/statvfs.h index 51f37af1e..a8d661a5c 100644 --- a/src/libc/include/sys/statvfs.h +++ b/src/libc/include/sys/statvfs.h @@ -30,15 +30,8 @@ #include #include -#ifndef _FSBLKCNT_T -#define _FSBLKCNT_T -typedef __darwin_fsblkcnt_t fsblkcnt_t; -#endif - -#ifndef _FSFILCNT_T -#define _FSFILCNT_T -typedef __darwin_fsfilcnt_t fsfilcnt_t; -#endif +#include +#include /* Following structure is used as a statvfs/fstatvfs function parameter */ struct statvfs { diff --git a/src/libc/include/termios.h b/src/libc/include/termios.h index 94208a5a5..94f315b58 100644 --- a/src/libc/include/termios.h +++ b/src/libc/include/termios.h @@ -26,11 +26,7 @@ #include #include #include <_types.h> - -#ifndef _PID_T -typedef __darwin_pid_t pid_t; -#define _PID_T -#endif +#include __BEGIN_DECLS pid_t tcgetsid(int); diff --git a/src/libc/include/time.h b/src/libc/include/time.h index 7e42ac552..dedea0b79 100644 --- a/src/libc/include/time.h +++ b/src/libc/include/time.h @@ -1,4 +1,3 @@ -/* Modified for Darling by Lubos Dolezel (2015) */ /* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * @@ -65,29 +64,12 @@ #define _TIME_H_ #include <_types.h> - -#define __need_struct_timespec -//#include <_structs.h> -#include "../../../kernel-include/sys/_structs.h" - -#ifndef NULL -#define NULL __DARWIN_NULL -#endif /* ! NULL */ - -#ifndef _CLOCK_T -#define _CLOCK_T -typedef __darwin_clock_t clock_t; -#endif - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef __darwin_time_t time_t; -#endif +#include +#include +#include +#include +#include +#include struct tm { int tm_sec; /* seconds after the minute [0-60] */ @@ -199,13 +181,62 @@ time_t timegm(struct tm * const); //Begin-Libc #ifndef LIBC_ALIAS_NANOSLEEP //End-Libc -int nanosleep(const struct timespec *, struct timespec *) __DARWIN_ALIAS_C(nanosleep); +int nanosleep(const struct timespec *__rqtp, struct timespec *__rmtp) __DARWIN_ALIAS_C(nanosleep); //Begin-Libc #else /* LIBC_ALIAS_NANOSLEEP */ -int nanosleep(const struct timespec *, struct timespec *) LIBC_ALIAS_C(nanosleep); +int nanosleep(const struct timespec *__rqtp, struct timespec *__rmtp) LIBC_ALIAS_C(nanosleep); #endif /* !LIBC_ALIAS_NANOSLEEP */ //End-Libc #endif + +#if !defined(_DARWIN_FEATURE_CLOCK_GETTIME) || _DARWIN_FEATURE_CLOCK_GETTIME != 0 +#if __DARWIN_C_LEVEL >= 199309L +#if __has_feature(enumerator_attributes) +#define __CLOCK_AVAILABILITY __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +#else +#define __CLOCK_AVAILABILITY +#endif + +typedef enum { +_CLOCK_REALTIME __CLOCK_AVAILABILITY = 0, +#define CLOCK_REALTIME _CLOCK_REALTIME +_CLOCK_MONOTONIC __CLOCK_AVAILABILITY = 6, +#define CLOCK_MONOTONIC _CLOCK_MONOTONIC +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +_CLOCK_MONOTONIC_RAW __CLOCK_AVAILABILITY = 4, +#define CLOCK_MONOTONIC_RAW _CLOCK_MONOTONIC_RAW +_CLOCK_MONOTONIC_RAW_APPROX __CLOCK_AVAILABILITY = 5, +#define CLOCK_MONOTONIC_RAW_APPROX _CLOCK_MONOTONIC_RAW_APPROX +_CLOCK_UPTIME_RAW __CLOCK_AVAILABILITY = 8, +#define CLOCK_UPTIME_RAW _CLOCK_UPTIME_RAW +_CLOCK_UPTIME_RAW_APPROX __CLOCK_AVAILABILITY = 9, +#define CLOCK_UPTIME_RAW_APPROX _CLOCK_UPTIME_RAW_APPROX +#endif +_CLOCK_PROCESS_CPUTIME_ID __CLOCK_AVAILABILITY = 12, +#define CLOCK_PROCESS_CPUTIME_ID _CLOCK_PROCESS_CPUTIME_ID +_CLOCK_THREAD_CPUTIME_ID __CLOCK_AVAILABILITY = 16 +#define CLOCK_THREAD_CPUTIME_ID _CLOCK_THREAD_CPUTIME_ID +} clockid_t; + +__CLOCK_AVAILABILITY +int clock_getres(clockid_t __clock_id, struct timespec *__res); + +__CLOCK_AVAILABILITY +int clock_gettime(clockid_t __clock_id, struct timespec *__tp); + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +__CLOCK_AVAILABILITY +__uint64_t clock_gettime_nsec_np(clockid_t __clock_id); +#endif + +__OSX_AVAILABLE(10.12) __IOS_PROHIBITED +__TVOS_PROHIBITED __WATCHOS_PROHIBITED +int clock_settime(clockid_t __clock_id, const struct timespec *__tp); + +#undef __CLOCK_AVAILABILITY +#endif /* __DARWIN_C_LEVEL */ +#endif /* _DARWIN_FEATURE_CLOCK_GETTIME */ + __END_DECLS #ifdef _USE_EXTENDED_LOCALES_ diff --git a/src/libc/include/unistd.h b/src/libc/include/unistd.h index 3f582dab0..43842478b 100644 --- a/src/libc/include/unistd.h +++ b/src/libc/include/unistd.h @@ -71,52 +71,17 @@ #include <_types.h> #include #include - -#ifndef _GID_T -#define _GID_T -typedef __darwin_gid_t gid_t; -#endif - -#ifndef _INTPTR_T -#define _INTPTR_T -typedef __darwin_intptr_t intptr_t; -#endif - -#ifndef _OFF_T -#define _OFF_T -typedef __darwin_off_t off_t; -#endif - -#ifndef _PID_T -#define _PID_T -typedef __darwin_pid_t pid_t; -#endif - -#ifndef _SIZE_T -#define _SIZE_T +#include +#include +#include +#include /* DO NOT REMOVE THIS COMMENT: fixincludes needs to see: * _GCC_SIZE_T */ -typedef __darwin_size_t size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __darwin_ssize_t ssize_t; -#endif - -#ifndef _UID_T -#define _UID_T -typedef __darwin_uid_t uid_t; /* user id */ -#endif - -#ifndef _USECONDS_T -#define _USECONDS_T -typedef __darwin_useconds_t useconds_t; -#endif - -#ifndef NULL -#define NULL __DARWIN_NULL -#endif /* ! NULL */ +#include +#include +#include +#include +#include #define STDIN_FILENO 0 /* standard input file descriptor */ #define STDOUT_FILENO 1 /* standard output file descriptor */ @@ -396,6 +361,11 @@ typedef __darwin_useconds_t useconds_t; #define _SC_PASS_MAX 131 #endif +/* 132-199 available for future use */ +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL +#define _SC_PHYS_PAGES 200 +#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */ + #if __DARWIN_C_LEVEL >= 199209L #ifndef _CS_PATH /* Defined in */ #define _CS_PATH 1 @@ -475,13 +445,13 @@ int close(int) LIBC_ALIAS_C(close); int dup(int); int dup2(int, int); -int execl(const char *, const char *, ...); -int execle(const char *, const char *, ...); -int execlp(const char *, const char *, ...); -int execv(const char *, char * const *); -int execve(const char *, char * const *, char * const *); -int execvp(const char *, char * const *); -pid_t fork(void); +int execl(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execle(const char * __path, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execlp(const char * __file, const char * __arg0, ...) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execv(const char * __path, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execve(const char * __file, char * const * __argv, char * const * __envp) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int execvp(const char * __file, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +pid_t fork(void) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; long fpathconf(int, int); char *getcwd(char *, size_t); gid_t getegid(void); @@ -566,10 +536,10 @@ int unlink(const char *); //Begin-Libc #ifndef LIBC_ALIAS_WRITE //End-Libc -ssize_t write(int, const void *, size_t) __DARWIN_ALIAS_C(write); +ssize_t write(int __fd, const void * __buf, size_t __nbyte) __DARWIN_ALIAS_C(write); //Begin-Libc #else /* LIBC_ALIAS_WRITE */ -ssize_t write(int, const void *, size_t) LIBC_ALIAS_C(write); +ssize_t write(int __fd, const void * __buf, size_t __nbyte) LIBC_ALIAS_C(write); #endif /* !LIBC_ALIAS_WRITE */ //End-Libc __END_DECLS @@ -627,6 +597,9 @@ __END_DECLS /* Begin XSI */ /* Removed in Issue 6 */ #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L +#if !defined(_POSIX_C_SOURCE) +__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED +#endif void *brk(const void *); int chroot(const char *) __POSIX_C_DEPRECATED(199506L); #endif @@ -700,20 +673,20 @@ int nice(int) LIBC_ALIAS(nice); //Begin-Libc #ifndef LIBC_ALIAS_PREAD //End-Libc -ssize_t pread(int, void *, size_t, off_t) __DARWIN_ALIAS_C(pread); +ssize_t pread(int __fd, void * __buf, size_t __nbyte, off_t __offset) __DARWIN_ALIAS_C(pread); //Begin-Libc #else /* LIBC_ALIAS_PREAD */ -ssize_t pread(int, void *, size_t, off_t) LIBC_ALIAS_C(pread); +ssize_t pread(int __fd, void * __buf, size_t __nbyte, off_t __offset) LIBC_ALIAS_C(pread); #endif /* !LIBC_ALIAS_PREAD */ //End-Libc //Begin-Libc #ifndef LIBC_ALIAS_PWRITE //End-Libc -ssize_t pwrite(int, const void *, size_t, off_t) __DARWIN_ALIAS_C(pwrite); +ssize_t pwrite(int __fd, const void * __buf, size_t __nbyte, off_t __offset) __DARWIN_ALIAS_C(pwrite); //Begin-Libc #else /* LIBC_ALIAS_PWRITE */ -ssize_t pwrite(int, const void *, size_t, off_t) LIBC_ALIAS_C(pwrite); +ssize_t pwrite(int __fd, const void * __buf, size_t __nbyte, off_t __offset) LIBC_ALIAS_C(pwrite); #endif /* !LIBC_ALIAS_PWRITE */ //End-Libc @@ -721,6 +694,9 @@ ssize_t pwrite(int, const void *, size_t, off_t) LIBC_ALIAS_C(pwrite); #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L /* Note that Issue 5 changed the argument as intprt_t, * but we keep it as int for binary compatability. */ +#if !defined(_POSIX_C_SOURCE) +__deprecated __WATCHOS_PROHIBITED __TVOS_PROHIBITED +#endif void *sbrk(int); #endif @@ -771,7 +747,7 @@ int usleep(useconds_t) __DARWIN_ALIAS_C(usleep); int usleep(useconds_t) LIBC_ALIAS_C(usleep); #endif /* !LIBC_ALIAS_USLEEP */ //End-Libc -pid_t vfork(void); +pid_t vfork(void) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; /* End XSI */ //Begin-Libc @@ -814,59 +790,71 @@ __END_DECLS #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL #include -#ifndef _DEV_T -#define _DEV_T -typedef __darwin_dev_t dev_t; -#endif - -#ifndef _MODE_T -#define _MODE_T -typedef __darwin_mode_t mode_t; -#endif - -#ifndef _UUID_T -#define _UUID_T -typedef __darwin_uuid_t uuid_t; -#endif /* _UUID_T */ +#include +#include +#include __BEGIN_DECLS void _Exit(int) __dead2; int accessx_np(const struct accessx_descriptor *, size_t, int *, uid_t); int acct(const char *); -int add_profil(char *, size_t, unsigned long, unsigned int); +int add_profil(char *, size_t, unsigned long, unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; void endusershell(void); -int execvP(const char *, const char *, char * const *); +int execvP(const char * __file, const char * __searchpath, char * const * __argv) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; char *fflagstostr(unsigned long); int getdomainname(char *, int); int getgrouplist(const char *, int, int *, int *); -int gethostuuid(uuid_t, const struct timespec *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); +#if defined(__has_include) +#if __has_include() +#include +#else +#include +#endif +#else +#include +#endif mode_t getmode(const void *, mode_t); int getpeereid(int, uid_t *, gid_t *); int getsgroups_np(int *, uuid_t); char *getusershell(void); int getwgroups_np(int *, uuid_t); int initgroups(const char *, int); -int iruserok(unsigned long, int, const char *, const char *); -int iruserok_sa(const void *, int, int, const char *, const char *); int issetugid(void); char *mkdtemp(char *); int mknod(const char *, mode_t, dev_t); int mkpath_np(const char *path, mode_t omode) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); /* returns errno */ +int mkpathat_np(int dfd, const char *path, mode_t omode) /* returns errno */ + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); int mkstemp(char *); int mkstemps(char *, int); char *mktemp(char *); +int mkostemp(char *path, int oflags) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +int mkostemps(char *path, int slen, int oflags) + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); +/* Non-portable mkstemp that uses open_dprotected_np */ +int mkstemp_dprotected_np(char *path, int dpclass, int dpflags) + __OSX_UNAVAILABLE __IOS_AVAILABLE(10.0) + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0); int nfssvc(int, void *); int profil(char *, size_t, unsigned long, unsigned int); int pthread_setugid_np(uid_t, gid_t); int pthread_getugid_np( uid_t *, gid_t *); -int rcmd(char **, int, const char *, const char *, const char *, int *); -int rcmd_af(char **, int, const char *, const char *, const char *, int *, - int); int reboot(int); int revoke(const char *); -int rresvport(int *); -int rresvport_af(int *, int); -int ruserok(const char *, int, const char *, const char *); + +__deprecated int rcmd(char **, int, const char *, const char *, const char *, int *); +__deprecated int rcmd_af(char **, int, const char *, const char *, const char *, int *, + int); +__deprecated int rresvport(int *); +__deprecated int rresvport_af(int *, int); +__deprecated int iruserok(unsigned long, int, const char *, const char *); +__deprecated int iruserok_sa(const void *, int, int, const char *, const char *); +__deprecated int ruserok(const char *, int, const char *, const char *); + int setdomainname(const char *, int); int setgroups(int, const gid_t *); void sethostid(long); @@ -901,12 +889,18 @@ void setusershell(void); int setwgroups_np(int, const uuid_t); int strtofflags(char **, unsigned long *, unsigned long *); int swapon(const char *); -int syscall(int, ...); int ttyslot(void); int undelete(const char *); int unwhiteout(const char *); void *valloc(size_t); +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +__OS_AVAILABILITY_MSG(ios,deprecated=10.0,"syscall(2) is unsupported; " + "please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().") +__OS_AVAILABILITY_MSG(macosx,deprecated=10.12,"syscall(2) is unsupported; " + "please switch to a supported interface. For SYS_kdebug_trace use kdebug_signpost().") +int syscall(int, ...); + extern char *suboptarg; /* getsubopt(3) external variable */ int getsubopt(char **, char * const *, char **); @@ -932,8 +926,8 @@ int setattrlist(const char*,void*,void*,size_t,unsigned int) __DARWIN_ALIAS(s int setattrlist(const char*,void*,void*,size_t,unsigned int) LIBC_ALIAS(setattrlist); #endif /* !LIBC_ALIAS_SETATTRLIST */ //End-Libc -int exchangedata(const char*,const char*,unsigned int); -int getdirentriesattr(int,void*,void*,size_t,unsigned int*,unsigned int*,unsigned int*,unsigned int); +int exchangedata(const char*,const char*,unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int getdirentriesattr(int,void*,void*,size_t,unsigned int*,unsigned int*,unsigned int*,unsigned int) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; #else /* __LP64__ */ int fgetattrlist(int,void*,void*,size_t,unsigned long) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); @@ -956,15 +950,15 @@ int setattrlist(const char*,void*,void*,size_t,unsigned long) __DARWIN_ALIAS(set int setattrlist(const char*,void*,void*,size_t,unsigned long) LIBC_ALIAS(setattrlist); #endif /* !LIBC_ALIAS_SETATTRLIST */ //End-Libc -int exchangedata(const char*,const char*,unsigned long); -int getdirentriesattr(int,void*,void*,size_t,unsigned long*,unsigned long*,unsigned long*,unsigned long); +int exchangedata(const char*,const char*,unsigned long) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; +int getdirentriesattr(int,void*,void*,size_t,unsigned long*,unsigned long*,unsigned long*,unsigned long) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; #endif /* __LP64__ */ struct fssearchblock; struct searchstate; -int searchfs(const char *, struct fssearchblock *, unsigned long *, unsigned int, unsigned int, struct searchstate *); +int searchfs(const char *, struct fssearchblock *, unsigned long *, unsigned int, unsigned int, struct searchstate *) __WATCHOS_PROHIBITED __TVOS_PROHIBITED; int fsctl(const char *,unsigned long,void*,unsigned int); int ffsctl(int,unsigned long,void*,unsigned int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0); diff --git a/src/libc/include/utime.h b/src/libc/include/utime.h index fb9b3f073..106e49494 100644 --- a/src/libc/include/utime.h +++ b/src/libc/include/utime.h @@ -59,11 +59,7 @@ #define _UTIME_H_ #include <_types.h> - -#ifndef _TIME_T -#define _TIME_T -typedef __darwin_time_t time_t; -#endif /* _TIME_T */ +#include struct utimbuf { time_t actime; /* Access time */ diff --git a/src/libc/include/utmp.h b/src/libc/include/utmp.h index 5a8b8a965..01eb53170 100644 --- a/src/libc/include/utmp.h +++ b/src/libc/include/utmp.h @@ -72,11 +72,7 @@ */ #include <_types.h> - -#ifndef _TIME_T -#define _TIME_T -typedef __darwin_time_t time_t; -#endif +#include /* These files no longer exist in 10.5 and later */ #define _PATH_UTMP "/var/run/utmp" diff --git a/src/libc/include/vis.h b/src/libc/include/vis.h index a6e860480..d0001cc37 100644 --- a/src/libc/include/vis.h +++ b/src/libc/include/vis.h @@ -20,6 +20,9 @@ * * @APPLE_LICENSE_HEADER_END@ */ +/* $NetBSD: vis.h,v 1.21 2013/02/20 17:01:15 christos Exp $ */ +/* $FreeBSD$ */ + /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -32,11 +35,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -59,34 +58,35 @@ #define _VIS_H_ #include <_types.h> - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif +#include /* * to select alternate encoding format */ -#define VIS_OCTAL 0x01 /* use octal \ddd format */ -#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */ +#define VIS_OCTAL 0x0001 /* use octal \ddd format */ +#define VIS_CSTYLE 0x0002 /* use \[nrft0..] where appropiate */ /* * to alter set of characters encoded (default is to encode all * non-graphic except space, tab, and newline). */ -#define VIS_SP 0x04 /* also encode space */ -#define VIS_TAB 0x08 /* also encode tab */ -#define VIS_NL 0x10 /* also encode newline */ +#define VIS_SP 0x0004 /* also encode space */ +#define VIS_TAB 0x0008 /* also encode tab */ +#define VIS_NL 0x0010 /* also encode newline */ #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) -#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ +#define VIS_SAFE 0x0020 /* only encode "unsafe" characters */ /* * other */ -#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ -#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ -#define VIS_GLOB 0x100 /* encode glob(3) magics */ +#define VIS_NOSLASH 0x0040 /* inhibit printing '\' */ +#define VIS_HTTP1808 0x0080 /* http-style escape % hex hex */ +#define VIS_HTTPSTYLE 0x0080 /* http-style escape % hex hex */ +#define VIS_GLOB 0x0100 /* encode glob(3) magic characters */ +#define VIS_MIMESTYLE 0x0200 /* mime-style escape = HEX HEX */ +#define VIS_HTTP1866 0x0400 /* http-style &#num; or &string; */ +#define VIS_NOESCAPE 0x0800 /* don't decode `\' */ +#define _VIS_END 0x1000 /* for unvis */ /* * unvis return codes @@ -100,16 +100,38 @@ typedef __darwin_size_t size_t; /* * unvis flags */ -#define UNVIS_END 1 /* no more characters */ +#define UNVIS_END _VIS_END /* no more characters */ #include __BEGIN_DECLS char *vis(char *, int, int, int); +char *nvis(char *, size_t, int, int, int); + +char *svis(char *, int, int, int, const char *); +char *snvis(char *, size_t, int, int, int, const char *); + int strvis(char *, const char *, int); +int strnvis(char *, size_t, const char *, int); + +int strsvis(char *, const char *, int, const char *); +int strsnvis(char *, size_t, const char *, int, const char *); + int strvisx(char *, const char *, size_t, int); +int strnvisx(char *, size_t, const char *, size_t, int); +int strenvisx(char *, size_t, const char *, size_t, int, int *); + +int strsvisx(char *, const char *, size_t, int, const char *); +int strsnvisx(char *, size_t, const char *, size_t, int, const char *); +int strsenvisx(char *, size_t, const char *, size_t , int, const char *, + int *); + int strunvis(char *, const char *); +int strnunvis(char *, size_t, const char *); + int strunvisx(char *, const char *, int); +int strnunvisx(char *, size_t, const char *, int); + int unvis(char *, int, int *, int); __END_DECLS diff --git a/src/libc/include/wchar.h b/src/libc/include/wchar.h index fdb80ad4e..bd16be11f 100644 --- a/src/libc/include/wchar.h +++ b/src/libc/include/wchar.h @@ -71,36 +71,12 @@ #include #include -#ifndef NULL -#define NULL __DARWIN_NULL -#endif /* ! NULL */ - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif - -#ifndef _MBSTATE_T -#define _MBSTATE_T -typedef __darwin_mbstate_t mbstate_t; -#endif - -#ifndef _CT_RUNE_T -#define _CT_RUNE_T -typedef __darwin_ct_rune_t ct_rune_t; -#endif - -#ifndef _RUNE_T -#define _RUNE_T -typedef __darwin_rune_t rune_t; -#endif - -#ifndef __cplusplus -#ifndef _WCHAR_T -#define _WCHAR_T -typedef __darwin_wchar_t wchar_t; -#endif /* _WCHAR_T */ -#endif /* __cplusplus */ +#include +#include +#include +#include +#include +#include #ifndef WCHAR_MIN #define WCHAR_MIN __DARWIN_WCHAR_MIN diff --git a/src/libc/include/wctype.h b/src/libc/include/wctype.h index 518f4b820..bebb2bf96 100644 --- a/src/libc/include/wctype.h +++ b/src/libc/include/wctype.h @@ -33,22 +33,22 @@ #include #include <_types.h> +#include <_types/_wctrans_t.h> -#ifndef _WCTRANS_T -#define _WCTRANS_T -typedef __darwin_wctrans_t wctrans_t; -#endif - +//Begin-Libc /* * _EXTERNALIZE_WCTYPE_INLINES_TOP_ is defined in locale/iswctype.c to tell us * to generate code for extern versions of all top-level inline functions. */ #ifdef _EXTERNALIZE_WCTYPE_INLINES_TOP_ #define _USE_CTYPE_INLINE_ -#define __DARWIN_WCTYPE_TOP_static_inline +#define __DARWIN_WCTYPE_TOP_inline #else /* !_EXTERNALIZE_WCTYPE_INLINES_TOP_ */ -#define __DARWIN_WCTYPE_TOP_static_inline static __inline +//End-Libc +#define __DARWIN_WCTYPE_TOP_inline __header_inline +//Begin-Libc #endif /* _EXTERNALIZE_WCTYPE_INLINES_TOP_ */ +//End-Libc #include <_wctype.h> #include @@ -59,50 +59,50 @@ typedef __darwin_wctrans_t wctrans_t; #if !defined(_DONT_USE_CTYPE_INLINE_) && \ (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswblank(wint_t _wc) { return (__istype(_wc, _CTYPE_B)); } #if !defined(_ANSI_SOURCE) -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswascii(wint_t _wc) { return ((_wc & ~0x7F) == 0); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswhexnumber(wint_t _wc) { return (__istype(_wc, _CTYPE_X)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswideogram(wint_t _wc) { return (__istype(_wc, _CTYPE_I)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswnumber(wint_t _wc) { return (__istype(_wc, _CTYPE_D)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswphonogram(wint_t _wc) { return (__istype(_wc, _CTYPE_Q)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswrune(wint_t _wc) { return (__istype(_wc, 0xFFFFFFF0L)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswspecial(wint_t _wc) { return (__istype(_wc, _CTYPE_T)); diff --git a/src/libc/include/wordexp.h b/src/libc/include/wordexp.h index 643276c61..705b15c4e 100644 --- a/src/libc/include/wordexp.h +++ b/src/libc/include/wordexp.h @@ -48,11 +48,8 @@ WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. #include #include <_types.h> - -#ifndef _SIZE_T -#define _SIZE_T -typedef __darwin_size_t size_t; -#endif +#include +#include typedef struct { size_t we_wordc; @@ -75,14 +72,14 @@ typedef struct { #define WRDE_BADCHAR 1 #define WRDE_BADVAL 2 #define WRDE_CMDSUB 3 -#define WRDE_NOSPACE 4 -#define WRDE_NOSYS 5 +#define WRDE_NOSPACE 4 +#define WRDE_NOSYS 5 #define WRDE_SYNTAX 6 __BEGIN_DECLS -int wordexp(const char * __restrict, wordexp_t * __restrict, int); -void wordfree(wordexp_t *); +int wordexp(const char * __restrict, wordexp_t * __restrict, int) __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_NA); +void wordfree(wordexp_t *) __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_NA); __END_DECLS #endif /* _WORDEXP_H */ diff --git a/src/libc/include/x86-64/libc-features.h b/src/libc/include/x86-64/libc-features.h deleted file mode 100644 index d5cd72239..000000000 --- a/src/libc/include/x86-64/libc-features.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _LIBC_FEATURES_H_ -#define _LIBC_FEATURES_H_ - -#if !defined(__x86_64__) -#error Mismatched libc-features.h architecture -#endif - -#define UNIFDEF_LEGACY_RUNE_APIS 1 -#define LEGACY_CRT1_ENVIRON 1 -#define UNIFDEF_LEGACY_UTMP_APIS 1 -/* #undef UNIFDEF_MOVE_LOCALTIME */ -/* #undef UNIFDEF_TZDIR_SYMLINK */ -#if __DARWIN_ONLY_VERS_1050 -# error Feature mismatch: __DARWIN_ONLY_VERS_1050 == 1 -#endif /* __DARWIN_ONLY_VERS_1050 */ -#if !__DARWIN_ONLY_UNIX_CONFORMANCE -# error Feature mismatch: __DARWIN_ONLY_UNIX_CONFORMANCE == 0 -#endif /* !__DARWIN_ONLY_UNIX_CONFORMANCE */ -#if __DARWIN_ONLY_64_BIT_INO_T -# error Feature mismatch: __DARWIN_ONLY_64_BIT_INO_T == 1 -#endif /* __DARWIN_ONLY_64_BIT_INO_T */ -#define __APPLE_PR3417676_HACK__ 1 -/* #undef PLOCKSTAT 1 */ -// #define NOTIFY_TZ 1 /* Darling: we don't have libnotify yet */ -/* #undef LIBC_NO_LIBCRASHREPORTERCLIENT */ -/* #undef FEATURE_SMALL_STDIOBUF */ -#define XPRINTF_PERF 1 -#endif // _LIBC_FEATURES_H_ diff --git a/src/libc/include/xlocale/__wctype.h b/src/libc/include/xlocale/__wctype.h index 06e905b09..63a7310f0 100644 --- a/src/libc/include/xlocale/__wctype.h +++ b/src/libc/include/xlocale/__wctype.h @@ -27,85 +27,85 @@ #if !defined(_DONT_USE_CTYPE_INLINE_) && \ (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswalnum_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_A|_CTYPE_D, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswalpha_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_A, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswcntrl_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_C, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswctype_l(wint_t _wc, wctype_t _charclass, locale_t _l) { return (__istype_l(_wc, _charclass, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswdigit_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_D, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswgraph_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_G, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswlower_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_L, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswprint_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_R, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswpunct_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_P, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswspace_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_S, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswupper_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_U, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswxdigit_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_X, _l)); } -__DARWIN_WCTYPE_TOP_static_inline wint_t +__DARWIN_WCTYPE_TOP_inline wint_t towlower_l(wint_t _wc, locale_t _l) { return (__tolower_l(_wc, _l)); } -__DARWIN_WCTYPE_TOP_static_inline wint_t +__DARWIN_WCTYPE_TOP_inline wint_t towupper_l(wint_t _wc, locale_t _l) { return (__toupper_l(_wc, _l)); diff --git a/src/libc/include/xlocale/_ctype.h b/src/libc/include/xlocale/_ctype.h index c4f493c85..3da4cdfa9 100644 --- a/src/libc/include/xlocale/_ctype.h +++ b/src/libc/include/xlocale/_ctype.h @@ -39,11 +39,16 @@ __END_DECLS //Begin-Libc #ifdef __LIBC__ -__DARWIN_CTYPE_static_inline int +__DARWIN_CTYPE_inline int __maskrune_l(__darwin_ct_rune_t _c, unsigned long _f, locale_t _l) { - return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype_l(_c, _l) : - __locale_ptr(_l)->__lc_ctype->_CurrentRuneLocale.__runetype[_c]) & _f; + /* _CurrentRuneLocale.__runetype is __uint32_t + * _f is unsigned long + * ___runetype_l(_c, _l) is unsigned long + * retval is int + */ + return (int)((_c < 0 || _c >= _CACHED_RUNES) ? (__uint32_t)___runetype_l(_c, _l) : + __locale_ptr(_l)->__lc_ctype->_CurrentRuneLocale.__runetype[_c]) & (__uint32_t)_f; } #else /* !__LIBC__ */ //End-Libc @@ -54,28 +59,28 @@ __END_DECLS #endif /* __LIBC__ */ //End-Libc -__DARWIN_CTYPE_static_inline int +__DARWIN_CTYPE_inline int __istype_l(__darwin_ct_rune_t _c, unsigned long _f, locale_t _l) { return !!(isascii(_c) ? (_DefaultRuneLocale.__runetype[_c] & _f) : __maskrune_l(_c, _f, _l)); } -__DARWIN_CTYPE_static_inline __darwin_ct_rune_t +__DARWIN_CTYPE_inline __darwin_ct_rune_t __toupper_l(__darwin_ct_rune_t _c, locale_t _l) { return isascii(_c) ? _DefaultRuneLocale.__mapupper[_c] : ___toupper_l(_c, _l); } -__DARWIN_CTYPE_static_inline __darwin_ct_rune_t +__DARWIN_CTYPE_inline __darwin_ct_rune_t __tolower_l(__darwin_ct_rune_t _c, locale_t _l) { return isascii(_c) ? _DefaultRuneLocale.__maplower[_c] : ___tolower_l(_c, _l); } -__DARWIN_CTYPE_static_inline int +__DARWIN_CTYPE_inline int __wcwidth_l(__darwin_ct_rune_t _c, locale_t _l) { unsigned int _x; @@ -90,127 +95,127 @@ __wcwidth_l(__darwin_ct_rune_t _c, locale_t _l) #ifndef _EXTERNALIZE_CTYPE_INLINES_ -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int digittoint_l(int c, locale_t l) { return (__maskrune_l(c, 0x0F, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isalnum_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_A|_CTYPE_D, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isalpha_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_A, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isblank_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_B, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int iscntrl_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_C, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isdigit_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_D, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isgraph_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_G, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int ishexnumber_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_X, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isideogram_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_I, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int islower_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_L, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isnumber_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_D, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isphonogram_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_Q, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isprint_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_R, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int ispunct_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_P, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isrune_l(int c, locale_t l) { return (__istype_l(c, 0xFFFFFFF0L, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isspace_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_S, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isspecial_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_T, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isupper_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_U, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int isxdigit_l(int c, locale_t l) { return (__istype_l(c, _CTYPE_X, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int tolower_l(int c, locale_t l) { return (__tolower_l(c, l)); } -__DARWIN_CTYPE_TOP_static_inline int +__DARWIN_CTYPE_TOP_inline int toupper_l(int c, locale_t l) { return (__toupper_l(c, l)); diff --git a/src/libc/include/xlocale/_stdio.h b/src/libc/include/xlocale/_stdio.h index 64ff86f02..c48f7632a 100644 --- a/src/libc/include/xlocale/_stdio.h +++ b/src/libc/include/xlocale/_stdio.h @@ -26,50 +26,50 @@ __BEGIN_DECLS -int fprintf_l(FILE * __restrict, locale_t, const char * __restrict, ...) +int fprintf_l(FILE * __restrict, locale_t __restrict, const char * __restrict, ...) __printflike(3, 4); -int fscanf_l(FILE * __restrict, locale_t, const char * __restrict, ...) +int fscanf_l(FILE * __restrict, locale_t __restrict, const char * __restrict, ...) __scanflike(3, 4); -int printf_l(locale_t, const char * __restrict, ...) +int printf_l(locale_t __restrict, const char * __restrict, ...) __printflike(2, 3); -int scanf_l(locale_t, const char * __restrict, ...) +int scanf_l(locale_t __restrict, const char * __restrict, ...) __scanflike(2, 3); -int sprintf_l(char * __restrict, locale_t, const char * __restrict, ...) - __printflike(3, 4); -int sscanf_l(const char * __restrict, locale_t, const char * __restrict, ...) +int sprintf_l(char * __restrict, locale_t __restrict, const char * __restrict, ...) + __printflike(3, 4) __swift_unavailable("Use snprintf_l instead."); +int sscanf_l(const char * __restrict, locale_t __restrict, const char * __restrict, ...) __scanflike(3, 4); -int vfprintf_l(FILE * __restrict, locale_t, const char * __restrict, va_list) +int vfprintf_l(FILE * __restrict, locale_t __restrict, const char * __restrict, va_list) __printflike(3, 0); -int vprintf_l(locale_t, const char * __restrict, va_list) +int vprintf_l(locale_t __restrict, const char * __restrict, va_list) __printflike(2, 0); -int vsprintf_l(char * __restrict, locale_t, const char * __restrict, va_list) - __printflike(3, 0); +int vsprintf_l(char * __restrict, locale_t __restrict, const char * __restrict, va_list) + __printflike(3, 0) __swift_unavailable("Use vsnprintf_l instead."); -#if __DARWIN_C_LEVEL >= 200112L -int snprintf_l(char * __restrict, size_t, locale_t, const char * __restrict, ...) +#if __DARWIN_C_LEVEL >= 200112L || defined(__cplusplus) +int snprintf_l(char * __restrict, size_t, locale_t __restrict, const char * __restrict, ...) __printflike(4, 5); -int vfscanf_l(FILE * __restrict, locale_t, const char * __restrict, va_list) +int vfscanf_l(FILE * __restrict, locale_t __restrict, const char * __restrict, va_list) __scanflike(3, 0); -int vscanf_l(locale_t, const char * __restrict, va_list) +int vscanf_l(locale_t __restrict, const char * __restrict, va_list) __scanflike(2, 0); -int vsnprintf_l(char * __restrict, size_t, locale_t, const char * __restrict, va_list) +int vsnprintf_l(char * __restrict, size_t, locale_t __restrict, const char * __restrict, va_list) __printflike(4, 0); -int vsscanf_l(const char * __restrict, locale_t, const char * __restrict, va_list) +int vsscanf_l(const char * __restrict, locale_t __restrict, const char * __restrict, va_list) __scanflike(3, 0); #endif -#if __DARWIN_C_LEVEL >= 200809L -int dprintf_l(int, locale_t, const char * __restrict, ...) +#if __DARWIN_C_LEVEL >= 200809L || defined(__cplusplus) +int dprintf_l(int, locale_t __restrict, const char * __restrict, ...) __printflike(3, 4) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); -int vdprintf_l(int, locale_t, const char * __restrict, va_list) +int vdprintf_l(int, locale_t __restrict, const char * __restrict, va_list) __printflike(3, 0) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); #endif -#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL -int asprintf_l(char **, locale_t, const char *, ...) +#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL || defined(__cplusplus) +int asprintf_l(char ** __restrict, locale_t __restrict, const char * __restrict, ...) __printflike(3, 4); -int vasprintf_l(char **, locale_t, const char *, va_list) +int vasprintf_l(char ** __restrict, locale_t __restrict, const char * __restrict, va_list) __printflike(3, 0); #endif diff --git a/src/libc/include/xlocale/_wctype.h b/src/libc/include/xlocale/_wctype.h index d22654d94..43cbeaec1 100644 --- a/src/libc/include/xlocale/_wctype.h +++ b/src/libc/include/xlocale/_wctype.h @@ -27,43 +27,43 @@ #if !defined(_DONT_USE_CTYPE_INLINE_) && \ (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswblank_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_B, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswhexnumber_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_X, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswideogram_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_I, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswnumber_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_D, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswphonogram_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_Q, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswrune_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, 0xFFFFFFF0L, _l)); } -__DARWIN_WCTYPE_TOP_static_inline int +__DARWIN_WCTYPE_TOP_inline int iswspecial_l(wint_t _wc, locale_t _l) { return (__istype_l(_wc, _CTYPE_T, _l)); diff --git a/src/libc/locale/FreeBSD/ascii.c b/src/libc/locale/FreeBSD/ascii.c index e2b2b8357..4c910ea72 100644 --- a/src/libc/locale/FreeBSD/ascii.c +++ b/src/libc/locale/FreeBSD/ascii.c @@ -6,6 +6,11 @@ * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,7 +37,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/ascii.c,v 1.1 2008/01/21 23:48:12 ache Exp $"); +__FBSDID("$FreeBSD$"); #include #include @@ -55,7 +60,7 @@ static size_t _ascii_wcrtomb(char * __restrict, wchar_t, static size_t _ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict, locale_t); -__private_extern__ int +int _ascii_init(struct __xlocale_st_runelocale *xrl) { @@ -137,6 +142,7 @@ _ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, nchr = 0; while (len-- > 0 && nms-- > 0) { if (*s & 0x80) { + *src = s; errno = EILSEQ; return ((size_t)-1); } @@ -171,6 +177,7 @@ _ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, nchr = 0; while (len-- > 0 && nwc-- > 0) { if (*s < 0 || *s > 127) { + *src = s; errno = EILSEQ; return ((size_t)-1); } diff --git a/src/libc/locale/FreeBSD/big5.c b/src/libc/locale/FreeBSD/big5.c index 12c88ba28..bb3daf0f8 100644 --- a/src/libc/locale/FreeBSD/big5.c +++ b/src/libc/locale/FreeBSD/big5.c @@ -61,7 +61,7 @@ typedef struct { wchar_t ch; } _BIG5State; -__private_extern__ int +int _BIG5_init(struct __xlocale_st_runelocale *xrl) { diff --git a/src/libc/locale/FreeBSD/collate.c b/src/libc/locale/FreeBSD/collate.c index 268db3f6f..d468783ae 100644 --- a/src/libc/locale/FreeBSD/collate.c +++ b/src/libc/locale/FreeBSD/collate.c @@ -109,12 +109,11 @@ __collate_load_tables(const char *encoding, locale_t loc) /* 'PathLocale' must be already set & checked. */ /* Range checking not needed, encoding has fixed size */ - (void)strcpy(buf, _PathLocale); - (void)strcat(buf, "/"); - (void)strcat(buf, encoding); + (void)strcpy(buf, encoding); (void)strcat(buf, "/LC_COLLATE"); - if ((fp = fopen(buf, "r")) == NULL) + if ((fp = fdopen(__open_path_locale(buf), "r")) == NULL) { return (_LDP_ERROR); + } if (fread(strbuf, sizeof(strbuf), 1, fp) != 1) { saverr = errno; diff --git a/src/libc/locale/FreeBSD/euc.c b/src/libc/locale/FreeBSD/euc.c index 1b60aa3a0..5504b7b0b 100644 --- a/src/libc/locale/FreeBSD/euc.c +++ b/src/libc/locale/FreeBSD/euc.c @@ -76,7 +76,7 @@ _EUC_free_extra(struct __xlocale_st_runelocale *xrl) free(xrl->_CurrentRuneLocale.__variable); } -__private_extern__ int +int _EUC_init(struct __xlocale_st_runelocale *xrl) { _EucInfo *ei; diff --git a/src/libc/locale/FreeBSD/gb18030.c b/src/libc/locale/FreeBSD/gb18030.c index c63d05028..466246587 100644 --- a/src/libc/locale/FreeBSD/gb18030.c +++ b/src/libc/locale/FreeBSD/gb18030.c @@ -54,7 +54,7 @@ typedef struct { u_char bytes[4]; } _GB18030State; -__private_extern__ int +int _GB18030_init(struct __xlocale_st_runelocale *xrl) { @@ -97,7 +97,7 @@ _GB18030_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, } ncopy = MIN(MIN(n, GB18030_MB_CUR_MAX), sizeof(gs->bytes) - gs->count); - memcpy(gs->bytes + gs->count, s, ncopy); + strncpy(gs->bytes + gs->count, s, ncopy); ocount = gs->count; gs->count += ncopy; s = (char *)gs->bytes; diff --git a/src/libc/locale/FreeBSD/gb2312.c b/src/libc/locale/FreeBSD/gb2312.c index a84b1cfea..559ada45e 100644 --- a/src/libc/locale/FreeBSD/gb2312.c +++ b/src/libc/locale/FreeBSD/gb2312.c @@ -49,7 +49,7 @@ typedef struct { u_char bytes[2]; } _GB2312State; -__private_extern__ int +int _GB2312_init(struct __xlocale_st_runelocale *xrl) { @@ -114,7 +114,7 @@ _GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } ncopy = MIN(MIN(n, GB2312_MB_CUR_MAX), sizeof(gs->bytes) - gs->count); - memcpy(gs->bytes + gs->count, s, ncopy); + strncpy(gs->bytes + gs->count, s, ncopy); ocount = gs->count; gs->count += ncopy; s = (char *)gs->bytes; diff --git a/src/libc/locale/FreeBSD/gbk.c b/src/libc/locale/FreeBSD/gbk.c index c38338b13..fb68b6b28 100644 --- a/src/libc/locale/FreeBSD/gbk.c +++ b/src/libc/locale/FreeBSD/gbk.c @@ -54,7 +54,7 @@ typedef struct { wchar_t ch; } _GBKState; -__private_extern__ int +int _GBK_init(struct __xlocale_st_runelocale *xrl) { diff --git a/src/libc/locale/FreeBSD/isspecial.3 b/src/libc/locale/FreeBSD/isspecial.3 index 0a0ab37e2..dc18f3aae 100644 --- a/src/libc/locale/FreeBSD/isspecial.3 +++ b/src/libc/locale/FreeBSD/isspecial.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/locale/isspecial.3,v 1.3 2009/09/04 07:44:58 des Exp $ +.\" $FreeBSD$ .\" .Dd March 30, 2004 .Dt ISSPECIAL 3 @@ -41,6 +41,9 @@ The .Fn isspecial function tests for a special character. +Special characters are locale dependent, and not necessarily consistent between +different locales. +Examples might include fractions and numbers inside circles. .Sh RETURN VALUES The .Fn isspecial diff --git a/src/libc/locale/FreeBSD/ldpart.c b/src/libc/locale/FreeBSD/ldpart.c index 6a08e150f..10172af82 100644 --- a/src/libc/locale/FreeBSD/ldpart.c +++ b/src/libc/locale/FreeBSD/ldpart.c @@ -70,12 +70,10 @@ __part_load_locale(const char *name, /* 'PathLocale' must be already set & checked. */ /* Range checking not needed, 'name' size is limited */ - strcpy(filename, _PathLocale); - strcat(filename, "/"); - strcat(filename, name); + strcpy(filename, name); strcat(filename, "/"); strcat(filename, category_filename); - if ((fd = _open(filename, O_RDONLY)) < 0) + if ((fd = __open_path_locale(filename)) < 0) return (_LDP_ERROR); if (_fstat(fd, &st) != 0) goto bad_locale; diff --git a/src/libc/locale/FreeBSD/localeconv.c b/src/libc/locale/FreeBSD/localeconv.c index 11afdb51d..bad6ae89f 100644 --- a/src/libc/locale/FreeBSD/localeconv.c +++ b/src/libc/locale/FreeBSD/localeconv.c @@ -115,8 +115,6 @@ __setonlyClocaleconv(int val) struct lconv * localeconv_l(locale_t loc) { - struct lconv *lc; - NORMALIZE_LOCALE(loc); if (loc->__mlocale_changed) { diff --git a/src/libc/locale/FreeBSD/mblocal.h b/src/libc/locale/FreeBSD/mblocal.h index f5d3fc19a..8029a7011 100644 --- a/src/libc/locale/FreeBSD/mblocal.h +++ b/src/libc/locale/FreeBSD/mblocal.h @@ -34,26 +34,26 @@ /* * Rune initialization function prototypes. */ -__private_extern__ int _none_init(struct __xlocale_st_runelocale *); -__private_extern__ int _ascii_init(struct __xlocale_st_runelocale *); -__private_extern__ int _UTF2_init(struct __xlocale_st_runelocale *); -__private_extern__ int _UTF8_init(struct __xlocale_st_runelocale *); -__private_extern__ int _EUC_init(struct __xlocale_st_runelocale *); -__private_extern__ int _GB18030_init(struct __xlocale_st_runelocale *); -__private_extern__ int _GB2312_init(struct __xlocale_st_runelocale *); -__private_extern__ int _GBK_init(struct __xlocale_st_runelocale *); -__private_extern__ int _BIG5_init(struct __xlocale_st_runelocale *); -__private_extern__ int _MSKanji_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _none_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _ascii_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _UTF2_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _UTF8_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _EUC_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _GB18030_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _GB2312_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _GBK_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _BIG5_init(struct __xlocale_st_runelocale *); +__attribute__((visibility("hidden"))) int _MSKanji_init(struct __xlocale_st_runelocale *); -__private_extern__ size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, +__attribute__((visibility("hidden"))) size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict, locale_t); -__private_extern__ int _none_mbsinit(const mbstate_t *, locale_t); -__private_extern__ size_t _none_mbsnrtowcs(wchar_t * __restrict dst, +__attribute__((visibility("hidden"))) int _none_mbsinit(const mbstate_t *, locale_t); +__attribute__((visibility("hidden"))) size_t _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps __unused, locale_t); -__private_extern__ size_t _none_wcrtomb(char * __restrict, wchar_t, +__attribute__((visibility("hidden"))) size_t _none_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict, locale_t); -__private_extern__ size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, +__attribute__((visibility("hidden"))) size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict, locale_t); extern size_t __mbsnrtowcs_std(wchar_t * __restrict, const char ** __restrict, diff --git a/src/libc/locale/FreeBSD/mbtowc.c b/src/libc/locale/FreeBSD/mbtowc.c index 5f7d57fd4..aeb75b7be 100644 --- a/src/libc/locale/FreeBSD/mbtowc.c +++ b/src/libc/locale/FreeBSD/mbtowc.c @@ -43,7 +43,7 @@ mbtowc_l(wchar_t * __restrict pwc, const char * __restrict s, size_t n, NORMALIZE_LOCALE(loc); if (s == NULL) { /* No support for state dependent encodings. */ - // loc->__mbs_mbtowc = initial; + loc->__mbs_mbtowc = initial; return (0); } rval = loc->__lc_ctype->__mbrtowc(pwc, s, n, &loc->__mbs_mbtowc, loc); diff --git a/src/libc/locale/FreeBSD/mskanji.c b/src/libc/locale/FreeBSD/mskanji.c index 3bf9a4d66..0b854f3b7 100644 --- a/src/libc/locale/FreeBSD/mskanji.c +++ b/src/libc/locale/FreeBSD/mskanji.c @@ -59,7 +59,7 @@ typedef struct { wchar_t ch; } _MSKanjiState; -__private_extern__ int +int _MSKanji_init(struct __xlocale_st_runelocale *xrl) { diff --git a/src/libc/locale/FreeBSD/none.c b/src/libc/locale/FreeBSD/none.c index c3c75cf6a..b6a346dc3 100644 --- a/src/libc/locale/FreeBSD/none.c +++ b/src/libc/locale/FreeBSD/none.c @@ -1,4 +1,6 @@ /*- + * Copyright 2013 Garrett D'Amore + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. @@ -6,6 +8,11 @@ * This code is derived from software contributed to Berkeley by * Paul Borman at Krystal Technologies. * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -35,7 +42,7 @@ static char sccsid[] = "@(#)none.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.15 2007/10/13 16:28:22 ache Exp $"); +__FBSDID("$FreeBSD$"); #include "xlocale_private.h" @@ -54,7 +61,7 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.15 2007/10/13 16:28:22 ache E int __mb_cur_max = 1; int __mb_sb_limit = 256; /* Expected to be <= _CACHED_RUNES */ -__private_extern__ int +int _none_init(struct __xlocale_st_runelocale *xrl) { @@ -68,7 +75,7 @@ _none_init(struct __xlocale_st_runelocale *xrl) return(0); } -__private_extern__ int +int _none_mbsinit(const mbstate_t *ps __unused, locale_t loc __unused) { @@ -79,7 +86,7 @@ _none_mbsinit(const mbstate_t *ps __unused, locale_t loc __unused) return (1); } -__private_extern__ size_t +size_t _none_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, mbstate_t * __restrict ps __unused, locale_t loc __unused) { @@ -95,7 +102,7 @@ _none_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, return (*s == '\0' ? 0 : 1); } -__private_extern__ size_t +size_t _none_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps __unused, locale_t loc __unused) { @@ -111,7 +118,7 @@ _none_wcrtomb(char * __restrict s, wchar_t wc, return (1); } -__private_extern__ size_t +size_t _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t nms, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) { @@ -136,7 +143,7 @@ _none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, return (nchr); } -__private_extern__ size_t +size_t _none_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, size_t len, mbstate_t * __restrict ps __unused, locale_t loc __unused) { @@ -157,6 +164,7 @@ _none_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, nchr = 0; while (len-- > 0 && nwc-- > 0) { if (*s < 0 || *s > UCHAR_MAX) { + *src = s; errno = EILSEQ; return ((size_t)-1); } diff --git a/src/libc/locale/FreeBSD/setlocale.3 b/src/libc/locale/FreeBSD/setlocale.3 index 6d3be0354..8c263b9c3 100644 --- a/src/libc/locale/FreeBSD/setlocale.3 +++ b/src/libc/locale/FreeBSD/setlocale.3 @@ -29,7 +29,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)setlocale.3 8.1 (Berkeley) 6/9/93 -.\" $FreeBSD: src/lib/libc/locale/setlocale.3,v 1.35 2007/01/09 00:28:00 imp Exp $ +.\" $FreeBSD$ .\" .Dd November 21, 2003 .Dt SETLOCALE 3 @@ -60,7 +60,6 @@ The .Fn setlocale function recognizes several categories of routines. These are the categories and the sets of routines they select: -.Pp .Bl -tag -width LC_MONETARY .It Dv LC_ALL Set the entire locale generically. @@ -106,21 +105,25 @@ function. .Pp Only three locales are defined by default: the empty string -.Li "\&""\|"" +.Li \&"\|" (which denotes the native environment) and the -.Li "\&""C"" +.Li \&"C" and -.Li "\&""POSIX"" -locales (which denote the C-language environment). +.Li \&"POSIX" +locales (which denote the C language environment). A .Fa locale argument of .Dv NULL causes .Fn setlocale -to return the current locale. +to return the current locale. An argument of +.Li \&"\|" +will determine the name of the new locale taking into account the environment +variables LANG and LC_*. If these environment variables yield a locale that is +invalid, NULL will be returned and the current locale will remain unchanged. By default, C programs start in the -.Li "\&""C"" +.Li \&"C" locale. The only function in the library that sets the locale is .Fn setlocale ; @@ -150,6 +153,11 @@ locale file for the locale .Em locale and the category .Em category . +.It Pa /usr/local/share/locale/ Ns Em locale/category +locale file for the locale +.Em locale +and the category +.Em category . .El .Sh ERRORS No errors are defined. diff --git a/src/libc/locale/FreeBSD/setlocale.c b/src/libc/locale/FreeBSD/setlocale.c index 9729e5442..11b259e97 100644 --- a/src/libc/locale/FreeBSD/setlocale.c +++ b/src/libc/locale/FreeBSD/setlocale.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.51 2007/01/09 00:28:00 i #include #include #include +#include #include "collate.h" #include "lmonetary.h" /* for __monetary_load_locale() */ #include "lnumeric.h" /* for __numeric_load_locale() */ @@ -59,7 +60,7 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.51 2007/01/09 00:28:00 i /* * Category names for getenv() */ -static char *categories[_LC_LAST] = { +static const char * const categories[_LC_LAST] = { "LC_ALL", "LC_COLLATE", "LC_CTYPE", @@ -93,8 +94,6 @@ char *_PathLocale; static char new_categories[_LC_LAST][ENCODING_LEN + 1]; static char saved_categories[_LC_LAST][ENCODING_LEN + 1]; -static char current_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)]; - static char *currentlocale(void); static char *loadlocale(int); __private_extern__ const char *__get_locale_env(int); @@ -226,7 +225,17 @@ currentlocale() { int i; - (void)strcpy(current_locale_string, current_categories[1]); + size_t bufsiz = _LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1); + static char *current_locale_string = NULL; + + if (current_locale_string == NULL) { + current_locale_string = malloc(bufsiz); + if (current_locale_string == NULL) { + return NULL; + } + } + + (void)strlcpy(current_locale_string, current_categories[1], bufsiz); for (i = 2; i < _LC_LAST; ++i) if (strcmp(current_categories[1], current_categories[i])) { @@ -354,3 +363,31 @@ __detect_path_locale(void) return (0); } +__private_extern__ int +__open_path_locale(const char *subpath) +{ + char filename[PATH_MAX]; + int fd; + + strcpy(filename, _PathLocale); + strcat(filename, "/"); + strcat(filename, subpath); + fd = _open(filename, O_RDONLY); + if (fd >= 0) { + return fd; + } + + strcpy(filename, _PATH_LOCALE); + strcat(filename, "/"); + strcat(filename, subpath); + fd = _open(filename, O_RDONLY); + if (fd >= 0) { + return fd; + } + + strcpy(filename, "/usr/local/share/locale"); + strcat(filename, "/"); + strcat(filename, subpath); + return _open(filename, O_RDONLY); +} + diff --git a/src/libc/locale/FreeBSD/setlocale.h b/src/libc/locale/FreeBSD/setlocale.h index b21f6f71a..fd002f267 100644 --- a/src/libc/locale/FreeBSD/setlocale.h +++ b/src/libc/locale/FreeBSD/setlocale.h @@ -38,5 +38,6 @@ extern char *_PathLocale; int __detect_path_locale(void); int __wrap_setrunelocale(const char *, locale_t); +int __open_path_locale(const char *); #endif /* !_SETLOCALE_H_ */ diff --git a/src/libc/locale/FreeBSD/setrunelocale.c b/src/libc/locale/FreeBSD/setrunelocale.c index fbb227534..213a62b9d 100644 --- a/src/libc/locale/FreeBSD/setrunelocale.c +++ b/src/libc/locale/FreeBSD/setrunelocale.c @@ -107,12 +107,10 @@ __setrunelocale(const char *encoding, locale_t loc) */ /* Range checking not needed, encoding length already checked before */ - (void) strcpy(name, _PathLocale); - (void) strcat(name, "/"); - (void) strcat(name, encoding); + (void) strcpy(name, encoding); (void) strcat(name, "/LC_CTYPE"); - if ((fp = fopen(name, "r")) == NULL) + if ((fp = fdopen(__open_path_locale(name), "r")) == NULL) return (errno == 0 ? ENOENT : errno); if ((xrl = _Read_RuneMagi(fp)) == NULL) { diff --git a/src/libc/locale/FreeBSD/table.c b/src/libc/locale/FreeBSD/table.c index 667b84628..747b6047d 100644 --- a/src/libc/locale/FreeBSD/table.c +++ b/src/libc/locale/FreeBSD/table.c @@ -248,7 +248,7 @@ _RuneLocale _DefaultRuneLocale __attribute__((section("__DATA,__constrw"))) = { }, }; -__private_extern__ struct __xlocale_st_runelocale _DefaultRuneXLocale __attribute__((section("__DATA,__constrw"))) = { +struct __xlocale_st_runelocale _DefaultRuneXLocale __attribute__((section("__DATA,__constrw"))) = { 0, XPERMANENT, "C", diff --git a/src/libc/locale/FreeBSD/utf2.c b/src/libc/locale/FreeBSD/utf2.c index d611aa8d8..006b32ff3 100644 --- a/src/libc/locale/FreeBSD/utf2.c +++ b/src/libc/locale/FreeBSD/utf2.c @@ -58,7 +58,7 @@ typedef struct { wchar_t lbound; } _UTF2State; -__private_extern__ int +int _UTF2_init(struct __xlocale_st_runelocale *xrl) { diff --git a/src/libc/locale/FreeBSD/utf8.c b/src/libc/locale/FreeBSD/utf8.c index 97515df86..100573eed 100644 --- a/src/libc/locale/FreeBSD/utf8.c +++ b/src/libc/locale/FreeBSD/utf8.c @@ -37,7 +37,44 @@ __FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.16 2007/10/15 09:51:30 ache E #include #include "mblocal.h" -#define UTF8_MB_CUR_MAX 6 +/* + * 10952550: detect ill-formed UTF-8 + * Unicode 6.0, section D92, mandates specific byte sequences for well- + * formed UTF-8. UTF-8 sequences are now limited to 4 bytes, while the + * FreeBSD code originally handled up to 6. Illegal surrogate code point + * sequences are now detected. And while "non-shortest forms" were detected, + * this only happened after completing the sequence. Now, all ill-formed + * sequences are detected at the earliest point. + * + * Table 3-7. Well-Formed UTF-8 Byte Sequences + * + * Code Points 1st 2nd 3rd 4th Byte + * U+0000..U+007F 00..7F + * U+0080..U+07FF C2..DF 80..BF + * U+0800..U+0FFF E0 A0..BF 80..BF + * U+1000..U+CFFF E1..EC 80..BF 80..BF + * U+D000..U+D7FF ED 80..9F 80..BF + * U+E000..U+FFFF EE..EF 80..BF 80..BF + * U+10000..U+3FFFF F0 90..BF 80..BF 80..BF + * U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF + * U+100000..U+10FFFF F4 80..8F 80..BF 80..BF + * + * Note that while any 3rd and 4th byte can be in the range 80..BF, the + * second byte is often limited to a smaller range. + */ + +typedef struct { + unsigned char lowerbound; + unsigned char upperbound; +} SecondByte; +static SecondByte sb_00_00 = {0x00, 0x00}; +static SecondByte sb_80_8F = {0x80, 0x8F}; +static SecondByte sb_80_9F = {0x80, 0x9F}; +static SecondByte sb_80_BF = {0x80, 0xBF}; +static SecondByte sb_90_BF = {0x90, 0xBF}; +static SecondByte sb_A0_BF = {0xA0, 0xBF}; + +#define UTF8_MB_CUR_MAX 4 static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict, locale_t); @@ -53,10 +90,10 @@ static size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, typedef struct { wchar_t ch; int want; - wchar_t lbound; + SecondByte sb; } _UTF8State; -__private_extern__ int +int _UTF8_init(struct __xlocale_st_runelocale *xrl) { @@ -89,11 +126,12 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, { _UTF8State *us; int ch, i, mask, want; - wchar_t lbound, wch; + wchar_t wch; + SecondByte sb; us = (_UTF8State *)ps; - if (us->want < 0 || us->want > 6) { + if (us->want < 0 || us->want > UTF8_MB_CUR_MAX) { errno = EINVAL; return ((size_t)-1); } @@ -122,38 +160,50 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, * interesting bits of the first octet. We already know * the character is at least two bytes long. * - * We also specify a lower bound for the character code to - * detect redundant, non-"shortest form" encodings. For - * example, the sequence C0 80 is _not_ a legal representation - * of the null character. This enforces a 1-to-1 mapping - * between character codes and their multibyte representations. + * We detect if the first byte is illegal, and set sb to + * the legal range of the second byte. */ ch = (unsigned char)*s; if ((ch & 0x80) == 0) { mask = 0x7f; want = 1; - lbound = 0; + sb = sb_00_00; } else if ((ch & 0xe0) == 0xc0) { + if (ch < 0xc2) goto malformed; mask = 0x1f; want = 2; - lbound = 0x80; + sb = sb_80_BF; } else if ((ch & 0xf0) == 0xe0) { mask = 0x0f; want = 3; - lbound = 0x800; + switch (ch) { + case 0xe0: + sb = sb_A0_BF; + break; + case 0xed: + sb = sb_80_9F; + break; + default: + sb = sb_80_BF; + break; + } } else if ((ch & 0xf8) == 0xf0) { + if (ch > 0xf4) goto malformed; mask = 0x07; want = 4; - lbound = 0x10000; - } else if ((ch & 0xfc) == 0xf8) { - mask = 0x03; - want = 5; - lbound = 0x200000; - } else if ((ch & 0xfe) == 0xfc) { - mask = 0x01; - want = 6; - lbound = 0x4000000; + switch (ch) { + case 0xf0: + sb = sb_90_BF; + break; + case 0xf4: + sb = sb_80_8F; + break; + default: + sb = sb_80_BF; + break; + } } else { +malformed: /* * Malformed input; input is not UTF-8. */ @@ -162,7 +212,7 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, } } else { want = us->want; - lbound = us->lbound; + sb = us->sb; } /* @@ -174,31 +224,21 @@ _UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, else wch = us->ch; for (i = (us->want == 0) ? 1 : 0; i < MIN(want, n); i++) { - if ((*s & 0xc0) != 0x80) { - /* - * Malformed input; bad characters in the middle - * of a character. - */ - errno = EILSEQ; - return ((size_t)-1); - } + if (sb.lowerbound) { + if ((unsigned char)*s < sb.lowerbound || + (unsigned char)*s > sb.upperbound) goto malformed; + sb = sb_00_00; + } else if ((*s & 0xc0) != 0x80) goto malformed; wch <<= 6; wch |= *s++ & 0x3f; } if (i < want) { /* Incomplete multibyte sequence. */ us->want = want - i; - us->lbound = lbound; + us->sb = sb; us->ch = wch; return ((size_t)-2); } - if (wch < lbound) { - /* - * Malformed input; redundant encoding. - */ - errno = EILSEQ; - return ((size_t)-1); - } if (pwc != NULL) *pwc = wch; us->want = 0; @@ -324,18 +364,15 @@ _UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps, locale lead = 0xc0; len = 2; } else if ((wc & ~0xffff) == 0) { + if (wc >= 0xd800 && wc <= 0xdfff) goto illegal; lead = 0xe0; len = 3; } else if ((wc & ~0x1fffff) == 0) { + if (wc > 0x10ffff) goto illegal; lead = 0xf0; len = 4; - } else if ((wc & ~0x3ffffff) == 0) { - lead = 0xf8; - len = 5; - } else if ((wc & ~0x7fffffff) == 0) { - lead = 0xfc; - len = 6; } else { +illegal: errno = EILSEQ; return ((size_t)-1); } diff --git a/src/libc/locale/rune.3 b/src/libc/locale/rune.3 index 2d5ddb72d..c34654eaf 100644 --- a/src/libc/locale/rune.3 +++ b/src/libc/locale/rune.3 @@ -263,6 +263,9 @@ as a multibyte string. .It Pa /usr/share/locale/ Ns Em locale Ns /LC_CTYPE binary LC_CTYPE file for the locale .Em locale . +.It Pa /usr/local/share/locale/ Ns Em locale Ns /LC_CTYPE +binary LC_CTYPE file for the locale +.Em locale . .El .Sh SEE ALSO .Xr mbrune 3 , diff --git a/src/libc/locale/runedepreciated.c b/src/libc/locale/runedepreciated.c index 8457252b3..85bc78d75 100644 --- a/src/libc/locale/runedepreciated.c +++ b/src/libc/locale/runedepreciated.c @@ -76,7 +76,7 @@ __sputrune(rune_t rune, char *string, size_t n, char **result) char buf[MB_CUR_MAX]; size_t converted = wcrtomb(buf, rune, NULL); - if (converted < 0) { + if (converted == (size_t)-1) { if (result) *result = string; } else if (n >= converted) { @@ -86,7 +86,7 @@ __sputrune(rune_t rune, char *string, size_t n, char **result) *result = string + converted; } else if (result) *result = NULL; - return (converted < 0 ? 0 : converted); + return (converted == (size_t)-1 ? 0 : converted); } __private_extern__ rune_t diff --git a/src/libc/locale/xlocale.c b/src/libc/locale/xlocale.c index 93bdb9670..1e1c443d8 100644 --- a/src/libc/locale/xlocale.c +++ b/src/libc/locale/xlocale.c @@ -42,8 +42,8 @@ static char C[] = "C"; static struct _xlocale __c_locale = C_LOCALE_INITIALIZER; const locale_t _c_locale = (const locale_t)&__c_locale; -__private_extern__ struct _xlocale __global_locale = C_LOCALE_INITIALIZER; -__private_extern__ pthread_key_t __locale_key = (pthread_key_t)-1; +struct _xlocale __global_locale = C_LOCALE_INITIALIZER; +pthread_key_t __locale_key = (pthread_key_t)-1; extern int __collate_load_tables(const char *, locale_t); extern int __detect_path_locale(void); @@ -391,10 +391,7 @@ querylocale(int mask, locale_t loc) errno = EINVAL; return NULL; } - if (loc == NULL) - loc = __current_locale(); - else if (loc == LC_GLOBAL_LOCALE) - loc = &__global_locale; + DEFAULT_CURRENT_LOCALE(loc); m = ffs(mask); if (m == 0 || m > _LC_NUM_MASK) { errno = EINVAL; @@ -483,18 +480,13 @@ ___mb_cur_max_l(locale_t loc) static void __xlocale_release(void *loc) { - XL_RELEASE((locale_t)loc); + locale_t l = loc; + XL_RELEASE(l); } /* * Called from the Libc initializer to setup the thread-specific key. */ -/* - * Partition _pthread_keys in a lower part that dyld can use, and an upper - * part for libSystem. The libSystem part starts at __pthread_tsd_first = 10. - * dyld will set this value to 1. - */ - __private_extern__ void __xlocale_init(void) { diff --git a/src/libc/locale/xlocale_private.h b/src/libc/locale/xlocale_private.h index 9ffc10f47..2301aa0ff 100644 --- a/src/libc/locale/xlocale_private.h +++ b/src/libc/locale/xlocale_private.h @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2005, 2008 Apple Inc. All rights reserved. * @@ -42,14 +41,13 @@ #include "lmonetary.h" #include "lnumeric.h" #include "timelocal.h" +#include #undef MB_CUR_MAX #define MB_CUR_MAX (__current_locale()->__lc_ctype->__mb_cur_max) #undef MB_CUR_MAX_L #define MB_CUR_MAX_L(x) ((x)->__lc_ctype->__mb_cur_max) -extern int __is_threaded; - typedef void (*__free_extra_t)(void *); #define XPERMANENT ((__free_extra_t)-1) @@ -164,6 +162,13 @@ struct _xlocale { struct lconv __lc_localeconv; }; +#define DEFAULT_CURRENT_LOCALE(x) \ + if ((x) == NULL) { \ + (x) = __current_locale(); \ + } else if ((x) == LC_GLOBAL_LOCALE) { \ + (x) = &__global_locale; \ + } + #define NORMALIZE_LOCALE(x) if ((x) == NULL) { \ (x) = _c_locale; \ } else if ((x) == LC_GLOBAL_LOCALE) { \ @@ -175,13 +180,19 @@ struct _xlocale { if ((x)->__free_extra) \ (*(x)->__free_extra)((x)); \ free((x)); \ + (x) = NULL; \ } #define XL_RETAIN(x) if ((x) && (x)->__free_extra != XPERMANENT) { OSAtomicIncrement32Barrier(&(x)->__refcount); } #define XL_UNLOCK(x) UNLOCK((x)->__lock); -__private_extern__ struct __xlocale_st_runelocale _DefaultRuneXLocale; -__private_extern__ struct _xlocale __global_locale; -__private_extern__ pthread_key_t __locale_key; +__attribute__((visibility("hidden"))) +extern struct __xlocale_st_runelocale _DefaultRuneXLocale; + +__attribute__((visibility("hidden"))) +extern struct _xlocale __global_locale; + +__attribute__((visibility("hidden"))) +extern pthread_key_t __locale_key; __BEGIN_DECLS @@ -192,7 +203,15 @@ void __xlocale_init(void); static inline __attribute__((always_inline)) locale_t __current_locale(void) { - if (__locale_key == ~0) return &__global_locale; +#if TARGET_IPHONE_SIMULATOR + /* Crash in _objc_inform for duplicate class name during simulator launch + * TODO: Remove after the simulator's libSystem is initialized properly. + */ + if (__locale_key == (pthread_key_t)-1) { + return &__global_locale; + } +#endif + locale_t __locale = (locale_t)pthread_getspecific(__locale_key); return (__locale ? __locale : &__global_locale); } diff --git a/src/libc/man/FreeBSD/environ.7 b/src/libc/man/FreeBSD/environ.7 new file mode 100644 index 000000000..901f7eb58 --- /dev/null +++ b/src/libc/man/FreeBSD/environ.7 @@ -0,0 +1,291 @@ +.\" Copyright (c) 1983, 1990, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)environ.7 8.3 (Berkeley) 4/19/94 +.\" $FreeBSD$ +.\" +.Dd April 12, 2003 +.Dt ENVIRON 7 +.Os +.Sh NAME +.Nm environ +.Nd user environment +.Sh SYNOPSIS +.Ar extern char **environ ; +.Sh DESCRIPTION +An array of strings called the +.Ar environment +is made available by +.Xr execve 2 +when a process begins. +By convention these strings have the form +.Dq Ar name=value . +The following names are used by various commands: +.Bl -tag -width LC_MONETARY +.It Ev BLOCKSIZE +The size of the block units used by several commands, most notably +.Xr df 1 , +.Xr du 1 +and +.Xr ls 1 . +This variable is processed by the +.Xr getbsize 3 +function. +.It Ev COLUMNS +The user's preferred width in column positions for the terminal. +Utilities such as +.Xr ls 1 +and +.Xr who 1 +use this to format output into columns. +If unset or empty, utilities will use an +.Xr ioctl 2 +call to ask the terminal driver for the width. +.It Ev EDITOR +Default editor name. +.It Ev EXINIT +A startup list of commands read by +.Xr ex 1 +and +.Xr vi 1 . +.It Ev HOME +A user's login directory, set by +.Xr login 1 +from the password file +.Xr passwd 5 . +.It Ev LANG +This variable configures all programs which use +.Xr setlocale 3 +to use the specified locale unless the +.Ev LC_* +variables are set. +.It Ev LC_ALL +Overrides the values of +.Ev LC_COLLATE , +.Ev LC_CTYPE , +.Ev LC_MESSAGES , +.Ev LC_MONETARY , +.Ev LC_NUMERIC , +.Ev LC_TIME +and +.Ev LANG . +.It Ev LC_COLLATE +Locale to be used for ordering of strings. +.It Ev LC_CTYPE +Locale to be used for character classification +(letter, space, digit, etc.) and for interpreting byte sequences as +multibyte characters. +.It Ev LC_MESSAGES +Locale to be used for diagnostic messages. +.It Ev LC_MONETARY +Locale to be used for interpreting monetary input +and formatting output. +.It Ev LC_NUMERIC +Locale to be used for interpreting numeric input and +formatting output. +.It Ev LC_TIME +Locale to be used for interpreting dates input and +for formatting output. +.It Ev MAIL +The location of the user's +mailbox instead of the default in /var/mail, +used by +.Xr mail 1 , +.Xr sh 1 , +and many other mail clients. +.It Ev NLSPATH +List of directories to be searched for the message catalog referred to by +.Ev LC_MESSAGES . +See +.Xr catopen 3 . +.It Ev PAGER +Default paginator program. +The program specified by this variable is used by +.Xr mail 1 , +.Xr man 1 , +.Xr ftp 1 , +etc, to display information which is longer than the current display. +.It Ev PATH +The sequence of directories, separated by colons, searched by +.Xr csh 1 , +.Xr sh 1 , +.Xr system 3 , +.Xr execvp 3 , +etc, when looking for an executable file. +.Ev PATH +is set to ``/usr/bin:/bin'' initially by +.Xr login 1 . +.It Ev PRINTER +The name of the default printer to be used by +.Xr lpr 1 , +.Xr lpq 1 , +and +.Xr lprm 1 . +.It Ev PWD +The current directory pathname. +.It Ev SHELL +The full pathname of the user's login shell. +.It Ev TERM +The kind of terminal for which output is to be prepared. +This information is used by commands, such as +.Xr nroff 1 +or +.Xr plot 1 +which may exploit special terminal capabilities. +See +.Pa /usr/share/misc/termcap +.Pq Xr termcap 5 +for a list of terminal types. +.It Ev TERMCAP +The string describing the terminal in +.Ev TERM , +or, if +it begins with a '/', the name of the termcap file. +See +.Ev TERMPATH +below, and +.Xr termcap 5 . +.It Ev TERMPATH +A sequence of pathnames of termcap files, separated by colons or spaces, +which are searched for terminal descriptions in the order listed. +Having +no +.Ev TERMPATH +is equivalent to a +.Ev TERMPATH +of +.Dq Pa $HOME/.termcap:/etc/termcap . +.Ev TERMPATH +is ignored if +.Ev TERMCAP +contains a full pathname. +.It Ev TMPDIR +The directory in which to store temporary files. +Most applications use either +.Dq /tmp +or +.Dq /var/tmp . +Setting this variable will make them use another directory. +.It Ev TZ +The timezone to use when displaying dates. +The normal format is a pathname relative to +.Dq Pa /usr/share/zoneinfo . +For example, the command +.Dq env TZ=America/Los_Angeles date +displays the current time in California. +See +.Xr tzset 3 +for more information. +.It Ev USER +The login name of the user. +.El +.Pp +Further names may be placed in the environment by the +.Ic export +command and +.Ar name=value +arguments in +.Xr sh 1 , +or by the +.Ic setenv +command if you use +.Xr csh 1 . +It is unwise to change certain +.Xr sh 1 +variables that are frequently exported by +.Pa .profile +files, such as +.Ev MAIL , +.Ev PS1 , +.Ev PS2 , +and +.Ev IFS , +unless you know what you are doing. +.Pp +The current environment variables can be printed with +.Xr env 1 , +.Xr set 1 +or +.Xr printenv 1 +in +.Xr sh 1 +and +.Xr env 1 , +.Xr printenv 1 +or the +.Cm printenv +built-in command in +.Xr csh 1 . +.Sh PROGRAMMING +Programs can query and modify the environment, using the environment routines +.Xr getenv 3 , +.Xr putenv 3 , +.Xr setenv 3 +and +.Xr unsetenv 3 . +Direct access can be made through the global variable +.Va environ , +though it is recommended that changes to the enviroment still be made through +the environment routines. +.Pp +Shared libraries and bundles don't have direct access to +.Va environ , +which is only available to the loader +.Xr ld 1 +when a complete program is being linked. +The environment routines can still be used, but if direct access to +.Va environ +is needed, the +.Fn _NSGetEnviron +routine, defined in +.In crt_externs.h , +can be used to retrieve the address of +.Va environ +at runtime. +.Sh SEE ALSO +.Xr cd 1 , +.Xr csh 1 , +.Xr env 1 , +.Xr ex 1 , +.Xr login 1 , +.Xr printenv 1 , +.Xr sh 1 , +.Xr execve 2 , +.Xr execle 3 , +.Xr getenv 3 , +.Xr putenv 3 , +.Xr setenv 3 , +.Xr unsetenv 3 , +.Xr setlocale 3 , +.Xr system 3 , +.Xr termcap 3 , +.Xr termcap 5 +.Sh HISTORY +The +.Nm +manual page appeared in +.Bx 4.2 . diff --git a/src/libc/man/environ.7 b/src/libc/man/environ.7 deleted file mode 100644 index cd510e453..000000000 --- a/src/libc/man/environ.7 +++ /dev/null @@ -1,215 +0,0 @@ -.\" $NetBSD: environ.7,v 1.4 1995/07/03 19:45:07 jtc Exp $ -.\" -.\" Copyright (c) 1983, 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)environ.7 8.3 (Berkeley) 4/19/94 -.\" -.Dd April 19, 1994 -.Dt ENVIRON 7 -.Os BSD 4.2 -.Sh NAME -.Nm environ -.Nd user environment -.Sh SYNOPSIS -.Ar extern char **environ ; -.Sh DESCRIPTION -An array of strings called the -.Ar environment -is made available by -.Xr execve 2 -when a process begins. By convention these strings have the form -.Dq Ar name=value . -The following names are used by various commands: -.Bl -tag -width BLOCKSIZE -.It Ev BLOCKSIZE -The size of the block units used by several commands, most notably -.Xr df 1 , -.Xr du 1 -and -.Xr ls 1 . -BLOCKSIZE may be specified in units of a byte by specifying a number, -in units of a kilobyte by specifying a number followed by ``K'' or -``k'', in units of a megabyte by specifying a number followed by ``M'' -or ``m'' and in units of a gigabyte by specifying a number followed -by ``G'' or ``g''. -Sizes less than 512 bytes or greater than a gigabyte are ignored. -.It Ev EXINIT -A startup list of commands read by -.Xr ex 1 , -.Xr edit 1 , -and -.Xr vi 1 . -.It Ev HOME -A user's login directory, set by -.Xr login 1 -from the password file -.Xr passwd 5 . -.It Ev PATH -The sequence of directories, separated by colons, searched by -.Xr csh 1 , -.Xr sh 1 , -.Xr system 3 , -.Xr execvp 3 , -etc, when looking for an executable file. -PATH is set to ``/usr/bin:/bin'' initially by -.Xr login 1 . -.It Ev PRINTER -The name of the default printer to be used by -.Xr lpr 1 , -.Xr lpq 1 , -and -.Xr lprm 1 . -.It Ev SHELL -The full pathname of the user's login shell. -.It Ev TERM -The kind of terminal for which output is to be prepared. -This information is used by commands, such as -.Xr nroff 1 -or -.Xr plot 1 -which may exploit special terminal capabilities. See -.Pa /usr/share/misc/termcap -.Pq Xr termcap 5 -for a list of terminal types. -.It Ev TERMCAP -The string describing the terminal in TERM, or, if -it begins with a '/', the name of the termcap file. -See -.Ev TERMPATH -below, -.Xr termcap 5 , -and -.Xr termcap . -.It Ev TERMPATH -A sequence of pathnames of termcap files, separated by colons or spaces, -which are searched for terminal descriptions in the order listed. Having -no -.Ev TERMPATH -is equivalent to a -.Ev TERMPATH -of -.Dq Pa $HOME/.termcap:/etc/termcap . -.Ev TERMPATH -is ignored if -.Ev TERMCAP -contains a full pathname. -.It Ev TMPDIR -The directory in which to store temporary files. -Most applications use either -.Dq /tmp -or -.Dq /var/tmp . -Setting this variable will make them use another directory. -.It Ev TZ -The timezone to use when displaying dates. -The normal format is a pathname relative to -.Dq /usr/share/zoneinfo . -For example, the command -.Dq env TZ=US/Pacific date -displays the current time in California. -See -.Xr tzset 3 -for more information. -.It Ev LOGNAME -The login name of the user. -.It Ev USER -Deprecated synonym of -.Ev LOGNAME -(for backwards compatibility). -.El -.Pp -Further names may be placed in the environment by the -.Xr export -command and -.Ar name=value -arguments in -.Xr sh 1 , -or by the -.Xr setenv -command if you use -.Xr csh 1 . -It is unwise to change certain -.Xr sh 1 -variables that are frequently exported by -.Pa .profile -files, such as -.Ev MAIL , -.Ev PS1 , -.Ev PS2 , -and -.Ev IFS , -unless you know what you are doing. -.Sh PROGRAMMING -Programs can query and modify the environment, using the environment routines -.Xr getenv 3 , -.Xr putenv 3 , -.Xr setenv 3 -and -.Xr unsetenv 3 . -Direct access can be made through the global variable -.Va environ , -though it is recommended that changes to the enviroment still be made through -the environment routines. -.Pp -Shared libraries and bundles don't have direct access to -.Va environ , -which is only available to the loader -.Xr ld 1 -when a complete program is being linked. -The environment routines can still be used, but if direct access to -.Va environ -is needed, the -.Fn _NSGetEnviron -routine, defined in -.In crt_externs.h , -can be used to retrieve the address of -.Va environ -at runtime. -.Sh SEE ALSO -.Xr csh 1 , -.Xr ex 1 , -.Xr login 1 , -.Xr sh 1 , -.Xr getenv 3 , -.Xr putenv 3 , -.Xr setenv 3 , -.Xr unsetenv 3 , -.Xr execve 2 , -.Xr execle 3 , -.Xr system 3 , -.Xr termcap 3 , -.Xr termcap 5 -.Sh HISTORY -The -.Nm environ -manual page appeared in -.Bx 4.2 . diff --git a/src/libc/man/manpages.lst b/src/libc/man/manpages.lst index c009e7861..d2d41a5c9 100644 --- a/src/libc/man/manpages.lst +++ b/src/libc/man/manpages.lst @@ -7,8 +7,6 @@ creat.2 creat.2 gethostuuid.2 gethostuuid.2 killpg.2 killpg.2 nanosleep.2 nanosleep.2 -pthread_kill.2 pthread_kill.2 -pthread_sigmask.2 pthread_sigmask.2 sigblock.2 sigblock.2 sigpause.2 sigpause.2 sigsetmask.2 sigsetmask.2 sigmask.2 @@ -53,16 +51,13 @@ addr2ascii.3 addr2ascii.3 ascii2addr.3 alarm.3 alarm.3 alloca.3 alloca.3 arc4random.3 arc4random.3 arc4random_addrandom.3 arc4random_buf.3 arc4random_stir.3 arc4random_uniform.3 -asl.3 asl.3 asl_add_log_file.3 asl_close.3 asl_free.3 asl_get.3 asl_key.3 asl_log.3 asl_new.3 asl_open.3 asl_remove_log_file.3 asl_search.3 asl_send.3 asl_set.3 asl_set_filter.3 asl_set_query.3 asl_unset.3 asl_vlog.3 aslresponse_free.3 aslresponse_next.3 assert.3 assert.3 atexit.3 atexit.3 atexit_b.3 atof.3 atof.3 atof_l.3 atoi.3 atoi.3 atoi_l.3 atol.3 atol.3 atol_l.3 atoll.3 atoll_l.3 -atomic.3 atomic.3 OSAtomicAdd32.3 OSAtomicAdd32Barrier.3 OSAtomicAdd64.3 OSAtomicAdd64Barrier.3 OSAtomicAnd32.3 OSAtomicAnd32Barrier.3 OSAtomicAnd32Orig.3 OSAtomicAnd32OrigBarrier.3 OSAtomicCompareAndSwap32.3 OSAtomicCompareAndSwap32Barrier.3 OSAtomicCompareAndSwap64.3 OSAtomicCompareAndSwap64Barrier.3 OSAtomicCompareAndSwapInt.3 OSAtomicCompareAndSwapIntBarrier.3 OSAtomicCompareAndSwapLong.3 OSAtomicCompareAndSwapLongBarrier.3 OSAtomicCompareAndSwapPtr.3 OSAtomicCompareAndSwapPtrBarrier.3 OSAtomicDecrement32.3 OSAtomicDecrement32Barrier.3 OSAtomicDecrement64.3 OSAtomicDecrement64Barrier.3 OSAtomicDequeue.3 OSAtomicEnqueue.3 OSAtomicIncrement32.3 OSAtomicIncrement32Barrier.3 OSAtomicIncrement64.3 OSAtomicIncrement64Barrier.3 OSAtomicOr32.3 OSAtomicOr32Barrier.3 OSAtomicOr32Orig.3 OSAtomicOr32OrigBarrier.3 OSAtomicTestAndClear.3 OSAtomicTestAndClearBarrier.3 OSAtomicTestAndSet.3 OSAtomicTestAndSetBarrier.3 OSAtomicXor32.3 OSAtomicXor32Barrier.3 OSAtomicXor32Orig.3 OSAtomicXor32OrigBarrier.3 backtrace.3 backtrace.3 backtrace_symbols.3 backtrace_symbols_fd.3 -barrier.3 barrier.3 OSMemoryBarrier.3 -basename.3 basename.3 +basename.3 basename.3 basename_r.3 bcmp.3 bcmp.3 bcopy.3 bcopy.3 bitstring.3 bitstring.3 bit_alloc.3 bit_clear.3 bit_decl.3 bit_ffs.3 bit_nclear.3 bit_nset.3 bit_set.3 bit_test.3 bitstr_size.3 @@ -73,11 +68,11 @@ btowc.3 btowc.3 wctob.3 btowc_l.3 wctob_l.3 btree.3 btree.3 byteorder.3 byteorder.3 htonl.3 htons.3 ntohl.3 ntohs.3 bzero.3 bzero.3 -cache.3 cache.3 sys_cache_control.3 sys_icache_invalidate.3 sys_dcache_flush.3 catclose.3 catclose.3 catgets.3 catgets.3 catopen.3 catopen.3 clock.3 clock.3 +clock_gettime.3 clock_gettime.3 clock_settime.3 clock_getres.3 clock_gettime_nsec_np.3 confstr.3 confstr.3 crypt.3 crypt.3 encrypt.3 setkey.3 ctermid.3 ctermid.3 ctermid_r.3 @@ -89,8 +84,8 @@ dbm.3 dbm.3 dbm_clearerr.3 dbm_close.3 dbm_delete.3 dbm_dirfno.3 dbm_error.3 dbm dbopen.3 dbopen.3 db.3 devname.3 devname.3 devname_r.3 digittoint.3 digittoint.3 digittoint_l.3 -directory.3 directory.3 closedir.3 dirfd.3 opendir.3 readdir.3 readdir_r.3 rewinddir.3 seekdir.3 telldir.3 -dirname.3 dirname.3 +directory.3 directory.3 closedir.3 dirfd.3 fdopendir.3 opendir.3 readdir.3 readdir_r.3 rewinddir.3 seekdir.3 telldir.3 +dirname.3 dirname.3 dirname_r.3 div.3 div.3 duplocale.3 duplocale.3 ecvt.3 ecvt.3 fcvt.3 gcvt.3 @@ -102,7 +97,6 @@ exit.3 exit.3 _Exit.3 fclose.3 fclose.3 ferror.3 ferror.3 clearerr.3 clearerr_unlocked.3 feof.3 feof_unlocked.3 ferror_unlocked.3 fileno.3 fileno_unlocked.3 fflush.3 fflush.3 fpurge.3 -ffs.3 ffs.3 ffsl.3 fls.3 flsl.3 fgetln.3 fgetln.3 fgets.3 fgets.3 gets.3 fgetwln.3 fgetwln.3 fgetwln_l.3 @@ -127,14 +121,12 @@ fwide.3 fwide.3 getbsize.3 getbsize.3 getc.3 getc.3 fgetc.3 getc_unlocked.3 getchar.3 getchar_unlocked.3 getw.3 getcap.3 getcap.3 cgetcap.3 cgetclose.3 cgetent.3 cgetfirst.3 cgetmatch.3 cgetnext.3 cgetnum.3 cgetset.3 cgetstr.3 cgetustr.3 -getcontext.3 getcontext.3 setcontext.3 getcwd.3 getcwd.3 getwd.3 getdate.3 getdate.3 getdomainname.3 getdomainname.3 setdomainname.3 getenv.3 getenv.3 putenv.3 setenv.3 unsetenv.3 gethostid.3 gethostid.3 sethostid.3 gethostname.3 gethostname.3 sethostname.3 -getiopolicy_np.3 getiopolicy_np.3 setiopolicy_np.3 getlastlogx.3 getlastlogx.3 getlastlogxbyname.3 getutmp.3 getutmpx.3 utmpxname.3 getline.3 getline.3 getdelim.3 getloadavg.3 getloadavg.3 @@ -194,10 +186,6 @@ lockf.3 lockf.3 login.3 login.3 logwtmp.3 logout.3 lsearch.3 lsearch.3 lfind.3 lutimes.3 lutimes.3 -makecontext.3 makecontext.3 swapcontext.3 -malloc.3 malloc.3 calloc.3 free.3 realloc.3 reallocf.3 valloc.3 -malloc_size.3 malloc_size.3 malloc_good_size.3 -malloc_zone_malloc.3 malloc_zone_malloc.3 malloc_create_zone.3 malloc_destroy_zone.3 malloc_default_zone.3 malloc_zone_from_ptr.3 malloc_zone_calloc.3 malloc_zone_valloc.3 malloc_zone_realloc.3 malloc_zone_memalign.3 malloc_zone_free.3 mblen.3 mblen.3 mblen_l.3 mbrlen.3 mbrlen.3 mbrlen_l.3 mbrtowc.3 mbrtowc.3 mbrtowc_l.3 @@ -214,10 +202,10 @@ memmem.3 memmem.3 memmove.3 memmove.3 memory.3 memory.3 memset.3 memset.3 +memset_s.3 memset_s.3 memset_pattern.3 memset_pattern.3 memset_pattern4.3 memset_pattern8.3 memset_pattern16.3 mkpath_np.3 mkpath_np.3 mktemp.3 mktemp.3 mkdtemp.3 mkstemp.3 mkstemps.3 -moncontrol.3 moncontrol.3 monstartup.3 mpool.3 mpool.3 mpool_close.3 mpool_filter.3 mpool_get.3 mpool_new.3 mpool_open.3 mpool_put.3 mpool_sync.3 multibyte.3 multibyte.3 newlocale.3 newlocale.3 @@ -232,50 +220,8 @@ popen.3 popen.3 pclose.3 posix_memalign.3 posix_memalign.3 printf.3 printf.3 asprintf.3 dprintf.3 fprintf.3 snprintf.3 sprintf.3 vasprintf.3 vdprintf.3 vfprintf.3 vprintf.3 vsnprintf.3 vsprintf.3 printf_l.3 printf_l.3 asprintf_l.3 fprintf_l.3 snprintf_l.3 sprintf_l.3 vasprintf_l.3 vfprintf_l.3 vprintf_l.3 vsnprintf_l.3 vsprintf_l.3 -pselect.3 pselect.3 psignal.3 psignal.3 sys_siglist.3 sys_signame.3 strsignal.3 sys_siglist.3 sys_signame.3 psort.3 psort.3 psort_b.3 psort_r.3 -pthread.3 pthread.3 -pthread_atfork.3 pthread_atfork.3 -pthread_attr.3 pthread_attr.3 pthread_attr_destroy.3 pthread_attr_getdetachstate.3 pthread_attr_getinheritsched.3 pthread_attr_getschedparam.3 pthread_attr_getschedpolicy.3 pthread_attr_getscope.3 pthread_attr_getstackaddr.3 pthread_attr_getstacksize.3 pthread_attr_init.3 pthread_attr_setdetachstate.3 pthread_attr_setinheritsched.3 pthread_attr_setschedparam.3 pthread_attr_setschedpolicy.3 pthread_attr_setscope.3 pthread_attr_setstackaddr.3 pthread_attr_setstacksize.3 -pthread_cancel.3 pthread_cancel.3 -pthread_cleanup_pop.3 pthread_cleanup_pop.3 -pthread_cleanup_push.3 pthread_cleanup_push.3 -pthread_cond_broadcast.3 pthread_cond_broadcast.3 -pthread_cond_destroy.3 pthread_cond_destroy.3 -pthread_cond_init.3 pthread_cond_init.3 -pthread_cond_signal.3 pthread_cond_signal.3 -pthread_cond_timedwait.3 pthread_cond_timedwait.3 -pthread_cond_wait.3 pthread_cond_wait.3 -pthread_condattr.3 pthread_condattr.3 pthread_condattr_destroy.3 pthread_condattr_init.3 -pthread_create.3 pthread_create.3 -pthread_detach.3 pthread_detach.3 -pthread_equal.3 pthread_equal.3 -pthread_exit.3 pthread_exit.3 -pthread_getschedparam.3 pthread_getschedparam.3 pthread_setschedparam.3 -pthread_getspecific.3 pthread_getspecific.3 -pthread_join.3 pthread_join.3 -pthread_key_create.3 pthread_key_create.3 -pthread_key_delete.3 pthread_key_delete.3 -pthread_mutex_destroy.3 pthread_mutex_destroy.3 -pthread_mutex_init.3 pthread_mutex_init.3 -pthread_mutex_lock.3 pthread_mutex_lock.3 -pthread_mutex_trylock.3 pthread_mutex_trylock.3 -pthread_mutex_unlock.3 pthread_mutex_unlock.3 -pthread_mutexattr.3 pthread_mutexattr.3 pthread_mutexattr_destroy.3 pthread_mutexattr_getprioceiling.3 pthread_mutexattr_getprotocol.3 pthread_mutexattr_gettype.3 pthread_mutexattr_init.3 pthread_mutexattr_setprioceiling.3 pthread_mutexattr_setprotocol.3 pthread_mutexattr_settype.3 -pthread_once.3 pthread_once.3 -pthread_rwlock_destroy.3 pthread_rwlock_destroy.3 -pthread_rwlock_init.3 pthread_rwlock_init.3 -pthread_rwlock_rdlock.3 pthread_rwlock_rdlock.3 pthread_rwlock_tryrdlock.3 -pthread_rwlock_unlock.3 pthread_rwlock_unlock.3 -pthread_rwlock_wrlock.3 pthread_rwlock_wrlock.3 pthread_rwlock_trywrlock.3 -pthread_rwlockattr_destroy.3 pthread_rwlockattr_destroy.3 -pthread_rwlockattr_getpshared.3 pthread_rwlockattr_getpshared.3 -pthread_rwlockattr_init.3 pthread_rwlockattr_init.3 -pthread_rwlockattr_setpshared.3 pthread_rwlockattr_setpshared.3 -pthread_self.3 pthread_self.3 -pthread_setcancelstate.3 pthread_setcancelstate.3 pthread_setcanceltype.3 pthread_testcancel.3 -pthread_setspecific.3 pthread_setspecific.3 putc.3 putc.3 fputc.3 putc_unlocked.3 putchar.3 putchar_unlocked.3 putw.3 putwc.3 putwc.3 fputwc.3 putwchar.3 putwc_l.3 putwc_l.3 fputwc_l.3 putwchar_l.3 @@ -287,7 +233,7 @@ raise.3 raise.3 rand.3 rand.3 rand_r.3 srand.3 sranddev.3 rand48.3 rand48.3 _rand48.3 drand48.3 erand48.3 jrand48.3 lcong48.3 lrand48.3 mrand48.3 nrand48.3 seed48.3 srand48.3 random.3 random.3 initstate.3 setstate.3 srandom.3 srandomdev.3 -rcmdsh.3 rcmdsh.3 +rbtree.3 rbtree.3 readpassphrase.3 readpassphrase.3 realpath.3 realpath.3 recno.3 recno.3 @@ -299,7 +245,6 @@ scandir.3 scandir.3 alphasort.3 scandir_b.3 scanf.3 scanf.3 fscanf.3 sscanf.3 vfscanf.3 vscanf.3 vsscanf.3 scanf_l.3 scanf_l.3 fscanf_l.3 sscanf_l.3 vfscanf_l.3 vscanf_l.3 vsscanf_l.3 setbuf.3 setbuf.3 setbuffer.3 setlinebuf.3 setvbuf.3 -setjmp.3 setjmp.3 _longjmp.3 _setjmp.3 longjmp.3 longjmperr.3 longjmperror.3 siglongjmp.3 sigsetjmp.3 setlocale.3 setlocale.3 setmode.3 setmode.3 getmode.3 setruid.3 setruid.3 setrgid.3 @@ -310,7 +255,6 @@ sigsetops.3 sigsetops.3 sigaddset.3 sigdelset.3 sigemptyset.3 sigfillset.3 sigis sleep.3 sleep.3 sockatmark.3 sockatmark.3 sourcefilter.3 sourcefilter.3 getsourcefilter.3 getipv4sourcefilter.3 setsourcefilter.3 setipv4sourcefilter.3 -spinlock.3 spinlock.3 OSSpinLockLock.3 OSSpinLockTry.3 OSSpinLockUnlock.3 statvfs.3 statvfs.3 fstatvfs.3 stdarg.3 stdarg.3 va_arg.3 va_copy.3 va_end.3 va_start.3 stdio.3 stdio.3 @@ -320,7 +264,6 @@ strchr.3 strchr.3 strrchr.3 strcmp.3 strcmp.3 strncmp.3 strcoll.3 strcoll.3 strcoll_l.3 strcpy.3 strcpy.3 stpcpy.3 stpncpy.3 strncpy.3 -strcspn.3 strcspn.3 strdup.3 strdup.3 strndup.3 strerror.3 strerror.3 perror.3 strerror_r.3 sys_errlist.3 sys_nerr.3 strfmon.3 strfmon.3 strfmon_l.3 @@ -333,7 +276,7 @@ strmode.3 strmode.3 strpbrk.3 strpbrk.3 strptime.3 strptime.3 strptime_l.3 strsep.3 strsep.3 -strspn.3 strspn.3 +strspn.3 strspn.3 strcspn.3 strstr.3 strstr.3 strcasestr.3 strcasestr_l.3 strnstr.3 strtod.3 strtod.3 strtof.3 strtold.3 strtod_l.3 strtod_l.3 strtof_l.3 strtold_l.3 @@ -348,7 +291,6 @@ sync_volume_np.3 sync_volume_np.3 fsync_volume_np.3 sysconf.3 sysconf.3 sysctl.3 sysctl.3 sysctlbyname.3 sysctlnametomib.3 sysexits.3 sysexits.3 -syslog.3 syslog.3 closelog.3 openlog.3 setlogmask.3 vsyslog.3 system.3 system.3 tcgetpgrp.3 tcgetpgrp.3 tcgetsid.3 tcgetsid.3 @@ -360,6 +302,7 @@ time2posix.3 time2posix.3 posix2time.3 timegm.3 timegm.3 timelocal.3 times.3 times.3 timezone.3 timezone.3 +timingsafe_bcmp.3 timingsafe_bcmp.3 tmpnam.3 tmpnam.3 tempnam.3 tmpfile.3 toascii.3 toascii.3 tolower.3 tolower.3 tolower_l.3 @@ -370,7 +313,6 @@ tsearch.3 tsearch.3 tdelete.3 tfind.3 twalk.3 ttyname.3 ttyname.3 isatty.3 ttyslot.3 tzset.3 tzset.3 tzsetwall.3 ualarm.3 ualarm.3 -ucontext.3 ucontext.3 ulimit.3 ulimit.3 uname.3 uname.3 ungetc.3 ungetc.3 @@ -379,7 +321,7 @@ unvis.3 unvis.3 strunvis.3 strunvisx.3 uselocale.3 uselocale.3 usleep.3 usleep.3 utime.3 utime.3 -vis.3 vis.3 strvis.3 strvisx.3 +vis.3 vis.3 nvis.3 strvis.3 strnvis.3 strvisx.3 strnvisx.3 strenvisx.3 svis.3 snvis.3 strsvis.3 strsnvis.3 strsvisx.3 strsnvisx.3 strsenvisx.3 wcrtomb.3 wcrtomb.3 wcrtomb_l.3 wcscoll.3 wcscoll.3 wcscoll_l.3 wcsftime.3 wcsftime.3 wcsftime_l.3 @@ -403,6 +345,10 @@ wprintf_l.3 wprintf_l.3 fwprintf_l.3 swprintf_l.3 vwprintf_l.3 vfwprintf_l.3 vsw wscanf.3 wscanf.3 fwscanf.3 swscanf.3 vfwscanf.3 vswscanf.3 vwscanf.3 wscanf_l.3 wscanf_l.3 fwscanf_l.3 swscanf_l.3 vfwscanf_l.3 vswscanf_l.3 vwscanf_l.3 xlocale.3 xlocale.3 +xprintf.3 xprintf.3 asxprintf.3 dxprintf.3 fxprintf.3 sxprintf.3 vasxprintf.3 vdxprintf.3 vfxprintf.3 vsxprintf.3 vxprintf.3 +xprintf_comp.3 xprintf_comp.3 free_printf_comp.3 new_printf_comp.3 +xprintf_domain.3 xprintf_domain.3 copy_printf_domain.3 free_printf_domain.3 new_printf_domain.3 register_printf_domain_function.3 register_printf_domain_render_std.3 +xprintf_exec.3 xprintf_exec.3 asxprintf_exec.3 dxprintf_exec.3 fxprintf_exec.3 sxprintf_exec.3 vasxprintf_exec.3 vdxprintf_exec.3 vfxprintf_exec.3 vsxprintf_exec.3 vxprintf_exec.3 # man5 big5.5 big5.5 @@ -417,6 +363,7 @@ utf2.5 utf2.5 utf8.5 utf8.5 utmp.5 utmp.5 lastlog.5 wtmp.5 utmpx.5 utmpx.5 +xprintf.5 xprintf.5 # man7 environ.7 environ.7 diff --git a/src/libc/net/FreeBSD/addr2ascii.c b/src/libc/net/FreeBSD/addr2ascii.c index 708b0f594..9ae6bf3be 100644 --- a/src/libc/net/FreeBSD/addr2ascii.c +++ b/src/libc/net/FreeBSD/addr2ascii.c @@ -42,6 +42,8 @@ __FBSDID("$FreeBSD: src/lib/libc/net/addr2ascii.c,v 1.2 2002/03/22 21:52:28 obri #include #include +#include + /*- * Convert a network address from binary to printable numeric format. * This API is copied from INRIA's IPv6 implementation, but it is a @@ -59,16 +61,20 @@ __FBSDID("$FreeBSD: src/lib/libc/net/addr2ascii.c,v 1.2 2002/03/22 21:52:28 obri * naming and the poor choice of arguments. */ char * -addr2ascii(af, addrp, len, buf) - int af; - const void *addrp; - int len; /* should be size_t XXX */ - char *buf; /* XXX should pass length of buffer */ +addr2ascii(int af, const void *addrp, int len, char *buf) { - static char staticbuf[64]; /* 64 for AF_LINK > 16 for AF_INET */ - - if (!buf) + if (buf == NULL) { + static char *staticbuf = NULL; + + if (staticbuf == NULL) { + staticbuf = malloc(64); // 64 for AF_LINK > 16 for AF_INET + if (staticbuf == NULL) { + return NULL; + } + } + buf = staticbuf; + } switch(af) { case AF_INET: diff --git a/src/libc/net/FreeBSD/linkaddr.c b/src/libc/net/FreeBSD/linkaddr.c index 85f9f0fa7..a43ced3a3 100644 --- a/src/libc/net/FreeBSD/linkaddr.c +++ b/src/libc/net/FreeBSD/linkaddr.c @@ -50,9 +50,7 @@ __FBSDID("$FreeBSD: src/lib/libc/net/linkaddr.c,v 1.4 2007/01/09 00:28:02 imp Ex #define LETTER (4*3) void -link_addr(addr, sdl) - const char *addr; - struct sockaddr_dl *sdl; +link_addr(const char *addr, struct sockaddr_dl *sdl) { char *cp = sdl->sdl_data; char *cplim = sdl->sdl_len + (char *)sdl; @@ -118,11 +116,10 @@ link_addr(addr, sdl) return; } -static char hexlist[] = "0123456789abcdef"; +static const char hexlist[] = "0123456789abcdef"; char * -link_ntoa(sdl) - const struct sockaddr_dl *sdl; +link_ntoa(const struct sockaddr_dl *sdl) { static char obuf[64]; char *out = obuf; @@ -131,6 +128,18 @@ link_ntoa(sdl) u_char *inlim = in + sdl->sdl_alen; int firsttime = 1; + /* + * the length of the output string is length of network name (eg "le0") + * plus 3 * each byte (eg. "XX.") assuming the print representation is + * two bytes plus the period + * + * The ":" is accounted for as the last byte doesn't have a "." at the + * end + */ + if (sdl->sdl_nlen + 3*sdl->sdl_alen >= sizeof(obuf)) { + goto exit; + } + if (sdl->sdl_nlen) { bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen); out += sdl->sdl_nlen; @@ -148,9 +157,12 @@ link_ntoa(sdl) i >>= 4; out[0] = hexlist[i]; out += 2; - } else + } else { *out++ = hexlist[i]; + } } + +exit: *out = 0; return (obuf); } diff --git a/src/libc/net/FreeBSD/sourcefilter.c b/src/libc/net/FreeBSD/sourcefilter.c index a5a3cca16..779a96ba6 100644 --- a/src/libc/net/FreeBSD/sourcefilter.c +++ b/src/libc/net/FreeBSD/sourcefilter.c @@ -344,7 +344,8 @@ getsourcefilter(int s, uint32_t interface, struct sockaddr *group, { struct __msfilterreq msfr; sockunion_t *psu; - int err, level, nsrcs, optlen, optname; + int err, level, nsrcs, optname; + unsigned int optlen; if (interface == 0 || group == NULL || numsrc == NULL || fmode == NULL) { diff --git a/src/libc/net/inet_ntop.c b/src/libc/net/inet_ntop.c index a4c977d73..a5ad5c60f 100644 --- a/src/libc/net/inet_ntop.c +++ b/src/libc/net/inet_ntop.c @@ -1,3 +1,25 @@ +/* + * Copyright (c) 2003,2005,2006,2011,2012 Apple, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ #include #include @@ -13,6 +35,19 @@ static const char *hexchars = "0123456789abcdef"; +const char * inet_ntop6(const struct in6_addr *addr, char *dst, socklen_t size); +const char * inet_ntop4(const struct in_addr *addr, char *dst, socklen_t size); + +const char * +inet_ntop(int af, const void *addr, char *buf, socklen_t len) +{ + if (af == AF_INET6) return inet_ntop6(addr, buf, len); + if (af == AF_INET) return inet_ntop4(addr, buf, len); + + errno = EAFNOSUPPORT; + return NULL; +} + const char * inet_ntop6(const struct in6_addr *addr, char *dst, socklen_t size) { @@ -43,16 +78,26 @@ inet_ntop6(const struct in6_addr *addr, char *dst, socklen_t size) j = IN6_IS_ADDR_V4COMPAT(addr); if ((i != 0) || (j != 0)) { + const char *prefix; + socklen_t prefix_len; + if (i != 0) { + prefix = "::ffff:"; + prefix_len = 7; + } else { + prefix = "::"; + prefix_len = 2; + } a4.s_addr = addr->__u6_addr.__u6_addr32[3]; - sprintf(tmp, "::%s%s", (i != 0) ? "ffff:" : "", inet_ntoa(a4)); + inet_ntop4(&a4, tmp, sizeof(tmp)); len = strlen(tmp) + 1; - if (len > size) + if (prefix_len + len > size) { errno = ENOSPC; return NULL; } - memcpy(dst, tmp, len); + memcpy(dst, prefix, prefix_len); + memcpy(dst + prefix_len, tmp, len); return dst; } @@ -194,13 +239,3 @@ inet_ntop4(const struct in_addr *addr, char *dst, socklen_t size) memcpy(dst, tmp, len); return dst; } - -const char * -inet_ntop(int af, const void *addr, char *buf, socklen_t len) -{ - if (af == AF_INET6) return inet_ntop6(addr, buf, len); - if (af == AF_INET) return inet_ntop4(addr, buf, len); - - errno = EAFNOSUPPORT; - return NULL; -} diff --git a/src/libc/net/rcmdsh.3 b/src/libc/net/rcmdsh.3 deleted file mode 100644 index 43e6a8daa..000000000 --- a/src/libc/net/rcmdsh.3 +++ /dev/null @@ -1,116 +0,0 @@ -.\" $OpenBSD: rcmdsh.3,v 1.6 1999/07/05 04:41:00 aaron Exp $ -.\" -.\" Copyright (c) 1983, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc/net/rcmdsh.3,v 1.2 2001/11/09 15:19:25 ru Exp $ -.\" -.Dd September 1, 1996 -.Dt RCMDSH 3 -.Os -.Sh NAME -.Nm rcmdsh -.Nd return a stream to a remote command without superuser -.Sh SYNOPSIS -.In unistd.h -.Ft int -.Fo rcmdsh -.Fa "char **ahost" -.Fa "int inport" -.Fa "const char *locuser" -.Fa "const char *remuser" -.Fa "const char *cmd" -.Fa "const char *rshprog" -.Fc -.Sh DESCRIPTION -The -.Fn rcmdsh -function -is used by normal users to execute a command on -a remote machine using an authentication scheme based -on reserved port numbers using -.Xr rshd 8 -or the value of -.Fa rshprog -(if -.No non- Ns Dv NULL ) . -.Pp -The -.Fn rcmdsh -function -looks up the host -.Fa *ahost -using -.Xr gethostbyname 3 , -returning \-1 if the host does not exist. -Otherwise -.Fa *ahost -is set to the standard name of the host -and a connection is established to a server -residing at the well-known Internet port -.Dq Li shell/tcp -(or whatever port is used by -.Fa rshprog ) . -The parameter -.Fa inport -is ignored; it is only included to provide an interface similar to -.Xr rcmd 3 . -.Pp -If the connection succeeds, -a socket in the -.Ux -domain of type -.Dv SOCK_STREAM -is returned to the caller, and given to the remote -command as stdin, stdout, and stderr. -.Sh RETURN VALUES -The -.Fn rcmdsh -function -returns a valid socket descriptor on success. -Otherwise, \-1 is returned -and a diagnostic message is printed on the standard error. -.Sh SEE ALSO -.Xr rsh 1 , -.Xr socketpair 2 , -.Xr rcmd 3 , -.Xr rshd 8 -.Sh BUGS -If -.Xr rsh 1 -encounters an error, a file descriptor is still returned instead of \-1. -.Sh HISTORY -The -.Fn rcmdsh -function first appeared in -.Ox 2.0 , -and made its way into -.Fx 5.0 . diff --git a/src/libc/os/CMakeLists.txt b/src/libc/os/CMakeLists.txt index ef81e00f9..b9cd2ec8a 100644 --- a/src/libc/os/CMakeLists.txt +++ b/src/libc/os/CMakeLists.txt @@ -3,6 +3,6 @@ project(libc-os) cmake_minimum_required(VERSION 2.4.0) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) -set(os_sources assumes.c debug_private.c alloc_once_impl.c) +set(os_sources assumes.c debug_private.c) add_library(libc-os OBJECT ${os_sources}) diff --git a/src/libc/os/activity.h b/src/libc/os/activity.h deleted file mode 100644 index 58b364cdb..000000000 --- a/src/libc/os/activity.h +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright (c) 2013-2016 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __OS_ACTIVITY_H__ -#define __OS_ACTIVITY_H__ - -#include - -#include -#include -#include -#include - -__BEGIN_DECLS - -#if ((defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) \ - || (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && __WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0) \ - || (defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) \ - || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12)) -#define OS_ACTIVITY_OBJECT_API 1 -#else -#if OS_ACTIVITY_OBJECT_API -#error Please change your minimum OS requirements because OS_ACTIVITY_OBJECT_API is not available -#endif // OS_ACTIVITY_OBJECT_API -#define OS_ACTIVITY_OBJECT_API 0 -#endif - -extern struct mach_header __dso_handle; - -#define OS_LOG_STRING(_var, _str) \ - _Static_assert(__builtin_constant_p(_str), "formatters/labels/descriptions must be a constant string"); \ - __attribute__((section("__TEXT,__oslogstring,cstring_literals"),internal_linkage)) static const char _var[] __asm(OS_STRINGIFY(OS_CONCAT(LOSACTIVITY_, __COUNTER__))) = _str - -/*! - * @typedef os_breadcrumb_t - * An opaque value for the breadcrumb ID. - */ -__API_DEPRECATED("No longer supported", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0)) -typedef uint32_t os_breadcrumb_t; - -#define OS_ACTIVITY_NULL 0 - -/*! - * @enum os_activity_flag_t - * - * @discussion - * Support flags for os_activity_create or os_activity_start. - * - * @constant OS_ACTIVITY_FLAG_DEFAULT - * Use the default flags. - * - * @constant OS_ACTIVITY_FLAG_DETACHED - * Detach the newly created activity from the provided activity (if any). If passed in conjunction - * with an exiting activity, the activity will only note what activity "created" the new one, but - * will make the new activity a top level activity. This allows users to see what activity triggered - * work without actually relating the activities. - * - * @constant OS_ACTIVITY_FLAG_IF_NONE_PRESENT - * Will only create a new activity if none present. If an activity ID is already present, a new object - * will be returned with the same activity ID underneath. - */ -OS_ENUM(os_activity_flag, uint32_t, - OS_ACTIVITY_FLAG_DEFAULT = 0, - OS_ACTIVITY_FLAG_DETACHED = 0x1, - OS_ACTIVITY_FLAG_IF_NONE_PRESENT = 0x2 -); - -#if OS_ACTIVITY_OBJECT_API - -#define OS_ACTIVITY_NULL NULL - -/*! - * @typedef os_activity_t - * An opaque activity object. - */ -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -#if OS_OBJECT_USE_OBJC -OS_OBJECT_DECL(os_activity); -#else -typedef struct os_activity_s *os_activity_t; -#endif /* OS_OBJECT_USE_OBJC */ - -/*! - * @const OS_ACTIVITY_NONE - * - * @discussion - * Create activity with no current traits, this is the equivalent of a - * detached activity. - */ -#define OS_ACTIVITY_NONE OS_OBJECT_GLOBAL_OBJECT(os_activity_t, _os_activity_none) -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -OS_EXPORT -const struct os_activity_s _os_activity_none; - -/*! - * @const OS_ACTIVITY_CURRENT - * - * @discussion - * Create activity and links to the current activity if one is present. - * If no activity is present it is treated as if it is detached. - */ -#define OS_ACTIVITY_CURRENT OS_OBJECT_GLOBAL_OBJECT(os_activity_t, _os_activity_current) -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -OS_EXPORT -const struct os_activity_s _os_activity_current; - -#else // !OS_ACTIVITY_OBJECT_API - -#define OS_ACTIVITY_NULL 0 - -/*! - * @typedef os_activity_t - * An opaque activity identifier. - */ -__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(9.0)) -typedef uint64_t os_activity_t; - -#endif // OS_ACTIVITY_OBJECT_API - -/*! - * @typedef os_activity_id_t - * An value representing the activity ID assigned to an newly created activity. - */ -__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(9.0)) -typedef uint64_t os_activity_id_t; - -#if !defined(__TRACE_BUILDING_TRACE__) -/*! - * @typedef os_activity_scope_state_t - * Structure that is populated by os_activity_scope_enter and restored using - * os_activity_scope_leave. - */ -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -typedef struct os_activity_scope_state_s { - uint64_t opaque[2]; -} *os_activity_scope_state_t; -#else -typedef struct os_activity_scope_state_s *os_activity_scope_state_t; -#endif - -#pragma mark - Internal support functions - -#if OS_ACTIVITY_OBJECT_API -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -OS_EXPORT OS_NOTHROW OS_WARN_RESULT_NEEDS_RELEASE OS_NOT_TAIL_CALLED OS_OBJECT_RETURNS_RETAINED -os_activity_t -_os_activity_create(void *dso, const char *description, os_activity_t activity, os_activity_flag_t flags); -#endif - -/*! - * @function _os_activity_label_useraction - * - * @abstract - * Internal function for use by os_activity_label_useraction. Do not use directly. - */ -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED -void -_os_activity_label_useraction(void *dso, const char *name); - -/*! - * @function _os_activity_initiate - * - * @abstract - * Do not use directly because your description will not be preserved. - */ -__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(9.0)) -OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED -void -_os_activity_initiate(void *dso, const char *description, os_activity_flag_t flags, os_block_t activity_block OS_NOESCAPE); - -/*! - * @function _os_activity_initiate_f - * - * @abstract - * Do not use directly because your description will not be preserved. - */ -__API_AVAILABLE(macosx(10.10), ios(8.0), watchos(2.0), tvos(9.0)) -OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED -void -_os_activity_initiate_f(void *dso, const char *description, os_activity_flag_t flags, void *context, os_function_t function); - -#pragma mark - Internal deprecated function support - -/*! - * @function _os_activity_set_breadcrumb - * - * @abstract - * Internal function for setting breadcrumb. Do not use directly. - */ -__API_DEPRECATED_WITH_REPLACEMENT("os_activity_label_useraction", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0)) -OS_EXPORT OS_NOTHROW OS_NOT_TAIL_CALLED -void -_os_activity_set_breadcrumb(void *dso, const char *name); - -/*! - * @function _os_activity_start - * - * @abstract - * Internal function for activity start, do not use directly will not preserve - * description. - */ -__API_DEPRECATED("use combination of os_activity_create and os_activity_apply/os_activity_scope", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0)) -OS_EXPORT OS_NOTHROW OS_WARN_RESULT OS_NOT_TAIL_CALLED -os_activity_t -_os_activity_start(void *dso, const char *description, os_activity_flag_t flags); - -#pragma mark - activity related - -/*! - * @function os_activity_initiate - * - * @abstract - * Synchronously initiates an activity using provided block. - * - * @discussion - * Synchronously initiates an activity using the provided block and creates - * a tracing buffer as appropriate. All new activities are created as a - * subactivity of an existing activity on the current thread. - * - * os_activity_initiate("indexing database", OS_ACTIVITY_FLAG_DEFAULT, ^(void) { - * // either do work directly or issue work asynchronously - * }); - * - * @param description - * A constant string describing the activity, e.g., "performClick" or - * "menuSelection". - * - * @param flags - * Flags to be used when initiating the activity, typically OS_ACTIVITY_FLAG_DEFAULT. - * - * @param activity_block - * The block to execute a given activity - */ -#define os_activity_initiate(description, flags, activity_block) __extension__({ \ - OS_LOG_STRING(__description, description); \ - _os_activity_initiate(&__dso_handle, __description, flags, activity_block); \ -}) - -/*! - * @function os_activity_initiate_f - * - * @abstract - * Synchronously initiates an activity using the provided function. - * - * @discussion - * Synchronously initiates an activity using the provided function and creates - * a tracing buffer as appropriate. All new activities are created as a - * subactivity of an existing activity on the current thread. - * - * os_activity_initiate_f("indexing database", OS_ACTIVITY_FLAG_DEFAULT, context, function); - * - * @param description - * A constant string describing the activity, e.g., "performClick" or - * "menuSelection". - * - * @param flags - * Flags to be used when initiating the activity, typically OS_ACTIVITY_FLAG_DEFAULT. - * - * @param context - * An optional context that will be supplied to the activity function. - * - * @param activity_func - * The function to execute for the new activity. - */ -#define os_activity_initiate_f(description, flags, context, function) __extension__({ \ - OS_LOG_STRING(__description, description); \ - _os_activity_initiate_f(&__dso_handle, __description, flags, context, function); \ -}) - -#if OS_ACTIVITY_OBJECT_API -/*! - * @function os_activity_create - * - * @abstract - * Creates an os_activity_t object which can be passed to os_activity_apply function. - * - * @discussion - * Creates an os_activity_t object which can be passed to os_activity_apply function. - * - * @param description - * Pass a description for the activity. The description must be a constant string - * within the calling executable or library. - * - * @param parent_activity - * Depending on flags will link the newly created activity to the value passed or - * note where the activity was created. Possible activities include: OS_ACTIVITY_NONE, - * OS_ACTIVITY_CURRENT or any existing os_activity_t object created using os_activity_create. - * - * @param flags - * A valid os_activity_flag_t which will determine behavior of the newly created activity. - * - * @result - * Returns an os_activity_t object which can be used with os_activity_apply. - */ -#define os_activity_create(description, parent_activity, flags) __extension__({ \ - OS_LOG_STRING(__description, description); \ - os_activity_t __activity = _os_activity_create(&__dso_handle, __description, parent_activity, flags); \ - __activity; \ -}) - -/*! - * @function os_activity_apply - * - * @abstract - * Execute a block using a given activity object. - * - * @discussion - * Execute a block using a given activity object. - * - * @param activity - * There are global objects available which include: OS_ACTIVITY_NONE, OS_ACTIVITY_CURRENT - * or an existing os_activity_t object. - * - * @param block - * Pass the block to be executed within the context of the given activity. - */ -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -OS_EXPORT OS_NOTHROW -void -os_activity_apply(os_activity_t activity, os_block_t block OS_NOESCAPE); - -/*! - * @function os_activity_apply_f - * - * @abstract - * Execute a given function with a provided activity. - * - * @discussion - * Execute a given function with a provided activity. - * - * @param activity - * There are global objects available which include: OS_ACTIVITY_NONE, OS_ACTIVITY_CURRENT - * or an existing os_activity_t object. - * - * @param context - * Context to pass to the function which may be NULL. - * - * @param function - * Pass the function to be executed within the context of the given activity. - */ -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -OS_EXPORT OS_NOTHROW -void -os_activity_apply_f(os_activity_t activity, void *context, os_function_t function); - -/*! - * @function os_activity_scope_enter - * - * @abstract - * Will change the current execution context to use the provided activity. - * - * @discussion - * Will change the current execution context to use the provided activity. An activity - * can be created and then applied to the current scope by doing: - * - * struct os_activity_scope_state_s state; - * os_activity_t activity = os_activity_create("my new activity", 0); - * os_activity_scope_enter(activity, &state); - * ... do some work ... - * os_activity_scope_leave(&state); - * - * To auto-cleanup state call: - * - * os_activity_scope(activity); - * - * @param activity - * Pass a valid activity created with os_activity_create or any global object. - * - * @param state - * A stack-based struct os_activity_scope_state_s to store the state. - */ -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -OS_EXPORT OS_NOTHROW -void -os_activity_scope_enter(os_activity_t activity, os_activity_scope_state_t state); - -/*! - * @function os_activity_scope_leave - * - * @abstract - * Will pop state up to the state provided. - * - * @discussion - * Will leave scope using the state provided. If state is not present an error will be - * generated. - * - * @param state - * Must be a valid value filled by os_activity_scope_enter call. - */ -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -OS_EXPORT OS_NOTHROW -void -os_activity_scope_leave(os_activity_scope_state_t state); - -#if defined(__GNUC__) -#define _os_activity_scope(var, activity) \ - struct os_activity_scope_state_s var __attribute__((__cleanup__(os_activity_scope_leave))); \ - os_activity_scope_enter(activity, &var) -#define os_activity_scope(activity) _os_activity_scope(OS_CONCAT(scope, __COUNTER__), activity) -#endif - -#endif // OS_ACTIVITY_OBJECT_API - -/*! - * @function os_activity_start - * - * @abstract - * Starts a new activity immediately within the current context. - * - * @discussion - * Starts a new activity immediately within the current context. Deprecated please use new - * os_activity_create and os_activity_apply. - * - * os_activity_t activity = os_activity_start("indexing database", OS_ACTIVITY_FLAG_DEFAULT); - * < do some work > - * os_activity_end(activity); - * - * @param description - * A constant string describing the activity, e.g., "performClick" or - * "menuSelection". - * - * @param flags - * Flags to be used when initiating the activity, typically OS_ACTIVITY_FLAG_DEFAULT. - * - * @result - * Returns a valid os_activity_id_t or 0 on failure. - */ -#define os_activity_start(description, flags) __extension__({ \ - OS_LOG_STRING(__description, description); \ - os_activity_t _aid = _os_activity_start(&__dso_handle, __description, flags); \ - _aid; \ -}) - -/*! - * @function os_activity_end - * - * @abstract - * Ends the specified activity on the current thread. - * - * @discussion - * Ends the specified activity on the current thread. Does not signify anything - * other than the originator has received control back from the activity. Work - * could still be in flight related to the activity. - * - * @param activity - * An os_activity_t returned from os_activity_start. - */ -__API_DEPRECATED("use combination of os_activity_create and os_activity_apply/os_activity_scope", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0)) -OS_EXPORT OS_NOTHROW -void -os_activity_end(os_activity_t activity); - -/*! - * @function os_activity_get_active - * - * @abstract - * Returns the stack of nested activities associated with the current thread. - * - * @discussion - * Activities have a sense of nesting and therefore there could be more than - * one activity involved on the current thread. This should be used by - * diagnostic tools only for making additional decisions about a situation. - * - * @param entries - * Pass a buffer of sufficient size to hold the the number of os_activity_id_t - * being requested. - * - * @param count - * Pointer to the requested number of activity identifiers. - * On output will be filled with the number of activities that are available. - * - * @result - * Number of activity identifiers written to 'entries' - */ -__API_DEPRECATED("No longer supported", macosx(10.10, 10.12), ios(8.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0)) -OS_EXPORT OS_NOTHROW -unsigned int -os_activity_get_active(os_activity_id_t *entries, unsigned int *count); - -/*! - * @function os_activity_get_identifier - * - * @abstract - * Returns the current activity ID and will fill the parent_id if present. - * - * @discussion - * Returns the current activity ID and will fill the parent_id if present. - * - * @param parent_id - * If non-null will set the parent activity ID. - * - * @result - * The identifier for the provided activity. - */ -__API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) -OS_EXPORT OS_NOTHROW OS_NONNULL1 OS_WARN_RESULT -os_activity_id_t -os_activity_get_identifier(os_activity_t activity, os_activity_id_t *parent_id); - -/*! - * @function os_activity_label_useraction - * - * @abstract - * Label an activity that is auto-generated by AppKit/UIKit with a name that is useful - * for debugging macro-level user actions. - * - * @discussion - * Label an activity that is auto-generated by AppKit/UIKit with a name that is useful - * for debugging macro-level user actions. The API should be called early within the scope - * of the IBAction and before any sub-activities are created. The name provided will - * be shown in tools in additon to the underlying AppKit/UIKit provided name. This API - * can only be called once and only on the activity created by AppKit/UIKit. These actions - * help determine workflow of the user in order to reproduce problems that occur. - * For example, a control press and/or menu item selection can be labeled: - * - * os_activity_label_useraction("New mail message"); - * os_activity_label_useraction("Empty trash"); - * - * Where the underlying AppKit/UIKit name will be "gesture:" or "menuSelect:". - * - * @param name - * A constant string that describes the the action. - */ -#define os_activity_label_useraction(label) __extension__({ \ - OS_LOG_STRING(__label, label); \ - _os_activity_label_useraction(&__dso_handle, __label); \ -}) - -#pragma mark - application breadcrumbs - -/*! - * @function os_activity_set_breadcrumb - * - * @abstract - * This flags the current activity as a "breadcrumb", i.e., an interesting event. - * - * @discussion - * Not all activities are interesting events at the macro-level. Some activities - * can be flagged as a breadcrumb for evalutating cross activity interactions. - * This can only be called once per activity, other requests will be ignored. - * - * @param name - * A constant string that describes the breadcrumb. - */ -#define os_activity_set_breadcrumb(name) __extension__({ \ - OS_LOG_STRING(__name, name); \ - _os_activity_set_breadcrumb(&__dso_handle, __name); \ -}) - -__END_DECLS - -#endif // __OS_ACTIVITY_H__ diff --git a/src/libc/os/alloc_once_impl.c b/src/libc/os/alloc_once_impl.c deleted file mode 100644 index 28388824c..000000000 --- a/src/libc/os/alloc_once_impl.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "alloc_once_impl.h" -#include -#include - -static pthread_mutex_t mutexes[OS_ALLOC_ONCE_KEY_MAX]; -static pthread_once_t mutexes_once = PTHREAD_ONCE_INIT; -static void* blocks[OS_ALLOC_ONCE_KEY_MAX]; - -static void init_mutexes(void); - -void* os_alloc_once(int key, size_t size, void(*ctor)(void*)) -{ - if (key < 0 || key >= OS_ALLOC_ONCE_KEY_MAX) - return NULL; - - pthread_once(&mutexes_once, init_mutexes); - - if (size != 0 && blocks[key] == NULL) - { - pthread_mutex_lock(&mutexes[key]); - - if (blocks[key] == NULL) - { - int npages = (size+4095)/4096; - blocks[key] = mmap(NULL, npages*4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); - if (ctor != NULL) - ctor(blocks[key]); - } - - pthread_mutex_unlock(&mutexes[key]); - } - - return blocks[key]; -} - -static void init_mutexes(void) -{ - int i = 0; - for (i = 0; i < OS_ALLOC_ONCE_KEY_MAX-1; i++) - pthread_mutex_init(&mutexes, NULL); -} - diff --git a/src/libc/os/alloc_once_impl.h b/src/libc/os/alloc_once_impl.h deleted file mode 100644 index 6f3f1e5dd..000000000 --- a/src/libc/os/alloc_once_impl.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _ALLOC_ONCE_IMPL_H_ -#define _ALLOC_ONCE_IMPL_H_ -#include - -#define OS_ALLOC_ONCE_KEY_MAX 32 - -void* os_alloc_once(int key, size_t size, void(*ctor)(void*)); - -#endif - diff --git a/src/libc/os/alloc_once_private.h b/src/libc/os/alloc_once_private.h deleted file mode 100644 index 6f65f84a9..000000000 --- a/src/libc/os/alloc_once_private.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2012-2013 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#ifndef __OS_ALLOC__ -#define __OS_ALLOC__ - -#ifndef __OS_ALLOC_INDIRECT__ -#define __OS_ALLOC_INDIRECT__ -#endif // __OS_ALLOC_INDIRECT__ - -#include - -/* Keys for use with os_once_alloc. */ - -/* Keys for Libsystem. */ -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_NOTIFY 0 -#define OS_ALLOC_ONCE_KEY_LIBXPC 1 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_C 2 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_INFO 3 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_NETWORK 4 -#define OS_ALLOC_ONCE_KEY_LIBCACHE 5 -#define OS_ALLOC_ONCE_KEY_LIBCOMMONCRYPTO 6 -#define OS_ALLOC_ONCE_KEY_LIBDISPATCH 7 -#define OS_ALLOC_ONCE_KEY_LIBDYLD 8 -#define OS_ALLOC_ONCE_KEY_LIBKEYMGR 9 -#define OS_ALLOC_ONCE_KEY_LIBLAUNCH 10 -#define OS_ALLOC_ONCE_KEY_LIBMACHO 11 -#define OS_ALLOC_ONCE_KEY_OS_TRACE 12 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_BLOCKS 13 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_MALLOC 14 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_PLATFORM 15 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_PTHREAD 16 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_STATS 17 - -/* Keys OS_ALLOC_ONCE_KEY_MAX - 10 upwards are reserved for the system. */ -#define OS_ALLOC_ONCE_KEY_RESERVED_0 (OS_ALLOC_ONCE_KEY_MAX - 10) -#define OS_ALLOC_ONCE_KEY_RESERVED_1 (OS_ALLOC_ONCE_KEY_MAX - 9) -#define OS_ALLOC_ONCE_KEY_RESERVED_2 (OS_ALLOC_ONCE_KEY_MAX - 8) -#define OS_ALLOC_ONCE_KEY_RESERVED_3 (OS_ALLOC_ONCE_KEY_MAX - 7) -#define OS_ALLOC_ONCE_KEY_RESERVED_4 (OS_ALLOC_ONCE_KEY_MAX - 6) -#define OS_ALLOC_ONCE_KEY_RESERVED_5 (OS_ALLOC_ONCE_KEY_MAX - 5) -#define OS_ALLOC_ONCE_KEY_RESERVED_6 (OS_ALLOC_ONCE_KEY_MAX - 4) -#define OS_ALLOC_ONCE_KEY_RESERVED_7 (OS_ALLOC_ONCE_KEY_MAX - 3) -#define OS_ALLOC_ONCE_KEY_RESERVED_8 (OS_ALLOC_ONCE_KEY_MAX - 2) -#define OS_ALLOC_ONCE_KEY_RESERVED_9 (OS_ALLOC_ONCE_KEY_MAX - 1) - -/* OS_ALLOC_ONCE_KEY_MAX cannot be used. */ - -#endif // __OS_ALLOC__ diff --git a/src/libc/os/alloc_once_private.h b/src/libc/os/alloc_once_private.h new file mode 120000 index 000000000..1a0252d60 --- /dev/null +++ b/src/libc/os/alloc_once_private.h @@ -0,0 +1 @@ +../../libsystem/alloc_once_private.h \ No newline at end of file diff --git a/src/libc/os/assumes.c b/src/libc/os/assumes.c index da5ab00e4..e51d3995e 100644 --- a/src/libc/os/assumes.c +++ b/src/libc/os/assumes.c @@ -40,7 +40,6 @@ #include #include #include "os/assumes.h" -#include "gen/assumes.h" #include #define OSX_ASSUMES_LOG_REDIRECT_SECT_NAME "__osx_log_func" @@ -383,34 +382,3 @@ _os_avoid_tail_call(void) { // no-op } - -#pragma mark Legacy -void -_osx_assumes_log(uint64_t code) -{ - _os_assumes_log(code); -} - -char * -_osx_assert_log(uint64_t code) -{ - return _os_assert_log_impl(code); -} - -void -_osx_assumes_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code) -{ - _os_assumes_log_ctx_impl(callout, ctx, code); -} - -char * -_osx_assert_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code) -{ - return _os_assert_log_ctx_impl(callout, ctx, code); -} - -void -_osx_avoid_tail_call(void) -{ - _os_avoid_tail_call(); -} diff --git a/src/libc/os/assumes.h b/src/libc/os/assumes.h index 4f9d71c9d..c120f4ec0 100644 --- a/src/libc/os/assumes.h +++ b/src/libc/os/assumes.h @@ -122,7 +122,7 @@ typedef bool (*os_log_callout_t)(_SIMPLE_STRING asl_message, void *ctx, const ch __typeof__(e) _e = os_slowpath(e); \ if (_e) { \ if (os_constant(e)) { \ - __OS_COMPILETIME_ASSERT__(!e); \ + __OS_COMPILETIME_ASSERT__(!(e)); \ } \ _os_assumes_log((uint64_t)(uintptr_t)_e); \ _os_avoid_tail_call(); \ @@ -165,7 +165,7 @@ typedef bool (*os_log_callout_t)(_SIMPLE_STRING asl_message, void *ctx, const ch __typeof__(e) _e = os_slowpath(e); \ if (_e) { \ if (os_constant(e)) { \ - __OS_COMPILETIME_ASSERT__(!e); \ + __OS_COMPILETIME_ASSERT__(!(e)); \ } \ \ char *_fail_message = _os_assert_log((uint64_t)(uintptr_t)_e); \ @@ -203,7 +203,7 @@ typedef bool (*os_log_callout_t)(_SIMPLE_STRING asl_message, void *ctx, const ch __typeof__(e) _e = os_slowpath(e); \ if (_e) { \ if (os_constant(e)) { \ - __OS_COMPILETIME_ASSERT__(!e); \ + __OS_COMPILETIME_ASSERT__(!(e)); \ } \ _os_assumes_log_ctx((f), (ctx), (uintptr_t)_e); \ _os_avoid_tail_call(); \ @@ -237,7 +237,7 @@ typedef bool (*os_log_callout_t)(_SIMPLE_STRING asl_message, void *ctx, const ch __typeof__(e) _e = os_slowpath(e); \ if (_e) { \ if (os_constant(e)) { \ - __OS_COMPILETIME_ASSERT__(!e); \ + __OS_COMPILETIME_ASSERT__(!(e)); \ } \ \ char *_fail_message = _os_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)_e); \ @@ -255,9 +255,6 @@ typedef bool (*os_log_callout_t)(_SIMPLE_STRING asl_message, void *ctx, const ch } \ }) -#define os_slowpath(x) (x) -#define os_fastpath(x) (x) - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0) extern void _os_crash(const char *); diff --git a/src/libc/os/availability.h b/src/libc/os/availability.h deleted file mode 100644 index 3ba4e0391..000000000 --- a/src/libc/os/availability.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2008-2016 Apple Inc. All rights reserved. - * - * @APPLE_APACHE_LICENSE_HEADER_START@ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @APPLE_APACHE_LICENSE_HEADER_END@ - */ - -#ifndef __OS_AVAILABILITY__ -#define __OS_AVAILABILITY__ - -#include - -/* - Macros for defining which versions/platform a given symbol can be used. - - @see http://clang.llvm.org/docs/AttributeReference.html#availability - */ - -/* - * API Introductions - * - * Use to specify the release that a particular API became available. - * - * Platform names: - * macos, ios, tvos, watchos - * - * Examples: - * API_AVAILABLE(macos(10.10)) - * API_AVAILABLE(macos(10.9), ios(10.0)) - * API_AVAILABLE(macos(10.4), ios(8.0), watchos(2.0), tvos(10.0)) - */ - -#define API_AVAILABLE(...) __API_AVAILABLE_GET_MACRO(__VA_ARGS__,__API_AVAILABLE4, __API_AVAILABLE3, __API_AVAILABLE2, __API_AVAILABLE1)(__VA_ARGS__) - -/* - * API Deprecations - * - * Use to specify the release that a particular API became unavailable. - * - * Platform names: - * macos, ios, tvos, watchos - * - * Examples: - * - * API_DEPRECATED("No longer supported", macos(10.4, 10.8)) - * API_DEPRECATED("No longer supported", macos(10.4, 10.8), ios(2.0, 3.0), watchos(2.0, 3.0), tvos(9.0, 10.0)) - * - * API_DEPRECATED_WITH_REPLACEMENT("-setName:", tvos(10.0, 10.4), ios(9.0, 10.0)) - * API_DEPRECATED_WITH_REPLACEMENT("SomeClassName", macos(10.4, 10.6), watchos(2.0, 3.0)) - */ - -#define API_DEPRECATED(...) __API_DEPRECATED_MSG_GET_MACRO(__VA_ARGS__,__API_DEPRECATED_MSG5,__API_DEPRECATED_MSG4,__API_DEPRECATED_MSG3,__API_DEPRECATED_MSG2,__API_DEPRECATED_MSG1)(__VA_ARGS__) -#define API_DEPRECATED_WITH_REPLACEMENT(...) __API_DEPRECATED_REP_GET_MACRO(__VA_ARGS__,__API_DEPRECATED_REP5,__API_DEPRECATED_REP4,__API_DEPRECATED_REP3,__API_DEPRECATED_REP2,__API_DEPRECATED_REP1)(__VA_ARGS__) - - - -/* - * API Unavailability - * Use to specify that an API is unavailable for a particular platform. - * - * Example: - * API_UNAVAILABLE(macos) - * API_UNAVAILABLE(watchos, tvos) - */ - -#define API_UNAVAILABLE(...) __API_UNAVAILABLE_GET_MACRO(__VA_ARGS__,__API_UNAVAILABLE3,__API_UNAVAILABLE2,__API_UNAVAILABLE1)(__VA_ARGS__) - -#endif /* __OS_AVAILABILITY__ */ diff --git a/src/libc/os/base_private.h b/src/libc/os/base_private.h deleted file mode 100644 index 67b6db20a..000000000 --- a/src/libc/os/base_private.h +++ /dev/null @@ -1,4 +0,0 @@ -//#include "gen/assumes.h" -#define OS_FORMAT_PRINTF(a,b) __attribute__ ((format (printf, a, b))) -#define OS_CONST const - diff --git a/src/libc/os/debug_private.c b/src/libc/os/debug_private.c index 05786d996..d38a9a20a 100644 --- a/src/libc/os/debug_private.c +++ b/src/libc/os/debug_private.c @@ -172,7 +172,7 @@ _os_debug_log_init(void *globals) #define OS_ALLOC_ONCE_KEY_OS_DEBUG_LOG OS_ALLOC_ONCE_KEY_OS_TRACE #endif -static inline /* OS_CONST */ +static inline OS_CONST struct os_debug_log_globals_s * os_debug_log_globals(void) { @@ -254,7 +254,7 @@ static __attribute__((always_inline)) void _os_debug_logv(int level, const char *msg, va_list ap) { - if (os_slowpath(os_debug_log_globals()->errors_only) && level > LOG_ERR) { + if (os_slowpath((bool)os_debug_log_globals()->errors_only) && level > LOG_ERR) { // more important = lower integer return; } @@ -274,7 +274,7 @@ _os_debug_logv(int level, const char *msg, va_list ap) __OS_COMPILETIME_ASSERT__(pfxlen >= timelen); if (os_fastpath(len > pfxlen)) { - if (os_slowpath(os_debug_log_globals()->prepend_timestamp)) { + if (os_slowpath((bool)os_debug_log_globals()->prepend_timestamp)) { char tmp = buf[timelen]; snprintf(buf, timelen + 1, "%16llu", _os_debug_log_ticks_since_start()); buf[timelen] = tmp; // snprintf's null diff --git a/src/libc/os/object.h b/src/libc/os/object.h deleted file mode 100644 index 7d1e5ce85..000000000 --- a/src/libc/os/object.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2011-2012 Apple Inc. All rights reserved. - * - * @APPLE_APACHE_LICENSE_HEADER_START@ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @APPLE_APACHE_LICENSE_HEADER_END@ - */ - -#ifndef __OS_OBJECT__ -#define __OS_OBJECT__ - -#ifdef __APPLE__ -#include -#endif - -/*! - * @header - * - * @preprocinfo - * By default, libSystem objects such as GCD and XPC objects are declared as - * Objective-C types when building with an Objective-C compiler. This allows - * them to participate in ARC, in RR management by the Blocks runtime and in - * leaks checking by the static analyzer, and enables them to be added to Cocoa - * collections. - * - * NOTE: this requires explicit cancellation of dispatch sources and xpc - * connections whose handler blocks capture the source/connection object, - * resp. ensuring that such captures do not form retain cycles (e.g. by - * declaring the source as __weak). - * - * To opt-out of this default behavior, add -DOS_OBJECT_USE_OBJC=0 to your - * compiler flags. - * - * This mode requires a platform with the modern Objective-C runtime, the - * Objective-C GC compiler option to be disabled, and at least a Mac OS X 10.8 - * deployment target. - */ - -#ifndef OS_OBJECT_HAVE_OBJC_SUPPORT -#if defined(__OBJC2__) && !defined(__OBJC_GC__) && ( \ - __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8 || \ - __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0) -#define OS_OBJECT_HAVE_OBJC_SUPPORT 1 -#else -#define OS_OBJECT_HAVE_OBJC_SUPPORT 0 -#endif -#endif - -#if OS_OBJECT_HAVE_OBJC_SUPPORT -#ifndef OS_OBJECT_USE_OBJC -#define OS_OBJECT_USE_OBJC 1 -#endif -#elif defined(OS_OBJECT_USE_OBJC) && OS_OBJECT_USE_OBJC -/* Unsupported platform for OS_OBJECT_USE_OBJC=1 */ -#undef OS_OBJECT_USE_OBJC -#define OS_OBJECT_USE_OBJC 0 -#else -#define OS_OBJECT_USE_OBJC 0 -#endif - -#if OS_OBJECT_USE_OBJC -#import -#define OS_OBJECT_CLASS(name) OS_##name -#define OS_OBJECT_DECL(name, ...) \ - @protocol OS_OBJECT_CLASS(name) __VA_ARGS__ \ - @end \ - typedef NSObject *name##_t -#define OS_OBJECT_DECL_SUBCLASS(name, super) \ - OS_OBJECT_DECL(name, ) -#if defined(__has_attribute) && __has_attribute(ns_returns_retained) -#define OS_OBJECT_RETURNS_RETAINED __attribute__((__ns_returns_retained__)) -#else -#define OS_OBJECT_RETURNS_RETAINED -#endif -#if defined(__has_feature) && __has_feature(objc_arc) -#define OS_OBJECT_BRIDGE __bridge -#else -#define OS_OBJECT_BRIDGE -#endif -#ifndef OS_OBJECT_USE_OBJC_RETAIN_RELEASE -#if defined(__has_feature) && __has_feature(objc_arc) || \ - defined(__clang_analyzer__) -#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 1 -#else -#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 0 -#endif -#endif -#else -/*! @parseOnly */ -#define OS_OBJECT_RETURNS_RETAINED -/*! @parseOnly */ -#define OS_OBJECT_BRIDGE -#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 0 -#endif - -#endif diff --git a/src/libc/os/object.h b/src/libc/os/object.h new file mode 120000 index 000000000..83904b35d --- /dev/null +++ b/src/libc/os/object.h @@ -0,0 +1 @@ +../../external/libdispatch/os/object.h \ No newline at end of file diff --git a/src/libc/os/overflow.h b/src/libc/os/overflow.h new file mode 100644 index 000000000..8d0fd9949 --- /dev/null +++ b/src/libc/os/overflow.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +/* + * Facilities for performing type- and overflow-checked arithmetic. These + * functions return non-zero if overflow occured, zero otherwise. In either case, + * the potentially overflowing operation is fully performed, mod the size of the + * output type. See: + * http://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins + * for full details. + * + * The compiler enforces that users of os_*_overflow() check the return value to + * determine whether overflow occured. + */ + +#ifndef _OS_OVERFLOW_H +#define _OS_OVERFLOW_H + +#include +#include +#include + +bool __header_always_inline OS_WARN_RESULT +__os_warn_unused(__const bool x) +{ + return x; +} + +#if __has_builtin(__builtin_add_overflow) && \ + __has_builtin(__builtin_sub_overflow) && \ + __has_builtin(__builtin_mul_overflow) + +#define os_add_overflow(a, b, res) __os_warn_unused(__builtin_add_overflow((a), (b), (res))) +#define os_sub_overflow(a, b, res) __os_warn_unused(__builtin_sub_overflow((a), (b), (res))) +#define os_mul_overflow(a, b, res) __os_warn_unused(__builtin_mul_overflow((a), (b), (res))) + +#else + +/* compile-time assertion that 'x' and 'y' are equivalent types */ +#ifdef __cplusplus +#define __OS_TYPE_CHECK(x, y) do { \ + __typeof__(x) _x; \ + __typeof__(y) _y; \ + (void)(&_x == &_y, "overflow arithmetic: incompatible types"); \ +} while (0) +#else +#define __OS_TYPE_CHECK(x, y) do { \ + _Static_assert(__builtin_types_compatible_p(__typeof(x),__typeof(y)), \ + "overflow arithmetic: incompatible types"); \ +} while (0) +#endif + +#define __os_add_overflow_func(T,U,V) _Generic((T), \ + unsigned: __builtin_uadd_overflow, \ + unsigned long: __builtin_uaddl_overflow, \ + unsigned long long: __builtin_uaddll_overflow, \ + int: __builtin_sadd_overflow, \ + long: __builtin_saddl_overflow, \ + long long: __builtin_saddll_overflow \ + )(T,U,V) + +#define __os_sub_overflow_func(T,U,V) _Generic((T), \ + unsigned: __builtin_usub_overflow, \ + unsigned long: __builtin_usubl_overflow, \ + unsigned long long: __builtin_usubll_overflow, \ + int: __builtin_ssub_overflow, \ + long: __builtin_ssubl_overflow, \ + long long: __builtin_ssubll_overflow \ + )(T,U,V) + +#define __os_mul_overflow_func(T,U,V) _Generic((T), \ + unsigned: __builtin_umul_overflow, \ + unsigned long: __builtin_umull_overflow, \ + unsigned long long: __builtin_umulll_overflow, \ + int: __builtin_smul_overflow, \ + long: __builtin_smull_overflow, \ + long long: __builtin_smulll_overflow \ + )(T,U,V) + +#define os_add_overflow(a, b, res) __os_warn_unused(__extension__({ \ + __OS_TYPE_CHECK((a), (b)); \ + __OS_TYPE_CHECK((b), *(res)); \ + __os_add_overflow_func((a), (b), (res)); \ +})) + +#define os_sub_overflow(a, b, res) __os_warn_unused(__extension__({ \ + __OS_TYPE_CHECK((a), (b)); \ + __OS_TYPE_CHECK((b), *(res)); \ + __os_sub_overflow_func((a), (b), (res)); \ +})) + +#define os_mul_overflow(a, b, res) __os_warn_unused(__extension__({ \ + __OS_TYPE_CHECK((a), (b)); \ + __OS_TYPE_CHECK((b), *(res)); \ + __os_mul_overflow_func((a), (b), (res)); \ +})) + +#endif /* __has_builtin(...) */ + +/* os_add3_overflow(a, b, c) -> (a + b + c) */ +#define os_add3_overflow(a, b, c, res) __os_warn_unused(__extension__({ \ + __typeof(*(res)) _tmp; \ + bool _s, _t; \ + _s = os_add_overflow((a), (b), &_tmp); \ + _t = os_add_overflow((c), _tmp, (res)); \ + _s | _t; \ +})) + +/* os_add_and_mul_overflow(a, b, x) -> (a + b)*x */ +#define os_add_and_mul_overflow(a, b, x, res) __os_warn_unused(__extension__({ \ + __typeof(*(res)) _tmp; \ + bool _s, _t; \ + _s = os_add_overflow((a), (b), &_tmp); \ + _t = os_mul_overflow((x), _tmp, (res)); \ + _s | _t; \ +})) + +/* os_mul_and_add_overflow(a, x, b) -> a*x + b */ +#define os_mul_and_add_overflow(a, x, b, res) __os_warn_unused(__extension__({ \ + __typeof(*(res)) _tmp; \ + bool _s, _t; \ + _s = os_mul_overflow((a), (x), &_tmp); \ + _t = os_add_overflow((b), _tmp, (res)); \ + _s | _t; \ +})) + +#endif /* _OS_OVERFLOW_H */ diff --git a/src/libc/platform/CMakeLists.txt b/src/libc/platform/CMakeLists.txt deleted file mode 100644 index be0ee3d7f..000000000 --- a/src/libc/platform/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -project(libc-platform) - -cmake_minimum_required(VERSION 2.4.0) - -set(platform_sources OSAtomic.c) - -add_library(libc-platform OBJECT ${platform_sources}) - - diff --git a/src/libc/platform/OSAtomic.c b/src/libc/platform/OSAtomic.c deleted file mode 100644 index 73c42ce0e..000000000 --- a/src/libc/platform/OSAtomic.c +++ /dev/null @@ -1,33 +0,0 @@ -#include - -// In OS X 10.10 (or something) the following became full-fledged symbols -// provided in libsystem_platform (not released as open source). - -int32_t OSAtomicIncrement32( volatile int32_t *__theValue ) - { return OSAtomicAdd32( 1, __theValue); } - - -int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue ) - { return OSAtomicAdd32Barrier( 1, __theValue); } - -int32_t OSAtomicDecrement32( volatile int32_t *__theValue ) - { return OSAtomicAdd32( -1, __theValue); } - -int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue ) - { return OSAtomicAdd32Barrier( -1, __theValue); } - - -int64_t OSAtomicIncrement64( volatile int64_t *__theValue ) - { return OSAtomicAdd64( 1, __theValue); } - -int64_t OSAtomicIncrement64Barrier( volatile int64_t *__theValue ) - { return OSAtomicAdd64Barrier( 1, __theValue); } - - -int64_t OSAtomicDecrement64( volatile int64_t *__theValue ) - { return OSAtomicAdd64( -1, __theValue); } - - -int64_t OSAtomicDecrement64Barrier( volatile int64_t *__theValue ) - { return OSAtomicAdd64Barrier( -1, __theValue); } - diff --git a/src/libc/platform/TODO b/src/libc/platform/TODO deleted file mode 100644 index 23296b9cd..000000000 --- a/src/libc/platform/TODO +++ /dev/null @@ -1,4 +0,0 @@ -A new library libsystem_platform, cotains all OSAtomic, setjmp/longjmp, ffs, swapcontext and other functions. - -They should all be moved here and built as a separate library. - diff --git a/src/libc/posix1e/acl_file.c b/src/libc/posix1e/acl_file.c index b09c7020e..6b62d13fb 100644 --- a/src/libc/posix1e/acl_file.c +++ b/src/libc/posix1e/acl_file.c @@ -38,6 +38,7 @@ static acl_t acl_get_file1(const char *path, acl_type_t acl_type, int follow); +int acl_delete_fd_np(int filedes, acl_type_t type); int acl_delete_fd_np(int filedes, acl_type_t type) { @@ -45,6 +46,7 @@ acl_delete_fd_np(int filedes, acl_type_t type) return(-1); } +int acl_delete_file_np(const char *path, acl_type_t type); int acl_delete_file_np(const char *path, acl_type_t type) { @@ -52,6 +54,7 @@ acl_delete_file_np(const char *path, acl_type_t type) return(-1); } +int acl_delete_link_np(const char *path, acl_type_t type); int acl_delete_link_np(const char *path, acl_type_t type) { diff --git a/src/libc/posix1e/acl_perm.c b/src/libc/posix1e/acl_perm.c index 579915d0e..d19e05682 100644 --- a/src/libc/posix1e/acl_perm.c +++ b/src/libc/posix1e/acl_perm.c @@ -81,6 +81,9 @@ #if __DARWIN_ACL_CHANGE_OWNER != KAUTH_VNODE_CHANGE_OWNER # error __DARWIN_ACL_CHANGE_OWNER != KAUTH_VNODE_CHANGE_OWNER #endif +#if __DARWIN_ACL_SYNCHRONIZE != KAUTH_VNODE_SYNCHRONIZE +# error __DARWIN_ACL_SYNCHRONIZE != KAUTH_VNODE_SYNCHRONIZE +#endif int acl_add_perm(acl_permset_t permset, acl_perm_t perm) diff --git a/src/libc/posix1e/acl_translate.c b/src/libc/posix1e/acl_translate.c index 527f686b3..2d400f694 100644 --- a/src/libc/posix1e/acl_translate.c +++ b/src/libc/posix1e/acl_translate.c @@ -227,6 +227,7 @@ static struct { {ACL_READ_SECURITY, "readsecurity", ACL_TYPE_FILE | ACL_TYPE_DIR}, {ACL_WRITE_SECURITY, "writesecurity", ACL_TYPE_FILE | ACL_TYPE_DIR}, {ACL_CHANGE_OWNER, "chown", ACL_TYPE_FILE | ACL_TYPE_DIR}, + {ACL_SYNCHRONIZE, "synchronize", ACL_TYPE_FILE | ACL_TYPE_DIR}, {0, NULL, 0} }; @@ -248,7 +249,6 @@ static struct { /* * reallocing snprintf with offset */ - static int raosnprintf(char **buf, size_t *size, ssize_t *offset, char *fmt, ...) { @@ -698,8 +698,8 @@ acl_to_text(acl_t acl, ssize_t *len_p) } } } - buf[(*len_p)++] = '\n'; - buf[(*len_p)] = 0; + + if(!raosnprintf(&buf, &bufsize, len_p, "\n")) goto err_nomem; return buf; err_nomem: diff --git a/src/libc/posix1e/aclvar.h b/src/libc/posix1e/aclvar.h index 33c432b60..448003778 100644 --- a/src/libc/posix1e/aclvar.h +++ b/src/libc/posix1e/aclvar.h @@ -105,7 +105,8 @@ struct _acl_permset { ACL_WRITE_EXTATTRIBUTES | \ ACL_READ_SECURITY | \ ACL_WRITE_SECURITY | \ - ACL_CHANGE_OWNER) + ACL_CHANGE_OWNER | \ + ACL_SYNCHRONIZE) #define _ACL_VALID_PERM(_f) (((_f) & ~_ACL_PERMS_MASK) == 0) diff --git a/src/libc/pthreads/CMakeLists.txt b/src/libc/pthreads/CMakeLists.txt deleted file mode 100644 index b53a19757..000000000 --- a/src/libc/pthreads/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -project(libc-pthreads) - -cmake_minimum_required(VERSION 2.4.0) - -set(CMAKE_C_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_C_FLAGS} -include ${CMAKE_CURRENT_SOURCE_DIR}/../../duct/include/commpage.h -include ${DARLING_TOP_DIRECTORY}/platform-include/sys/time.h") - -set(pthreads_sources - pthread.c - pthread_cancelable.c - pthread_cond.c - pthread_mutex.c - pthread_rwlock.c - pthread_tsd.c - thread_setup.c -) - -SET_SOURCE_FILES_PROPERTIES(pthread.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_PTHREAD_CANCEL -DLIBC_ALIAS_PTHREAD_SETCANCELSTATE -DLIBC_ALIAS_PTHREAD_SETCANCELTYPE -DLIBC_ALIAS_PTHREAD_SIGMASK -DLIBC_ALIAS_PTHREAD_TESTCANCEL") -SET_SOURCE_FILES_PROPERTIES(pthread_cancelable.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT") -SET_SOURCE_FILES_PROPERTIES(thread_setup.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0") -SET_SOURCE_FILES_PROPERTIES(pthread_cond.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_INIT -DLIBC_ALIAS_PTHREAD_COND_WAIT") -SET_SOURCE_FILES_PROPERTIES(pthread_rwlock.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_PTHREAD_RWLOCK_INIT -DLIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_DESTROY -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK") - -add_library(libc-pthreads OBJECT ${pthreads_sources}) - -# Cancelable variant -set(pthreads-cancelable_sources - pthread_cancelable.c) - -add_library(libc-pthreads_cancelable OBJECT ${pthreads-cancelable_sources}) -SET_TARGET_PROPERTIES(libc-pthreads_cancelable PROPERTIES COMPILE_DEFINITIONS "BUILDING_VARIANT;VARIANT_CANCELABLE") -SET_TARGET_PROPERTIES(libc-pthreads_cancelable PROPERTIES COMPILE_FLAGS "-U__DARWIN_NON_CANCELABLE") - -# Legacy variant -set(pthreads-legacy_sources - pthread.c - pthread_cond.c - pthread_mutex.c - pthread_rwlock.c - pthread_cancelable.c) - -add_library(libc-pthreads_legacy OBJECT ${pthreads-legacy_sources}) -SET_TARGET_PROPERTIES(libc-pthreads_legacy PROPERTIES COMPILE_FLAGS "-DBUILDING_VARIANT -DVARIANT_LEGACY -U_DARWIN_C_SOURCE -U_POSIX_C_SOURCE -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0") - -# DYLD variant - -add_library(libc-pthreads_dyld OBJECT pthread.c pthread_mutex.c pthread_tsd.c pthread_cond.c pthread_cancelable.c) -SET_TARGET_PROPERTIES(libc-pthreads_dyld PROPERTIES COMPILE_FLAGS "-UBUILDING_VARIANT -DVARIANT_DYLD -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN") diff --git a/src/libc/pthreads/mk_pthread_impl.c b/src/libc/pthreads/mk_pthread_impl.c deleted file mode 100644 index 8654c45a1..000000000 --- a/src/libc/pthreads/mk_pthread_impl.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * This program will generate the stuff necessary to "publish" the POSIX - * header in a machine dependent fashion. - */ - -#include -#include - -int -main(void) -{ - printf("#ifndef _PTHREAD_IMPL_H_\n"); - printf("#define _PTHREAD_IMPL_H_\n"); - printf("/*\n"); - printf(" * Internal implementation details\n"); - printf(" */\n"); - printf("\n"); - printf("#define __PTHREAD_SIZE__ %zd\n", sizeof(struct _pthread)-sizeof(long)); - printf("#define __PTHREAD_ATTR_SIZE__ %zd\n", sizeof(pthread_attr_t)-sizeof(long)); - printf("#define __PTHREAD_MUTEXATTR_SIZE__ %zd\n", sizeof(pthread_mutexattr_t)-sizeof(long)); - printf("#define __PTHREAD_MUTEX_SIZE__ %zd\n", sizeof(pthread_mutex_t)-sizeof(long)); - printf("#define __PTHREAD_CONDATTR_SIZE__ %zd\n", sizeof(pthread_condattr_t)-sizeof(long)); - printf("#define __PTHREAD_COND_SIZE__ %zd\n", sizeof(pthread_cond_t)-sizeof(long)); - printf("#define __PTHREAD_ONCE_SIZE__ %zd\n", sizeof(pthread_once_t)-sizeof(long)); - printf("#define __PTHREAD_sig_OFFSET__ %zd\n", offsetof(struct _pthread, sig)); - printf("#define __PTHREAD_cleanup_stack_OFFSET__ %zd\n", offsetof(struct _pthread, __cleanup_stack)); - printf("#define __PTHREAD_guardsize_OFFSET__ %zd\n", offsetof(struct _pthread, guardsize)); - printf("#define __PTHREAD_param_OFFSET__ %zd\n", offsetof(struct _pthread, param)); - printf("#define __PTHREAD_mutexes_OFFSET__ %zd\n", offsetof(struct _pthread, mutexes)); - printf("#define __PTHREAD_joiner_OFFSET__ %zd\n", offsetof(struct _pthread, joiner)); - printf("#define __PTHREAD_exit_value_OFFSET__ %zd\n", offsetof(struct _pthread, exit_value)); - printf("#define __PTHREAD_death_OFFSET__ %zd\n", offsetof(struct _pthread, death)); - printf("#define __PTHREAD_kernel_thread_OFFSET__ %zd\n", offsetof(struct _pthread, kernel_thread)); - printf("#define __PTHREAD_fun_OFFSET__ %zd\n", offsetof(struct _pthread, fun)); - printf("#define __PTHREAD_arg_OFFSET__ %zd\n", offsetof(struct _pthread, arg)); - printf("#define __PTHREAD_cancel_state_OFFSET__ %zd\n", offsetof(struct _pthread, cancel_state)); - printf("#define __PTHREAD_err_no_OFFSET__ %zd\n", offsetof(struct _pthread, err_no)); - printf("#define __PTHREAD_tsd_OFFSET__ %zd\n", offsetof(struct _pthread, tsd)); - printf("#define __PTHREAD_stackaddr_OFFSET__ %zd\n", offsetof(struct _pthread, stackaddr)); - printf("#define __PTHREAD_stacksize_OFFSET__ %zd\n", offsetof(struct _pthread, stacksize)); - printf("#define __PTHREAD_reply_port_OFFSET__ %zd\n", offsetof(struct _pthread, reply_port)); - printf("#define __PTHREAD_cthread_self_OFFSET__ %zd\n", offsetof(struct _pthread, cthread_self)); - printf("#define __PTHREAD_freeStackOnExit_OFFSET__ %zd\n", offsetof(struct _pthread, freeStackOnExit)); - printf("#define __PTHREAD_plist_OFFSET__ %zd\n", offsetof(struct _pthread, plist)); - printf("/*\n"); - printf(" * [Internal] data structure signatures\n"); - printf(" */\n"); - printf("#define _PTHREAD_MUTEX_SIG_init 0x%08X\n", _PTHREAD_MUTEX_SIG_init); - printf("#define _PTHREAD_COND_SIG_init 0x%08X\n", _PTHREAD_COND_SIG_init); - printf("#define _PTHREAD_ONCE_SIG_init 0x%08X\n", _PTHREAD_ONCE_SIG_init); - printf("/*\n"); - printf(" * POSIX scheduling policies \n"); - printf(" */\n"); - printf("#define SCHED_OTHER %d\n", SCHED_OTHER); - printf("#define SCHED_FIFO %d\n", SCHED_FIFO); - printf("#define SCHED_RR %d\n", SCHED_RR); - printf("\n"); - printf("#define __SCHED_PARAM_SIZE__ %ld\n", (long) sizeof(struct sched_param)-sizeof(int)); - printf("\n"); - printf("#endif _PTHREAD_IMPL_H_\n"); - - exit(0); -} diff --git a/src/libc/pthreads/plockstat.d b/src/libc/pthreads/plockstat.d deleted file mode 100644 index 0b6a5ccbf..000000000 --- a/src/libc/pthreads/plockstat.d +++ /dev/null @@ -1,24 +0,0 @@ -typedef struct _opaque_pthread_mutex_t pthread_mutex_t; -typedef struct _opaque_pthread_rwlock_t pthread_rwlock_t; - -provider plockstat { - probe mutex__acquire(pthread_mutex_t *mutex, int recursive, int spin_count); - probe mutex__release(pthread_mutex_t *mutex, int recursive); - probe mutex__error(pthread_mutex_t *mutex, int errno); - probe mutex__block(pthread_mutex_t *mutex); - probe mutex__blocked(pthread_mutex_t *mutex, int successful); - probe mutex__spin(pthread_mutex_t *mutex); - probe mutex__spun(pthread_mutex_t *mutex, int successful, int spin_count); - - probe rw__acquire(pthread_rwlock_t *rwlock, int write_lock); - probe rw__block(pthread_rwlock_t *rwlock, int write_lock); - probe rw__blocked(pthread_rwlock_t *rwlock, int write_lock, int successful); - probe rw__release(pthread_rwlock_t *rwlock, int write_lock); - probe rw__error(pthread_rwlock_t *rwlock, int write_lock, int error); -}; - -#pragma D attributes Evolving/Evolving/ISA provider plockstat provider -#pragma D attributes Private/Private/Unknown provider plockstat module -#pragma D attributes Private/Private/Unknown provider plockstat function -#pragma D attributes Evolving/Evolving/ISA provider plockstat name -#pragma D attributes Evolving/Evolving/ISA provider plockstat args diff --git a/src/libc/pthreads/posix_sched.h b/src/libc/pthreads/posix_sched.h deleted file mode 100644 index 8bbc4a5da..000000000 --- a/src/libc/pthreads/posix_sched.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * POSIX Realtime Scheduling Framework - IEEE 1003.1b - */ - -#ifndef _POSIX_SCHED_H -#define _POSIX_SCHED_H - -struct sched_param -{ - int sched_priority; - int quantum; -}; - -/* - * POSIX scheduling policies - */ - -#define SCHED_OTHER POLICY_TIMESHARE -#define SCHED_FIFO POLICY_FIFO -#define SCHED_RR POLICY_RR - -#endif /* _POSIX_SCHED_H */ diff --git a/src/libc/pthreads/pthread.3 b/src/libc/pthreads/pthread.3 deleted file mode 100644 index fee3f7f97..000000000 --- a/src/libc/pthreads/pthread.3 +++ /dev/null @@ -1,442 +0,0 @@ -.\" Portions Copyright (c) 2001 Apple Computer, Inc. All Rights Reserved. -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/share/man/man3/pthread.3,v 1.12.2.4 2001/08/17 13:08:36 ru Exp $ -.\" -.Dd November 5, 2001 -.Dt PTHREAD 3 -.Os Darwin -.Sh NAME -.Nm pthread -.Nd POSIX thread functions -.Sh SYNOPSIS -.Fd #include -.Sh DESCRIPTION -POSIX threads are a set of functions that support applications with -requirements for multiple flows of control, called -.Fa threads , -within a process. -Multithreading is used to improve the performance of a -program. -.Pp -The POSIX thread functions are summarized in this section in the following -groups: -.Bl -bullet -offset indent -.It -Thread Routines -.It -Attribute Object Routines -.It -Mutex Routines -.It -Condition Variable Routines -.It -Read/Write Lock Routines -.It -Per-Thread Context Routines -.It -Cleanup Routines -.El -.Sh THREAD ROUTINES -.Bl -tag -width Er -.It Xo -.Ft int -.Fn pthread_create "pthread_t *thread" "const pthread_attr_t *attr" "void *(*start_routine)(void *)" "void *arg" -.Xc -Creates a new thread of execution. -.It Xo -.Ft int -.Fn pthread_detach "pthread_t thread" -.Xc -Marks a thread for deletion. -.It Xo -.Ft int -.Fn pthread_equal "pthread_t t1" "pthread_t t2" -.Xc -Compares two thread IDs. -.It Xo -.Ft void -.Fn pthread_exit "void *value_ptr" -.Xc -Terminates the calling thread. -.It Xo -.Ft int -.Fn pthread_join "pthread_t thread" "void **value_ptr" -.Xc -Causes the calling thread to wait for the termination of the specified thread. -.It Xo -.Ft int -.Fn pthread_cancel "pthread_t thread" -.Xc -Cancels execution of a thread. -.It Xo -.Ft int -.Fn pthread_once "pthread_once_t *once_control" "void (*init_routine)(void)" -.Xc -Calls an initialization routine once. -.It Xo -.Ft pthread_t -.Fn pthread_self void -.Xc -Returns the thread ID of the calling thread. -.It Xo -.Ft int -.Fn pthread_atfork "void (*prepare)(void)" "void (*parent)(void)" "void (*child)(void)" -.Xc -Registers handlers to be called before and after -.Fn fork -.El -.Sh ATTRIBUTE OBJECT ROUTINES -.Bl -tag -width Er -.It Xo -.Ft int -.Fn pthread_attr_destroy "pthread_attr_t *attr" -.Xc -Destroy a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_getinheritsched "const pthread_attr_t *attr" "int *inheritsched" -.Xc -Get the inherit scheduling attribute from a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_getschedparam "const pthread_attr_t *attr" "struct sched_param *param" -.Xc -Get the scheduling parameter attribute from a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_getschedpolicy "const pthread_attr_t *attr" "int *policy" -.Xc -Get the scheduling policy attribute from a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_getscope "const pthread_attr_t *attr" "int *contentionscope" -.Xc -Get the contention scope attribute from a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_getstacksize "const pthread_attr_t *attr" "size_t *stacksize" -.Xc -Get the stack size attribute from a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_getstackaddr "const pthread_attr_t *attr" "void **stackaddr" -.Xc -Get the stack address attribute from a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_getdetachstate "const pthread_attr_t *attr" "int *detachstate" -.Xc -Get the detach state attribute from a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_init "pthread_attr_t *attr" -.Xc -Initialize a thread attributes object with default values. -.It Xo -.Ft int -.Fn pthread_attr_setinheritsched "pthread_attr_t *attr" "int inheritsched" -.Xc -Set the inherit scheduling attribute in a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_setschedparam "pthread_attr_t *attr" "const struct sched_param *param" -.Xc -Set the scheduling parameter attribute in a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_setschedpolicy "pthread_attr_t *attr" "int policy" -.Xc -Set the scheduling policy attribute in a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_setscope "pthread_attr_t *attr" "int contentionscope" -.Xc -Set the contention scope attribute in a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_setstacksize "pthread_attr_t *attr" "size_t stacksize" -.Xc -Set the stack size attribute in a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_setstackaddr "pthread_attr_t *attr" "void *stackaddr" -.Xc -Set the stack address attribute in a thread attributes object. -.It Xo -.Ft int -.Fn pthread_attr_setdetachstate "pthread_attr_t *attr" "int detachstate" -.Xc -Set the detach state in a thread attributes object. -.El -.Sh MUTEX ROUTINES -.Bl -tag -width Er -.It Xo -.Ft int -.Fn pthread_mutexattr_destroy "pthread_mutexattr_t *attr" -.Xc -Destroy a mutex attributes object. -.It Xo -.Ft int -.Fn pthread_mutexattr_init "pthread_mutexattr_t *attr" -.Xc -Initialize a mutex attributes object with default values. -.It Xo -.Ft int -.Fn pthread_mutex_destroy "pthread_mutex_t *mutex" -.Xc -Destroy a mutex. -.It Xo -.Ft int -.Fn pthread_mutex_init "pthread_mutex_t *mutex" "const pthread_mutexattr_t *attr" -.Xc -Initialize a mutex with specified attributes. -.It Xo -.Ft int -.Fn pthread_mutex_lock "pthread_mutex_t *mutex" -.Xc -Lock a mutex and block until it becomes available. -.It Xo -.Ft int -.Fn pthread_mutex_trylock "pthread_mutex_t *mutex" -.Xc -Try to lock a mutex, but don't block if the mutex is locked by another thread, -including the current thread. -.It Xo -.Ft int -.Fn pthread_mutex_unlock "pthread_mutex_t *mutex" -.Xc -Unlock a mutex. -.El -.Sh CONDITION VARIABLE ROUTINES -.Bl -tag -width Er -.It Xo -.Ft int -.Fn pthread_condattr_init "pthread_condattr_t *attr" -.Xc -Initialize a condition variable attributes object with default values. -.It Xo -.Ft int -.Fn pthread_condattr_destroy "pthread_condattr_t *attr" -.Xc -Destroy a condition variable attributes object. -.It Xo -.Ft int -.Fn pthread_cond_broadcast "pthread_cond_t *cond" -.Xc -Unblock all threads currently blocked on the specified condition variable. -.It Xo -.Ft int -.Fn pthread_cond_destroy "pthread_cond_t *cond" -.Xc -Destroy a condition variable. -.It Xo -.Ft int -.Fn pthread_cond_init "pthread_cond_t *cond" "const pthread_condattr_t *attr" -.Xc -Initialize a condition variable with specified attributes. -.It Xo -.Ft int -.Fn pthread_cond_signal "pthread_cond_t *cond" -.Xc -Unblock at least one of the threads blocked on the specified condition variable. -.It Xo -.Ft int -.Fn pthread_cond_timedwait "pthread_cond_t *cond" "pthread_mutex_t *mutex" "const struct timespec *abstime" -.Xc -Wait no longer than the specified time for a condition and lock the specified mutex. -.It Xo -.Ft int -.Fn pthread_cond_wait "pthread_cond_t *" "pthread_mutex_t *mutex" -.Xc -Wait for a condition and lock the specified mutex. -.El -.Sh READ/WRITE LOCK ROUTINES -.Bl -tag -width Er -.It Xo -.Ft int -.Fn pthread_rwlock_destroy "pthread_rwlock_t *lock" -.Xc -Destroy a read/write lock object. -.It Xo -.Ft int -.Fn pthread_rwlock_init "pthread_rwlock_t *lock" "const pthread_rwlockattr_t *attr" -.Xc -Initialize a read/write lock object. -.It Xo -.Ft int -.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock" -.Xc -Lock a read/write lock for reading, blocking until the lock can be -acquired. -.It Xo -.Ft int -.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock" -.Xc -Attempt to lock a read/write lock for reading, without blocking if the -lock is unavailable. -.It Xo -.Ft int -.Fn pthread_rwlock_trywrlock "pthread_rwlock_t *lock" -.Xc -Attempt to lock a read/write lock for writing, without blocking if the -lock is unavailable. -.It Xo -.Ft int -.Fn pthread_rwlock_unlock "pthread_rwlock_t *lock" -.Xc -Unlock a read/write lock. -.It Xo -.Ft int -.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock" -.Xc -Lock a read/write lock for writing, blocking until the lock can be -acquired. -.It Xo -.Ft int -.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr" -.Xc -Destroy a read/write lock attribute object. -.It Xo -.Ft int -.Fn pthread_rwlockattr_getpshared "const pthread_rwlockattr_t *attr" "int *pshared" -.Xc -Retrieve the process shared setting for the read/write lock attribute -object. -.It Xo -.Ft int -.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr" -.Xc -Initialize a read/write lock attribute object. -.It Xo -.Ft int -.Fn pthread_rwlockattr_setpshared "pthread_rwlockattr_t *attr" "int pshared" -.Xc -Set the process shared setting for the read/write lock attribute object. -.El -.Sh PER-THREAD CONTEXT ROUTINES -.Bl -tag -width Er -.It Xo -.Ft int -.Fn pthread_key_create "pthread_key_t *key" "void (*routine)(void *)" -.Xc -Create a thread-specific data key. -.It Xo -.Ft int -.Fn pthread_key_delete "pthread_key_t key" -.Xc -Delete a thread-specific data key. -.It Xo -.Ft "void *" -.Fn pthread_getspecific "pthread_key_t key" -.Xc -Get the thread-specific value for the specified key. -.It Xo -.Ft int -.Fn pthread_setspecific "pthread_key_t key" "const void *value_ptr" -.Xc -Set the thread-specific value for the specified key. -.El -.Sh CLEANUP ROUTINES -.Bl -tag -width Er -.It Xo -.Ft void -.Fn pthread_cleanup_pop "int execute" -.Xc -Remove the routine at the top of the calling thread's cancellation cleanup -stack and optionally invoke it. -.It Xo -.Ft void -.Fn pthread_cleanup_push "void (*routine)(void *)" "void *routine_arg" -.Xc -Push the specified cancellation cleanup handler onto the calling thread's -cancellation stack. -.El -.Sh INSTALLATION -The default system libraries include -.Nm pthread -functions. -No additional libraries or CFLAGS are necessary to use this API. -.Sh SEE ALSO -.Xr pthread_cleanup_pop 3 , -.Xr pthread_cleanup_push 3 , -.Xr pthread_cond_broadcast 3 , -.Xr pthread_cond_destroy 3 , -.Xr pthread_cond_init 3 , -.Xr pthread_cond_signal 3 , -.Xr pthread_cond_timedwait 3 , -.Xr pthread_cond_wait 3 , -.Xr pthread_create 3 , -.Xr pthread_detach 3 , -.Xr pthread_equal 3 , -.Xr pthread_exit 3 , -.Xr pthread_getspecific 3 , -.Xr pthread_join 3 , -.Xr pthread_key_delete 3 , -.Xr pthread_mutex_destroy 3 , -.Xr pthread_mutex_init 3 , -.Xr pthread_mutex_lock 3 , -.Xr pthread_mutex_trylock 3 , -.Xr pthread_mutex_unlock 3 , -.Xr pthread_once 3 , -.Xr pthread_rwlock_destroy 3 , -.Xr pthread_rwlock_init 3 , -.Xr pthread_rwlock_rdlock 3 , -.Xr pthread_rwlock_unlock 3 , -.Xr pthread_rwlock_wrlock 3 , -.Xr pthread_rwlockattr_destroy 3 , -.Xr pthread_rwlockattr_getpshared 3 , -.Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 , -.Xr pthread_self 3 , -.Xr pthread_setspecific 3 -.Sh STANDARDS -The functions in -.Fa libc -with the -.Fa pthread_ -prefix and not -.Fa _np -suffix or -.Fa pthread_rwlock -prefix conform to -.St -p1003.1-96 . -.Pp -The functions in libc with the -.Fa pthread_ -prefix and -.Fa _np -suffix are non-portable extensions to POSIX threads. -.Pp -The functions in libc with the -.Fa pthread_rwlock -prefix are extensions created by The Open Group as part of the -.St -susv2 . diff --git a/src/libc/pthreads/pthread.c b/src/libc/pthreads/pthread.c deleted file mode 100644 index b94314d8f..000000000 --- a/src/libc/pthreads/pthread.c +++ /dev/null @@ -1,3634 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2000-2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * POSIX Pthread Library - */ - -#include "pthread_internals.h" -#include "pthread_workqueue.h" - -#include -#include /* For printf(). */ -#include -#include /* For __mach_errno_addr() prototype. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define __APPLE_API_PRIVATE -#include -#include -#if defined(__ppc__) -#include -#endif -#include /* for at_fork handlers */ - - -extern int _pthread_setcancelstate_internal(int state, int *oldstate, int conforming); -extern int __pthread_sigmask(int, const sigset_t *, sigset_t *); - -#ifndef BUILDING_VARIANT /* [ */ - -__private_extern__ struct __pthread_list __pthread_head = TAILQ_HEAD_INITIALIZER(__pthread_head); - - - -int32_t workq_targetconc[WORKQ_NUM_PRIOQUEUE]; - -/* Per-thread kernel support */ -extern void _pthread_set_self(pthread_t); -extern void mig_init(int); -static int _pthread_create_pthread_onstack(pthread_attr_t *attrs, void **stack, pthread_t *thread); -static kern_return_t _pthread_free_pthread_onstack(pthread_t t, int freestruct, int termthread); -static void _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs, void * stack, size_t stacksize, int kernalloc, int nozero); -static int _new_pthread_create_suspended(pthread_t *thread, - const pthread_attr_t *attr, - void *(*start_routine)(void *), - void *arg, - int create_susp); - -/* the registered libdispatch worker function */ -static void (*__libdispatch_workerfunction)(int, int, void *) = NULL; - -/* Get CPU capabilities from the kernel */ -__private_extern__ void _init_cpu_capabilities(void); - -/* Needed to tell the malloc subsystem we're going multithreaded */ -extern void set_malloc_singlethreaded(int); - -/* Used when we need to call into the kernel with no reply port */ -extern pthread_lock_t reply_port_lock; -int _pthread_find_thread(pthread_t thread); - -/* Mach message used to notify that a thread needs to be reaped */ - -typedef struct _pthread_reap_msg_t { - mach_msg_header_t header; - pthread_t thread; - mach_msg_trailer_t trailer; -} pthread_reap_msg_t; - -/* Utilitie */ - -__private_extern__ uintptr_t commpage_pfz_base=0; - -void __pthread_pfz_setup(const char *apple[]) __attribute__ ((visibility ("hidden"))); - -static uintptr_t __pfz_from_kernel(const char *str) -{ - unsigned long tmpval; - /* Skip over key to the first value */ - str = strchr(str, '='); - if (str == NULL) - return 0; - str++; - tmpval = strtoul(str, NULL, 0); /* may err by 0 or ULONG_MAX */ - if (tmpval == ULONG_MAX) - tmpval = 0; - - return (uintptr_t) tmpval; -} - -void -__pthread_pfz_setup(const char *apple[]) -{ - const char **p; - for (p = apple; p && *p; p++) { - /* checking if matching apple variable is at begining */ - if (strstr(*p, "pfz=") == *p) { - commpage_pfz_base = __pfz_from_kernel(*p); - bzero(*p,strlen(*p)); - break; - } - } - - if (commpage_pfz_base == 0) - commpage_pfz_base = _COMM_PAGE_TEXT_START; - - return; -} - - -/* We'll implement this when the main thread is a pthread */ -/* Use the local _pthread struct to avoid malloc before our MiG reply port is set */ -static struct _pthread _thread = {0}; - -/* This global should be used (carefully) by anyone needing to know if a -** pthread has been created. -*/ -int __is_threaded = 0; -/* _pthread_count is protected by _pthread_list_lock */ -static int _pthread_count = 1; -int __unix_conforming = 0; -static int __workqueue_newspis = 0; -static int __workqueue_oldspis = 0; -__private_extern__ size_t pthreadsize = 0; - -/* under rosetta we will use old style creation of threads */ -static int __oldstyle = 0; - -__private_extern__ pthread_lock_t _pthread_list_lock = LOCK_INITIALIZER; - -/* Same implementation as LOCK, but without the __is_threaded check */ -int _spin_tries = 0; -extern kern_return_t syscall_thread_switch(mach_port_name_t, int, mach_msg_timeout_t); -__private_extern__ void _spin_lock_retry(pthread_lock_t *lock) -{ - int tries = _spin_tries; - do { - if (tries-- > 0) - continue; - syscall_thread_switch(THREAD_NULL, SWITCH_OPTION_DEPRESS, 1); - tries = _spin_tries; - } while(!_spin_lock_try(lock)); -} - -static mach_port_t thread_recycle_port = MACH_PORT_NULL; - -/* These are used to keep track of a semaphore pool shared by mutexes and condition -** variables. -*/ - -static semaphore_t *sem_pool = NULL; -static int sem_pool_count = 0; -static int sem_pool_current = 0; -static pthread_lock_t sem_pool_lock = LOCK_INITIALIZER; - -static int default_priority; -static int max_priority; -static int min_priority; -static int pthread_concurrency; - -static OSSpinLock __workqueue_list_lock = OS_SPINLOCK_INIT; - -static void _pthread_exit(pthread_t self, void *value_ptr) __dead2; -static void _pthread_setcancelstate_exit(pthread_t self, void *value_ptr, int conforming); -static pthread_attr_t _pthread_attr_default = {0}; -static void _pthread_workq_init(pthread_workqueue_t wq, const pthread_workqueue_attr_t * attr); -static int kernel_workq_setup = 0; -static volatile int32_t kernel_workq_count = 0; -static volatile unsigned int user_workq_count = 0; /* number of outstanding workqueues */ -static volatile unsigned int user_workitem_count = 0; /* number of outstanding workitems */ -#define KERNEL_WORKQ_ELEM_MAX 64 /* Max number of elements in the kerrel */ -static int wqreadyprio = 0; /* current highest prio queue ready with items */ - -__private_extern__ struct __pthread_workitem_pool __pthread_workitem_pool_head = TAILQ_HEAD_INITIALIZER(__pthread_workitem_pool_head); -__private_extern__ struct __pthread_workqueue_pool __pthread_workqueue_pool_head = TAILQ_HEAD_INITIALIZER(__pthread_workqueue_pool_head); - -static struct _pthread_workitem * __workqueue_pool_ptr; -static size_t __workqueue_pool_size = 0; -static int __workqueue_nitems = 0; - -struct _pthread_workqueue_head __pthread_workq0_head; -struct _pthread_workqueue_head __pthread_workq1_head; -struct _pthread_workqueue_head __pthread_workq2_head; -struct _pthread_workqueue_head __pthread_workq3_head; -pthread_workqueue_head_t __pthread_wq_head_tbl[WORKQ_NUM_PRIOQUEUE] = {&__pthread_workq0_head, &__pthread_workq1_head, &__pthread_workq2_head, &__pthread_workq3_head}; - -static void workqueue_list_lock(void); -static void workqueue_list_unlock(void); -static int valid_workq(pthread_workqueue_t); -static void pick_nextworkqueue_droplock(void); -static int post_nextworkitem(pthread_workqueue_t workq); -static void _pthread_workq_return(pthread_t self); -static pthread_workqueue_attr_t _pthread_wq_attr_default = {0}; -extern void start_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_workitem_t item, int reuse); -extern void thread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int flags); -static pthread_workitem_t alloc_workitem(void); -static void free_workitem(pthread_workitem_t); -static void grow_workitem(void); -static pthread_workqueue_t alloc_workqueue(void); -static void free_workqueue(pthread_workqueue_t); -static int _pthread_work_internal_init(void); -static void workqueue_exit(pthread_t self, pthread_workqueue_t workq, pthread_workitem_t item); -void _pthread_fork_child_postinit(); - -void pthread_workqueue_atfork_prepare(void); -void pthread_workqueue_atfork_parent(void); -void pthread_workqueue_atfork_child(void); - -#ifndef VARIANT_DYLD -extern void dispatch_atfork_prepare(void); -extern void dispatch_atfork_parent(void); -extern void dispatch_atfork_child(void); -#else -#define dispatch_atfork_prepare() -#define dispatch_atfork_parent() -#define dispatch_atfork_child() -#endif - -/* workq_kernreturn commands */ -#define WQOPS_QUEUE_ADD 1 -#define WQOPS_QUEUE_REMOVE 2 -#define WQOPS_THREAD_RETURN 4 -#define WQOPS_THREAD_SETCONC 8 -#define WQOPS_QUEUE_NEWSPISUPP 0x10 /* this is to check for newer SPI support */ -#define WQOPS_QUEUE_REQTHREADS 0x20 /* request number of threads of a prio */ - -/* flag values for reuse field in the libc side _pthread_wqthread */ -#define WQ_FLAG_THREAD_PRIOMASK 0x0000ffff -#define WQ_FLAG_THREAD_OVERCOMMIT 0x00010000 /* thread is with overcommit prio */ -#define WQ_FLAG_THREAD_REUSE 0x00020000 /* thread is being reused */ -#define WQ_FLAG_THREAD_NEWSPI 0x00040000 /* the call is with new SPIs */ - - -#define WORKQUEUE_OVERCOMMIT 0x10000 /* the work_kernreturn() for overcommit in prio field */ - -/* - * Flags filed passed to bsdthread_create and back in pthread_start -31 <---------------------------------> 0 -_________________________________________ -| flags(8) | policy(8) | importance(16) | ------------------------------------------ -*/ -__private_extern__ -void _pthread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int flags); - -__private_extern__ -void _pthread_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_workitem_t item, int reuse); - -#define PTHREAD_START_CUSTOM 0x01000000 -#define PTHREAD_START_SETSCHED 0x02000000 -#define PTHREAD_START_DETACHED 0x04000000 -#define PTHREAD_START_POLICY_BITSHIFT 16 -#define PTHREAD_START_POLICY_MASK 0xff -#define PTHREAD_START_IMPORTANCE_MASK 0xffff - -static int pthread_setschedparam_internal(pthread_t, mach_port_t, int, const struct sched_param *); -extern pthread_t __bsdthread_create(void *(*func)(void *), void * func_arg, void * stack, pthread_t thread, unsigned int flags); -extern int __bsdthread_register(void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), void (*)(pthread_t, mach_port_t, void *, pthread_workitem_t, int), int,void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), int32_t *,__uint64_t); -extern int __bsdthread_terminate(void * freeaddr, size_t freesize, mach_port_t kport, mach_port_t joinsem); -extern __uint64_t __thread_selfid( void ); -extern int __pthread_canceled(int); -extern void _pthread_keys_init(void); -extern int __pthread_kill(mach_port_t, int); -extern int __pthread_markcancel(int); -extern int __workq_open(void); - - -extern int __workq_kernreturn(int, pthread_workitem_t, int, int); - -#if defined(__ppc__) || defined(__ppc64__) -static const vm_address_t PTHREAD_STACK_HINT = 0xF0000000; -#elif defined(__i386__) || defined(__x86_64__) -static const vm_address_t PTHREAD_STACK_HINT = 0xB0000000; -#elif defined(__arm__) -static const vm_address_t PTHREAD_STACK_HINT = 0x30000000; -#else -#error Need to define a stack address hint for this architecture -#endif - -/* Set the base address to use as the stack pointer, before adjusting due to the ABI - * The guardpages for stackoverflow protection is also allocated here - * If the stack was already allocated(stackaddr in attr) then there are no guardpages - * set up for the thread - */ - -static int -_pthread_allocate_stack(pthread_attr_t *attrs, void **stack) -{ - kern_return_t kr; - vm_address_t stackaddr; - size_t guardsize; - - assert(attrs->stacksize >= PTHREAD_STACK_MIN); - if (attrs->stackaddr != NULL) { - /* No guard pages setup in this case */ - assert(((uintptr_t)attrs->stackaddr % vm_page_size) == 0); - *stack = attrs->stackaddr; - return 0; - } - - guardsize = attrs->guardsize; - stackaddr = PTHREAD_STACK_HINT; - kr = vm_map(mach_task_self(), &stackaddr, - attrs->stacksize + guardsize, - vm_page_size-1, - VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE , MEMORY_OBJECT_NULL, - 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL, - VM_INHERIT_DEFAULT); - if (kr != KERN_SUCCESS) - kr = vm_allocate(mach_task_self(), - &stackaddr, attrs->stacksize + guardsize, - VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE); - if (kr != KERN_SUCCESS) { - return EAGAIN; - } - /* The guard page is at the lowest address */ - /* The stack base is the highest address */ - if (guardsize) - kr = vm_protect(mach_task_self(), stackaddr, guardsize, FALSE, VM_PROT_NONE); - *stack = (void *)(stackaddr + attrs->stacksize + guardsize); - return 0; -} - -static int -_pthread_create_pthread_onstack(pthread_attr_t *attrs, void **stack, pthread_t *thread) -{ - kern_return_t kr; - pthread_t t; - vm_address_t stackaddr; - size_t guardsize, allocsize; - - assert(attrs->stacksize >= PTHREAD_STACK_MIN); - - if (attrs->stackaddr != NULL) { - /* No guard pages setup in this case */ - assert(((uintptr_t)attrs->stackaddr % vm_page_size) == 0); - *stack = attrs->stackaddr; - t = (pthread_t)malloc(pthreadsize); - _pthread_struct_init(t, attrs, attrs->stackaddr, 0, 0, 0); - t->freeStackOnExit = 0; - t->freeaddr = 0; - t->freesize = 0; - *thread = t; - return 0; - } - - guardsize = attrs->guardsize; - allocsize = attrs->stacksize + guardsize + pthreadsize; - stackaddr = PTHREAD_STACK_HINT; - kr = vm_map(mach_task_self(), &stackaddr, - allocsize, - vm_page_size-1, - VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE , MEMORY_OBJECT_NULL, - 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL, - VM_INHERIT_DEFAULT); - if (kr != KERN_SUCCESS) - kr = vm_allocate(mach_task_self(), - &stackaddr, allocsize, - VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE); - if (kr != KERN_SUCCESS) { - return EAGAIN; - } - /* The guard page is at the lowest address */ - /* The stack base is the highest address */ - if (guardsize) - kr = vm_protect(mach_task_self(), stackaddr, guardsize, FALSE, VM_PROT_NONE); - - - *stack = (void *)(stackaddr + attrs->stacksize + guardsize); - - t = (pthread_t)(stackaddr + attrs->stacksize + guardsize); - _pthread_struct_init(t, attrs, *stack, 0, 0, 1); - t->kernalloc = 0; - t->freesize = allocsize; - t->freeaddr = (void *)stackaddr; - t->freeStackOnExit = 1; - *thread = t; - - return 0; -} - -static kern_return_t -_pthread_free_pthread_onstack(pthread_t t, int freestruct, int termthread) -{ - kern_return_t res = 0; - vm_address_t freeaddr; - size_t freesize; - int thread_count; - mach_port_t kport; - semaphore_t joinsem = SEMAPHORE_NULL; - -#if PTH_TRACE - __kdebug_trace(0x900001c, freestruct, termthread, 0, 0, 0); -#endif - kport = t->kernel_thread; - joinsem = t->joiner_notify; - - if (t->freeStackOnExit) { - freeaddr = (vm_address_t)t->freeaddr; - if (freestruct) - freesize = t->stacksize + t->guardsize + pthreadsize; - else - freesize = t->stacksize + t->guardsize; - if (termthread) { - mig_dealloc_reply_port(MACH_PORT_NULL); - LOCK(_pthread_list_lock); - if (freestruct != 0) { - TAILQ_REMOVE(&__pthread_head, t, plist); - /* if parent has not returned from create yet keep pthread_t */ -#if PTH_LISTTRACE - __kdebug_trace(0x9000010, t, 0, 0, 1, 0); -#endif - if (t->parentcheck == 0) - freesize -= pthreadsize; - } - t->childexit = 1; - thread_count = --_pthread_count; - UNLOCK(_pthread_list_lock); - -#if PTH_TRACE - __kdebug_trace(0x9000020, freeaddr, freesize, kport, 1, 0); -#endif - if (thread_count <=0) - exit(0); - else - __bsdthread_terminate((void *)freeaddr, freesize, kport, joinsem); - LIBC_ABORT("thread %p didn't terminate", t); - } else { -#if PTH_TRACE - __kdebug_trace(0x9000024, freeaddr, freesize, 0, 1, 0); -#endif - res = vm_deallocate(mach_task_self(), freeaddr, freesize); - } - } else { - if (termthread) { - mig_dealloc_reply_port(MACH_PORT_NULL); - LOCK(_pthread_list_lock); - if (freestruct != 0) { - TAILQ_REMOVE(&__pthread_head, t, plist); -#if PTH_LISTTRACE - __kdebug_trace(0x9000010, t, 0, 0, 2, 0); -#endif - } - thread_count = --_pthread_count; - t->childexit = 1; - UNLOCK(_pthread_list_lock); - - if (freestruct) { -#if PTH_TRACE - __kdebug_trace(0x9000008, t, 0, 0, 2, 0); -#endif - free(t); - } - - freeaddr = 0; - freesize = 0; -#if PTH_TRACE - __kdebug_trace(0x9000020, 0, 0, kport, 2, 0); -#endif - - if (thread_count <=0) - exit(0); - else - __bsdthread_terminate(NULL, 0, kport, joinsem); - LIBC_ABORT("thread %p didn't terminate", t); - } else if (freestruct) { - t->sig = _PTHREAD_NO_SIG; -#if PTH_TRACE - __kdebug_trace(0x9000024, t, 0, 0, 2, 0); -#endif - free(t); - } - } - return(res); -} - - - -/* - * Destroy a thread attribute structure - */ -int -pthread_attr_destroy(pthread_attr_t *attr) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) - { - attr->sig = 0; - return (0); - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* - * Get the 'detach' state from a thread attribute structure. - * Note: written as a helper function for info hiding - */ -int -pthread_attr_getdetachstate(const pthread_attr_t *attr, - int *detachstate) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) - { - *detachstate = attr->detached; - return (0); - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* - * Get the 'inherit scheduling' info from a thread attribute structure. - * Note: written as a helper function for info hiding - */ -int -pthread_attr_getinheritsched(const pthread_attr_t *attr, - int *inheritsched) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) - { - *inheritsched = attr->inherit; - return (0); - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* - * Get the scheduling parameters from a thread attribute structure. - * Note: written as a helper function for info hiding - */ -int -pthread_attr_getschedparam(const pthread_attr_t *attr, - struct sched_param *param) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) - { - *param = attr->param; - return (0); - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* - * Get the scheduling policy from a thread attribute structure. - * Note: written as a helper function for info hiding - */ -int -pthread_attr_getschedpolicy(const pthread_attr_t *attr, - int *policy) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) - { - *policy = attr->policy; - return (0); - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* Retain the existing stack size of 512K and not depend on Main thread default stack size */ -static const size_t DEFAULT_STACK_SIZE = (512*1024); -/* - * Initialize a thread attribute structure to default values. - */ -int -pthread_attr_init(pthread_attr_t *attr) -{ - attr->stacksize = DEFAULT_STACK_SIZE; - attr->stackaddr = NULL; - attr->sig = _PTHREAD_ATTR_SIG; - attr->param.sched_priority = default_priority; - attr->param.quantum = 10; /* quantum isn't public yet */ - attr->detached = PTHREAD_CREATE_JOINABLE; - attr->inherit = _PTHREAD_DEFAULT_INHERITSCHED; - attr->policy = _PTHREAD_DEFAULT_POLICY; - attr->freeStackOnExit = 1; - attr->fastpath = 1; - attr->schedset = 0; - attr->guardsize = vm_page_size; - return (0); -} - -/* - * Set the 'detach' state in a thread attribute structure. - * Note: written as a helper function for info hiding - */ -int -pthread_attr_setdetachstate(pthread_attr_t *attr, - int detachstate) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) - { - if ((detachstate == PTHREAD_CREATE_JOINABLE) || - (detachstate == PTHREAD_CREATE_DETACHED)) - { - attr->detached = detachstate; - return (0); - } else - { - return (EINVAL); - } - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* - * Set the 'inherit scheduling' state in a thread attribute structure. - * Note: written as a helper function for info hiding - */ -int -pthread_attr_setinheritsched(pthread_attr_t *attr, - int inheritsched) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) - { - if ((inheritsched == PTHREAD_INHERIT_SCHED) || - (inheritsched == PTHREAD_EXPLICIT_SCHED)) - { - attr->inherit = inheritsched; - return (0); - } else - { - return (EINVAL); - } - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* - * Set the scheduling paramters in a thread attribute structure. - * Note: written as a helper function for info hiding - */ -int -pthread_attr_setschedparam(pthread_attr_t *attr, - const struct sched_param *param) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) - { - /* TODO: Validate sched_param fields */ - attr->param = *param; - attr->schedset = 1; - return (0); - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* - * Set the scheduling policy in a thread attribute structure. - * Note: written as a helper function for info hiding - */ -int -pthread_attr_setschedpolicy(pthread_attr_t *attr, - int policy) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) - { - if ((policy == SCHED_OTHER) || - (policy == SCHED_RR) || - (policy == SCHED_FIFO)) - { - attr->policy = policy; - attr->schedset = 1; - return (0); - } else - { - return (EINVAL); - } - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* - * Set the scope for the thread. - * We currently only provide PTHREAD_SCOPE_SYSTEM - */ -int -pthread_attr_setscope(pthread_attr_t *attr, - int scope) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) { - if (scope == PTHREAD_SCOPE_SYSTEM) { - /* No attribute yet for the scope */ - return (0); - } else if (scope == PTHREAD_SCOPE_PROCESS) { - return (ENOTSUP); - } - } - return (EINVAL); /* Not an attribute structure! */ -} - -/* - * Get the scope for the thread. - * We currently only provide PTHREAD_SCOPE_SYSTEM - */ -int -pthread_attr_getscope(const pthread_attr_t *attr, - int *scope) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) { - *scope = PTHREAD_SCOPE_SYSTEM; - return (0); - } - return (EINVAL); /* Not an attribute structure! */ -} - -/* Get the base stack address of the given thread */ -int -pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) { - *stackaddr = attr->stackaddr; - return (0); - } else { - return (EINVAL); /* Not an attribute structure! */ - } -} - -int -pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) -{ - if ((attr->sig == _PTHREAD_ATTR_SIG) && (((uintptr_t)stackaddr % vm_page_size) == 0)) { - attr->stackaddr = stackaddr; - attr->freeStackOnExit = 0; - attr->fastpath = 0; - return (0); - } else { - return (EINVAL); /* Not an attribute structure! */ - } -} - -int -pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) { - *stacksize = attr->stacksize; - return (0); - } else { - return (EINVAL); /* Not an attribute structure! */ - } -} - -int -pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) -{ - if ((attr->sig == _PTHREAD_ATTR_SIG) && ((stacksize % vm_page_size) == 0) && (stacksize >= PTHREAD_STACK_MIN)) { - attr->stacksize = stacksize; - return (0); - } else { - return (EINVAL); /* Not an attribute structure! */ - } -} - -int -pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t * stacksize) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) { - *stackaddr = (void *)((uintptr_t)attr->stackaddr - attr->stacksize); - *stacksize = attr->stacksize; - return (0); - } else { - return (EINVAL); /* Not an attribute structure! */ - } -} - -/* By SUSV spec, the stackaddr is the base address, the lowest addressable - * byte address. This is not the same as in pthread_attr_setstackaddr. - */ -int -pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize) -{ - if ((attr->sig == _PTHREAD_ATTR_SIG) && - (((uintptr_t)stackaddr % vm_page_size) == 0) && - ((stacksize % vm_page_size) == 0) && (stacksize >= PTHREAD_STACK_MIN)) { - attr->stackaddr = (void *)((uintptr_t)stackaddr + stacksize); - attr->stacksize = stacksize; - attr->freeStackOnExit = 0; - attr->fastpath = 0; - return (0); - } else { - return (EINVAL); /* Not an attribute structure! */ - } -} - - -/* - * Set the guardsize attribute in the attr. - */ -int -pthread_attr_setguardsize(pthread_attr_t *attr, - size_t guardsize) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) { - /* Guardsize of 0 is valid, ot means no guard */ - if ((guardsize % vm_page_size) == 0) { - attr->guardsize = guardsize; - attr->fastpath = 0; - return (0); - } else - return(EINVAL); - } - return (EINVAL); /* Not an attribute structure! */ -} - -/* - * Get the guardsize attribute in the attr. - */ -int -pthread_attr_getguardsize(const pthread_attr_t *attr, - size_t *guardsize) -{ - if (attr->sig == _PTHREAD_ATTR_SIG) { - *guardsize = attr->guardsize; - return (0); - } - return (EINVAL); /* Not an attribute structure! */ -} - - -/* - * Create and start execution of a new thread. - */ - -static void -_pthread_body(pthread_t self) -{ - _pthread_set_self(self); -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - if( (self->thread_id = __thread_selfid()) == (__uint64_t)-1) - printf("Failed to set thread_id in _pthread_body\n"); -#endif - _pthread_exit(self, (self->fun)(self->arg)); -} - -void -_pthread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int pflags) -{ -#if WQ_DEBUG - pthread_t pself; -#endif - pthread_attr_t *attrs = &_pthread_attr_default; - char * stackaddr; - - if ((pflags & PTHREAD_START_CUSTOM) == 0) { - stackaddr = (char *)self; - _pthread_struct_init(self, attrs, stackaddr, stacksize, 1, 1); -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - _pthread_set_self(self); -#endif - LOCK(_pthread_list_lock); - if (pflags & PTHREAD_START_SETSCHED) { - self->policy = ((pflags >> PTHREAD_START_POLICY_BITSHIFT) & PTHREAD_START_POLICY_MASK); - self->param.sched_priority = (pflags & PTHREAD_START_IMPORTANCE_MASK); - } - /* These are not joinable threads */ - if ((pflags & PTHREAD_START_DETACHED) == PTHREAD_START_DETACHED) { - self->detached &= ~PTHREAD_CREATE_JOINABLE; - self->detached |= PTHREAD_CREATE_DETACHED; - } - } else { -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - _pthread_set_self(self); -#endif - LOCK(_pthread_list_lock); - } - self->kernel_thread = kport; - self->fun = fun; - self->arg = funarg; - - /* Add to the pthread list */ - if (self->parentcheck == 0) { - TAILQ_INSERT_TAIL(&__pthread_head, self, plist); -#if PTH_LISTTRACE - __kdebug_trace(0x900000c, self, 0, 0, 3, 0); -#endif - _pthread_count++; - } - self->childrun = 1; - UNLOCK(_pthread_list_lock); - -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - if( (self->thread_id = __thread_selfid()) == (__uint64_t)-1) - printf("Failed to set thread_id in pthread_start\n"); -#endif - -#if WQ_DEBUG - pself = pthread_self(); - if (self != pself) - LIBC_ABORT("self %p != pself %p", self, pself); -#endif -#if PTH_TRACE - __kdebug_trace(0x9000030, self, pflags, 0, 0, 0); -#endif - - _pthread_exit(self, (self->fun)(self->arg)); -} - -int -_pthread_create(pthread_t t, - const pthread_attr_t *attrs, - void *stack, - const mach_port_t kernel_thread) -{ - int res; - res = 0; - - do - { - memset(t, 0, sizeof(*t)); - t->newstyle = 0; - t->schedset = 0; - t->kernalloc = 0; - t->tsd[0] = t; - t->max_tsd_key = 0; - t->wqthread = 0; - t->cur_workq = 0; - t->cur_workitem = 0; - t->stacksize = attrs->stacksize; - t->stackaddr = (void *)stack; - t->guardsize = attrs->guardsize; - t->kernel_thread = kernel_thread; - t->detached = attrs->detached; - t->inherit = attrs->inherit; - t->policy = attrs->policy; - t->param = attrs->param; - t->freeStackOnExit = attrs->freeStackOnExit; - t->cancel_error = 0; - t->sig = _PTHREAD_SIG; - t->reply_port = MACH_PORT_NULL; - t->cthread_self = NULL; - LOCK_INIT(t->lock); - t->plist.tqe_next = (struct _pthread *)0; - t->plist.tqe_prev = (struct _pthread **)0; - t->cancel_state = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; - t->__cleanup_stack = (struct __darwin_pthread_handler_rec *)NULL; - t->death = SEMAPHORE_NULL; - - if (kernel_thread != MACH_PORT_NULL) - (void)pthread_setschedparam_internal(t, kernel_thread, t->policy, &t->param); - } while (0); - return (res); -} - -void -_pthread_struct_init(pthread_t t, const pthread_attr_t *attrs, void * stack, size_t stacksize, int kernalloc, int nozero) -{ - mach_vm_offset_t stackaddr = (mach_vm_offset_t)(uintptr_t)stack; - - if (nozero == 0) { - memset(t, 0, sizeof(*t)); - t->plist.tqe_next = (struct _pthread *)0; - t->plist.tqe_prev = (struct _pthread **)0; - } - t->schedset = attrs->schedset; - t->tsd[0] = t; - if (kernalloc != 0) { - stackaddr = (mach_vm_offset_t)(uintptr_t)t; - - /* if allocated from kernel set values appropriately */ - t->stacksize = stacksize; - t->stackaddr = (void *)(uintptr_t)stackaddr; - t->freeStackOnExit = 1; - t->freeaddr = (void *)(uintptr_t)(stackaddr - stacksize - vm_page_size); - t->freesize = pthreadsize + stacksize + vm_page_size; - } else { - t->stacksize = attrs->stacksize; - t->stackaddr = (void *)stack; - } - t->guardsize = attrs->guardsize; - t->detached = attrs->detached; - t->inherit = attrs->inherit; - t->policy = attrs->policy; - t->param = attrs->param; - t->cancel_error = 0; - t->sig = _PTHREAD_SIG; - t->reply_port = MACH_PORT_NULL; - t->cthread_self = NULL; - LOCK_INIT(t->lock); - t->cancel_state = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED; - t->__cleanup_stack = (struct __darwin_pthread_handler_rec *)NULL; - t->death = SEMAPHORE_NULL; - t->newstyle = 1; - t->kernalloc = kernalloc; - t->wqthread = 0; - t->cur_workq = 0; - t->cur_workitem = 0; - t->max_tsd_key = 0; -} - -/* Need to deprecate this in future */ -int -_pthread_is_threaded(void) -{ - return __is_threaded; -} - -/* Non portable public api to know whether this process has(had) atleast one thread - * apart from main thread. There could be race if there is a thread in the process of - * creation at the time of call . It does not tell whether there are more than one thread - * at this point of time. - */ -int -pthread_is_threaded_np(void) -{ - return (__is_threaded); -} - -mach_port_t -pthread_mach_thread_np(pthread_t t) -{ - mach_port_t kport = MACH_PORT_NULL; - - if (t == NULL) - goto out; - - /* - * If the call is on self, return the kernel port. We cannot - * add this bypass for main thread as it might have exited, - * and we should not return stale port info. - */ - if (t == pthread_self()) - { - kport = t->kernel_thread; - goto out; - } - - if (_pthread_lookup_thread(t, &kport, 0) != 0) - return((mach_port_t)0); - -out: - return(kport); -} - -pthread_t pthread_from_mach_thread_np(mach_port_t kernel_thread) -{ - struct _pthread * p = NULL; - - /* No need to wait as mach port is already known */ - LOCK(_pthread_list_lock); - TAILQ_FOREACH(p, &__pthread_head, plist) { - if (p->kernel_thread == kernel_thread) - break; - } - UNLOCK(_pthread_list_lock); - return p; -} - -size_t -pthread_get_stacksize_np(pthread_t t) -{ - int ret; - size_t size = 0; - - if (t == NULL) - return(ESRCH); - - if ( t == pthread_self() || t == &_thread ) //since the main thread will not get de-allocated from underneath us - { - size=t->stacksize; - return size; - } - - - LOCK(_pthread_list_lock); - - if ((ret = _pthread_find_thread(t)) != 0) { - UNLOCK(_pthread_list_lock); - return(ret); - } - - size=t->stacksize; - UNLOCK(_pthread_list_lock); - - return(size); -} - -void * -pthread_get_stackaddr_np(pthread_t t) -{ - int ret; - void * addr = NULL; - - if (t == NULL) - return((void *)(uintptr_t)ESRCH); - - if(t == pthread_self() || t == &_thread) //since the main thread will not get deallocated from underneath us - return t->stackaddr; - - LOCK(_pthread_list_lock); - - if ((ret = _pthread_find_thread(t)) != 0) { - UNLOCK(_pthread_list_lock); - return((void *)(uintptr_t)ret); - } - addr = t->stackaddr; - UNLOCK(_pthread_list_lock); - - return(addr); -} - -mach_port_t -_pthread_reply_port(pthread_t t) -{ - return t->reply_port; -} - - -/* returns non-zero if the current thread is the main thread */ -int -pthread_main_np(void) -{ - pthread_t self = pthread_self(); - - return ((self->detached & _PTHREAD_CREATE_PARENT) == _PTHREAD_CREATE_PARENT); -} - - -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) -/* if we are passed in a pthread_t that is NULL, then we return - the current thread's thread_id. So folks don't have to call - pthread_self, in addition to us doing it, if they just want - their thread_id. -*/ -int -pthread_threadid_np(pthread_t thread, __uint64_t *thread_id) -{ - int rval=0; - pthread_t self = pthread_self(); - - if (thread_id == NULL) { - return(EINVAL); - } else if (thread == NULL || thread == self) { - *thread_id = self->thread_id; - return rval; - } - - LOCK(_pthread_list_lock); - if ((rval = _pthread_find_thread(thread)) != 0) { - UNLOCK(_pthread_list_lock); - return(rval); - } - *thread_id = thread->thread_id; - UNLOCK(_pthread_list_lock); - return rval; -} -#endif - -int -pthread_getname_np(pthread_t thread, char *threadname, size_t len) -{ - int rval; - rval = 0; - - if (thread == NULL) - return(ESRCH); - - LOCK(_pthread_list_lock); - if ((rval = _pthread_find_thread(thread)) != 0) { - UNLOCK(_pthread_list_lock); - return(rval); - } - strlcpy(threadname, thread->pthread_name, len); - UNLOCK(_pthread_list_lock); - return rval; -} - -int -pthread_setname_np(const char *threadname) -{ - int rval = 0; - int len = 0; - pthread_t current_thread = pthread_self(); - - if (threadname != NULL) - len = strlen(threadname); - - /* protytype is in pthread_internals.h */ - rval = proc_setthreadname((void *)threadname, len); - if (rval == 0) { - if (threadname != NULL) { - strlcpy(current_thread->pthread_name, threadname, MAXTHREADNAMESIZE); - } else { - memset(current_thread->pthread_name, 0 , MAXTHREADNAMESIZE); - } - - } - return rval; - -} - -static int -_new_pthread_create_suspended(pthread_t *thread, - const pthread_attr_t *attr, - void *(*start_routine)(void *), - void *arg, - int create_susp) -{ - pthread_attr_t *attrs; - void *stack; - int error; - unsigned int flags; - pthread_t t,t2; - kern_return_t kern_res; - mach_port_t kernel_thread = MACH_PORT_NULL; - int needresume; - task_t self = mach_task_self(); - int kernalloc = 0; - int susp = create_susp; - - if ((attrs = (pthread_attr_t *)attr) == (pthread_attr_t *)NULL) - { /* Set up default paramters */ - attrs = &_pthread_attr_default; - } else if (attrs->sig != _PTHREAD_ATTR_SIG) { - return EINVAL; - } - error = 0; - - if (((attrs->policy != _PTHREAD_DEFAULT_POLICY) || - (attrs->param.sched_priority != default_priority)) && (create_susp == 0)) { - needresume = 1; - susp = 1; - } else - needresume = 0; - - /* In default policy (ie SCHED_OTHER) only sched_priority is used. Check for - * any change in priority or policy is needed here. - */ - if ((__oldstyle == 1) || (create_susp != 0)) { - /* Rosetta or pthread_create_suspended() */ - /* running under rosetta */ - /* Allocate a stack for the thread */ -#if PTH_TRACE - __kdebug_trace(0x9000000, create_susp, 0, 0, 0, 0); -#endif - if ((error = _pthread_allocate_stack(attrs, &stack)) != 0) { - return(error); - } - t = (pthread_t)malloc(sizeof(struct _pthread)); - *thread = t; - if (susp) { - /* Create the Mach thread for this thread */ - PTHREAD_MACH_CALL(thread_create(self, &kernel_thread), kern_res); - if (kern_res != KERN_SUCCESS) - { - printf("Can't create thread: %d\n", kern_res); - return(EINVAL); - } - } - if ((error = _pthread_create(t, attrs, stack, kernel_thread)) != 0) - { - return(error); - } - set_malloc_singlethreaded(0); - __is_threaded = 1; - - /* Send it on it's way */ - t->arg = arg; - t->fun = start_routine; - t->newstyle = 0; - /* Now set it up to execute */ - LOCK(_pthread_list_lock); - TAILQ_INSERT_TAIL(&__pthread_head, t, plist); -#if PTH_LISTTRACE - __kdebug_trace(0x900000c, t, 0, 0, 4, 0); -#endif - _pthread_count++; - UNLOCK(_pthread_list_lock); - _pthread_setup(t, _pthread_body, stack, susp, needresume); - return(0); - } else { - - flags = 0; - if (attrs->fastpath == 1) - kernalloc = 1; - - if (attrs->detached == PTHREAD_CREATE_DETACHED) - flags |= PTHREAD_START_DETACHED; - if (attrs->schedset != 0) { - flags |= PTHREAD_START_SETSCHED; - flags |= ((attrs->policy & PTHREAD_START_POLICY_MASK) << PTHREAD_START_POLICY_BITSHIFT); - flags |= (attrs->param.sched_priority & PTHREAD_START_IMPORTANCE_MASK); - } - - set_malloc_singlethreaded(0); - __is_threaded = 1; - - if (kernalloc == 0) { - /* Allocate a stack for the thread */ - flags |= PTHREAD_START_CUSTOM; - if ((error = _pthread_create_pthread_onstack(attrs, &stack, &t)) != 0) { - return(error); - } - /* Send it on it's way */ - t->arg = arg; - t->fun = start_routine; - t->newstyle = 1; - -#if PTH_TRACE - __kdebug_trace(0x9000004, t, flags, 0, 0, 0); -#endif - - if ((t2 = __bsdthread_create(start_routine, arg, stack, t, flags)) == (pthread_t)-1) { - _pthread_free_pthread_onstack(t, 1, 0); - return (EAGAIN); - } - else t=t2; - LOCK(_pthread_list_lock); - t->parentcheck = 1; - if ((t->childexit != 0) && ((t->detached & PTHREAD_CREATE_DETACHED) == PTHREAD_CREATE_DETACHED)) { - /* detached child exited, mop up */ - UNLOCK(_pthread_list_lock); -#if PTH_TRACE - __kdebug_trace(0x9000008, t, 0, 0, 1, 0); -#endif - if(t->freeStackOnExit) - vm_deallocate(self, (mach_vm_address_t)(uintptr_t)t, pthreadsize); - else - free(t); - } else if (t->childrun == 0) { - TAILQ_INSERT_TAIL(&__pthread_head, t, plist); - _pthread_count++; -#if PTH_LISTTRACE - __kdebug_trace(0x900000c, t, 0, 0, 1, 0); -#endif - UNLOCK(_pthread_list_lock); - } else - UNLOCK(_pthread_list_lock); - - *thread = t; - -#if PTH_TRACE - __kdebug_trace(0x9000014, t, 0, 0, 1, 0); -#endif - return (0); - - } else { - /* kernel allocation */ -#if PTH_TRACE - __kdebug_trace(0x9000018, flags, 0, 0, 0, 0); -#endif - if ((t = __bsdthread_create(start_routine, arg, (void *)attrs->stacksize, NULL, flags)) == (pthread_t)-1) - return (EAGAIN); - /* Now set it up to execute */ - LOCK(_pthread_list_lock); - t->parentcheck = 1; - if ((t->childexit != 0) && ((t->detached & PTHREAD_CREATE_DETACHED) == PTHREAD_CREATE_DETACHED)) { - /* detached child exited, mop up */ - UNLOCK(_pthread_list_lock); -#if PTH_TRACE - __kdebug_trace(0x9000008, t, pthreadsize, 0, 2, 0); -#endif - vm_deallocate(self, (mach_vm_address_t)(uintptr_t)t, pthreadsize); - } else if (t->childrun == 0) { - TAILQ_INSERT_TAIL(&__pthread_head, t, plist); - _pthread_count++; -#if PTH_LISTTRACE - __kdebug_trace(0x900000c, t, 0, 0, 2, 0); -#endif - UNLOCK(_pthread_list_lock); - } else - UNLOCK(_pthread_list_lock); - - *thread = t; - -#if PTH_TRACE - __kdebug_trace(0x9000014, t, 0, 0, 2, 0); -#endif - return(0); - } - } -} - -static int -_pthread_create_suspended(pthread_t *thread, - const pthread_attr_t *attr, - void *(*start_routine)(void *), - void *arg, - int suspended) -{ - pthread_attr_t *attrs; - void *stack; - int res; - pthread_t t; - kern_return_t kern_res; - mach_port_t kernel_thread = MACH_PORT_NULL; - int needresume; - - if ((attrs = (pthread_attr_t *)attr) == (pthread_attr_t *)NULL) - { /* Set up default paramters */ - attrs = &_pthread_attr_default; - } else if (attrs->sig != _PTHREAD_ATTR_SIG) { - return EINVAL; - } - res = 0; - - /* In default policy (ie SCHED_OTHER) only sched_priority is used. Check for - * any change in priority or policy is needed here. - */ - if (((attrs->policy != _PTHREAD_DEFAULT_POLICY) || - (attrs->param.sched_priority != default_priority)) && (suspended == 0)) { - needresume = 1; - suspended = 1; - } else - needresume = 0; - - do - { - /* Allocate a stack for the thread */ - if ((res = _pthread_allocate_stack(attrs, &stack)) != 0) { - break; - } - t = (pthread_t)malloc(sizeof(struct _pthread)); - *thread = t; - if (suspended) { - /* Create the Mach thread for this thread */ - PTHREAD_MACH_CALL(thread_create(mach_task_self(), &kernel_thread), kern_res); - if (kern_res != KERN_SUCCESS) - { - printf("Can't create thread: %d\n", kern_res); - res = EINVAL; /* Need better error here? */ - break; - } - } - if ((res = _pthread_create(t, attrs, stack, kernel_thread)) != 0) - { - break; - } - set_malloc_singlethreaded(0); - __is_threaded = 1; - - /* Send it on it's way */ - t->arg = arg; - t->fun = start_routine; - /* Now set it up to execute */ - LOCK(_pthread_list_lock); - TAILQ_INSERT_TAIL(&__pthread_head, t, plist); -#if PTH_LISTTRACE - __kdebug_trace(0x900000c, t, 0, 0, 5, 0); -#endif - _pthread_count++; - UNLOCK(_pthread_list_lock); - _pthread_setup(t, _pthread_body, stack, suspended, needresume); - } while (0); - return (res); -} - -int -pthread_create(pthread_t *thread, - const pthread_attr_t *attr, - void *(*start_routine)(void *), - void *arg) -{ - return _new_pthread_create_suspended(thread, attr, start_routine, arg, 0); -} - -int -pthread_create_suspended_np(pthread_t *thread, - const pthread_attr_t *attr, - void *(*start_routine)(void *), - void *arg) -{ - return _pthread_create_suspended(thread, attr, start_routine, arg, 1); -} - -/* - * Make a thread 'undetached' - no longer 'joinable' with other threads. - */ -int -pthread_detach(pthread_t thread) -{ - int newstyle = 0; - int ret; - - if ((ret = _pthread_lookup_thread(thread, NULL, 1)) != 0) { - return (ret); /* Not a valid thread */ - } - - LOCK(thread->lock); - newstyle = thread->newstyle; - if (thread->detached & PTHREAD_CREATE_JOINABLE) - { - if (thread->detached & _PTHREAD_EXITED) { - UNLOCK(thread->lock); - pthread_join(thread, NULL); - return 0; - } else { - if (newstyle == 0) { - semaphore_t death = thread->death; - - thread->detached &= ~PTHREAD_CREATE_JOINABLE; - thread->detached |= PTHREAD_CREATE_DETACHED; - UNLOCK(thread->lock); - if (death) - (void) semaphore_signal(death); - } else { - mach_port_t joinport = thread->joiner_notify; - - thread->detached &= ~PTHREAD_CREATE_JOINABLE; - thread->detached |= PTHREAD_CREATE_DETACHED; - - UNLOCK(thread->lock); - if (joinport) { - semaphore_signal(joinport); - } - } - return(0); - } - } else { - UNLOCK(thread->lock); - return (EINVAL); - } -} - - -/* - * pthread_kill call to system call - */ -int -pthread_kill ( - pthread_t th, - int sig) -{ - int error = 0; - mach_port_t kport = MACH_PORT_NULL; - - if ((sig < 0) || (sig > NSIG)) - return(EINVAL); - - if (_pthread_lookup_thread(th, &kport, 0) != 0) - return (ESRCH); /* Not a valid thread */ - - /* if the thread is a workqueue thread, just return error */ - if ((th->wqthread != 0) && (th->wqkillset ==0)) { - return(ENOTSUP); - } - - error = __pthread_kill(kport, sig); - - if (error == -1) - error = errno; - return(error); -} - -int -__pthread_workqueue_setkill(int enable) -{ - pthread_t self = pthread_self(); - - LOCK(self->lock); - if (enable == 0) - self->wqkillset = 0; - else - self->wqkillset = 1; - UNLOCK(self->lock); - - return(0); - -} - -/* Announce that there are pthread resources ready to be reclaimed in a */ -/* subsequent pthread_exit or reaped by pthread_join. In either case, the Mach */ -/* thread underneath is terminated right away. */ -static -void _pthread_become_available(pthread_t thread, mach_port_t kernel_thread) { - pthread_reap_msg_t msg; - kern_return_t ret; - - msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, - MACH_MSG_TYPE_MOVE_SEND); - msg.header.msgh_size = sizeof msg - sizeof msg.trailer; - msg.header.msgh_remote_port = thread_recycle_port; - msg.header.msgh_local_port = kernel_thread; - msg.header.msgh_id = 0x44454144; /* 'DEAD' */ - msg.thread = thread; - ret = mach_msg_send(&msg.header); - assert(ret == MACH_MSG_SUCCESS); -} - -/* Reap the resources for available threads */ -__private_extern__ -int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr, int conforming) { - mach_port_type_t ptype; - kern_return_t ret; - task_t self; - - self = mach_task_self(); - if (kernel_thread != MACH_PORT_DEAD) { - ret = mach_port_type(self, kernel_thread, &ptype); - if (ret == KERN_SUCCESS && ptype != MACH_PORT_TYPE_DEAD_NAME) { - /* not quite dead yet... */ - return EAGAIN; - } - ret = mach_port_deallocate(self, kernel_thread); - if (ret != KERN_SUCCESS) { - fprintf(stderr, - "mach_port_deallocate(kernel_thread) failed: %s\n", - mach_error_string(ret)); - } - } - - if (th->reply_port != MACH_PORT_NULL) { - ret = mach_port_mod_refs(self, th->reply_port, - MACH_PORT_RIGHT_RECEIVE, -1); - if (ret != KERN_SUCCESS) { - fprintf(stderr, - "mach_port_mod_refs(reply_port) failed: %s\n", - mach_error_string(ret)); - } - } - - if (th->freeStackOnExit) { - vm_address_t addr = (vm_address_t)th->stackaddr; - vm_size_t size; - - size = (vm_size_t)th->stacksize + th->guardsize; - - addr -= size; - ret = vm_deallocate(self, addr, size); - if (ret != KERN_SUCCESS) { - fprintf(stderr, - "vm_deallocate(stack) failed: %s\n", - mach_error_string(ret)); - } - } - - - if (value_ptr) - *value_ptr = th->exit_value; - if (conforming) { - if ((th->cancel_state & (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) == - (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING) && (value_ptr != NULL)) - *value_ptr = PTHREAD_CANCELED; - th->sig = _PTHREAD_NO_SIG; - } - - - if (th != &_thread) - free(th); - - return 0; -} - -static -void _pthread_reap_threads(void) -{ - pthread_reap_msg_t msg; - kern_return_t ret; - - ret = mach_msg(&msg.header, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, - sizeof msg, thread_recycle_port, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - while (ret == MACH_MSG_SUCCESS) { - mach_port_t kernel_thread = msg.header.msgh_remote_port; - pthread_t thread = msg.thread; - - /* deal with race with thread_create_running() */ - if (kernel_thread == MACH_PORT_NULL && - kernel_thread != thread->kernel_thread) { - kernel_thread = thread->kernel_thread; - } - - if ( kernel_thread == MACH_PORT_NULL || - _pthread_reap_thread(thread, kernel_thread, (void **)0, 0) == EAGAIN) - { - /* not dead yet, put it back for someone else to reap, stop here */ - _pthread_become_available(thread, kernel_thread); - return; - } - - ret = mach_msg(&msg.header, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, - sizeof msg, thread_recycle_port, - MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - } -} - -/* For compatibility... */ - -pthread_t -_pthread_self() { - return pthread_self(); -} - -/* - * Terminate a thread. - */ -int __disable_threadsignal(int); - -static void -_pthread_exit(pthread_t self, void *value_ptr) -{ - struct __darwin_pthread_handler_rec *handler; - kern_return_t kern_res; - int thread_count; - int newstyle = self->newstyle; - - /* Make this thread not to receive any signals */ - __disable_threadsignal(1); - -#if PTH_TRACE - __kdebug_trace(0x900001c, self, newstyle, 0, 0, 0); -#endif - - /* set cancel state to disable and type to deferred */ - _pthread_setcancelstate_exit(self, value_ptr, __unix_conforming); - - while ((handler = self->__cleanup_stack) != 0) - { - (handler->__routine)(handler->__arg); - self->__cleanup_stack = handler->__next; - } - _pthread_tsd_cleanup(self); - - if (newstyle == 0) { - _pthread_reap_threads(); - - LOCK(self->lock); - self->detached |= _PTHREAD_EXITED; - - if (self->detached & PTHREAD_CREATE_JOINABLE) { - mach_port_t death = self->death; - self->exit_value = value_ptr; - UNLOCK(self->lock); - /* the joiner will need a kernel thread reference, leave ours for it */ - if (death) { - PTHREAD_MACH_CALL(semaphore_signal(death), kern_res); - if (kern_res != KERN_SUCCESS) - fprintf(stderr, - "semaphore_signal(death) failed: %s\n", - mach_error_string(kern_res)); - } - LOCK(_pthread_list_lock); - thread_count = --_pthread_count; - UNLOCK(_pthread_list_lock); - } else { - UNLOCK(self->lock); - LOCK(_pthread_list_lock); - TAILQ_REMOVE(&__pthread_head, self, plist); -#if PTH_LISTTRACE - __kdebug_trace(0x9000010, self, 0, 0, 5, 0); -#endif - thread_count = --_pthread_count; - UNLOCK(_pthread_list_lock); - /* with no joiner, we let become available consume our cached ref */ - _pthread_become_available(self, self->kernel_thread); - } - - if (thread_count <= 0) - exit(0); - - /* Use a new reference to terminate ourselves. Should never return. */ - PTHREAD_MACH_CALL(thread_terminate(mach_thread_self()), kern_res); - fprintf(stderr, "thread_terminate(mach_thread_self()) failed: %s\n", - mach_error_string(kern_res)); - } else { - semaphore_t joinsem = SEMAPHORE_NULL; - - if ((self->joiner_notify == (mach_port_t)0) && (self->detached & PTHREAD_CREATE_JOINABLE)) - joinsem = new_sem_from_pool(); - LOCK(self->lock); - self->detached |= _PTHREAD_EXITED; - - self->exit_value = value_ptr; - if (self->detached & PTHREAD_CREATE_JOINABLE) { - if (self->joiner_notify == (mach_port_t)0) { - self->joiner_notify = joinsem; - joinsem = SEMAPHORE_NULL; - } - UNLOCK(self->lock); - if (joinsem != SEMAPHORE_NULL) - restore_sem_to_pool(joinsem); - _pthread_free_pthread_onstack(self, 0, 1); - } else { - UNLOCK(self->lock); - /* with no joiner, we let become available consume our cached ref */ - if (joinsem != SEMAPHORE_NULL) - restore_sem_to_pool(joinsem); - _pthread_free_pthread_onstack(self, 1, 1); - } - } - LIBC_ABORT("thread %p didn't exit", self); -} - -void -pthread_exit(void *value_ptr) -{ - pthread_t self = pthread_self(); - /* if the current thread is a workqueue thread, just crash the app, as per libdispatch folks */ - if (self->wqthread == 0) { - _pthread_exit(self, value_ptr); - } else { - LIBC_ABORT("pthread_exit() may only be called against threads created via pthread_create()"); - } -} - -/* - * Get the scheduling policy and scheduling paramters for a thread. - */ -int -pthread_getschedparam(pthread_t thread, - int *policy, - struct sched_param *param) -{ - int ret; - - if (thread == NULL) - return(ESRCH); - - LOCK(_pthread_list_lock); - - if ((ret = _pthread_find_thread(thread)) != 0) { - UNLOCK(_pthread_list_lock); - return(ret); - } - if (policy != 0) - *policy = thread->policy; - if (param != 0) - *param = thread->param; - UNLOCK(_pthread_list_lock); - - return(0); -} - -/* - * Set the scheduling policy and scheduling paramters for a thread. - */ -static int -pthread_setschedparam_internal(pthread_t thread, - mach_port_t kport, - int policy, - const struct sched_param *param) -{ - policy_base_data_t bases; - policy_base_t base; - mach_msg_type_number_t count; - kern_return_t ret; - - switch (policy) - { - case SCHED_OTHER: - bases.ts.base_priority = param->sched_priority; - base = (policy_base_t)&bases.ts; - count = POLICY_TIMESHARE_BASE_COUNT; - break; - case SCHED_FIFO: - bases.fifo.base_priority = param->sched_priority; - base = (policy_base_t)&bases.fifo; - count = POLICY_FIFO_BASE_COUNT; - break; - case SCHED_RR: - bases.rr.base_priority = param->sched_priority; - /* quantum isn't public yet */ - bases.rr.quantum = param->quantum; - base = (policy_base_t)&bases.rr; - count = POLICY_RR_BASE_COUNT; - break; - default: - return (EINVAL); - } - ret = thread_policy(kport, policy, base, count, TRUE); - if (ret != KERN_SUCCESS) - return (EINVAL); - return (0); -} - -int -pthread_setschedparam(pthread_t t, - int policy, - const struct sched_param *param) -{ - mach_port_t kport = MACH_PORT_NULL; - int error; - int bypass = 1; - - if (t != pthread_self() && t != &_thread ) { //since the main thread will not get de-allocated from underneath us - bypass = 0; - if (_pthread_lookup_thread(t, &kport, 0) != 0) - return(ESRCH); - } else - kport = t->kernel_thread; - - error = pthread_setschedparam_internal(t, kport, policy, param); - if (error == 0) { - if (bypass == 0) { - /* ensure the thread is still valid */ - LOCK(_pthread_list_lock); - if ((error = _pthread_find_thread(t)) != 0) { - UNLOCK(_pthread_list_lock); - return(error); - } - t->policy = policy; - t->param = *param; - UNLOCK(_pthread_list_lock); - } else { - t->policy = policy; - t->param = *param; - } - } - return(error); -} - -/* - * Get the minimum priority for the given policy - */ -int -sched_get_priority_min(int policy) -{ - return default_priority - 16; -} - -/* - * Get the maximum priority for the given policy - */ -int -sched_get_priority_max(int policy) -{ - return default_priority + 16; -} - -/* - * Determine if two thread identifiers represent the same thread. - */ -int -pthread_equal(pthread_t t1, - pthread_t t2) -{ - return (t1 == t2); -} - -// Force LLVM not to optimise this to a call to __pthread_set_self, if it does -// then _pthread_set_self won't be bound when secondary threads try and start up. -void __attribute__((noinline)) -_pthread_set_self(pthread_t p) -{ - extern void __pthread_set_self(void *); - - if (p == 0) { - if (_thread.tsd[0] != 0) { - bzero(&_thread, sizeof(struct _pthread)); - } - p = &_thread; - } - p->tsd[0] = p; - __pthread_set_self(&p->tsd[0]); -} - -void -cthread_set_self(void *cself) -{ - pthread_t self = pthread_self(); - if ((self == (pthread_t)NULL) || (self->sig != _PTHREAD_SIG)) { - _pthread_set_self(cself); - return; - } - self->cthread_self = cself; -} - -void * -ur_cthread_self(void) { - pthread_t self = pthread_self(); - if ((self == (pthread_t)NULL) || (self->sig != _PTHREAD_SIG)) { - return (void *)self; - } - return self->cthread_self; -} - -/* - * cancellation handler for pthread once as the init routine can have a - * cancellation point. In that case we need to restore the spin unlock - */ -void -__pthread_once_cancel_handler(pthread_once_t *once_control) -{ - _spin_unlock(&once_control->lock); -} - - -/* - * Execute a function exactly one time in a thread-safe fashion. - */ -int -pthread_once(pthread_once_t *once_control, - void (*init_routine)(void)) -{ - _spin_lock(&once_control->lock); - if (once_control->sig == _PTHREAD_ONCE_SIG_init) - { - pthread_cleanup_push((void (*)(void *))__pthread_once_cancel_handler, once_control); - (*init_routine)(); - pthread_cleanup_pop(0); - once_control->sig = _PTHREAD_ONCE_SIG; - } - _spin_unlock(&once_control->lock); - return (0); /* Spec defines no possible errors! */ -} - -/* - * Insert a cancellation point in a thread. - */ -/*__private_extern__*/ void // accessed by libsystem.dylib -_pthread_testcancel(pthread_t thread, int isconforming) -{ - LOCK(thread->lock); - if ((thread->cancel_state & (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) == - (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) - { - UNLOCK(thread->lock); - if (isconforming) - pthread_exit(PTHREAD_CANCELED); - else - pthread_exit(0); - } - UNLOCK(thread->lock); -} - - - -int -pthread_getconcurrency(void) -{ - return(pthread_concurrency); -} - -int -pthread_setconcurrency(int new_level) -{ - if (new_level < 0) - return EINVAL; - pthread_concurrency = new_level; - return(0); -} - -/* - * Perform package initialization - called automatically when application starts - */ -int -pthread_init(void) -{ - pthread_attr_t *attrs; - pthread_t thread; - kern_return_t kr; - host_priority_info_data_t priority_info; - host_info_t info; - host_flavor_t flavor; - host_t host; - mach_msg_type_number_t count; - int mib[2]; - int ncpus = 0; - size_t len; - void *stackaddr; - - pthreadsize = round_page(sizeof (struct _pthread)); - count = HOST_PRIORITY_INFO_COUNT; - info = (host_info_t)&priority_info; - flavor = HOST_PRIORITY_INFO; - host = mach_host_self(); - kr = host_info(host, flavor, info, &count); - if (kr != KERN_SUCCESS) - printf("host_info failed (%d); probably need privilege.\n", kr); - else { - default_priority = priority_info.user_priority; - min_priority = priority_info.minimum_priority; - max_priority = priority_info.maximum_priority; - } - attrs = &_pthread_attr_default; - pthread_attr_init(attrs); - - TAILQ_INIT(&__pthread_head); - LOCK_INIT(_pthread_list_lock); - thread = &_thread; - TAILQ_INSERT_HEAD(&__pthread_head, thread, plist); - _pthread_set_self(thread); -#if PTH_LISTTRACE - __kdebug_trace(0x900000c, thread, 0, 0, 10, 0); -#endif - - /* In case of dyld reset the tsd keys from 1 - 10 */ - _pthread_keys_init(); - - mib[0] = CTL_KERN; - mib[1] = KERN_USRSTACK; - len = sizeof (stackaddr); - if (sysctl (mib, 2, &stackaddr, &len, NULL, 0) != 0) - stackaddr = (void *)USRSTACK; - _pthread_create(thread, attrs, stackaddr, mach_thread_self()); - thread->stacksize = DFLSSIZ; //initialize main thread's stacksize based on vmparam.h - thread->detached = PTHREAD_CREATE_JOINABLE|_PTHREAD_CREATE_PARENT; - - _init_cpu_capabilities(); - if ((ncpus = _NumCPUs()) > 1) - _spin_tries = MP_SPIN_TRIES; - - workq_targetconc[WORKQ_HIGH_PRIOQUEUE] = ncpus; - workq_targetconc[WORKQ_DEFAULT_PRIOQUEUE] = ncpus; - workq_targetconc[WORKQ_LOW_PRIOQUEUE] = ncpus; - workq_targetconc[WORKQ_BG_PRIOQUEUE] = ncpus; - - mach_port_deallocate(mach_task_self(), host); - -#if defined(__ppc__) - IF_ROSETTA() { - __oldstyle = 1; - } -#endif - -#if defined(_OBJC_PAGE_BASE_ADDRESS) -{ - vm_address_t objcRTPage = (vm_address_t)_OBJC_PAGE_BASE_ADDRESS; - kr = vm_map(mach_task_self(), - &objcRTPage, vm_page_size * 4, vm_page_size - 1, - VM_FLAGS_FIXED | VM_MAKE_TAG(0), // Which tag to use? - MACH_PORT_NULL, - (vm_address_t)0, FALSE, - (vm_prot_t)0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE, - VM_INHERIT_DEFAULT); - /* We ignore the return result here. The ObjC runtime will just have to deal. */ -} -#endif - //added so that thread_recycle_port is initialized on new launch. - _pthread_fork_child_postinit(); - mig_init(1); /* enable multi-threaded mig interfaces */ - if (__oldstyle == 0) { -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)), _pthread_start, &workq_targetconc[0], (uintptr_t)(&thread->tsd[__PTK_LIBDISPATCH_KEY0]) - (uintptr_t)(&thread->tsd[0])); -#else - __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)), NULL, &workq_targetconc[0], (uintptr_t)&thread->tsd[__PTK_LIBDISPATCH_KEY0] - (uintptr_t)thread); -#endif - } - -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - if( (thread->thread_id = __thread_selfid()) == (__uint64_t)-1) - printf("Failed to set thread_id in pthread_init\n"); -#endif - return 0; -} - -int sched_yield(void) -{ - swtch_pri(0); - return 0; -} - -/* This used to be the "magic" that gets the initialization routine called when the application starts */ -/* - * (These has been moved to setenv.c, so we can use it to fix a less than 10.5 - * crt1.o issue) - * static int _do_nothing(void) { return 0; } - * int (*_cthread_init_routine)(void) = _do_nothing; - */ - -/* Get a semaphore from the pool, growing it if necessary */ - -__private_extern__ semaphore_t new_sem_from_pool(void) { - kern_return_t res; - semaphore_t sem; - int i; - - LOCK(sem_pool_lock); - if (sem_pool_current == sem_pool_count) { - sem_pool_count += 16; - sem_pool = realloc(sem_pool, sem_pool_count * sizeof(semaphore_t)); - for (i = sem_pool_current; i < sem_pool_count; i++) { - PTHREAD_MACH_CALL(semaphore_create(mach_task_self(), &sem_pool[i], SYNC_POLICY_FIFO, 0), res); - } - } - sem = sem_pool[sem_pool_current++]; - UNLOCK(sem_pool_lock); - return sem; -} - -/* Put a semaphore back into the pool */ -__private_extern__ void restore_sem_to_pool(semaphore_t sem) { - LOCK(sem_pool_lock); - sem_pool[--sem_pool_current] = sem; - UNLOCK(sem_pool_lock); -} - -static void sem_pool_reset(void) { - LOCK(sem_pool_lock); - sem_pool_count = 0; - sem_pool_current = 0; - sem_pool = NULL; - UNLOCK(sem_pool_lock); -} - -__private_extern__ void _pthread_fork_child(pthread_t p) { - /* Just in case somebody had it locked... */ - UNLOCK(sem_pool_lock); - sem_pool_reset(); - /* No need to hold the pthread_list_lock as no one other than this - * thread is present at this time - */ - TAILQ_INIT(&__pthread_head); - LOCK_INIT(_pthread_list_lock); - TAILQ_INSERT_HEAD(&__pthread_head, p, plist); -#if PTH_LISTTRACE - __kdebug_trace(0x900000c, p, 0, 0, 10, 0); -#endif - _pthread_count = 1; -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - if( (p->thread_id = __thread_selfid()) == (__uint64_t)-1) - printf("Failed to set thread_id in pthread_fork_child\n"); -#endif -} - -void _pthread_fork_child_postinit() { - kern_return_t kr; - - kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &thread_recycle_port); - if (kr != KERN_SUCCESS) { - abort(); - } -} - -/* - * Query/update the cancelability 'state' of a thread - */ -int -_pthread_setcancelstate_internal(int state, int *oldstate, int conforming) -{ - pthread_t self = pthread_self(); - - - switch (state) { - case PTHREAD_CANCEL_ENABLE: - if (conforming) - __pthread_canceled(1); - break; - case PTHREAD_CANCEL_DISABLE: - if (conforming) - __pthread_canceled(2); - break; - default: - return EINVAL; - } - - self = pthread_self(); - LOCK(self->lock); - if (oldstate) - *oldstate = self->cancel_state & _PTHREAD_CANCEL_STATE_MASK; - self->cancel_state &= ~_PTHREAD_CANCEL_STATE_MASK; - self->cancel_state |= state; - UNLOCK(self->lock); - if (!conforming) - _pthread_testcancel(self, 0); /* See if we need to 'die' now... */ - return (0); -} - -/* When a thread exits set the cancellation state to DISABLE and DEFERRED */ -static void -_pthread_setcancelstate_exit(pthread_t self, void * value_ptr, int conforming) -{ - LOCK(self->lock); - self->cancel_state &= ~(_PTHREAD_CANCEL_STATE_MASK | _PTHREAD_CANCEL_TYPE_MASK); - self->cancel_state |= (PTHREAD_CANCEL_DISABLE | PTHREAD_CANCEL_DEFERRED); - if ((value_ptr == PTHREAD_CANCELED)) { -// 4597450: begin - self->detached |= _PTHREAD_WASCANCEL; -// 4597450: end - } - UNLOCK(self->lock); -} - -int -_pthread_join_cleanup(pthread_t thread, void ** value_ptr, int conforming) -{ - kern_return_t res; - int ret; - -#if PTH_TRACE - __kdebug_trace(0x9000028, thread, 0, 0, 1, 0); -#endif - /* The scenario where the joiner was waiting for the thread and - * the pthread detach happened on that thread. Then the semaphore - * will trigger but by the time joiner runs, the target thread could be - * freed. So we need to make sure that the thread is still in the list - * and is joinable before we continue with the join. - */ - LOCK(_pthread_list_lock); - if ((ret = _pthread_find_thread(thread)) != 0) { - UNLOCK(_pthread_list_lock); - /* returns ESRCH */ - return(ret); - } - if ((thread->detached & PTHREAD_CREATE_JOINABLE) == 0) { - /* the thread might be a detached thread */ - UNLOCK(_pthread_list_lock); - return(ESRCH); - - } - /* It is still a joinable thread and needs to be reaped */ - TAILQ_REMOVE(&__pthread_head, thread, plist); -#if PTH_LISTTRACE - __kdebug_trace(0x9000010, thread, 0, 0, 3, 0); -#endif - UNLOCK(_pthread_list_lock); - - if (value_ptr) - *value_ptr = thread->exit_value; - if (conforming) { - if ((thread->cancel_state & (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) == - (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING) && (value_ptr != NULL)) { - *value_ptr = PTHREAD_CANCELED; - } - } - if (thread->reply_port != MACH_PORT_NULL) { - res = mach_port_mod_refs(mach_task_self(), thread->reply_port, MACH_PORT_RIGHT_RECEIVE, -1); - if (res != KERN_SUCCESS) - fprintf(stderr,"mach_port_mod_refs(reply_port) failed: %s\n",mach_error_string(res)); - thread->reply_port = MACH_PORT_NULL; - } - if (thread->freeStackOnExit) { - thread->sig = _PTHREAD_NO_SIG; -#if PTH_TRACE - __kdebug_trace(0x9000028, thread, 0, 0, 2, 0); -#endif - vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)thread, pthreadsize); - } else { - thread->sig = _PTHREAD_NO_SIG; -#if PTH_TRACE - __kdebug_trace(0x9000028, thread, 0, 0, 3, 0); -#endif - free(thread); - } - return(0); -} - -/* ALWAYS called with list lock and return with list lock */ -int -_pthread_find_thread(pthread_t thread) -{ - pthread_t p; - -loop: - TAILQ_FOREACH(p, &__pthread_head, plist) { - if (p == thread) { - if (thread->kernel_thread == MACH_PORT_NULL) { - UNLOCK(_pthread_list_lock); - sched_yield(); - LOCK(_pthread_list_lock); - goto loop; - } - return(0); - } - } - return(ESRCH); -} - -int -_pthread_lookup_thread(pthread_t thread, mach_port_t * portp, int only_joinable) -{ - mach_port_t kport; - int ret = 0; - - if (thread == NULL) - return(ESRCH); - - LOCK(_pthread_list_lock); - - if ((ret = _pthread_find_thread(thread)) != 0) { - UNLOCK(_pthread_list_lock); - return(ret); - } - if ((only_joinable != 0) && ((thread->detached & PTHREAD_CREATE_DETACHED) != 0)) { - UNLOCK(_pthread_list_lock); - return(EINVAL); - } - kport = thread->kernel_thread; - UNLOCK(_pthread_list_lock); - if (portp != NULL) - *portp = kport; - return(0); -} - -/* XXXXXXXXXXXXX Pthread Workqueue Attributes XXXXXXXXXXXXXXXXXX */ -int -pthread_workqueue_attr_init_np(pthread_workqueue_attr_t * attrp) -{ - attrp->queueprio = WORKQ_DEFAULT_PRIOQUEUE; - attrp->sig = PTHREAD_WORKQUEUE_ATTR_SIG; - attrp->overcommit = 0; - return(0); -} - -int -pthread_workqueue_attr_destroy_np(pthread_workqueue_attr_t * attr) -{ - if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) - { - return (0); - } else - { - return (EINVAL); /* Not an attribute structure! */ - } -} - -int -pthread_workqueue_attr_getqueuepriority_np(const pthread_workqueue_attr_t * attr, int * qpriop) -{ - if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) { - *qpriop = attr->queueprio; - return (0); - } else { - return (EINVAL); /* Not an attribute structure! */ - } -} - - -int -pthread_workqueue_attr_setqueuepriority_np(pthread_workqueue_attr_t * attr, int qprio) -{ -int error = 0; - - if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) { - switch(qprio) { - case WORKQ_HIGH_PRIOQUEUE: - case WORKQ_DEFAULT_PRIOQUEUE: - case WORKQ_LOW_PRIOQUEUE: - case WORKQ_BG_PRIOQUEUE: - attr->queueprio = qprio; - break; - default: - error = EINVAL; - } - } else { - error = EINVAL; - } - return (error); -} - - -int -pthread_workqueue_attr_getovercommit_np(const pthread_workqueue_attr_t * attr, int * ocommp) -{ - if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) { - *ocommp = attr->overcommit; - return (0); - } else { - return (EINVAL); /* Not an attribute structure! */ - } -} - - -int -pthread_workqueue_attr_setovercommit_np(pthread_workqueue_attr_t * attr, int ocomm) -{ -int error = 0; - - if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) { - attr->overcommit = ocomm; - } else { - error = EINVAL; - } - return (error); -} -/* XXXXXXXXXXXXX Pthread Workqueue support routines XXXXXXXXXXXXXXXXXX */ - -static void -workqueue_list_lock() -{ - OSSpinLockLock(&__workqueue_list_lock); -} - -static void -workqueue_list_unlock() -{ - OSSpinLockUnlock(&__workqueue_list_lock); -} - -int -pthread_workqueue_init_np() -{ - int ret; - - if (__workqueue_newspis != 0) - return(EPERM); - __workqueue_oldspis = 1; - - workqueue_list_lock(); - ret =_pthread_work_internal_init(); - workqueue_list_unlock(); - - return(ret); -} - -int -pthread_workqueue_requestconcurrency_np(int queue, int request_concurrency) -{ - int error = 0; - - if (__workqueue_newspis != 0) - return(EPERM); - - if (queue < 0 || queue > WORKQ_NUM_PRIOQUEUE) - return(EINVAL); - - error =__workq_kernreturn(WQOPS_THREAD_SETCONC, NULL, request_concurrency, queue); - - if (error == -1) - return(errno); - return(0); -} - -void -pthread_workqueue_atfork_prepare(void) -{ - /* - * NOTE: Any workq additions here - * should be for i386,x86_64 only - */ - dispatch_atfork_prepare(); -} - -void -pthread_workqueue_atfork_parent(void) -{ - /* - * NOTE: Any workq additions here - * should be for i386,x86_64 only - */ - dispatch_atfork_parent(); -} - -void -pthread_workqueue_atfork_child(void) -{ -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - pthread_t self = pthread_self(); - - __workqueue_list_lock = OS_SPINLOCK_INIT; - - /* already using new spis? */ - if (__workqueue_newspis != 0) { - /* prepare the kernel for workq action */ -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)), _pthread_start, &workq_targetconc[0], (uintptr_t)(&self->tsd[__PTK_LIBDISPATCH_KEY0]) - (uintptr_t)(&self->tsd[0])); -#else - __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)),NULL,NULL,0); -#endif - (void)__workq_open(); - kernel_workq_setup = 1; - return; - } - - /* not using old spis either? */ - if (__workqueue_oldspis == 0) - return; - - /* - * NOTE: workq additions here - * are for i386,x86_64 only as - * ppc and arm do not support it - */ - if (kernel_workq_setup != 0){ - kernel_workq_setup = 0; - _pthread_work_internal_init(); - } -#endif - dispatch_atfork_child(); -} - -static int -_pthread_work_internal_init(void) -{ - int i, error; - pthread_workqueue_head_t headp; - pthread_workqueue_t wq; -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - pthread_t self = pthread_self(); -#endif - - if (kernel_workq_setup == 0) { -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)), _pthread_start, &workq_targetconc[0], (uintptr_t)(&self->tsd[__PTK_LIBDISPATCH_KEY0]) - (uintptr_t)(&self->tsd[0])); -#else - __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)),NULL,NULL,0); -#endif - - _pthread_wq_attr_default.queueprio = WORKQ_DEFAULT_PRIOQUEUE; - _pthread_wq_attr_default.sig = PTHREAD_WORKQUEUE_ATTR_SIG; - - for( i = 0; i< WORKQ_NUM_PRIOQUEUE; i++) { - headp = __pthread_wq_head_tbl[i]; - TAILQ_INIT(&headp->wqhead); - headp->next_workq = 0; - } - - __workqueue_pool_ptr = NULL; - __workqueue_pool_size = round_page(sizeof(struct _pthread_workitem) * WORKITEM_POOL_SIZE); - - __workqueue_pool_ptr = (struct _pthread_workitem *)mmap(NULL, __workqueue_pool_size, - PROT_READ|PROT_WRITE, - MAP_ANON | MAP_PRIVATE, - 0, - 0); - - if (__workqueue_pool_ptr == MAP_FAILED) { - /* Not expected to fail, if it does, always malloc for work items */ - __workqueue_nitems = WORKITEM_POOL_SIZE; - __workqueue_pool_ptr = NULL; - } else - __workqueue_nitems = 0; - - /* sets up the workitem pool */ - grow_workitem(); - - /* since the size is less than a page, leaving this in malloc pool */ - wq = (struct _pthread_workqueue *)malloc(sizeof(struct _pthread_workqueue) * WORKQUEUE_POOL_SIZE); - bzero(wq, (sizeof(struct _pthread_workqueue) * WORKQUEUE_POOL_SIZE)); - for (i = 0; i < WORKQUEUE_POOL_SIZE; i++) { - TAILQ_INSERT_TAIL(&__pthread_workqueue_pool_head, &wq[i], wq_list); - } - - if (error = __workq_open()) { - TAILQ_INIT(&__pthread_workitem_pool_head); - TAILQ_INIT(&__pthread_workqueue_pool_head); - if (__workqueue_pool_ptr != NULL) { - munmap((void *)__workqueue_pool_ptr, __workqueue_pool_size); - } - free(wq); - return(ENOMEM); - } - kernel_workq_setup = 1; - } - return(0); -} - - -/* This routine is called with list lock held */ -static pthread_workitem_t -alloc_workitem(void) -{ - pthread_workitem_t witem; - - if (TAILQ_EMPTY(&__pthread_workitem_pool_head)) { - /* the chunk size is set so some multiple of it is pool size */ - if (__workqueue_nitems < WORKITEM_POOL_SIZE) { - grow_workitem(); - } else { - workqueue_list_unlock(); - witem = malloc(sizeof(struct _pthread_workitem)); - workqueue_list_lock(); - witem->fromcache = 0; - goto out; - } - } - witem = TAILQ_FIRST(&__pthread_workitem_pool_head); - TAILQ_REMOVE(&__pthread_workitem_pool_head, witem, item_entry); - witem->fromcache = 1; -out: - witem->flags = 0; - witem->item_entry.tqe_next = 0; - witem->item_entry.tqe_prev = 0; - user_workitem_count++; - return(witem); -} - -/* This routine is called with list lock held */ -static void -free_workitem(pthread_workitem_t witem) -{ - user_workitem_count--; - witem->flags = 0; - if (witem->fromcache != 0) - TAILQ_INSERT_TAIL(&__pthread_workitem_pool_head, witem, item_entry); - else - free(witem); -} - -static void -grow_workitem(void) -{ - pthread_workitem_t witemp; - int i; - - witemp = &__workqueue_pool_ptr[__workqueue_nitems]; - bzero(witemp, (sizeof(struct _pthread_workitem) * WORKITEM_CHUNK_SIZE)); - for (i = 0; i < WORKITEM_CHUNK_SIZE; i++) { - witemp[i].fromcache = 1; - TAILQ_INSERT_TAIL(&__pthread_workitem_pool_head, &witemp[i], item_entry); - } - __workqueue_nitems += WORKITEM_CHUNK_SIZE; -} - -/* This routine is called with list lock held */ -static pthread_workqueue_t -alloc_workqueue(void) -{ - pthread_workqueue_t wq; - - if (TAILQ_EMPTY(&__pthread_workqueue_pool_head)) { - workqueue_list_unlock(); - wq = malloc(sizeof(struct _pthread_workqueue)); - workqueue_list_lock(); - } else { - wq = TAILQ_FIRST(&__pthread_workqueue_pool_head); - TAILQ_REMOVE(&__pthread_workqueue_pool_head, wq, wq_list); - } - user_workq_count++; - return(wq); -} - -/* This routine is called with list lock held */ -static void -free_workqueue(pthread_workqueue_t wq) -{ - user_workq_count--; - TAILQ_INSERT_TAIL(&__pthread_workqueue_pool_head, wq, wq_list); -} - -static void -_pthread_workq_init(pthread_workqueue_t wq, const pthread_workqueue_attr_t * attr) -{ - bzero(wq, sizeof(struct _pthread_workqueue)); - if (attr != NULL) { - wq->queueprio = attr->queueprio; - wq->overcommit = attr->overcommit; - } else { - wq->queueprio = WORKQ_DEFAULT_PRIOQUEUE; - wq->overcommit = 0; - } - LOCK_INIT(wq->lock); - wq->flags = 0; - TAILQ_INIT(&wq->item_listhead); - TAILQ_INIT(&wq->item_kernhead); -#if WQ_LISTTRACE - __kdebug_trace(0x90080ac, wq, &wq->item_listhead, wq->item_listhead.tqh_first, wq->item_listhead.tqh_last, 0); -#endif - wq->wq_list.tqe_next = 0; - wq->wq_list.tqe_prev = 0; - wq->sig = PTHREAD_WORKQUEUE_SIG; - wq->headp = __pthread_wq_head_tbl[wq->queueprio]; -} - -int -valid_workq(pthread_workqueue_t workq) -{ - if (workq->sig == PTHREAD_WORKQUEUE_SIG) - return(1); - else - return(0); -} - - -/* called with list lock */ -static void -pick_nextworkqueue_droplock() -{ - int i, curwqprio, val, found; - pthread_workqueue_head_t headp; - pthread_workqueue_t workq; - pthread_workqueue_t nworkq = NULL; - -#if WQ_TRACE - __kdebug_trace(0x9008098, kernel_workq_count, 0, 0, 0, 0); -#endif -loop: - while (kernel_workq_count < KERNEL_WORKQ_ELEM_MAX) { - found = 0; - for (i = 0; i < WORKQ_NUM_PRIOQUEUE; i++) { - wqreadyprio = i; /* because there is nothing else higher to run */ - headp = __pthread_wq_head_tbl[i]; - - if (TAILQ_EMPTY(&headp->wqhead)) - continue; - workq = headp->next_workq; - if (workq == NULL) - workq = TAILQ_FIRST(&headp->wqhead); - curwqprio = workq->queueprio; - nworkq = workq; /* starting pt */ - while (kernel_workq_count < KERNEL_WORKQ_ELEM_MAX) { - headp->next_workq = TAILQ_NEXT(workq, wq_list); - if (headp->next_workq == NULL) - headp->next_workq = TAILQ_FIRST(&headp->wqhead); -#if WQ_TRACE - __kdebug_trace(0x9008098, kernel_workq_count, workq, 0, 1, 0); -#endif - val = post_nextworkitem(workq); - - if (val != 0) { - /* things could have changed so reasses */ - /* If kernel queue is full , skip */ - if (kernel_workq_count >= KERNEL_WORKQ_ELEM_MAX) - break; - /* If anything with higher prio arrived, then reevaluate */ - if (wqreadyprio < curwqprio) - goto loop; /* we need re evaluate again */ - /* we can post some more work items */ - found = 1; - } - - /* cannot use workq here as it could be freed */ - if (TAILQ_EMPTY(&headp->wqhead)) - break; - /* if we found nothing to run and only one workqueue in the list, skip */ - if ((val == 0) && (workq == headp->next_workq)) - break; - workq = headp->next_workq; - if (workq == NULL) - workq = TAILQ_FIRST(&headp->wqhead); - if (val != 0) - nworkq = workq; - /* if we found nothing to run and back to workq where we started */ - if ((val == 0) && (workq == nworkq)) - break; - } - if (kernel_workq_count >= KERNEL_WORKQ_ELEM_MAX) - break; - } - /* nothing found to run? */ - if (found == 0) - break; - } - workqueue_list_unlock(); -} - -static int -post_nextworkitem(pthread_workqueue_t workq) -{ - int error, prio; - pthread_workitem_t witem; - pthread_workqueue_head_t headp; - void (*func)(pthread_workqueue_t, void *); - - if ((workq->flags & PTHREAD_WORKQ_SUSPEND) == PTHREAD_WORKQ_SUSPEND) { - return(0); - } -#if WQ_TRACE - __kdebug_trace(0x900809c, workq, workq->item_listhead.tqh_first, 0, 1, 0); -#endif - if (TAILQ_EMPTY(&workq->item_listhead)) { - return(0); - } - if ((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == PTHREAD_WORKQ_BARRIER_ON) - return(0); - - witem = TAILQ_FIRST(&workq->item_listhead); - headp = workq->headp; -#if WQ_TRACE - __kdebug_trace(0x900809c, workq, witem, 0, 0xee, 0); -#endif - if ((witem->flags & PTH_WQITEM_BARRIER) == PTH_WQITEM_BARRIER) { -#if WQ_TRACE - __kdebug_trace(0x9000064, workq, 0, 0, 2, 0); -#endif - - if ((witem->flags & PTH_WQITEM_APPLIED) != 0) { - return(0); - } - /* Also barrier when nothing is there needs to be handled */ - /* Nothing to wait for */ - if (workq->kq_count != 0) { - witem->flags |= PTH_WQITEM_APPLIED; - workq->flags |= PTHREAD_WORKQ_BARRIER_ON; - workq->barrier_count = workq->kq_count; -#if WQ_TRACE - __kdebug_trace(0x9000064, 1, workq->barrier_count, 0, 0, 0); -#endif - return(1); - } else { -#if WQ_TRACE - __kdebug_trace(0x9000064, 2, workq->barrier_count, 0, 0, 0); -#endif - if (witem->func != NULL) { - /* since we are going to drop list lock */ - witem->flags |= PTH_WQITEM_APPLIED; - workq->flags |= PTHREAD_WORKQ_BARRIER_ON; - workqueue_list_unlock(); - func = (void (*)(pthread_workqueue_t, void *))witem->func; - (*func)(workq, witem->func_arg); -#if WQ_TRACE - __kdebug_trace(0x9000064, 3, workq->barrier_count, 0, 0, 0); -#endif - workqueue_list_lock(); - workq->flags &= ~PTHREAD_WORKQ_BARRIER_ON; - } - TAILQ_REMOVE(&workq->item_listhead, witem, item_entry); -#if WQ_LISTTRACE - __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0); -#endif - free_workitem(witem); -#if WQ_TRACE - __kdebug_trace(0x9000064, 4, workq->barrier_count, 0, 0, 0); -#endif - return(1); - } - } else if ((witem->flags & PTH_WQITEM_DESTROY) == PTH_WQITEM_DESTROY) { -#if WQ_TRACE - __kdebug_trace(0x9000068, 1, workq->kq_count, 0, 0, 0); -#endif - if ((witem->flags & PTH_WQITEM_APPLIED) != 0) { - return(0); - } - witem->flags |= PTH_WQITEM_APPLIED; - workq->flags |= (PTHREAD_WORKQ_BARRIER_ON | PTHREAD_WORKQ_TERM_ON); - workq->barrier_count = workq->kq_count; - workq->term_callback = (void (*)(struct _pthread_workqueue *,void *))witem->func; - workq->term_callarg = witem->func_arg; - TAILQ_REMOVE(&workq->item_listhead, witem, item_entry); -#if WQ_LISTTRACE - __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0); -#endif - if ((TAILQ_EMPTY(&workq->item_listhead)) && (workq->kq_count == 0)) { - if (!(TAILQ_EMPTY(&workq->item_kernhead))) { -#if WQ_TRACE - __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 0xff, 0); -#endif - } - free_workitem(witem); - workq->flags |= PTHREAD_WORKQ_DESTROYED; -#if WQ_TRACE - __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 1, 0); -#endif - headp = __pthread_wq_head_tbl[workq->queueprio]; - if (headp->next_workq == workq) { - headp->next_workq = TAILQ_NEXT(workq, wq_list); - if (headp->next_workq == NULL) { - headp->next_workq = TAILQ_FIRST(&headp->wqhead); - if (headp->next_workq == workq) - headp->next_workq = NULL; - } - } - workq->sig = 0; - TAILQ_REMOVE(&headp->wqhead, workq, wq_list); - if (workq->term_callback != NULL) { - workqueue_list_unlock(); - (*workq->term_callback)(workq, workq->term_callarg); - workqueue_list_lock(); - } - free_workqueue(workq); - return(1); - } else { - TAILQ_INSERT_HEAD(&workq->item_listhead, witem, item_entry); -#if WQ_LISTTRACE - __kdebug_trace(0x90080b0, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0); -#endif - } -#if WQ_TRACE - __kdebug_trace(0x9000068, 2, workq->barrier_count, 0, 0, 0); -#endif - return(1); - } else { -#if WQ_TRACE - __kdebug_trace(0x9000060, witem, workq, witem->func_arg, 0xfff, 0); -#endif - TAILQ_REMOVE(&workq->item_listhead, witem, item_entry); -#if WQ_LISTTRACE - __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0); -#endif - TAILQ_INSERT_TAIL(&workq->item_kernhead, witem, item_entry); - if ((witem->flags & PTH_WQITEM_KERN_COUNT) == 0) { - workq->kq_count++; - witem->flags |= PTH_WQITEM_KERN_COUNT; - } - OSAtomicIncrement32Barrier(&kernel_workq_count); - workqueue_list_unlock(); - - prio = workq->queueprio; - if (workq->overcommit != 0) { - prio |= WORKQUEUE_OVERCOMMIT; - } - - if (( error =__workq_kernreturn(WQOPS_QUEUE_ADD, witem, workq->affinity, prio)) == -1) { - OSAtomicDecrement32Barrier(&kernel_workq_count); - workqueue_list_lock(); -#if WQ_TRACE - __kdebug_trace(0x900007c, witem, workq, witem->func_arg, workq->kq_count, 0); -#endif - TAILQ_REMOVE(&workq->item_kernhead, witem, item_entry); - TAILQ_INSERT_HEAD(&workq->item_listhead, witem, item_entry); -#if WQ_LISTTRACE - __kdebug_trace(0x90080b0, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0); -#endif - if ((workq->flags & (PTHREAD_WORKQ_BARRIER_ON | PTHREAD_WORKQ_TERM_ON)) != 0) - workq->flags |= PTHREAD_WORKQ_REQUEUED; - } else - workqueue_list_lock(); -#if WQ_TRACE - __kdebug_trace(0x9000060, witem, workq, witem->func_arg, workq->kq_count, 0); -#endif - return(1); - } - /* noone should come here */ -#if 1 - printf("error in logic for next workitem\n"); - LIBC_ABORT("error in logic for next workitem"); -#endif - return(0); -} - -void -_pthread_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_workitem_t item, int reuse) -{ - int ret; - pthread_attr_t *attrs = &_pthread_attr_default; - pthread_workqueue_t workq; -#if WQ_DEBUG - pthread_t pself; -#endif - int thread_reuse = 0; - int thread_priority = 0; - int thread_newspi = 0; - int thread_options = 0; - - if (reuse & WQ_FLAG_THREAD_NEWSPI) { - thread_reuse = reuse & WQ_FLAG_THREAD_REUSE; - if ((reuse & WQ_FLAG_THREAD_OVERCOMMIT) != 0) - thread_options = WORKQ_ADDTHREADS_OPTION_OVERCOMMIT; - thread_priority = reuse & WQ_FLAG_THREAD_PRIOMASK; - thread_newspi = 1; - workq = NULL; - } else { - thread_reuse = (reuse == 0)? 0: WQ_FLAG_THREAD_REUSE; - workq = item->workq; - } - - - if (thread_reuse == 0) { - /* reuse is set to 0, when a thread is newly created to run a workitem */ - _pthread_struct_init(self, attrs, stackaddr, DEFAULT_STACK_SIZE, 1, 1); - self->wqthread = 1; - self->wqkillset = 0; - self->parentcheck = 1; - - /* These are not joinable threads */ - self->detached &= ~PTHREAD_CREATE_JOINABLE; - self->detached |= PTHREAD_CREATE_DETACHED; -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - _pthread_set_self(self); -#endif -#if WQ_TRACE - __kdebug_trace(0x9000050, self, item, item->func_arg, 0, 0); -#endif - self->kernel_thread = kport; - if (thread_newspi != 0) { - self->fun = (void *(*)(void *))__libdispatch_workerfunction; - self->arg = thread_priority; - } else { - self->fun = (void *(*)(void *))item->func; - self->arg = item->func_arg; - } - /* Add to the pthread list */ - LOCK(_pthread_list_lock); - TAILQ_INSERT_TAIL(&__pthread_head, self, plist); -#if PTH_LISTTRACE - __kdebug_trace(0x900000c, self, 0, 0, 10, 0); -#endif - _pthread_count++; - UNLOCK(_pthread_list_lock); - -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) - if( (self->thread_id = __thread_selfid()) == (__uint64_t)-1) - printf("Failed to set thread_id in pthread_wqthread\n"); -#endif - - } else { - /* reuse is set to 1, when a thread is resued to run another work item */ -#if WQ_TRACE - __kdebug_trace(0x9000054, self, item, item->func_arg, 0, 0); -#endif - /* reset all tsd from 1 to KEYS_MAX */ - if (self == NULL) - LIBC_ABORT("_pthread_wqthread: pthread %p setup to be NULL", self); - - if (thread_newspi != 0) { - self->fun = (void *(*)(void *))__libdispatch_workerfunction; - self->arg = NULL; - } else { - self->fun = (void *(*)(void *))item->func; - self->arg = item->func_arg; - } - } - -#if WQ_DEBUG - if (reuse == 0) { - pself = pthread_self(); - if (self != pself) { -#if WQ_TRACE - __kdebug_trace(0x9000078, self, pself, item->func_arg, 0, 0); -#endif - printf("pthread_self not set: pself %p, passed in %p\n", pself, self); - _pthread_set_self(self); - pself = pthread_self(); - if (self != pself) - printf("(2)pthread_self not set: pself %p, passed in %p\n", pself, self); - pself = self; - } - } else { - pself = pthread_self(); - if (self != pself) { - printf("(3)pthread_self not set in reuse: pself %p, passed in %p\n", pself, self); - LIBC_ABORT("(3)pthread_self not set in reuse: pself %p, passed in %p", pself, self); - } - } -#endif /* WQ_DEBUG */ - - if (thread_newspi != 0) { - (*__libdispatch_workerfunction)(thread_priority, thread_options, NULL); - _pthread_workq_return(self); - } else { - self->cur_workq = workq; - self->cur_workitem = item; - OSAtomicDecrement32Barrier(&kernel_workq_count); - - ret = (int)(intptr_t)(*self->fun)(self->arg); - /* If we reach here without going through the above initialization path then don't go through - * with the teardown code path ( e.g. setjmp/longjmp ). Instead just exit this thread. - */ - if (self != pthread_self()) { - pthread_exit(PTHREAD_CANCELED); - } - - workqueue_exit(self, workq, item); - } -} - -static void -workqueue_exit(pthread_t self, pthread_workqueue_t workq, pthread_workitem_t item) -{ - pthread_workitem_t baritem; - pthread_workqueue_head_t headp; - void (*func)(pthread_workqueue_t, void *); - - workqueue_list_lock(); - - TAILQ_REMOVE(&workq->item_kernhead, item, item_entry); - workq->kq_count--; -#if WQ_TRACE - __kdebug_trace(0x9000070, self, 1, item->func_arg, workq->kq_count, 0); -#endif - free_workitem(item); - - if ((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == PTHREAD_WORKQ_BARRIER_ON) { - workq->barrier_count--; -#if WQ_TRACE - __kdebug_trace(0x9000084, self, workq->barrier_count, workq->kq_count, 1, 0); -#endif - if (workq->barrier_count <= 0 ) { - /* Need to remove barrier item from the list */ - baritem = TAILQ_FIRST(&workq->item_listhead); -#if WQ_DEBUG - if ((baritem->flags & (PTH_WQITEM_BARRIER | PTH_WQITEM_DESTROY| PTH_WQITEM_APPLIED)) == 0) - printf("Incorect bar item being removed in barrier processing\n"); -#endif /* WQ_DEBUG */ - /* if the front item is a barrier and call back is registered, run that */ - if (((baritem->flags & PTH_WQITEM_BARRIER) == PTH_WQITEM_BARRIER) && (baritem->func != NULL)) { - workqueue_list_unlock(); - func = (void (*)(pthread_workqueue_t, void *))baritem->func; - (*func)(workq, baritem->func_arg); - workqueue_list_lock(); - } - TAILQ_REMOVE(&workq->item_listhead, baritem, item_entry); -#if WQ_LISTTRACE - __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0); -#endif - free_workitem(baritem); - workq->flags &= ~PTHREAD_WORKQ_BARRIER_ON; -#if WQ_TRACE - __kdebug_trace(0x9000058, self, item, item->func_arg, 0, 0); -#endif - if ((workq->flags & PTHREAD_WORKQ_TERM_ON) != 0) { - headp = __pthread_wq_head_tbl[workq->queueprio]; - workq->flags |= PTHREAD_WORKQ_DESTROYED; -#if WQ_TRACE - __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 2, 0); -#endif - if (headp->next_workq == workq) { - headp->next_workq = TAILQ_NEXT(workq, wq_list); - if (headp->next_workq == NULL) { - headp->next_workq = TAILQ_FIRST(&headp->wqhead); - if (headp->next_workq == workq) - headp->next_workq = NULL; - } - } - TAILQ_REMOVE(&headp->wqhead, workq, wq_list); - workq->sig = 0; - if (workq->term_callback != NULL) { - workqueue_list_unlock(); - (*workq->term_callback)(workq, workq->term_callarg); - workqueue_list_lock(); - } - free_workqueue(workq); - } else { - /* if there are higher prio schedulabel item reset to wqreadyprio */ - if ((workq->queueprio < wqreadyprio) && (!(TAILQ_EMPTY(&workq->item_listhead)))) - wqreadyprio = workq->queueprio; - } - } - } -#if WQ_TRACE - else { - __kdebug_trace(0x9000070, self, 2, item->func_arg, workq->barrier_count, 0); - } - - __kdebug_trace(0x900005c, self, item, 0, 0, 0); -#endif - pick_nextworkqueue_droplock(); - _pthread_workq_return(self); -} - -static void -_pthread_workq_return(pthread_t self) -{ - __workq_kernreturn(WQOPS_THREAD_RETURN, NULL, 0, 0); - - /* This is the way to terminate the thread */ - _pthread_exit(self, NULL); -} - - -/* XXXXXXXXXXXXX Pthread Workqueue functions XXXXXXXXXXXXXXXXXX */ - -int -pthread_workqueue_setdispatch_np(void (*worker_func)(int, int, void *)) -{ - int error = 0; - - if (__workqueue_oldspis != 0) - return(EPERM); - - __workqueue_newspis = 1; - - if (__libdispatch_workerfunction == NULL) { - __libdispatch_workerfunction = worker_func; - /* check whether the kernel supports new SPIs */ - error = __workq_kernreturn(WQOPS_QUEUE_NEWSPISUPP, NULL, 0, 0); - if (error == -1){ - __libdispatch_workerfunction = NULL; - error = ENOTSUP; - __workqueue_newspis = 0; - } else { - /* prepare the kernel for workq action */ - (void)__workq_open(); - kernel_workq_setup = 1; - if (__is_threaded == 0) - __is_threaded = 1; - __workqueue_newspis = 1; - } - } else { - error = EBUSY; - } - - return(error); -} - -int -pthread_workqueue_addthreads_np(int queue_priority, int options, int numthreads) -{ - int priority = queue_priority & WQ_FLAG_THREAD_PRIOMASK; - int error = 0; - - /* new spi not inited yet?? */ - if (__workqueue_newspis == 0) - return(EPERM); - - - if ((options & WORKQ_ADDTHREADS_OPTION_OVERCOMMIT) != 0) - priority |= WORKQUEUE_OVERCOMMIT; - - error = __workq_kernreturn(WQOPS_QUEUE_REQTHREADS, NULL, numthreads, priority); - - if (error == -1) - return(errno); - else - return(0); -} - -int -pthread_workqueue_create_np(pthread_workqueue_t * workqp, const pthread_workqueue_attr_t * attr) -{ - pthread_workqueue_t wq; - pthread_workqueue_head_t headp; - -#if defined(__ppc__) - IF_ROSETTA() { - return(ENOTSUP); - } -#endif - if (__workqueue_newspis != 0) - return(EPERM); - - if (__workqueue_oldspis == 0) - __workqueue_oldspis = 1; - - if ((attr != NULL) && (attr->sig != PTHREAD_WORKQUEUE_ATTR_SIG)) { - return(EINVAL); - } - - if (__is_threaded == 0) - __is_threaded = 1; - - workqueue_list_lock(); - if (kernel_workq_setup == 0) { - int ret = _pthread_work_internal_init(); - if (ret != 0) { - workqueue_list_unlock(); - return(ret); - } - } - - wq = alloc_workqueue(); - - _pthread_workq_init(wq, attr); - - headp = __pthread_wq_head_tbl[wq->queueprio]; - TAILQ_INSERT_TAIL(&headp->wqhead, wq, wq_list); - if (headp->next_workq == NULL) { - headp->next_workq = TAILQ_FIRST(&headp->wqhead); - } - - workqueue_list_unlock(); - - *workqp = wq; - - return(0); -} - -int -pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp) -{ - pthread_workitem_t witem; - - if (__workqueue_newspis != 0) - return(EPERM); - - if (valid_workq(workq) == 0) { - return(EINVAL); - } - - workqueue_list_lock(); - - /* - * Allocate the workitem here as it can drop the lock. - * Also we can evaluate the workqueue state only once. - */ - witem = alloc_workitem(); - witem->func = workitem_func; - witem->func_arg = workitem_arg; - witem->workq = workq; - - /* alloc workitem can drop the lock, check the state */ - if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_DESTROYED)) != 0) { - free_workitem(witem); - workqueue_list_unlock(); - *itemhandlep = 0; - return(ESRCH); - } - - if (itemhandlep != NULL) - *itemhandlep = (pthread_workitem_handle_t *)witem; - if (gencountp != NULL) - *gencountp = 0; -#if WQ_TRACE - __kdebug_trace(0x9008090, witem, witem->func, witem->func_arg, workq, 0); -#endif - TAILQ_INSERT_TAIL(&workq->item_listhead, witem, item_entry); -#if WQ_LISTTRACE - __kdebug_trace(0x90080a4, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0); -#endif - - if (((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == 0) && (workq->queueprio < wqreadyprio)) - wqreadyprio = workq->queueprio; - - pick_nextworkqueue_droplock(); - - return(0); -} - -int -pthread_workqueue_getovercommit_np(pthread_workqueue_t workq, unsigned int *ocommp) -{ - if (__workqueue_newspis != 0) - return(EPERM); - - if (valid_workq(workq) == 0) { - return(EINVAL); - } - - if (ocommp != NULL) - *ocommp = workq->overcommit; - return(0); -} - - -#else /* !BUILDING_VARIANT ] [ */ -extern int __unix_conforming; -extern int _pthread_count; -extern int __workqueue_newspis; -extern int __workqueue_oldspis; - -extern pthread_lock_t _pthread_list_lock; -extern void _pthread_testcancel(pthread_t thread, int isconforming); -extern int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr, int conforming); - -#endif /* !BUILDING_VARIANT ] */ - -#if __DARWIN_UNIX03 - -__private_extern__ void -__posix_join_cleanup(void *arg) -{ - pthread_t thread = (pthread_t)arg; - int already_exited, res; - void * dummy; - semaphore_t death; - int newstyle; - - LOCK(thread->lock); - already_exited = (thread->detached & _PTHREAD_EXITED); - - newstyle = thread->newstyle; - -#if WQ_TRACE - __kdebug_trace(0x900002c, thread, newstyle, 0, 0, 0); -#endif - if (newstyle == 0) { - death = thread->death; - if (!already_exited){ - thread->joiner = (struct _pthread *)NULL; - UNLOCK(thread->lock); - restore_sem_to_pool(death); - } else { - UNLOCK(thread->lock); - while ((res = _pthread_reap_thread(thread, - thread->kernel_thread, - &dummy, 1)) == EAGAIN) - { - sched_yield(); - } - restore_sem_to_pool(death); - - } - - } else { - /* leave another thread to join */ - thread->joiner = (struct _pthread *)NULL; - UNLOCK(thread->lock); - } -} - -#endif /* __DARWIN_UNIX03 */ - - -/* - * Wait for a thread to terminate and obtain its exit value. - */ -/* -int -pthread_join(pthread_t thread, - void **value_ptr) - -moved to pthread_cancelable.c */ - -/* - * Cancel a thread - */ -int -pthread_cancel(pthread_t thread) -{ -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; -#endif /* __DARWIN_UNIX03 */ - - if (_pthread_lookup_thread(thread, NULL, 0) != 0) - return(ESRCH); - - /* if the thread is a workqueue thread, then return error */ - if (thread->wqthread != 0) { - return(ENOTSUP); - } -#if __DARWIN_UNIX03 - int state; - - LOCK(thread->lock); - state = thread->cancel_state |= _PTHREAD_CANCEL_PENDING; - UNLOCK(thread->lock); - if (state & PTHREAD_CANCEL_ENABLE) - __pthread_markcancel(thread->kernel_thread); -#else /* __DARWIN_UNIX03 */ - thread->cancel_state |= _PTHREAD_CANCEL_PENDING; -#endif /* __DARWIN_UNIX03 */ - return (0); -} - -void -pthread_testcancel(void) -{ - pthread_t self = pthread_self(); - -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; - _pthread_testcancel(self, 1); -#else /* __DARWIN_UNIX03 */ - _pthread_testcancel(self, 0); -#endif /* __DARWIN_UNIX03 */ - -} - - -/* - * Query/update the cancelability 'state' of a thread - */ -int -pthread_setcancelstate(int state, int *oldstate) -{ -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) { - __unix_conforming = 1; - } - return (_pthread_setcancelstate_internal(state, oldstate, 1)); -#else /* __DARWIN_UNIX03 */ - return (_pthread_setcancelstate_internal(state, oldstate, 0)); -#endif /* __DARWIN_UNIX03 */ - -} - - - -/* - * Query/update the cancelability 'type' of a thread - */ -int -pthread_setcanceltype(int type, int *oldtype) -{ - pthread_t self = pthread_self(); - -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; -#endif /* __DARWIN_UNIX03 */ - - if ((type != PTHREAD_CANCEL_DEFERRED) && - (type != PTHREAD_CANCEL_ASYNCHRONOUS)) - return EINVAL; - self = pthread_self(); - LOCK(self->lock); - if (oldtype) - *oldtype = self->cancel_state & _PTHREAD_CANCEL_TYPE_MASK; - self->cancel_state &= ~_PTHREAD_CANCEL_TYPE_MASK; - self->cancel_state |= type; - UNLOCK(self->lock); -#if !__DARWIN_UNIX03 - _pthread_testcancel(self, 0); /* See if we need to 'die' now... */ -#endif /* __DARWIN_UNIX03 */ - return (0); -} - -int -pthread_sigmask(int how, const sigset_t * set, sigset_t * oset) -{ -#if __DARWIN_UNIX03 - int err = 0; - - if (__pthread_sigmask(how, set, oset) == -1) { - err = errno; - } - return(err); -#else /* __DARWIN_UNIX03 */ - return(__pthread_sigmask(how, set, oset)); -#endif /* __DARWIN_UNIX03 */ -} - -/* -int -sigwait(const sigset_t * set, int * sig) - -moved to pthread_cancelable.c */ diff --git a/src/libc/pthreads/pthread.h b/src/libc/pthreads/pthread.h deleted file mode 100644 index 132d42e8f..000000000 --- a/src/libc/pthreads/pthread.h +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * POSIX Threads - IEEE 1003.1c - */ - -#ifndef _PTHREAD_H -#define _PTHREAD_H - -#include <_types.h> -#ifndef __POSIX_LIB__ -#include -#endif -#include -#include - -#ifndef _PTHREAD_ATTR_T -#define _PTHREAD_ATTR_T -typedef __darwin_pthread_attr_t pthread_attr_t; -#endif - -#ifndef _PTHREAD_COND_T -#define _PTHREAD_COND_T -typedef __darwin_pthread_cond_t pthread_cond_t; -#endif - -#ifndef _PTHREAD_CONDATTR_T -#define _PTHREAD_CONDATTR_T -typedef __darwin_pthread_condattr_t pthread_condattr_t; -#endif - -#ifndef _PTHREAD_KEY_T -#define _PTHREAD_KEY_T -typedef __darwin_pthread_key_t pthread_key_t; -#endif - -#ifndef _PTHREAD_MUTEX_T -#define _PTHREAD_MUTEX_T -typedef __darwin_pthread_mutex_t pthread_mutex_t; -#endif - -#ifndef _PTHREAD_MUTEXATTR_T -#define _PTHREAD_MUTEXATTR_T -typedef __darwin_pthread_mutexattr_t pthread_mutexattr_t; -#endif - -#ifndef _PTHREAD_ONCE_T -#define _PTHREAD_ONCE_T -typedef __darwin_pthread_once_t pthread_once_t; -#endif - -#ifndef _PTHREAD_RWLOCK_T -#define _PTHREAD_RWLOCK_T -typedef __darwin_pthread_rwlock_t pthread_rwlock_t; -#endif - -#ifndef _PTHREAD_RWLOCKATTR_T -#define _PTHREAD_RWLOCKATTR_T -typedef __darwin_pthread_rwlockattr_t pthread_rwlockattr_t; -#endif - -#ifndef _PTHREAD_T -#define _PTHREAD_T -typedef __darwin_pthread_t pthread_t; -#endif - -#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) - -#ifndef _MACH_PORT_T -#define _MACH_PORT_T -typedef __darwin_mach_port_t mach_port_t; -#endif - -#ifndef _SIGSET_T -#define _SIGSET_T -typedef __darwin_sigset_t sigset_t; -#endif - -#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ - -/* - * These symbols indicate which [optional] features are available - * They can be tested at compile time via '#ifdef XXX' - * The way to check for pthreads is like so: - - * #include - * #ifdef _POSIX_THREADS - * #include - * #endif - - */ - -/* These will be moved to unistd.h */ - -/* - * Note: These data structures are meant to be opaque. Only enough - * structure is exposed to support initializers. - * All of the typedefs will be moved to - */ - -#include -#include - -__BEGIN_DECLS -/* - * Threads - */ - - -/* - * Cancel cleanup handler management. Note, since these are implemented as macros, - * they *MUST* occur in matched pairs! - */ - -#define pthread_cleanup_push(func, val) \ - { \ - struct __darwin_pthread_handler_rec __handler; \ - pthread_t __self = pthread_self(); \ - __handler.__routine = func; \ - __handler.__arg = val; \ - __handler.__next = __self->__cleanup_stack; \ - __self->__cleanup_stack = &__handler; - -#define pthread_cleanup_pop(execute) \ - /* Note: 'handler' must be in this same lexical context! */ \ - __self->__cleanup_stack = __handler.__next; \ - if (execute) (__handler.__routine)(__handler.__arg); \ - } - -/* - * Thread attributes - */ - -#define PTHREAD_CREATE_JOINABLE 1 -#define PTHREAD_CREATE_DETACHED 2 - -#define PTHREAD_INHERIT_SCHED 1 -#define PTHREAD_EXPLICIT_SCHED 2 - -#define PTHREAD_CANCEL_ENABLE 0x01 /* Cancel takes place at next cancellation point */ -#define PTHREAD_CANCEL_DISABLE 0x00 /* Cancel postponed */ -#define PTHREAD_CANCEL_DEFERRED 0x02 /* Cancel waits until cancellation point */ -#define PTHREAD_CANCEL_ASYNCHRONOUS 0x00 /* Cancel occurs immediately */ - -/* Value returned from pthread_join() when a thread is canceled */ -#define PTHREAD_CANCELED ((void *) 1) - -/* We only support PTHREAD_SCOPE_SYSTEM */ -#define PTHREAD_SCOPE_SYSTEM 1 -#define PTHREAD_SCOPE_PROCESS 2 - -/* We only support PTHREAD_PROCESS_PRIVATE */ -#define PTHREAD_PROCESS_SHARED 1 -#define PTHREAD_PROCESS_PRIVATE 2 - -/* - * Mutex protocol attributes - */ -#define PTHREAD_PRIO_NONE 0 -#define PTHREAD_PRIO_INHERIT 1 -#define PTHREAD_PRIO_PROTECT 2 - -/* - * Mutex type attributes - */ -#define PTHREAD_MUTEX_NORMAL 0 -#define PTHREAD_MUTEX_ERRORCHECK 1 -#define PTHREAD_MUTEX_RECURSIVE 2 -#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL -/* - * RWLock variables - */ - -#define PTHREAD_RWLOCK_INITIALIZER {_PTHREAD_RWLOCK_SIG_init, {0}} -/* - * Mutex variables - */ - -#define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}} - -#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER {_PTHREAD_ERRORCHECK_MUTEX_SIG_init, {0}} -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER {_PTHREAD_RECURSIVE_MUTEX_SIG_init, {0}} -#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ - -/* - * Condition variable attributes - */ - -/* - * Condition variables - */ - -#define PTHREAD_COND_INITIALIZER {_PTHREAD_COND_SIG_init, {0}} - -/* - * Initialization control (once) variables - */ - -#define PTHREAD_ONCE_INIT {_PTHREAD_ONCE_SIG_init, {0}} - -/* - * Prototypes for all PTHREAD interfaces - */ -int pthread_atfork(void (*)(void), void (*)(void), - void (*)(void)); -int pthread_attr_destroy(pthread_attr_t *); -int pthread_attr_getdetachstate(const pthread_attr_t *, - int *); -int pthread_attr_getguardsize(const pthread_attr_t * __restrict, - size_t * __restrict); -int pthread_attr_getinheritsched(const pthread_attr_t * __restrict, - int * __restrict); -int pthread_attr_getschedparam(const pthread_attr_t * __restrict, - struct sched_param * __restrict); -int pthread_attr_getschedpolicy(const pthread_attr_t * __restrict, - int * __restrict); -int pthread_attr_getscope(const pthread_attr_t * __restrict, int * __restrict); -int pthread_attr_getstack(const pthread_attr_t * __restrict, - void ** __restrict, size_t * __restrict); -int pthread_attr_getstackaddr(const pthread_attr_t * __restrict, - void ** __restrict); -int pthread_attr_getstacksize(const pthread_attr_t * __restrict, - size_t * __restrict); -int pthread_attr_init(pthread_attr_t *); -int pthread_attr_setdetachstate(pthread_attr_t *, - int ); -int pthread_attr_setguardsize(pthread_attr_t *, size_t ); -int pthread_attr_setinheritsched(pthread_attr_t *, - int ); -int pthread_attr_setschedparam(pthread_attr_t * __restrict, - const struct sched_param * __restrict); -int pthread_attr_setschedpolicy(pthread_attr_t *, - int ); -int pthread_attr_setscope(pthread_attr_t *, int); -int pthread_attr_setstack(pthread_attr_t *, - void *, size_t ); -int pthread_attr_setstackaddr(pthread_attr_t *, - void *); -int pthread_attr_setstacksize(pthread_attr_t *, size_t ); -int pthread_cancel(pthread_t ) __DARWIN_ALIAS(pthread_cancel); - -int pthread_cond_broadcast(pthread_cond_t *); -int pthread_cond_destroy(pthread_cond_t *); -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_COND_INIT -//End-Libc -int pthread_cond_init(pthread_cond_t * __restrict, - const pthread_condattr_t * __restrict) __DARWIN_ALIAS(pthread_cond_init); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_COND_INIT */ -int pthread_cond_init(pthread_cond_t * __restrict, - const pthread_condattr_t * __restrict) LIBC_ALIAS(pthread_cond_init); -#endif /* !LIBC_ALIAS_PTHREAD_COND_INIT */ -//End-Libc -int pthread_cond_signal(pthread_cond_t *); -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -//End-Libc -int pthread_cond_timedwait(pthread_cond_t * __restrict, - pthread_mutex_t * __restrict, - const struct timespec * __restrict) __DARWIN_ALIAS_C(pthread_cond_timedwait); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_COND_TIMEDWAIT */ -int pthread_cond_timedwait(pthread_cond_t * __restrict, - pthread_mutex_t * __restrict, - const struct timespec * __restrict) LIBC_ALIAS_C(pthread_cond_timedwait); -#endif /* !LIBC_ALIAS_PTHREAD_COND_TIMEDWAIT */ -//End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_COND_WAIT -//End-Libc -int pthread_cond_wait(pthread_cond_t * __restrict, - pthread_mutex_t * __restrict) __DARWIN_ALIAS_C(pthread_cond_wait); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_COND_WAIT */ -int pthread_cond_wait(pthread_cond_t * __restrict, - pthread_mutex_t * __restrict) LIBC_ALIAS_C(pthread_cond_wait); -#endif /* !LIBC_ALIAS_PTHREAD_COND_WAIT */ -//End-Libc -int pthread_condattr_destroy(pthread_condattr_t *); -int pthread_condattr_init(pthread_condattr_t *); -int pthread_condattr_getpshared(const pthread_condattr_t * __restrict, - int * __restrict); -int pthread_condattr_setpshared(pthread_condattr_t *, - int ); -int pthread_create(pthread_t * __restrict, - const pthread_attr_t * __restrict, - void *(*)(void *), - void * __restrict); -int pthread_detach(pthread_t ); -int pthread_equal(pthread_t , - pthread_t ); -void pthread_exit(void *) __dead2; -int pthread_getconcurrency(void); -int pthread_getschedparam(pthread_t , int * __restrict, struct sched_param * __restrict); -void *pthread_getspecific(pthread_key_t ); -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_JOIN -//End-Libc -int pthread_join(pthread_t , void **) __DARWIN_ALIAS_C(pthread_join); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_JOIN */ -int pthread_join(pthread_t , void **) LIBC_ALIAS_C(pthread_join); -#endif /* !LIBC_ALIAS_PTHREAD_JOIN */ -//End-Libc -int pthread_key_create(pthread_key_t *, void (*)(void *)); -int pthread_key_delete(pthread_key_t ); -int pthread_mutex_destroy(pthread_mutex_t *); -int pthread_mutex_getprioceiling(const pthread_mutex_t * __restrict, int * __restrict); -int pthread_mutex_init(pthread_mutex_t * __restrict, const pthread_mutexattr_t * __restrict); -int pthread_mutex_lock(pthread_mutex_t *); -int pthread_mutex_setprioceiling(pthread_mutex_t * __restrict, int, int * __restrict); -int pthread_mutex_trylock(pthread_mutex_t *); -int pthread_mutex_unlock(pthread_mutex_t *); -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY -//End-Libc -int pthread_mutexattr_destroy(pthread_mutexattr_t *) __DARWIN_ALIAS(pthread_mutexattr_destroy); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY */ -int pthread_mutexattr_destroy(pthread_mutexattr_t *) LIBC_ALIAS(pthread_mutexattr_destroy); -#endif /* !LIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY */ -//End-Libc -int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t * __restrict, int * __restrict); -int pthread_mutexattr_getprotocol(const pthread_mutexattr_t * __restrict, int * __restrict); -int pthread_mutexattr_getpshared(const pthread_mutexattr_t * __restrict, int * __restrict); -int pthread_mutexattr_gettype(const pthread_mutexattr_t * __restrict, int * __restrict); -int pthread_mutexattr_init(pthread_mutexattr_t *); -int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int); -int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int); -int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int ); -int pthread_mutexattr_settype(pthread_mutexattr_t *, int); -int pthread_once(pthread_once_t *, void (*)(void)); -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_DESTROY -//End-Libc -int pthread_rwlock_destroy(pthread_rwlock_t * ) __DARWIN_ALIAS(pthread_rwlock_destroy); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_RWLOCK_DESTROY */ -int pthread_rwlock_destroy(pthread_rwlock_t * ) LIBC_ALIAS(pthread_rwlock_destroy); -#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_DESTROY */ -//End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_INIT -//End-Libc -int pthread_rwlock_init(pthread_rwlock_t * __restrict, const pthread_rwlockattr_t * __restrict) __DARWIN_ALIAS(pthread_rwlock_init); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_RWLOCK_INIT */ -int pthread_rwlock_init(pthread_rwlock_t * __restrict, const pthread_rwlockattr_t * __restrict) LIBC_ALIAS(pthread_rwlock_init); -#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_INIT */ -//End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK -//End-Libc -int pthread_rwlock_rdlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_rdlock); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK */ -int pthread_rwlock_rdlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_rdlock); -#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK */ -//End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK -//End-Libc -int pthread_rwlock_tryrdlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_tryrdlock); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK */ -int pthread_rwlock_tryrdlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_tryrdlock); -#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK */ -//End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK -//End-Libc -int pthread_rwlock_trywrlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_trywrlock); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK */ -int pthread_rwlock_trywrlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_trywrlock); -#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK */ -//End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK -//End-Libc -int pthread_rwlock_wrlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_wrlock); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK */ -int pthread_rwlock_wrlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_wrlock); -#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK */ -//End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK -//End-Libc -int pthread_rwlock_unlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_unlock); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK */ -int pthread_rwlock_unlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_unlock); -#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK */ -//End-Libc -int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); -int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * __restrict, - int * __restrict); -int pthread_rwlockattr_init(pthread_rwlockattr_t *); -int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, - int ); -pthread_t pthread_self(void); - -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_SETCANCELSTATE -//End-Libc -int pthread_setcancelstate(int , int *) __DARWIN_ALIAS(pthread_setcancelstate); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_SETCANCELSTATE */ -int pthread_setcancelstate(int , int *) LIBC_ALIAS(pthread_setcancelstate); -#endif /* !LIBC_ALIAS_PTHREAD_SETCANCELSTATE */ -//End-Libc -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_SETCANCELTYPE -//End-Libc -int pthread_setcanceltype(int , int *) __DARWIN_ALIAS(pthread_setcanceltype); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_SETCANCELTYPE */ -int pthread_setcanceltype(int , int *) LIBC_ALIAS(pthread_setcanceltype); -#endif /* !LIBC_ALIAS_PTHREAD_SETCANCELTYPE */ -//End-Libc -int pthread_setconcurrency(int); -int pthread_setschedparam(pthread_t , - int , - const struct sched_param *); -int pthread_setspecific(pthread_key_t , - const void *); -void pthread_testcancel(void) __DARWIN_ALIAS(pthread_testcancel); - -#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) -/* returns non-zero if pthread_create or cthread_fork have been called */ -int pthread_is_threaded_np(void); - -int pthread_threadid_np(pthread_t,__uint64_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); - -int pthread_rwlock_longrdlock_np(pthread_rwlock_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); -int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); -int pthread_rwlock_downgrade_np(pthread_rwlock_t *); -int pthread_rwlock_upgrade_np(pthread_rwlock_t *); -int pthread_rwlock_tryupgrade_np(pthread_rwlock_t *); -int pthread_rwlock_held_np(pthread_rwlock_t *); -int pthread_rwlock_rdheld_np(pthread_rwlock_t *); -int pthread_rwlock_wrheld_np(pthread_rwlock_t *); - -/*SPI to set and get pthread name*/ -int pthread_getname_np(pthread_t,char*,size_t) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); -int pthread_setname_np(const char*) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); -/* returns non-zero if the current thread is the main thread */ -int pthread_main_np(void); - -/* return the mach thread bound to the pthread */ -mach_port_t pthread_mach_thread_np(pthread_t); -size_t pthread_get_stacksize_np(pthread_t); -void * pthread_get_stackaddr_np(pthread_t); - -/* Like pthread_cond_signal(), but only wake up the specified pthread */ -int pthread_cond_signal_thread_np(pthread_cond_t *, pthread_t); - -/* Like pthread_cond_timedwait, but use a relative timeout */ -int pthread_cond_timedwait_relative_np(pthread_cond_t *, - pthread_mutex_t *, - const struct timespec *); - -/* Like pthread_create(), but leaves the thread suspended */ -int pthread_create_suspended_np(pthread_t *, - const pthread_attr_t *, - void *(*)(void *), - void *); -int pthread_kill(pthread_t, int); - -pthread_t pthread_from_mach_thread_np(mach_port_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); - -//Begin-Libc -#ifndef LIBC_ALIAS_PTHREAD_SIGMASK -//End-Libc -int pthread_sigmask(int, const sigset_t *, sigset_t *) __DARWIN_ALIAS(pthread_sigmask); -//Begin-Libc -#else /* LIBC_ALIAS_PTHREAD_SIGMASK */ -int pthread_sigmask(int, const sigset_t *, sigset_t *) LIBC_ALIAS(pthread_sigmask); -#endif /* !LIBC_ALIAS_PTHREAD_SIGMASK */ -//End-Libc -void pthread_yield_np(void); -#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ -__END_DECLS -#endif /* _PTHREAD_H */ diff --git a/src/libc/pthreads/pthread_atfork.3 b/src/libc/pthreads/pthread_atfork.3 deleted file mode 100644 index bde203535..000000000 --- a/src/libc/pthreads/pthread_atfork.3 +++ /dev/null @@ -1,57 +0,0 @@ -.\" Copyright (c) 2004 Apple Computer, Inc. -.\" -.Dd August 12, 2004 -.Dt PTHREAD_ATFORK 3 -.Os -.Sh NAME -.Nm pthread_atfork -.Nd register handlers to be called before and after -.Fn fork -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn pthread_atfork "void (*prepare)(void)" "void (*parent)(void)" "void (*child)(void)" -.Sh DESCRIPTION -The -.Fn pthread_atfork -function is used to register functions to be called before and after -.Fn fork -The -.Fa prepare -handler is called before -.Fn fork , -while the -.Fa parent -and -.Fa child -handlers are called after -.Fn fork -in the parent and child process, respectively. -.Fa prepare -handlers are called in reverse order of their registration, while -.Fa parent -and -.Fa child -handlers are called in the order in which they were registered. Any of the handlers may -be NULL. -.Pp -Remember: only async-cancel-safe functions are allowed on the child side of -.Fn fork -.Sh RETURN VALUES -If successful, the -.Fn pthread_atfork -function will return zero; otherwise an error number will be returned to -indicate the error. -.Sh ERRORS -.Fn pthread_atfork -will fail if: -.Bl -tag -width Er -.It Bq Er ENOMEM -The system lacked the necessary resources to add another handler to the list. -.El -.Sh SEE ALSO -.Xr fork 2 -.Sh STANDARDS -.Fn pthread_atfork -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_attr.3 b/src/libc/pthreads/pthread_attr.3 deleted file mode 100644 index 101942549..000000000 --- a/src/libc/pthreads/pthread_attr.3 +++ /dev/null @@ -1,277 +0,0 @@ -.\" Copyright (C) 2000 Jason Evans . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice(s), this list of conditions and the following disclaimer as -.\" the first lines of this file unmodified other than the possible -.\" addition of one or more copyright notices. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice(s), this list of conditions and the following disclaimer in -.\" the documentation and/or other materials provided with the -.\" distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY -.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE -.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_attr.3,v 1.4.2.5 2001/08/17 15:42:51 ru Exp $ -.Dd April 28, 2000 -.Dt PTHREAD_ATTR 3 -.Os -.Sh NAME -.Nm pthread_attr_destroy , -.Nm pthread_attr_getdetachstate , -.Nm pthread_attr_getinheritsched , -.Nm pthread_attr_getschedparam , -.Nm pthread_attr_getschedpolicy , -.Nm pthread_attr_getscope , -.Nm pthread_attr_getstackaddr , -.Nm pthread_attr_getstacksize , -.Nm pthread_attr_init , -.Nm pthread_attr_setdetachstate , -.Nm pthread_attr_setinheritsched , -.Nm pthread_attr_setschedparam , -.Nm pthread_attr_setschedpolicy , -.Nm pthread_attr_setscope , -.Nm pthread_attr_setstackaddr , -.Nm pthread_attr_setstacksize -.Nd thread attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_attr_destroy -.Fa "pthread_attr_t *attr" -.Fc -.Ft int -.Fo pthread_attr_getdetachstate -.Fa "const pthread_attr_t *attr" -.Fa "int *detachstate" -.Fc -.Ft int -.Fo pthread_attr_getinheritsched -.Fa "const pthread_attr_t *restrict attr" -.Fa "int *restrict inheritsched" -.Fc -.Ft int -.Fo pthread_attr_getschedparam -.Fa "const pthread_attr_t *restrict attr" -.Fa "struct sched_param *restrict param" -.Fc -.Ft int -.Fo pthread_attr_getschedpolicy -.Fa "const pthread_attr_t *restrict attr" -.Fa "int *restrict policy" -.Fc -.Ft int -.Fo pthread_attr_getscope -.Fa "const pthread_attr_t *restrict attr" -.Fa "int *restrict contentionscope" -.Fc -.Ft int -.Fo pthread_attr_getstackaddr -.Fa "const pthread_attr_t *restrict attr" -.Fa "void **restrict stackaddr" -.Fc -.Ft int -.Fo pthread_attr_getstacksize -.Fa "const pthread_attr_t *restrict attr" -.Fa "size_t *restrict stacksize" -.Fc -.Ft int -.Fo pthread_attr_init -.Fa "pthread_attr_t *attr" -.Fc -.Ft int -.Fo pthread_attr_setdetachstate -.Fa "pthread_attr_t *attr" -.Fa "int detachstate" -.Fc -.Ft int -.Fo pthread_attr_setinheritsched -.Fa "pthread_attr_t *attr" -.Fa "int inheritsched" -.Fc -.Ft int -.Fo pthread_attr_setschedparam -.Fa "pthread_attr_t *restrict attr" -.Fa "const struct sched_param *restrict param" -.Fc -.Ft int -.Fo pthread_attr_setschedpolicy -.Fa "pthread_attr_t *attr" -.Fa "int policy" -.Fc -.Ft int -.Fo pthread_attr_setscope -.Fa "pthread_attr_t *attr" -.Fa "int contentionscope" -.Fc -.Ft int -.Fo pthread_attr_setstackaddr -.Fa "pthread_attr_t *attr" -.Fa "void *stackaddr" -.Fc -.Ft int -.Fo pthread_attr_setstacksize -.Fa "pthread_attr_t *attr" -.Fa "size_t stacksize" -.Fc -.Sh DESCRIPTION -Thread attributes are used to specify parameters to -.Fn pthread_create . -One attribute object can be used in multiple calls to -.Fn pthread_create , -with or without modifications between calls. -.Pp -The -.Fn pthread_attr_init -function initializes -.Fa attr -with all the default thread attributes. -.Pp -The -.Fn pthread_attr_destroy -function destroys -.Fa attr . -.Pp -The -.Fn pthread_attr_set* -functions set the attribute that corresponds to each function name. -.Pp -The -.Fn pthread_attr_get* -functions copy the value of the attribute that corresponds to each function name -to the location pointed to by the second function parameter. -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Sh ERRORS -.Fn pthread_attr_init -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er ENOMEM -Out of memory. -.El -.Pp -.Fn pthread_attr_destroy -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Fn pthread_attr_setstacksize -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.It Bq Er EINVAL -.Fa stacksize -is less than -.Dv PTHREAD_STACK_MIN . -.\" ======== -.It Bq Er EINVAL -.Fa stacksize -is not a multiple of the system page size. -.El -.Pp -.Fn pthread_attr_setdetachstate -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr -or -.Fa detachstate . -.El -.Pp -.Fn pthread_attr_setinheritsched -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Fn pthread_attr_setschedparam -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.It Bq Er ENOTSUP -Invalid value for -.Fa param . -.El -.Pp -.Fn pthread_attr_setschedpolicy -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.It Bq Er ENOTSUP -Invalid or unsupported value for -.Fa policy . -.El -.Pp -.Fn pthread_attr_setscope -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.It Bq Er ENOTSUP -Invalid or unsupported value for -.Fa contentionscope . -.El -.Sh SEE ALSO -.Xr pthread_create 3 -.Sh STANDARDS -.Fn pthread_attr_init , -.Fn pthread_attr_destroy , -.Fn pthread_attr_setstacksize , -.Fn pthread_attr_getstacksize , -.Fn pthread_attr_setstackaddr , -.Fn pthread_attr_getstackaddr , -.Fn pthread_attr_setdetachstate , -and -.Fn pthread_attr_getdetachstate -conform to -.St -p1003.1-96 -.Pp -.Fn pthread_attr_setinheritsched , -.Fn pthread_attr_getinheritsched , -.Fn pthread_attr_setschedparam , -.Fn pthread_attr_getschedparam , -.Fn pthread_attr_setschedpolicy , -.Fn pthread_attr_getschedpolicy , -.Fn pthread_attr_setscope , -and -.Fn pthread_attr_getscope -conform to -.St -susv2 diff --git a/src/libc/pthreads/pthread_attr_init_destroy.3 b/src/libc/pthreads/pthread_attr_init_destroy.3 deleted file mode 100644 index 236a093ba..000000000 --- a/src/libc/pthreads/pthread_attr_init_destroy.3 +++ /dev/null @@ -1,64 +0,0 @@ -.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved. -.Dd December 31, 2007 -.Dt PTHREAD_ATTR 3 -.Os -.Sh NAME -.Nm pthread_attr_destroy , -.Nm pthread_attr_init -.Nd thread attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_attr_destroy -.Fa "pthread_attr_t *attr" -.Fc -.Ft int -.Fo pthread_attr_init -.Fa "pthread_attr_t *attr" -.Fc -.Sh DESCRIPTION -Thread attributes are used to specify parameters to -.Fn pthread_create . -One attribute object can be used in multiple calls to -.Fn pthread_create , -with or without modifications between calls. -.Pp -The -.Fn pthread_attr_init -function initializes -.Fa attr -with all the default thread attributes. -.Pp -The -.Fn pthread_attr_destroy -function destroys -.Fa attr . -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Sh ERRORS -.Fn pthread_attr_init -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er ENOMEM -Out of memory. -.El -.Pp -.Fn pthread_attr_destroy -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Sh SEE ALSO -.Xr pthread_create 3 -.Sh STANDARDS -.Fn pthread_attr_init , -.Fn pthread_attr_destroy -conform to -.St -p1003.1-96 -.Pp diff --git a/src/libc/pthreads/pthread_attr_set_getdetachstate.3 b/src/libc/pthreads/pthread_attr_set_getdetachstate.3 deleted file mode 100644 index ee30399bd..000000000 --- a/src/libc/pthreads/pthread_attr_set_getdetachstate.3 +++ /dev/null @@ -1,86 +0,0 @@ -.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved. -.Dd December 31, 2007 -.Dt PTHREAD_ATTR 3 -.Os -.Sh NAME -.Nm pthread_attr_getdetachstate , -.Nm pthread_attr_setdetachstate -.Nd thread attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_attr_getdetachstate -.Fa "const pthread_attr_t *attr" -.Fa "int *detachstate" -.Fc -.Ft int -.Fo pthread_attr_setdetachstate -.Fa "pthread_attr_t *attr" -.Fa "int detachstate" -.Fc -.Sh DESCRIPTION -Thread attributes are used to specify parameters to -.Fn pthread_create . -One attribute object can be used in multiple calls to -.Fn pthread_create , -with or without modifications between calls. -.Pp -One of these thread attributes governs the creation state of the new thread. The new thread -can be either created "detached" or "joinable". The constants corresponding to these states are PTHREAD_CREATE_DETACHED and PTHREAD_CREATE_JOINABLE respectively. -Creating a "joinable" thread allows the user -to call -.Fn pthread_join -and -.Fn pthread_detach , -with the new thread's ID. A "detached" thread's ID cannot be used with -.Fn pthread_join -and -.Fn pthread_detach . -The default value for the "detachstate" attribute is PTHREAD_CREATE_JOINABLE. -.Pp -The -.Fn pthread_attr_setdetachstate -function sets the thread's "detachstate" attribute. -.Pp -The "detachstate" attribute is set within the -.Fa attr -argument, which can subsequently be used as an argument to -.Fn pthread_create . -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Fn pthread_attr_getdetachstate , -on success, will copy the value of the thread's "detachstate" attribute -to the location pointed to by the second function parameter. -.Sh ERRORS -.Fn pthread_attr_getdetachstate -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr -.El -.Pp -.Fn pthread_attr_setdetachstate -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr -or -.Fa detachstate . -.El -.Pp -.Sh SEE ALSO -.Xr pthread_create 3 , -.Xr pthread_join 3 , -.Xr pthread_attr_init 3 , -.Xr pthread_detach 3 -.Sh STANDARDS -.Fn pthread_attr_setdetachstate , -.Fn pthread_attr_getdetachstate -conform to -.St -p1003.1-96 -.Pp diff --git a/src/libc/pthreads/pthread_attr_set_getinheritsched.3 b/src/libc/pthreads/pthread_attr_set_getinheritsched.3 deleted file mode 100644 index b5e52cc6f..000000000 --- a/src/libc/pthreads/pthread_attr_set_getinheritsched.3 +++ /dev/null @@ -1,85 +0,0 @@ -.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved. -.Dd December 31, 2007 -.Dt PTHREAD_ATTR 3 -.Os -.Sh NAME -.Nm pthread_attr_getinheritsched , -.Nm pthread_attr_setinheritsched -.Nd thread attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_attr_getinheritsched -.Fa "const pthread_attr_t *restrict attr" -.Fa "int *restrict inheritsched" -.Fc -.Ft int -.Fo pthread_attr_setinheritsched -.Fa "pthread_attr_t *attr" -.Fa "int inheritsched" -.Fc -.Sh DESCRIPTION -Thread attributes are used to specify parameters to -.Fn pthread_create . -One attribute object can be used in multiple calls to -.Fn pthread_create , -with or without modifications between calls. -.Pp -One of the thread attributes of interest is the "inheritsched" attribute. This attribute -controls the scheduling policy and related attributes of the newly created thread. The values of the -"inheritsched" attribute can be either PTHREAD_INHERIT_SCHED or PTHREAD_EXPLICIT_SCHED. -.Pp -PTHREAD_INHERIT_SCHED -.Pp - Indicates that the newly created thread should inherit all it's scheduling related attributes from it's creating -thread. It ignores the values of the relevant attributes within the -.Fa attr -argument. -.Pp -PTHREAD_EXPLICIT_SCHED -.Pp - Indicates that the newly created thread should set it's scheduling related attributes based on -.Fa attr -argument. -.Pp -The -.Fn pthread_attr_setinheritsched -functions set the "inheritsched" attribute within the -.Fa attr -argument to the desired value. -.Pp -The -.Fn pthread_attr_getinheritsched -functions copy the value of the "inheritsched" attribute to the location pointed to by the second function parameter. -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Sh ERRORS -.Pp -.Fn pthread_attr_getinheritsched -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Fn pthread_attr_setinheritsched -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Sh SEE ALSO -.Xr pthread_create 3 , -.Xr pthread_attr_init 3 , -.Xr pthread_attr_setschedparam 3 -.Sh STANDARDS -.Pp -.Fn pthread_attr_setinheritsched , -.Fn pthread_attr_getinheritsched -conform to -.St -susv2 diff --git a/src/libc/pthreads/pthread_attr_set_getschedparam.3 b/src/libc/pthreads/pthread_attr_set_getschedparam.3 deleted file mode 100644 index dff13e45f..000000000 --- a/src/libc/pthreads/pthread_attr_set_getschedparam.3 +++ /dev/null @@ -1,81 +0,0 @@ -.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved. -.Dd December 31, 2007 -.Dt PTHREAD_ATTR 3 -.Os -.Sh NAME -.Nm pthread_attr_getschedparam , -.Nm pthread_attr_setschedparam -.Nd thread attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_attr_getschedparam -.Fa "const pthread_attr_t *restrict attr" -.Fa "struct sched_param *restrict param" -.Fc -.Ft int -.Fo pthread_attr_setschedparam -.Fa "pthread_attr_t *restrict attr" -.Fa "const struct sched_param *restrict param" -.Fc -.Sh DESCRIPTION -Thread attributes are used to specify parameters to -.Fn pthread_create . -One attribute object can be used in multiple calls to -.Fn pthread_create , -with or without modifications between calls. -.Pp -.Fn pthread_attr_getschedparam -and -.Fn pthread_attr_setschedparam -get and set the scheduling parameters within the -.Fa attr -argument. See -.Fd /usr/include/sched.h -for the definition of -.Fa struct sched_param . -The -.Fa sched_priority -field of -.Fa struct sched_param -can be set to SCHED_OTHER, SCHED_FIFO and SCHED_RR. -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Fn pthread_attr_getschedparam , -on success, will copy the value of the thread's scheduling parameter attribute -to the location pointed to by the second function parameter. -.Sh ERRORS -.Pp -.Fn pthread_attr_getschedparam -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.El -.Pp -.Fn pthread_attr_setschedparam -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.It Bq Er ENOTSUP -Invalid value for -.Fa param . -.El -.Sh SEE ALSO -.Xr pthread_create 3 , -.Xr pthread_attr_init 3 , -.Xr pthread_attr_setinheritsched 3 -.Sh STANDARDS -.Pp -.Fn pthread_attr_setschedparam , -.Fn pthread_attr_getschedparam -conform to -.St -susv2 diff --git a/src/libc/pthreads/pthread_attr_set_getschedpolicy.3 b/src/libc/pthreads/pthread_attr_set_getschedpolicy.3 deleted file mode 100644 index d83e7a406..000000000 --- a/src/libc/pthreads/pthread_attr_set_getschedpolicy.3 +++ /dev/null @@ -1,73 +0,0 @@ -.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved. -.Dd December 31, 2007 -.Dt PTHREAD_ATTR 3 -.Os -.Sh NAME -.Nm pthread_attr_getschedpolicy , -.Nm pthread_attr_setschedpolicy -.Nd thread attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_attr_getschedpolicy -.Fa "const pthread_attr_t *restrict attr" -.Fa "int *restrict policy" -.Fc -.Ft int -.Fo pthread_attr_setschedpolicy -.Fa "pthread_attr_t *attr" -.Fa "int policy" -.Fc -.Sh DESCRIPTION -Thread attributes are used to specify parameters to -.Fn pthread_create . -One attribute object can be used in multiple calls to -.Fn pthread_create , -with or without modifications between calls. -.Pp -The functions -.Fn pthread_attr_setschedpolicy -and -.Fn pthread_attr_getschedpolicy , -set and get the attribute in the -.Fa attr -argument related to the scheduling policy. -The value for the aforementioned attribute can be SCHED_FIFO, SCHED_RR and SCHED_OTHER. -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Fn pthread_attr_getschedpolicy , -on success, will copy the value of the thread's scheduling policy attribute -to the location pointed to by the second function parameter. -.Sh ERRORS -.Pp -.Fn pthread_attr_getschedpolicy -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Fn pthread_attr_setschedpolicy -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.It Bq Er ENOTSUP -Invalid or unsupported value for -.Fa policy . -.El -.Sh SEE ALSO -.Xr pthread_create 3 , -.Xr pthread_attr_init 3 , -.Xr pthread_attr_setschedparam 3 , -.Xr pthread_attr_setinheritsched 3 -.Sh STANDARDS -.Fn pthread_attr_setschedpolicy , -.Fn pthread_attr_getschedpolicy -conform to -.St -susv2 diff --git a/src/libc/pthreads/pthread_attr_set_getscope.3 b/src/libc/pthreads/pthread_attr_set_getscope.3 deleted file mode 100644 index 20052977e..000000000 --- a/src/libc/pthreads/pthread_attr_set_getscope.3 +++ /dev/null @@ -1,75 +0,0 @@ -.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved. -.Dd December 31, 2007 -.Dt PTHREAD_ATTR 3 -.Os -.Sh NAME -.Nm pthread_attr_getscope , -.Nm pthread_attr_setscope -.Nd thread attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_attr_getscope -.Fa "const pthread_attr_t *restrict attr" -.Fa "int *restrict contentionscope" -.Fc -.Ft int -.Fo pthread_attr_setscope -.Fa "pthread_attr_t *attr" -.Fa "int contentionscope" -.Fc -.Sh DESCRIPTION -Thread attributes are used to specify parameters to -.Fn pthread_create . -One attribute object can be used in multiple calls to -.Fn pthread_create , -with or without modifications between calls. -.Pp -The -.Fn pthread_attr_setscope -and -.Fn pthread_attr_getscope -functions, respectively, set and get the attribute within -.Fa attr -argument that controls the contention scope of the thread. -The acceptable values are PTHREAD_SCOPE_SYSTEM, indicating a scheduling contention scope that -is system-wide, and PTHREAD_SCOPE_PROCESS, which indicates a process scheduling contention scope. -Currently on Mac OS X we only support PTHREAD_SCOPE_SYSTEM. -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Sh ERRORS -.Pp -.Fn pthread_attr_getscope -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.El -.Pp -.Fn pthread_attr_setscope -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.It Bq Er ENOTSUP -Invalid or unsupported value for -.Fa contentionscope . -.El -.Sh SEE ALSO -.Xr pthread_create 3 , -.Xr pthread_attr_init 3 , -.Xr pthread_attr_setinheritsched 3 , -.Xr pthread_attr_setschedpolicy 3 , -.Xr pthread_attr_setschedparam 3 -.Sh STANDARDS -.Fn pthread_attr_setscope , -.Fn pthread_attr_getscope -conform to -.St -susv2 diff --git a/src/libc/pthreads/pthread_attr_set_getstackaddr.3 b/src/libc/pthreads/pthread_attr_set_getstackaddr.3 deleted file mode 100644 index cf725ae5a..000000000 --- a/src/libc/pthreads/pthread_attr_set_getstackaddr.3 +++ /dev/null @@ -1,74 +0,0 @@ -.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved. -.Dd December 31, 2007 -.Dt PTHREAD_ATTR 3 -.Os -.Sh NAME -.Nm pthread_attr_getstackaddr , -.Nm pthread_attr_setstackaddr -.Nd thread attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_attr_getstackaddr -.Fa "const pthread_attr_t *restrict attr" -.Fa "void **restrict stackaddr" -.Fc -.Ft int -.Fo pthread_attr_setstackaddr -.Fa "pthread_attr_t *attr" -.Fa "void *stackaddr" -.Fc -.Sh DESCRIPTION -Thread attributes are used to specify parameters to -.Fn pthread_create . -One attribute object can be used in multiple calls to -.Fn pthread_create , -with or without modifications between calls. -.Pp -The functions -.Fn pthread_attr_setstackaddr -and -.Fn pthread_attr_getstackaddr -respectively, set and get the address at which the stack of the newly created thread should be located. -The stackaddr attribute is set within the -.Fa attr -argument, which can subsequently be used as an argument to -.Fn pthread_create . -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Fn pthread_attr_getstackaddr -returns the stackaddr attribute value in -.Fa stackaddr -if successful. -.Sh ERRORS -.Fn pthread_attr_setstackaddr -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.El -.Pp -.Fn pthread_attr_getstackaddr -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.El -.Pp -.Sh SEE ALSO -.Xr pthread_create 3 , -.Xr pthread_attr_init 3 , -.Xr pthread_attr_setdetachstate 3 , -.Xr pthread_attr_setstacksize 3 -.Sh STANDARDS -.Fn pthread_attr_setstackaddr , -.Fn pthread_attr_getstackaddr , -conform to -.St -p1003.1-96 diff --git a/src/libc/pthreads/pthread_attr_set_getstacksize.3 b/src/libc/pthreads/pthread_attr_set_getstacksize.3 deleted file mode 100644 index 3aadea660..000000000 --- a/src/libc/pthreads/pthread_attr_set_getstacksize.3 +++ /dev/null @@ -1,78 +0,0 @@ -.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved. -.Dd December 31, 2007 -.Dt PTHREAD_ATTR 3 -.Os -.Sh NAME -.Nm pthread_attr_getstacksize , -.Nm pthread_attr_setstacksize -.Nd thread attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_attr_getstacksize -.Fa "const pthread_attr_t *restrict attr" -.Fa "size_t *restrict stacksize" -.Fc -.Ft int -.Fo pthread_attr_setstacksize -.Fa "pthread_attr_t *attr" -.Fa "size_t stacksize" -.Fc -.Sh DESCRIPTION -Thread attributes are used to specify parameters to -.Fn pthread_create . -One attribute object can be used in multiple calls to -.Fn pthread_create , -with or without modifications between calls. -.Pp -The functions -.Fn pthread_attr_setstacksize -and -.Fn pthread_attr_getstacksize , -respectively, set and get the size of the stack that is to be created for the new thread. The stack size attribute is set within the -.Fa attr -argument, which can subsequently be used as an argument to -.Fn pthread_create . -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Fn pthread_attr_getstacksize -returns the stacksize attribute value in -.Fa stacksize -if successful. -.Sh ERRORS -.Fn pthread_attr_getstacksize -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Fn pthread_attr_setstacksize -will fail if: -.Bl -tag -width Er -.\" ======== -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.\" ======== -.It Bq Er EINVAL -.Fa stacksize -is less than -.Dv PTHREAD_STACK_MIN . -.\" ======== -.It Bq Er EINVAL -.Fa stacksize -is not a multiple of the system page size. -.El -.Sh SEE ALSO -.Xr pthread_create 3 , -.Xr pthread_attr_init 3 , -.Xr pthread_attr_setstackaddr 3 -.Sh STANDARDS -.Fn pthread_attr_setstacksize , -.Fn pthread_attr_getstacksize -conform to -.St -p1003.1-96 diff --git a/src/libc/pthreads/pthread_cancel.3 b/src/libc/pthreads/pthread_cancel.3 deleted file mode 100644 index fae332ed5..000000000 --- a/src/libc/pthreads/pthread_cancel.3 +++ /dev/null @@ -1,77 +0,0 @@ -.\" $FreeBSD: src/lib/libc_r/man/pthread_cancel.3,v 1.3.2.3 2001/03/06 16:46:08 ru Exp $ -.Dd January 17, 1999 -.Dt PTHREAD_CANCEL 3 -.Os -.Sh NAME -.Nm pthread_cancel -.Nd cancel execution of a thread -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn pthread_cancel "pthread_t thread" -.Sh DESCRIPTION -The -.Fn pthread_cancel -function requests that -.Fa thread -be canceled. -The target thread's cancelability state and type determines -when the cancellation takes effect. -When the cancellation is acted on, -the cancellation cleanup handlers for -.Fa thread -are called. -When the last cancellation cleanup handler returns, -the thread-specific data destructor functions will be called for -.Fa thread . -When the last destructor function returns, -.Fa thread -will be terminated. -.Pp -The cancellation processing in the target thread runs asynchronously with -respect to the calling thread returning from -.Fn pthread_cancel . -.Pp -A status of -.Dv PTHREAD_CANCELED -is made available to any threads joining with the target. -The symbolic -constant -.Dv PTHREAD_CANCELED -expands to a constant expression of type -.Ft "(void *)" , -whose value matches no pointer to an object in memory nor the value -.Dv NULL . -.Sh RETURN VALUES -If successful, the -.Fn pthread_cancel -functions will return zero. -Otherwise an error number will be returned to -indicate the error. -.Sh ERRORS -.Fn pthread_cancel -will fail if: -.Bl -tag -width Er -.It Bq Er ESRCH -No thread could be found corresponding to that specified by the given -thread ID. -.El -.Sh SEE ALSO -.Xr pthread_cleanup_pop 3 , -.Xr pthread_cleanup_push 3 , -.Xr pthread_exit 3 , -.Xr pthread_join 3 , -.Xr pthread_setcancelstate 3 , -.Xr pthread_setcanceltype 3 , -.Xr pthread_testcancel 3 -.Sh STANDARDS -.Fn pthread_cancel -conforms to -.St -p1003.1-96 . -.Sh AUTHORS -This man page was written by -.An David Leonard Aq d@openbsd.org -for the -.Ox -implementation of -.Fn pthread_cancel . diff --git a/src/libc/pthreads/pthread_cancelable.c b/src/libc/pthreads/pthread_cancelable.c deleted file mode 100644 index aa51be5ac..000000000 --- a/src/libc/pthreads/pthread_cancelable.c +++ /dev/null @@ -1,320 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2000-2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * POSIX Pthread Library - */ - -#include "pthread_internals.h" - -#include -#include /* For printf(). */ -#include -#include /* For __mach_errno_addr() prototype. */ -#include -#include -#include -#include -#include -#include -#include - -extern int __unix_conforming; -extern void __posix_join_cleanup(void *arg); -extern pthread_lock_t _pthread_list_lock; -extern void _pthread_testcancel(pthread_t thread, int isconforming); -extern int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr, int conforming); -extern int _pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime, - int isRelative, - int isconforming); -extern int __sigwait(const sigset_t *set, int *sig); - -#ifdef VARIANT_CANCELABLE -extern int __semwait_signal(int cond_sem, int mutex_sem, int timeout, int relative, __int64_t tv_sec, __int32_t tv_nsec); -#else -extern int __semwait_signal(int cond_sem, int mutex_sem, int timeout, int relative, __int64_t tv_sec, __int32_t tv_nsec) __asm__("___semwait_signal_nocancel"); -#endif - -/* - * Wait for a thread to terminate and obtain its exit value. - */ -int -pthread_join(pthread_t thread, - void **value_ptr) -{ - int res = 0; - pthread_t self = pthread_self(); - mach_port_t kthport; - int conforming = 0; -#if !__DARWIN_UNIX03 - kern_return_t kern_res; -#endif - -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; - -#ifdef VARIANT_CANCELABLE - _pthread_testcancel(self, 1); -#endif /* VARIANT_CANCELABLE */ -#endif /* __DARWIN_UNIX03 */ - - if ((res = _pthread_lookup_thread(thread, &kthport, 1)) != 0) - return(res); - - if (thread->sig == _PTHREAD_SIG) - { - if (thread->newstyle == 0) { - semaphore_t death = new_sem_from_pool(); /* in case we need it */ - - LOCK(thread->lock); - if ((thread->detached & PTHREAD_CREATE_JOINABLE) && - thread->death == SEMAPHORE_NULL) - { - - assert(thread->joiner == NULL); - if (thread != self && (self == NULL || self->joiner != thread)) - { - int already_exited = (thread->detached & _PTHREAD_EXITED); - - thread->death = death; - thread->joiner = self; - UNLOCK(thread->lock); - - if (!already_exited) - { -#if __DARWIN_UNIX03 - /* Wait for it to signal... */ - pthread_cleanup_push(__posix_join_cleanup, (void *)thread); - do { - res = __semwait_signal(death, 0, 0, 0, (int64_t)0, (int32_t)0); - } while ((res < 0) && (errno == EINTR)); - pthread_cleanup_pop(0); - -#else /* __DARWIN_UNIX03 */ - /* Wait for it to signal... */ - do { - PTHREAD_MACH_CALL(semaphore_wait(death), kern_res); - } while (kern_res != KERN_SUCCESS); -#endif /* __DARWIN_UNIX03 */ - } - - LOCK(_pthread_list_lock); - TAILQ_REMOVE(&__pthread_head, thread, plist); -#if WQ_TRACE - __kdebug_trace(0x9000010, thread, 0, 0, 16, 0); -#endif - UNLOCK(_pthread_list_lock); - /* ... and wait for it to really be dead */ - while ((res = _pthread_reap_thread(thread, - thread->kernel_thread, - value_ptr, __unix_conforming)) == EAGAIN) - { - sched_yield(); - } - - } else { - UNLOCK(thread->lock); - res = EDEADLK; - } - } else { - UNLOCK(thread->lock); - res = EINVAL; - } - restore_sem_to_pool(death); - return res; - } else { - /* new style */ - - semaphore_t death = SEMAPHORE_NULL; /* in case we need it */ - semaphore_t joinsem = SEMAPHORE_NULL; - - if (thread->joiner_notify == MACH_PORT_NULL) - death = new_sem_from_pool(); - - LOCK(thread->lock); - if ((thread->detached & PTHREAD_CREATE_JOINABLE) && - (thread->joiner == NULL)) - { - assert(thread->kernel_thread == kthport); - if (thread != self && (self == NULL || self->joiner != thread)) - { - if (thread->joiner_notify == MACH_PORT_NULL) { - if (death == SEMAPHORE_NULL) - LIBC_ABORT("thread %p: death == SEMAPHORE_NULL", thread); - thread->joiner_notify = death; - death = SEMAPHORE_NULL; - } - joinsem = thread->joiner_notify; - thread->joiner = self; - UNLOCK(thread->lock); - - if (death != SEMAPHORE_NULL) { - restore_sem_to_pool(death); - death = SEMAPHORE_NULL; - } -#if __DARWIN_UNIX03 - /* Wait for it to signal... */ - pthread_cleanup_push(__posix_join_cleanup, (void *)thread); - do { - res = __semwait_signal(joinsem, 0, 0, 0, (int64_t)0, (int32_t)0); - } while ((res < 0) && (errno == EINTR)); - pthread_cleanup_pop(0); -#else /* __DARWIN_UNIX03 */ - /* Wait for it to signal... */ - do { - PTHREAD_MACH_CALL(semaphore_wait(joinsem), kern_res); - } while (kern_res != KERN_SUCCESS); -#endif /* __DARWIN_UNIX03 */ - - restore_sem_to_pool(joinsem); - res = _pthread_join_cleanup(thread, value_ptr, conforming); - } else { - UNLOCK(thread->lock); - res = EDEADLK; - } - } else { - UNLOCK(thread->lock); - res = EINVAL; - } - if (death != SEMAPHORE_NULL) - restore_sem_to_pool(death); - return res; - }/* end of new style */ - } - return ESRCH; -} - -int -pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex) -{ - int conforming; -#if __DARWIN_UNIX03 - - if (__unix_conforming == 0) - __unix_conforming = 1; - -#ifdef VARIANT_CANCELABLE - conforming = 1; -#else /* !VARIANT_CANCELABLE */ - conforming = -1; -#endif /* VARIANT_CANCELABLE */ -#else /* __DARWIN_UNIX03 */ - conforming = 0; -#endif /* __DARWIN_UNIX03 */ - return (_pthread_cond_wait(cond, mutex, (struct timespec *)NULL, 0, conforming)); -} - -int -pthread_cond_timedwait(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime) -{ - int conforming; -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; - -#ifdef VARIANT_CANCELABLE - conforming = 1; -#else /* !VARIANT_CANCELABLE */ - conforming = -1; -#endif /* VARIANT_CANCELABLE */ -#else /* __DARWIN_UNIX03 */ - conforming = 0; -#endif /* __DARWIN_UNIX03 */ - - return (_pthread_cond_wait(cond, mutex, abstime, 0, conforming)); -} - -int -sigwait(const sigset_t * set, int * sig) -{ -#if __DARWIN_UNIX03 - int err = 0; - - if (__unix_conforming == 0) - __unix_conforming = 1; - -#ifdef VARIANT_CANCELABLE - _pthread_testcancel(pthread_self(), 1); -#endif /* VARIANT_CANCELABLE */ - - if (__sigwait(set, sig) == -1) { - err = errno; - -#ifdef VARIANT_CANCELABLE - _pthread_testcancel(pthread_self(), 1); -#endif /* VARIANT_CANCELABLE */ - - /* - * EINTR that isn't a result of pthread_cancel() - * is translated to 0. - */ - if (err == EINTR) { - err = 0; - } - } - return(err); -#else /* __DARWIN_UNIX03 */ - if (__sigwait(set, sig) == -1) { - /* - * EINTR that isn't a result of pthread_cancel() - * is translated to 0. - */ - if (errno != EINTR) { - return -1; - } - } - - return 0; -#endif /* __DARWIN_UNIX03 */ -} diff --git a/src/libc/pthreads/pthread_cleanup_pop.3 b/src/libc/pthreads/pthread_cleanup_pop.3 deleted file mode 100644 index f6d0401e2..000000000 --- a/src/libc/pthreads/pthread_cleanup_pop.3 +++ /dev/null @@ -1,66 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_cleanup_pop.3,v 1.5.2.3 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 30, 1998 -.Dt PTHREAD_CLEANUP_POP 3 -.Os -.Sh NAME -.Nm pthread_cleanup_pop -.Nd call the first cleanup routine -.Sh SYNOPSIS -.Fd #include -.Ft void -.Fn pthread_cleanup_pop "int execute" -.Sh DESCRIPTION -The -.Fn pthread_cleanup_pop -function pops the top cleanup routine off -of the current thread's cleanup routine stack and, if -.Fa execute -is non-zero, it will execute the function. -If there is no cleanup routine, -.Fn pthread_cleanup_pop -does nothing. -.Pp -.Fn pthread_cleanup_pop -must be paired with a corresponding -.Xr pthread_cleanup_push 3 -in the same lexical scope. -.Sh RETURN VALUES -.Fn pthread_cleanup_pop -does not return any value. -.Sh ERRORS -None -.Sh SEE ALSO -.Xr pthread_cleanup_push 3 , -.Xr pthread_exit 3 -.Sh STANDARDS -.Fn pthread_cleanup_pop -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_cleanup_push.3 b/src/libc/pthreads/pthread_cleanup_push.3 deleted file mode 100644 index 91ec386e9..000000000 --- a/src/libc/pthreads/pthread_cleanup_push.3 +++ /dev/null @@ -1,71 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_cleanup_push.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 30, 1998 -.Dt PTHREAD_CLEANUP_PUSH 3 -.Os -.Sh NAME -.Nm pthread_cleanup_push -.Nd add a cleanup function for thread exit -.Sh SYNOPSIS -.Fd #include -.Ft void -.Fo pthread_cleanup_push -.Fa "void \*[lp]*routine\*[rp]\*[lp]void *\*[rp]" -.Fa "void *arg" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_cleanup_push -function adds -.Fa routine -to the top of the stack of cleanup handlers that -get called when the current thread exits. -.Pp -When -.Fa routine -is called, it is passed -.Fa arg -as its only argument. -.Fn pthread_cleanup_push -must be paired with a corresponding -.Xr pthread_cleanup_pop 3 -in the same lexical scope. -.Sh RETURN VALUES -.Fn pthread_cleanup_push -does not return any value. -.Sh ERRORS -None -.Sh SEE ALSO -.Xr pthread_cleanup_pop 3 , -.Xr pthread_exit 3 -.Sh STANDARDS -.Fn pthread_cleanup_push -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_cond.c b/src/libc/pthreads/pthread_cond.c deleted file mode 100644 index 055956f1a..000000000 --- a/src/libc/pthreads/pthread_cond.c +++ /dev/null @@ -1,1103 +0,0 @@ -/* - * Copyright (c) 2000-2003, 2007, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * MkLinux - */ - -/* - * POSIX Pthread Library - */ - -#include "pthread_internals.h" -#include /* For struct timespec and getclock(). */ -#include - -#ifdef PLOCKSTAT -#include "plockstat.h" -#else /* !PLOCKSTAT */ -#define PLOCKSTAT_MUTEX_RELEASE(x, y) -#endif /* PLOCKSTAT */ - -extern int _pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *, int); -extern int __unix_conforming; -extern int usenew_mtximpl; - -#ifdef PR_5243343 -/* 5243343 - temporary hack to detect if we are running the conformance test */ -extern int PR_5243343_flag; -#endif /* PR_5243343 */ - -__private_extern__ int _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime, int isRelative, int isconforming); -#ifndef BUILDING_VARIANT -static void cond_cleanup(void *arg); -static void cond_dropwait(npthread_cond_t * cond, int error, uint32_t updateval); -static void __pthread_cond_set_signature(npthread_cond_t * cond); -static int _pthread_cond_destroy_locked(pthread_cond_t *cond); -#endif - -#if defined(__LP64__) -#define COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt) \ -{ \ - if (cond->misalign != 0) { \ - c_lseqcnt = &cond->c_seq[1]; \ - c_sseqcnt = &cond->c_seq[2]; \ - c_useqcnt = &cond->c_seq[0]; \ - } else { \ - /* aligned */ \ - c_lseqcnt = &cond->c_seq[0]; \ - c_sseqcnt = &cond->c_seq[1]; \ - c_useqcnt = &cond->c_seq[2]; \ - } \ -} -#else /* __LP64__ */ -#define COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt) \ -{ \ - if (cond->misalign != 0) { \ - c_lseqcnt = &cond->c_seq[1]; \ - c_sseqcnt = &cond->c_seq[2]; \ - c_useqcnt = &cond->c_seq[0]; \ - } else { \ - /* aligned */ \ - c_lseqcnt = &cond->c_seq[0]; \ - c_sseqcnt = &cond->c_seq[1]; \ - c_useqcnt = &cond->c_seq[2]; \ - } \ -} -#endif /* __LP64__ */ - - -#define _KSYN_TRACE_ 0 - -#if _KSYN_TRACE_ -/* The Function qualifiers */ -#define DBG_FUNC_START 1 -#define DBG_FUNC_END 2 -#define DBG_FUNC_NONE 0 - -int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); - -#define _KSYN_TRACE_UM_LOCK 0x9000060 -#define _KSYN_TRACE_UM_UNLOCK 0x9000064 -#define _KSYN_TRACE_UM_MHOLD 0x9000068 -#define _KSYN_TRACE_UM_MDROP 0x900006c -#define _KSYN_TRACE_UM_CVWAIT 0x9000070 -#define _KSYN_TRACE_UM_CVSIG 0x9000074 -#define _KSYN_TRACE_UM_CVBRD 0x9000078 -#define _KSYN_TRACE_UM_CDROPWT 0x90000a0 -#define _KSYN_TRACE_UM_CVCLRPRE 0x90000a4 - -#endif /* _KSYN_TRACE_ */ - - -#ifndef BUILDING_VARIANT /* [ */ - -int -pthread_condattr_init(pthread_condattr_t *attr) -{ - attr->sig = _PTHREAD_COND_ATTR_SIG; - attr->pshared = _PTHREAD_DEFAULT_PSHARED; - return (0); -} - -int -pthread_condattr_destroy(pthread_condattr_t *attr) -{ - attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */ - return (0); -} - -int -pthread_condattr_getpshared(const pthread_condattr_t *attr, - int *pshared) -{ - if (attr->sig == _PTHREAD_COND_ATTR_SIG) - { - *pshared = (int)attr->pshared; - return (0); - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - - - - -/* temp home till pshared is fixed correctly */ -int -pthread_condattr_setpshared(pthread_condattr_t * attr, int pshared) -{ - - if (attr->sig == _PTHREAD_COND_ATTR_SIG) - { -#if __DARWIN_UNIX03 - if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED)) -#else /* __DARWIN_UNIX03 */ - if ( pshared == PTHREAD_PROCESS_PRIVATE) -#endif /* __DARWIN_UNIX03 */ - { - attr->pshared = pshared; - return (0); - } else { - return (EINVAL); /* Invalid parameter */ - } - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } - -} - -__private_extern__ int -_pthread_cond_init(pthread_cond_t *ocond, - const pthread_condattr_t *attr, - int conforming) -{ - npthread_cond_t * cond = (npthread_cond_t *)ocond; - - cond->busy = (npthread_mutex_t *)NULL; - cond->c_seq[0] = 0; - cond->c_seq[1] = 0; - cond->c_seq[2] = 0; - cond->rfu = 0; - - if (((uintptr_t)cond & 0x07) != 0) { - cond->misalign = 1; - cond->c_seq[2] = PTH_RWS_CV_CBIT; - } else { - cond->misalign = 0; - cond->c_seq[1] = PTH_RWS_CV_CBIT; /* set Sword to 0c */ - } - if (conforming) { - if (attr) - cond->pshared = attr->pshared; - else - cond->pshared = _PTHREAD_DEFAULT_PSHARED; - } else - cond->pshared = _PTHREAD_DEFAULT_PSHARED; - /* - * For the new style mutex, interlocks are not held all the time. - * We needed the signature to be set in the end. And we need - * to protect against the code getting reorganized by compiler. - * cond->sig = _PTHREAD_COND_SIG; - */ - __pthread_cond_set_signature(cond); - return (0); -} - -int -pthread_cond_destroy(pthread_cond_t * ocond) -{ - npthread_cond_t *cond = (npthread_cond_t *)ocond; - int ret; - - /* to provide backwards compat for apps using united condtn vars */ - if((cond->sig != _PTHREAD_COND_SIG) && (cond->sig != _PTHREAD_COND_SIG_init)) - return(EINVAL); - - LOCK(cond->lock); - ret = _pthread_cond_destroy_locked(ocond); - UNLOCK(cond->lock); - - return(ret); -} - -static int -_pthread_cond_destroy_locked(pthread_cond_t * ocond) -{ - npthread_cond_t *cond = (npthread_cond_t *)ocond; - int ret; - volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; - uint32_t lcntval , ucntval, scntval; - uint64_t oldval64, newval64; - -retry: - if (cond->sig == _PTHREAD_COND_SIG) - { - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); - lcntval = *c_lseqcnt; - ucntval = *c_useqcnt; - scntval = *c_sseqcnt; - - if ((lcntval & PTHRW_COUNT_MASK) == (scntval & PTHRW_COUNT_MASK)) { - /* validate it is not busy */ - oldval64 = (((uint64_t)scntval) << 32); - oldval64 |= lcntval; - newval64 = oldval64; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) - goto retry; - cond->sig = _PTHREAD_NO_SIG; - ret = 0; - } else - ret = EBUSY; - } else if (cond->sig == _PTHREAD_COND_SIG_init) { - cond->sig = _PTHREAD_NO_SIG; - ret = 0; - } else - ret = EINVAL; /* Not an initialized condition variable structure */ - return (ret); -} - -/* - * Signal a condition variable, waking up all threads waiting for it. - */ -int -pthread_cond_broadcast(pthread_cond_t *ocond) -{ - npthread_cond_t * cond = (npthread_cond_t *)ocond; - int sig = cond->sig; - uint32_t flags, updateval; - uint32_t lcntval , ucntval, scntval; - uint64_t oldval64, newval64, mugen, cvlsgen, cvudgen, mtid=0; - int diffgen, error = 0; - volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; - uint32_t * pmtx = NULL; - uint32_t nlval, ulval; - int needclearpre = 0, retry_count = 0, uretry_count = 0; - int ucountreset = 0; - - /* to provide backwards compat for apps using united condtn vars */ - if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) - return(EINVAL); - - if (sig != _PTHREAD_COND_SIG) - { - LOCK(cond->lock); - if (cond->sig == _PTHREAD_COND_SIG_init) - { - _pthread_cond_init(ocond, NULL, 0); - /* just inited nothing to post */ - UNLOCK(cond->lock); - return (0); - } else if (cond->sig != _PTHREAD_COND_SIG) { - /* Not a condition variable */ - UNLOCK(cond->lock); - return (EINVAL); - } - UNLOCK(cond->lock); - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_START, (uint32_t)cond, 0, 0, 0, 0); -#endif - - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); -retry: - lcntval = *c_lseqcnt; - ucntval = *c_useqcnt; - scntval = *c_sseqcnt; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, scntval, 0); -#endif - - if (((lcntval & PTHRW_COUNT_MASK) == (scntval & PTHRW_COUNT_MASK)) || - ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK))) { - /* validate it is spurious and return */ - oldval64 = (((uint64_t)scntval) << 32); - oldval64 |= lcntval; - newval64 = oldval64; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) - goto retry; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, 0xf1f1f1f1, 0); - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_END, (uint32_t)cond, scntval, 0, 0xf1f1f1f1, 0); -#endif - return(0); - } - - /* validate to eliminate spurious values, race snapshots */ - if (is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) { - /* since ucntval may be newer, just redo */ - retry_count++; - if (retry_count > 8192) { - return(EAGAIN); - } else { - sched_yield(); - goto retry; - } - } else if (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) { - /* since ucntval may be newer, just redo */ - uretry_count++; - if (uretry_count > 8192) { - /* - * U value if not used for a while can go out of sync - * set this to S value and try one more time. - */ - if (ucountreset != 0) - return(EAGAIN); - else - if (OSAtomicCompareAndSwap32Barrier(ucntval, (scntval & PTHRW_COUNT_MASK), (volatile int32_t *)c_useqcnt) == TRUE) { - /* now the U is reset to S value */ - ucountreset = 1; - uretry_count = 0; - } - } - sched_yield(); - goto retry; - } - - if (is_seqlower(ucntval & PTHRW_COUNT_MASK, scntval & PTHRW_COUNT_MASK) != 0) { - /* If U < S, set U = S+diff due to intr's TO, etc */ - ulval = (scntval & PTHRW_COUNT_MASK); - } else { - /* If U >= S, set U = U+diff due to intr's TO, etc */ - ulval = (ucntval & PTHRW_COUNT_MASK); - } -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, lcntval, ucntval, scntval, diffgen, 0); -#endif - - diffgen = diff_genseq((lcntval & PTHRW_COUNT_MASK), (ulval & PTHRW_COUNT_MASK)); - - /* set U = L */ - ulval = (lcntval & PTHRW_COUNT_MASK); - if (OSAtomicCompareAndSwap32Barrier(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) { - goto retry; - } - - flags = 0; - if (cond->pshared == PTHREAD_PROCESS_SHARED) - flags |= _PTHREAD_MTX_OPT_PSHARED; - pmtx = NULL; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, 3, diffgen, flags, 0); -#endif - nlval = lcntval; - - /* pass old u val so kernel will know the diffgen */ - mugen = 0; - cvlsgen = ((uint64_t)scntval << 32) | nlval; - cvudgen = ((uint64_t)ucntval << 32) | diffgen; - - updateval = __psynch_cvbroad(ocond, cvlsgen, cvudgen, flags, (pthread_mutex_t *)pmtx, mugen, mtid); - - if (updateval != (uint32_t)-1) { - - /* if kernel granted woke some threads, updatwe S for them as they will not access cv on their way out */ - /* Were any threads woken or bits to be set? */ - if (updateval != 0) { -retry2: - needclearpre = 0; - lcntval = *c_lseqcnt; - ucntval = *c_useqcnt; - scntval = *c_sseqcnt; - /* update scntval with number of expected returns and bits */ - nlval = (scntval & PTHRW_COUNT_MASK) + (updateval & PTHRW_COUNT_MASK); - /* set bits */ - nlval |= ((scntval & PTH_RWS_CV_BITSALL) | (updateval & PTH_RWS_CV_BITSALL)); - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, 0x25, lcntval, scntval, updateval, 0); -#endif - /* if L==S and c&p bits are set, needs clearpre */ - if (((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) - && ((nlval & PTH_RWS_CV_BITSALL) == PTH_RWS_CV_BITSALL)) { - /* reset p bit but retain c bit on the sword */ - nlval &= PTH_RWS_CV_RESET_PBIT; - needclearpre = 1; - } - - oldval64 = (((uint64_t)scntval) << 32); - oldval64 |= lcntval; - newval64 = (((uint64_t)nlval) << 32); - newval64 |= lcntval; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, 0x25, nlval, scntval, updateval, 0); -#endif - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) - goto retry2; - - /* if L == S, then reset associated mutex */ - if ((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) { - cond->busy = (npthread_mutex_t *)NULL; - } - - if (needclearpre != 0) { - (void)__psynch_cvclrprepost(ocond, lcntval, ucntval, nlval, 0, lcntval, flags); - } - } - - } - error = 0; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_END, (uint32_t)cond, 0, error, 0, 0); -#endif - return(error); -} - - -/* - * Signal a condition variable, waking a specified thread. - */ - -int -pthread_cond_signal_thread_np(pthread_cond_t *ocond, pthread_t thread) -{ - npthread_cond_t * cond = (npthread_cond_t *)ocond; - int sig = cond->sig; - uint32_t flags, updateval; - uint32_t lcntval , ucntval, scntval; - uint32_t nlval, ulval=0; - volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; - uint64_t oldval64, newval64, mugen, cvlsgen, mtid = 0; - int needclearpre = 0, retry_count = 0, uretry_count = 0; - int error, ucountreset = 0; - - /* to provide backwards compat for apps using united condtn vars */ - - if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) - return(EINVAL); - - if (cond->sig != _PTHREAD_COND_SIG) { - LOCK(cond->lock); - if (cond->sig != _PTHREAD_COND_SIG) { - if (cond->sig == _PTHREAD_COND_SIG_init) { - _pthread_cond_init(ocond, NULL, 0); - /* just inited, nothing to post yet */ - UNLOCK(cond->lock); - return(0); - } else { - UNLOCK(cond->lock); - return(EINVAL); - } - } - UNLOCK(cond->lock); - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_START, (uint32_t)cond, 0, 0, 0, 0); -#endif - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); -retry: - lcntval = *c_lseqcnt; - ucntval = *c_useqcnt; - scntval = *c_sseqcnt; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, scntval, 0); -#endif - - if (((lcntval & PTHRW_COUNT_MASK) == (scntval & PTHRW_COUNT_MASK)) || - ((thread == 0) && ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK)))) { - /* If L <= S+U, it is spurious broadcasr */ - /* validate it is spurious and return */ - oldval64 = (((uint64_t)scntval) << 32); - oldval64 |= lcntval; - newval64 = oldval64; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) - goto retry; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, 0xf1f1f1f1, 0); - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_END, (uint32_t)cond, scntval, 0, 0xf1f1f1f1, 0); -#endif - return(0); - } - - if (thread == 0) { - /* validate to eliminate spurious values, race snapshots */ - if (is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) { - /* since ucntval may be newer, just redo */ - retry_count++; - if (retry_count > 8192) { - return(EAGAIN); - } else { - sched_yield(); - goto retry; - } - } else if (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) { - /* since ucntval may be newer, just redo */ - uretry_count++; - if (uretry_count > 8192) { - /* - * U value if not used for a while can go out of sync - * set this to S value and try one more time. - */ - if (ucountreset != 0) - return(EAGAIN); - else - if (OSAtomicCompareAndSwap32Barrier(ucntval, (scntval & PTHRW_COUNT_MASK), (volatile int32_t *)c_useqcnt) == TRUE) { - /* now the U is reset to S value */ - ucountreset = 1; - uretry_count = 0; - } - } - sched_yield(); - goto retry; - } - } /* thread == 0 ) */ - - if (thread == 0) { - /* - * skip manipulating U count as ESRCH from kernel cannot be handled properly. - * S count will cover the imbalance and next signal without thread or broadcast - * will correct it. But we need to send the right U to kernel so it will use - * that to look for the appropriate sequenc. So the ulval is computed anyway. - */ - - if (is_seqlower(ucntval & PTHRW_COUNT_MASK, scntval & PTHRW_COUNT_MASK) != 0) { - /* If U < S, set U = S+1 due to intr's TO, etc */ - ulval = (scntval & PTHRW_COUNT_MASK) + PTHRW_INC; - } else { - /* If U >= S, set U = U+1 due to intr's TO, etc */ - ulval = (ucntval & PTHRW_COUNT_MASK) + PTHRW_INC; - } - - if (OSAtomicCompareAndSwap32Barrier(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) { - goto retry; - } - } - - flags = 0; - if (cond->pshared == PTHREAD_PROCESS_SHARED) - flags |= _PTHREAD_MTX_OPT_PSHARED; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, 3, nlval, ulval, 0); -#endif - nlval = lcntval; - /* pass old u val so kernel will know the diffgen */ - mugen = 0; - cvlsgen = ((uint64_t)scntval << 32) | nlval; - - updateval = __psynch_cvsignal(ocond, cvlsgen, ucntval, pthread_mach_thread_np(thread), (pthread_mutex_t *)0, mugen, mtid, flags); - - - if (updateval != (uint32_t)-1) { - - /* if kernel granted woke some threads, updatwe S for them as they will not access cv on their way out */ - /* Were any threads woken or bits to be set? */ - if (updateval != 0) { -retry2: - lcntval = *c_lseqcnt; - ucntval = *c_useqcnt; - scntval = *c_sseqcnt; - /* update scntval with number of expected returns and bits */ - nlval = (scntval & PTHRW_COUNT_MASK) + (updateval & PTHRW_COUNT_MASK); - /* set bits */ - nlval |= ((scntval & PTH_RWS_CV_BITSALL) | (updateval & PTH_RWS_CV_BITSALL)); - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, 0x25, 0, 0, updateval, 0); -#endif - /* if L==S and c&p bits are set, needs clearpre */ - if (((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) - && ((nlval & PTH_RWS_CV_BITSALL) == PTH_RWS_CV_BITSALL)) { - /* reset p bit but retain c bit on the sword */ - nlval &= PTH_RWS_CV_RESET_PBIT; - needclearpre = 1; - } else - needclearpre = 0; - - oldval64 = (((uint64_t)scntval) << 32); - oldval64 |= lcntval; - newval64 = (((uint64_t)nlval) << 32); - newval64 |= lcntval; - -#if _KSYN_TRACE_ -(void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, 0x25, nlval, ulval, updateval, 0); -#endif - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) - goto retry2; - - /* if L == S, then reset associated mutex */ - if ((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) { - cond->busy = (npthread_mutex_t *)NULL; - } - - if (needclearpre != 0) { - (void)__psynch_cvclrprepost(ocond, lcntval, ucntval, nlval, 0, lcntval, flags); - } - } - } - - error = 0; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0); -#endif - return (error); -} - -/* - * Signal a condition variable, waking only one thread. - */ -int -pthread_cond_signal(pthread_cond_t *cond) -{ - return pthread_cond_signal_thread_np(cond, NULL); -} - -/* - * Manage a list of condition variables associated with a mutex - */ - - -/* - * Suspend waiting for a condition variable. - * Note: we have to keep a list of condition variables which are using - * this same mutex variable so we can detect invalid 'destroy' sequences. - * If isconforming < 0, we skip the _pthread_testcancel(), but keep the - * remaining conforming behavior.. - */ -__private_extern__ int -_pthread_cond_wait(pthread_cond_t *ocond, - pthread_mutex_t *omutex, - const struct timespec *abstime, - int isRelative, - int isconforming) -{ - int retval; - npthread_cond_t * cond = (npthread_cond_t *)ocond; - npthread_mutex_t * mutex = (npthread_mutex_t * )omutex; - mach_timespec_t then = {0,0}; - struct timespec cthen = {0,0}; - int sig = cond->sig; - int msig = mutex->sig; - npthread_mutex_t * pmtx; - uint32_t mtxgen, mtxugen, flags=0, updateval; - uint32_t lcntval , ucntval, scntval; - uint32_t nlval, ulval, savebits; - volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; - uint64_t oldval64, newval64, mugen, cvlsgen; - uint32_t * npmtx = NULL; - int error, local_error; - -extern void _pthread_testcancel(pthread_t thread, int isconforming); - - /* to provide backwards compat for apps using united condtn vars */ - if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init)) - return(EINVAL); - - if (isconforming) { - if((msig != _PTHREAD_MUTEX_SIG) && ((msig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) - return(EINVAL); - if (isconforming > 0) - _pthread_testcancel(pthread_self(), 1); - } - - if (cond->sig != _PTHREAD_COND_SIG) - { - LOCK(cond->lock); - if (cond->sig != _PTHREAD_COND_SIG) { - if (cond->sig == _PTHREAD_COND_SIG_init) { - _pthread_cond_init(ocond, NULL, 0); - } else { - UNLOCK(cond->lock); - return(EINVAL); - } - } - UNLOCK(cond->lock); - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_START, (uint32_t)cond, isRelative, 0, (uint32_t)abstime, 0); -#endif - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); - - /* send relative time to kernel */ - if (abstime) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_START, 0x11111111, abstime->tv_nsec, abstime->tv_sec, 0, 0); -#endif - if (isRelative == 0) { - struct timespec now; - struct timeval tv; - gettimeofday(&tv, NULL); - TIMEVAL_TO_TIMESPEC(&tv, &now); - - /* Compute relative time to sleep */ - then.tv_nsec = abstime->tv_nsec - now.tv_nsec; - then.tv_sec = abstime->tv_sec - now.tv_sec; - if (then.tv_nsec < 0) - { - then.tv_nsec += NSEC_PER_SEC; - then.tv_sec--; - } - if (((int)then.tv_sec < 0) || - ((then.tv_sec == 0) && (then.tv_nsec == 0))) - { - return ETIMEDOUT; - } - if (isconforming != 0) { - cthen.tv_sec = abstime->tv_sec; - cthen.tv_nsec = abstime->tv_nsec; - if ((cthen.tv_sec < 0) || (cthen.tv_nsec < 0)) { - return EINVAL; - } - if (cthen.tv_nsec >= NSEC_PER_SEC) { - return EINVAL; - } - } - } else { - then.tv_sec = abstime->tv_sec; - then.tv_nsec = abstime->tv_nsec; - if ((then.tv_sec == 0) && (then.tv_nsec == 0)) { - return ETIMEDOUT; - } - } - if(isconforming && ((then.tv_sec < 0) || (then.tv_nsec < 0))) { - return EINVAL; - } - if (then.tv_nsec >= NSEC_PER_SEC) { - return EINVAL; - } - } - - if ((cond->busy != (npthread_mutex_t *)NULL) && (cond->busy != mutex)) - return (EINVAL); - - pmtx = mutex; -retry: - lcntval = *c_lseqcnt; - ucntval = *c_useqcnt; - scntval = *c_sseqcnt; - - oldval64 = (((uint64_t)scntval) << 32); - oldval64 |= lcntval; - - /* remove c and p bits on S word */ - savebits = scntval & PTH_RWS_CV_BITSALL; - ulval = (scntval & PTHRW_COUNT_MASK); - nlval = lcntval + PTHRW_INC; - newval64 = (((uint64_t)ulval) << 32); - newval64 |= nlval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) - goto retry; - - cond->busy = mutex; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, scntval, 0); -#endif - retval = __mtx_droplock(pmtx, PTHRW_INC, &flags, &npmtx, &mtxgen, &mtxugen); - - /* TBD: cases are for normal (non owner for recursive mutex; error checking)*/ - if (retval != 0) - return(EINVAL); - if ((flags & _PTHREAD_MTX_OPT_NOTIFY) == 0) { - npmtx = NULL; - mugen = 0; - } else - mugen = ((uint64_t)mtxugen << 32) | mtxgen; - flags &= ~_PTHREAD_MTX_OPT_MUTEX; /* reset the mutex bit as this is cvar */ - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 3, (uint32_t)mutex, flags, 0); -#endif - - - cvlsgen = ((uint64_t)(ulval | savebits)<< 32) | nlval; - - if (isconforming) { - pthread_cleanup_push(cond_cleanup, (void *)cond); - updateval = __psynch_cvwait(ocond, cvlsgen, ucntval, (pthread_mutex_t *)npmtx, mugen, flags, (int64_t)then.tv_sec, (int32_t)then.tv_nsec); - _pthread_testcancel(pthread_self(), isconforming); - pthread_cleanup_pop(0); - } else { - updateval = __psynch_cvwait(ocond, cvlsgen, ucntval, (pthread_mutex_t *)npmtx, mugen, flags, (int64_t)then.tv_sec, (int32_t)then.tv_nsec); - - } - - retval = 0; - - if (updateval == (uint32_t)-1) { - local_error = errno; - error = local_error & 0xff; - if (error == ETIMEDOUT) { - retval = ETIMEDOUT; - } else if (error == EINTR) { - /* - ** EINTR can be treated as a spurious wakeup unless we were canceled. - */ - retval = 0; - } else - retval = EINVAL; -//#if _KSYN_TRACE_ -// (void)__kdebug_trace(0x9000070 | 0, (uint32_t)cond, 0xf1f1f2f2, local_error, error, 0); -//#endif - - /* add unlock ref to show one less waiter */ - cond_dropwait(cond, local_error, 0); - } else { -//#if _KSYN_TRACE_ -// (void)__kdebug_trace(0x9000070 | 0, (uint32_t)cond, 0xf3f3f4f4, updateval, 0, 0); -//#endif - /* succesful wait */ - if (updateval != 0) { - /* the return due to prepost and might have bit states */ - /* update S and return for prepo if needed */ - cond_dropwait(cond, 0, updateval); - } - retval = 0; - } -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 4, retval, 0, 0); -#endif - pthread_mutex_lock(omutex); - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_END, (uint32_t)cond, 0, 0, retval, 0); -#endif - return(retval); -} - -/* - * For the new style mutex, interlocks are not held all the time. - * We needed the signature to be set in the end. And we need - * to protect against the code getting reorganized by compiler. - */ -static void -__pthread_cond_set_signature(npthread_cond_t * cond) -{ - cond->sig = _PTHREAD_COND_SIG; -} - - -static void -cond_cleanup(void *arg) -{ - npthread_cond_t *cond = (npthread_cond_t *)arg; - pthread_mutex_t *mutex; - -// 4597450: begin - pthread_t thread = pthread_self(); - int thcanceled = 0; - - LOCK(thread->lock); - thcanceled = (thread->detached & _PTHREAD_WASCANCEL); - UNLOCK(thread->lock); - - if (thcanceled == 0) - return; - -// 4597450: end - mutex = (pthread_mutex_t *) cond->busy; - - /* add unlock ref to show one less waiter */ - cond_dropwait(cond, thread->cancel_error, 0); - - /* - ** Can't do anything if this fails -- we're on the way out - */ - if (mutex != NULL) - (void)pthread_mutex_lock(mutex); -} - -#define ECVCERORR 256 -#define ECVPERORR 512 - -void -cond_dropwait(npthread_cond_t * cond, int error, uint32_t updateval) -{ - int sig = cond->sig; - pthread_cond_t * ocond = (pthread_cond_t *)cond; - int needclearpre = 0; - uint32_t diffgen, nlval, ulval, flags; - uint32_t lcntval , ucntval, scntval, lval; - volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt; - uint64_t oldval64, newval64; - - /* to provide backwards compat for apps using united condtn vars */ - - if (sig != _PTHREAD_COND_SIG) - return; - - COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt); - - if (error != 0) { - lval = PTHRW_INC; - if ((error & ECVCERORR) != 0) - lval |= PTH_RWS_CV_CBIT; - if ((error & ECVPERORR) != 0) - lval |= PTH_RWS_CV_PBIT; - } else { - lval = updateval; - } -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_START, (uint32_t)cond, error, updateval, 0xee, 0); -#endif -retry: - lcntval = *c_lseqcnt; - ucntval = *c_useqcnt; - scntval = *c_sseqcnt; - - diffgen = diff_genseq((lcntval & PTHRW_COUNT_MASK), (scntval & PTHRW_COUNT_MASK)); /* pendig waiters */ -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, lcntval, scntval, diffgen, 0); -#endif - if (diffgen <= 0) { - /* TBD: Assert, should not be the case */ - /* validate it is spurious and return */ - oldval64 = (((uint64_t)scntval) << 32); - oldval64 |= lcntval; - newval64 = oldval64; - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) - goto retry; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0); -#endif - return; - } - - /* update S by one */ - oldval64 = (((uint64_t)scntval) << 32); - oldval64 |= lcntval; - - /* update scntval with number of expected returns and bits */ - ulval = (scntval & PTHRW_COUNT_MASK) + (lval & PTHRW_COUNT_MASK); - /* set bits */ - ulval |= ((scntval & PTH_RWS_CV_BITSALL) | (lval & PTH_RWS_CV_BITSALL)); - - nlval = lcntval; - - needclearpre = 0; - - /* If L==S, need to return to kernel */ - if ((nlval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) { - if ((ulval & PTH_RWS_CV_BITSALL) == PTH_RWS_CV_BITSALL) { - /* reset p bit but retain c bit on the sword */ - needclearpre = 1; - ulval &= PTH_RWS_CV_RESET_PBIT; - } - } - - newval64 = (((uint64_t)ulval) << 32); - newval64 |= nlval; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, 0xffff, nlval, ulval, 0); -#endif - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE) - goto retry; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, 2, 0, 0xee, 0); -#endif - if ((nlval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) { - /* last usage remove the mutex */ - cond->busy = NULL; - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, nlval, ucntval, ulval, PTHRW_INC, 0); -#endif - if (needclearpre != 0) { - flags = 0; - if (cond->pshared == PTHREAD_PROCESS_SHARED) - flags |= _PTHREAD_MTX_OPT_PSHARED; - /* reset prepost */ - (void)__psynch_cvclrprepost(ocond, nlval, ucntval, ulval, 0, nlval, flags); - } -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_END, nlval, ucntval, ulval, PTHRW_INC, 0); -#endif - return; -} - - -int -pthread_cond_timedwait_relative_np(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime) -{ - return (_pthread_cond_wait(cond, mutex, abstime, 1, 0)); -} - - - -#else /* !BUILDING_VARIANT */ - -extern int _pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime, - int isRelative, - int isconforming); - -#endif /* !BUILDING_VARIANT ] */ -/* - * Initialize a condition variable. Note: 'attr' is ignored. - */ - -/* - * Initialize a condition variable. This is the public interface. - * We can't trust the lock, so initialize it first before taking - * it. - */ -int -pthread_cond_init(pthread_cond_t *cond, - const pthread_condattr_t *attr) -{ - int conforming; - -#if __DARWIN_UNIX03 - conforming = 1; -#else /* __DARWIN_UNIX03 */ - conforming = 0; -#endif /* __DARWIN_UNIX03 */ - - /* lock is same offset in both structures */ - LOCK_INIT(cond->lock); - - return (_pthread_cond_init(cond, attr, conforming)); -} - -/* -int -pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex) - -int -pthread_cond_timedwait(pthread_cond_t *cond, - pthread_mutex_t *mutex, - const struct timespec *abstime) - -moved to pthread_cancelable.c */ diff --git a/src/libc/pthreads/pthread_cond_broadcast.3 b/src/libc/pthreads/pthread_cond_broadcast.3 deleted file mode 100644 index 279636dfc..000000000 --- a/src/libc/pthreads/pthread_cond_broadcast.3 +++ /dev/null @@ -1,69 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_broadcast.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 28, 1998 -.Dt PTHREAD_COND_BROADCAST 3 -.Os -.Sh NAME -.Nm pthread_cond_broadcast -.Nd unblock all threads waiting for a condition variable -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn pthread_cond_broadcast "pthread_cond_t *cond" -.Sh DESCRIPTION -The -.Fn pthread_cond_broadcast -function unblocks all threads that are waiting for the condition variable -.Fa cond . -.Sh RETURN VALUES -If successful, the -.Fn pthread_cond_broadcast -function will return zero. -Otherwise, an error number will be returned -to indicate the error. -.Sh ERRORS -.Fn pthread_cond_broadcast -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa cond -is invalid. -.El -.Sh SEE ALSO -.Xr pthread_cond_destroy 3 , -.Xr pthread_cond_init 3 , -.Xr pthread_cond_signal 3 , -.Xr pthread_cond_timedwait 3 , -.Xr pthread_cond_wait 3 -.Sh STANDARDS -.Fn pthread_cond_broadcast -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_cond_destroy.3 b/src/libc/pthreads/pthread_cond_destroy.3 deleted file mode 100644 index 523bf8a37..000000000 --- a/src/libc/pthreads/pthread_cond_destroy.3 +++ /dev/null @@ -1,73 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_destroy.3,v 1.6.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 28, 1998 -.Dt PTHREAD_COND_DESTROY 3 -.Os -.Sh NAME -.Nm pthread_cond_destroy -.Nd destroy a condition variable -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn pthread_cond_destroy "pthread_cond_t *cond" -.Sh DESCRIPTION -The -.Fn pthread_cond_destroy -function frees the resources allocated by the condition variable -.Fa cond . -.Sh RETURN VALUES -If successful, the -.Fn pthread_cond_destroy -function will return zero. -Otherwise, an error number will be returned -to indicate the error. -.Sh ERRORS -.Fn pthread_cond_destroy -will fail if: -.Bl -tag -width Er -.It Bq Er EBUSY -The variable -.Fa cond -is locked by another thread. -.It Bq Er EINVAL -The value specified by -.Fa cond -is invalid. -.El -.Sh SEE ALSO -.Xr pthread_cond_broadcast 3 , -.Xr pthread_cond_init 3 , -.Xr pthread_cond_signal 3 , -.Xr pthread_cond_timedwait 3 , -.Xr pthread_cond_wait 3 -.Sh STANDARDS -.Fn pthread_cond_destroy -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_cond_init.3 b/src/libc/pthreads/pthread_cond_init.3 deleted file mode 100644 index a69fbacf6..000000000 --- a/src/libc/pthreads/pthread_cond_init.3 +++ /dev/null @@ -1,81 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_init.3,v 1.6.2.5 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 28, 1998 -.Dt PTHREAD_COND_INIT 3 -.Os -.Sh NAME -.Nm pthread_cond_init -.Nd create a condition variable -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_cond_init -.Fa "pthread_cond_t *restrict cond" -.Fa "const pthread_condattr_t *restrict attr" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_cond_init -function creates a new condition variable, with attributes specified with -.Fa attr . -If -.Fa attr -is NULL, the default attributes are used. -.Sh RETURN VALUES -If successful, the -.Fn pthread_cond_init -function will return zero and put the new condition variable id into -.Fa cond . -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -.Fn pthread_cond_init -will fail if: -.Bl -tag -width Er -.It Bq Er EAGAIN -The system temporarily lacks the resources to create another condition -variable. -.It Bq Er EINVAL -The value specified by -.Fa attr -is invalid. -.It Bq Er ENOMEM -The process cannot allocate enough memory to create another condition -variable. -.El -.Sh SEE ALSO -.Xr pthread_cond_broadcast 3 , -.Xr pthread_cond_destroy 3 , -.Xr pthread_cond_signal 3 , -.Xr pthread_cond_timedwait 3 , -.Xr pthread_cond_wait 3 -.Sh STANDARDS -.Fn pthread_cond_init -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_cond_signal.3 b/src/libc/pthreads/pthread_cond_signal.3 deleted file mode 100644 index 669b6fc9a..000000000 --- a/src/libc/pthreads/pthread_cond_signal.3 +++ /dev/null @@ -1,68 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_signal.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 28, 1998 -.Dt PTHREAD_COND_SIGNAL 3 -.Os -.Sh NAME -.Nm pthread_cond_signal -.Nd unblock a thread waiting for a condition variable -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fn pthread_cond_signal "pthread_cond_t *cond" -.Sh DESCRIPTION -The -.Fn pthread_cond_signal -function unblocks one thread waiting for the condition variable -.Fa cond . -.Sh RETURN VALUES -If successful, the -.Fn pthread_cond_signal -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -.Fn pthread_cond_signal -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa cond -is invalid. -.El -.Sh SEE ALSO -.Xr pthread_cond_broadcast 3 , -.Xr pthread_cond_destroy 3 , -.Xr pthread_cond_init 3 , -.Xr pthread_cond_timedwait 3 , -.Xr pthread_cond_wait 3 -.Sh STANDARDS -.Fn pthread_cond_signal -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_cond_timedwait.3 b/src/libc/pthreads/pthread_cond_timedwait.3 deleted file mode 100644 index dbf48e429..000000000 --- a/src/libc/pthreads/pthread_cond_timedwait.3 +++ /dev/null @@ -1,109 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_timedwait.3,v 1.8.2.6 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 28, 1998 -.Dt PTHREAD_COND_TIMEDWAIT 3 -.Os -.Sh NAME -.Nm pthread_cond_timedwait -.Nd "wait on a condition variable for a specific amount of time" -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_cond_timedwait -.Fa "pthread_cond_t *restrict cond" -.Fa "pthread_mutex_t *restrict mutex" -.Fa "const struct timespec *restrict abstime" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_cond_timedwait -function atomically blocks the current thread waiting on the condition -variable specified by -.Fa cond -and unblocks the mutex specified by -.Fa mutex . -The waiting thread unblocks only after another thread calls -.Xr pthread_cond_signal 3 , -or -.Xr pthread_cond_broadcast 3 -with the same condition variable, or if the system time reaches the -time specified in -.Fa abstime , -and the current thread reacquires the lock on -.Fa mutex . -.Pp -Values for struct timespec can be obtained by adding the required -time interval to the the current time obtained using -.Xr gettimeofday 2 . -.Pp -.Fa Note -that struct timeval and struct timespec use different units to specify -the time. Hence, the user should always take care to perform the time unit -conversions accordingly. -.Sh EXAMPLE -.Pp - struct timeval tv; - struct timespec ts; - gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec + 0; - ts.tv_nsec = 0; -.Pp -.Sh RETURN VALUES -If successful, the -.Fn pthread_cond_timedwait -function will return zero. -Otherwise, an error number will be returned to -indicate the error. -.Sh ERRORS -.Fn pthread_cond_timedwait -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa cond , -.Fa mutex -or -.Fa abstime -is invalid. -.It Bq Er ETIMEDOUT -The system time has reached or exceeded the time specified in -.Fa abstime . -.El -.Sh SEE ALSO -.Xr pthread_cond_broadcast 3 , -.Xr pthread_cond_destroy 3 , -.Xr pthread_cond_init 3 , -.Xr pthread_cond_signal 3 , -.Xr pthread_cond_wait 3 , -.Xr gettimeofday 2 -.Sh STANDARDS -.Fn pthread_cond_timedwait -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_cond_wait.3 b/src/libc/pthreads/pthread_cond_wait.3 deleted file mode 100644 index ab00653f7..000000000 --- a/src/libc/pthreads/pthread_cond_wait.3 +++ /dev/null @@ -1,80 +0,0 @@ -.\" Portions Copyright (c) 2001 Apple Computer, Inc. All Rights Reserved. -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_wait.3,v 1.8.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd November 5, 2001 -.Dt PTHREAD_COND_WAIT 3 -.Os Darwin -.Sh NAME -.Nm pthread_cond_wait -.Nd wait on a condition variable -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_cond_wait -.Fa "pthread_cond_t *restrict cond" -.Fa "pthread_mutex_t *restrict mutex" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_cond_wait -function atomically unlocks the -.Fa mutex -argument and waits on the -.Fa cond -argument. Before returning control to the calling function, -.Fn pthread_cond_wait -re-acquires the -.Fa mutex. -.Sh RETURN VALUES -If successful, the -.Fn pthread_cond_wait -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -.Fn pthread_cond_wait -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa cond -or the value specified by -.Fa mutex -is invalid. -.El -.Sh SEE ALSO -.Xr pthread_cond_broadcast 3 , -.Xr pthread_cond_destroy 3 , -.Xr pthread_cond_init 3 , -.Xr pthread_cond_signal 3 , -.Xr pthread_cond_timedwait 3 -.Sh STANDARDS -.Fn pthread_cond_wait -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_condattr.3 b/src/libc/pthreads/pthread_condattr.3 deleted file mode 100644 index 4db50278d..000000000 --- a/src/libc/pthreads/pthread_condattr.3 +++ /dev/null @@ -1,87 +0,0 @@ -.\" Copyright (C) 2000 Jason Evans . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice(s), this list of conditions and the following disclaimer as -.\" the first lines of this file unmodified other than the possible -.\" addition of one or more copyright notices. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice(s), this list of conditions and the following disclaimer in -.\" the documentation and/or other materials provided with the -.\" distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY -.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE -.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_condattr.3,v 1.9 2001/10/01 16:09:09 ru Exp $ -.Dd April 28, 2000 -.Dt PTHREAD_CONDATTR 3 -.Os -.Sh NAME -.Nm pthread_condattr_destroy , -.Nm pthread_condattr_init -.Nd condition attribute operations -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_condattr_destroy -.Fa "pthread_condattr_t *attr" -.Fc -.Ft int -.Fo pthread_condattr_init -.Fa "pthread_condattr_t *attr" -.Fc -.Sh DESCRIPTION -Condition attribute objects are used to specify parameters to -.Fn pthread_cond_init . -.Fx Ns 's -implementation of conditions does not support any non-default -attributes, so these functions are not very useful, though they are required to -to be present by -.Tn POSIX . -.Pp -The -.Fn pthread_condattr_init -function initializes a condition attribute object with the default attributes. -.Pp -The -.Fn pthread_condattr_destroy -function destroys a condition attribute object. -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Sh ERRORS -.Fn pthread_condattr_destroy -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Fn pthread_condattr_init -will fail if: -.Bl -tag -width Er -.It Bq Er ENOMEM -Out of memory. -.El -.Sh SEE ALSO -.Xr pthread_cond_init 3 -.Sh STANDARDS -.Fn pthread_condattr_init -and -.Fn pthread_condattr_destroy -conform to -.St -p1003.1-96 diff --git a/src/libc/pthreads/pthread_create.3 b/src/libc/pthreads/pthread_create.3 deleted file mode 100644 index c6a670cf5..000000000 --- a/src/libc/pthreads/pthread_create.3 +++ /dev/null @@ -1,123 +0,0 @@ -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_create.3,v 1.9.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_CREATE 3 -.Os -.Sh NAME -.Nm pthread_create -.Nd create a new thread -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_create -.Fa "pthread_t *restrict thread" -.Fa "const pthread_attr_t *restrict attr" -.Fa "void *(*start_routine)(void *)" -.Fa "void *restrict arg" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_create -function is used to create a new thread, with attributes specified by -.Fa attr , -within a process. -If -.Fa attr -is NULL, the default attributes are used. -If the attributes specified by -.Fa attr -are modified later, the thread's attributes are not affected. -Upon successful completion, -.Fn pthread_create -will store the ID of the created thread in the location specified by -.Fa thread . -.Pp -Upon its creation, the thread executes -.Fa start_routine , -with -.Fa arg -as its sole argument. -If -.Fa start_routine -returns, the effect is as if there was an implicit call to -.Fn pthread_exit , -using the return value of -.Fa start_routine -as the exit status. -Note that the thread in which -.Fn main -was originally invoked differs from this. -When it returns from -.Fn main , -the effect is as if there was an implicit call to -.Fn exit , -using the return value of -.Fn main -as the exit status. -.Pp -The signal state of the new thread is initialized as: -.Bl -bullet -offset indent -.It -The signal mask is inherited from the creating thread. -.It -The set of signals pending for the new thread is empty. -.El -.Sh RETURN VALUES -If successful, the -.Fn pthread_create -function will return zero. -Otherwise, an error number will be returned to -indicate the error. -.Sh ERRORS -.Fn pthread_create -will fail if: -.Bl -tag -width Er -.It Bq Er EAGAIN -The system lacked the necessary resources to create another thread, or -the system-imposed limit on the total number of threads in a process -[PTHREAD_THREADS_MAX] would be exceeded. -.It Bq Er EINVAL -The value specified by -.Fa attr -is invalid. -.El -.Sh SEE ALSO -.Xr fork 2 , -.Xr pthread_cleanup_pop 3 , -.Xr pthread_cleanup_push 3 , -.Xr pthread_exit 3 , -.Xr pthread_join 3 -.Sh STANDARDS -.Fn pthread_create -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_detach.3 b/src/libc/pthreads/pthread_detach.3 deleted file mode 100644 index f35495124..000000000 --- a/src/libc/pthreads/pthread_detach.3 +++ /dev/null @@ -1,89 +0,0 @@ -.\" Copyright (c) 1996-1998 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_detach.3,v 1.6.2.5 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_DETACH 3 -.Os -.Sh NAME -.Nm pthread_detach -.Nd detach a thread -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_detach -.Fa "pthread_t thread" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_detach -function is used to indicate to the implementation that storage for the -thread -.Fa thread -can be reclaimed when the thread terminates. -If -.Fa thread -has not terminated, -.Fn pthread_detach -will not cause it to terminate. -The effect of multiple -.Fn pthread_detach -calls on the same target thread is unspecified. -.Sh RETURN VALUES -If successful, the -.Fn pthread_detach -function will return zero. -Otherwise, an error number will be returned to -indicate the error. -Note that the function does not change the value -of errno, as it did for some drafts of the standard. -These early drafts -also passed a pointer to pthread_t as the argument. -Beware! -.Sh ERRORS -.Fn pthread_detach -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The implementation has detected that the value specified by -.Fa thread -does not refer to a joinable thread. -.It Bq Er ESRCH -No thread could be found corresponding to that specified by the given -thread ID, -.Fa thread . -.El -.Sh SEE ALSO -.Xr pthread_join 3 -.Sh STANDARDS -.Fn pthread_detach -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_equal.3 b/src/libc/pthreads/pthread_equal.3 deleted file mode 100644 index c86532924..000000000 --- a/src/libc/pthreads/pthread_equal.3 +++ /dev/null @@ -1,69 +0,0 @@ -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_equal.3,v 1.4.2.5 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_EQUAL 3 -.Os -.Sh NAME -.Nm pthread_equal -.Nd compare thread IDs -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_equal -.Fa "pthread_t t1" -.Fa "pthread_t t2" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_equal -function compares the thread IDs -.Fa t1 -and -.Fa t2 . -.Sh RETURN VALUES -The -.Fn pthread_equal -function will return non-zero if the thread IDs -.Fa t1 -and -.Fa t2 -correspond to the same thread. Otherwise, it will return zero. -.Sh ERRORS -None. -.Sh SEE ALSO -.Xr pthread_create 3 , -.Xr pthread_exit 3 -.Sh STANDARDS -.Fn pthread_equal -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_exit.3 b/src/libc/pthreads/pthread_exit.3 deleted file mode 100644 index 52b84034c..000000000 --- a/src/libc/pthreads/pthread_exit.3 +++ /dev/null @@ -1,104 +0,0 @@ -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_exit.3,v 1.8.2.6 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_EXIT 3 -.Os -.Sh NAME -.Nm pthread_exit -.Nd terminate the calling thread -.Sh SYNOPSIS -.Fd #include -.Ft void -.Fo pthread_exit -.Fa "void *value_ptr" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_exit -function terminates the calling thread and makes the value -.Fa value_ptr -available to any successful join with the terminating thread. -Any -cancellation cleanup handlers that have been pushed and are not yet popped -are popped in the reverse order that they were pushed and then executed. -After all cancellation handlers have been executed, if the thread has any -thread-specific data, appropriate destructor functions are called in an -unspecified order. -Thread termination does not release any application -visible process resources, including, but not limited to, mutexes and -file descriptors, nor does it perform any process level cleanup -actions, including, but not limited to, calling -.Fn atexit -routines that may exist. -.Pp -An implicit call to -.Fn pthread_exit -is made when a thread other than the thread in which -.Fn main -was first invoked returns from the start routine that was used to create -it. The function's return value serves as the thread's exit status. -.Pp -The behavior of -.Fn pthread_exit -is undefined if called from a cancellation handler or destructor function -that was invoked as the result of an implicit or explicit call to -.Fn pthread_exit . -.Pp -After a thread has terminated, the result of access to local (auto) -variables of the thread is undefined. -Thus, references to local variables -of the exiting thread should not be used for the -.Fn pthread_exit -.Fa value_ptr -parameter value. -.Pp -The process will exit with an exit status of 0 after the last thread has -been terminated. -The behavior is as if the implementation called -.Fn exit -with a zero argument at thread termination time. -.Sh RETURN VALUES -The -.Fn pthread_exit -function cannot return to its caller. -.Sh ERRORS -None. -.Sh SEE ALSO -.Xr _exit 2 , -.Xr exit 3 , -.Xr pthread_create 3 , -.Xr pthread_join 3 -.Sh STANDARDS -.Fn pthread_exit -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_getschedparam.3 b/src/libc/pthreads/pthread_getschedparam.3 deleted file mode 100644 index 854596cbc..000000000 --- a/src/libc/pthreads/pthread_getschedparam.3 +++ /dev/null @@ -1,96 +0,0 @@ -.\" Copyright (C) 2000 Jason Evans . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice(s), this list of conditions and the following disclaimer as -.\" the first lines of this file unmodified other than the possible -.\" addition of one or more copyright notices. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice(s), this list of conditions and the following disclaimer in -.\" the documentation and/or other materials provided with the -.\" distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY -.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE -.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_schedparam.3,v 1.2.2.4 2001/08/17 15:42:52 ru Exp $ -.Dd May 1, 2000 -.Dt PTHREAD_SCHEDPARAM 3 -.Os -.Sh NAME -.Nm pthread_getschedparam , -.Nm pthread_setschedparam -.Nd thread scheduling parameter manipulation -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_getschedparam -.Fa "pthread_t thread" -.Fa "int *restrict policy" -.Fa "struct sched_param *restrict param" -.Fc -.Ft int -.Fo pthread_setschedparam -.Fa "pthread_t thread" -.Fa "int policy" -.Fa "const struct sched_param *param" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_getschedparam -and -.Fn pthread_setschedparam -functions get and set the scheduling parameters of individual threads. -The scheduling policy for a thread can either be -.Dv SCHED_FIFO -(first in, first out) or -.Dv SCHED_RR -(round-robin). -The thread priority (accessed via -.Va param->sched_priority ) -must be at least -.Dv PTHREAD_MIN_PRIORITY -and no more than -.Dv PTHREAD_MAX_PRIORITY . -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Sh ERRORS -.Fn pthread_getschedparam -will fail if: -.Bl -tag -width Er -.It Bq Er ESRCH -Non-existent thread -.Va thread . -.El -.Pp -.Fn pthread_setschedparam -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Va policy . -.It Bq Er ENOTSUP -Invalid value for scheduling parameters. -.It Bq Er ESRCH -Non-existent thread -.Va thread . -.El -.Sh STANDARDS -.Fn pthread_setschedparam -and -.Fn pthread_getschedparam -conform to -.St -susv2 diff --git a/src/libc/pthreads/pthread_getspecific.3 b/src/libc/pthreads/pthread_getspecific.3 deleted file mode 100644 index 642aed82c..000000000 --- a/src/libc/pthreads/pthread_getspecific.3 +++ /dev/null @@ -1,83 +0,0 @@ -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_getspecific.3,v 1.6.2.3 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_GETSPECIFIC 3 -.Os -.Sh NAME -.Nm pthread_getspecific -.Nd get a thread-specific data value -.Sh SYNOPSIS -.Fd #include -.Ft void * -.Fo pthread_getspecific -.Fa "pthread_key_t key" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_getspecific -function returns the value that is currently bound to the specified -.Fa key , -on behalf of the calling thread. -.Pp -The effect of calling -.Fn pthread_getspecific -with a -.Fa key -value that was not obtained from -.Fn pthread_key_create , -or after a -.Fa key -has been deleted with -.Fn pthread_key_delete , -is undefined. -.Pp -.Fn pthread_getspecific -may be called from a thread-specific data destructor function. -.Sh RETURN VALUES -The -.Fn pthread_getspecific -function will return the thread-specific data value associated with the given -.Fa key . -If no thread-specific data value is associated with -.Fa key , -the value NULL is returned. -.Sh ERRORS -None. -.Sh SEE ALSO -.Xr pthread_key_create 3 , -.Xr pthread_key_delete 3 , -.Xr pthread_setspecific 3 -.Sh STANDARDS -.Fn pthread_getspecific -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_impl.h b/src/libc/pthreads/pthread_impl.h deleted file mode 100644 index 887b56d2c..000000000 --- a/src/libc/pthreads/pthread_impl.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _PTHREAD_IMPL_H_ -#define _PTHREAD_IMPL_H_ -/* - * Internal implementation details - */ - -/* This whole header file will disappear, so don't depend on it... */ - -#ifndef __POSIX_LIB__ - -/* - * [Internal] data structure signatures - */ -#define _PTHREAD_MUTEX_SIG_init 0x32AAABA7 - -#define _PTHREAD_ERRORCHECK_MUTEX_SIG_init 0x32AAABA1 -#define _PTHREAD_RECURSIVE_MUTEX_SIG_init 0x32AAABA2 -#define _PTHREAD_FIRSTFIT_MUTEX_SIG_init 0x32AAABA3 - -#define _PTHREAD_COND_SIG_init 0x3CB0B1BB -#define _PTHREAD_ONCE_SIG_init 0x30B1BCBA -#define _PTHREAD_RWLOCK_SIG_init 0x2DA8B3B4 - -/* - * POSIX scheduling policies - */ -#define SCHED_OTHER 1 -#define SCHED_FIFO 4 -#define SCHED_RR 2 - -#define __SCHED_PARAM_SIZE__ 4 - -#endif /* __POSIX_LIB__ */ - -#endif /* _PTHREAD_IMPL_H_ */ diff --git a/src/libc/pthreads/pthread_internals.h b/src/libc/pthreads/pthread_internals.h deleted file mode 100644 index 3a8b772f3..000000000 --- a/src/libc/pthreads/pthread_internals.h +++ /dev/null @@ -1,707 +0,0 @@ -/* - * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * POSIX Threads - IEEE 1003.1c - */ - -#ifndef _POSIX_PTHREAD_INTERNALS_H -#define _POSIX_PTHREAD_INTERNALS_H - -// suppress pthread_attr_t typedef in sys/signal.h -#define _PTHREAD_ATTR_T -struct _pthread_attr_t; /* forward reference */ -typedef struct _pthread_attr_t pthread_attr_t; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifndef __POSIX_LIB__ -#define __POSIX_LIB__ -#endif - -#include "posix_sched.h" /* For POSIX scheduling policy & parameter */ -#include /* For POSIX scheduling policy & parameter */ -#include "pthread_machdep.h" /* Machine-dependent definitions. */ -#include "pthread_spinlock.h" /* spinlock definitions. */ - -TAILQ_HEAD(__pthread_list, _pthread); - -extern int __pthread_lock_debug; -extern int __pthread_lock_old; - -extern struct __pthread_list __pthread_head; /* head of list of open files */ -extern pthread_lock_t _pthread_list_lock; -extern size_t pthreadsize; -/* - * Compiled-in limits - */ -#if TARGET_OS_EMBEDDED -#define _EXTERNAL_POSIX_THREAD_KEYS_MAX 256 -#define _INTERNAL_POSIX_THREAD_KEYS_MAX 256 -#define _INTERNAL_POSIX_THREAD_KEYS_END 512 -#else -#define _EXTERNAL_POSIX_THREAD_KEYS_MAX 512 -#define _INTERNAL_POSIX_THREAD_KEYS_MAX 256 -#define _INTERNAL_POSIX_THREAD_KEYS_END 768 -#endif - -/* - * Threads - */ -#define MAXTHREADNAMESIZE 64 -#define _PTHREAD_T -typedef struct _pthread -{ - long sig; /* Unique signature for this structure */ - struct __darwin_pthread_handler_rec *__cleanup_stack; - pthread_lock_t lock; /* Used for internal mutex on structure */ - uint32_t detached:8, - inherit:8, - policy:8, - freeStackOnExit:1, - newstyle:1, - kernalloc:1, - schedset:1, - wqthread:1, - wqkillset:1, - pad:2; - size_t guardsize; /* size in bytes to guard stack overflow */ -#if !defined(__LP64__) - int pad0; /* for backwards compatibility */ -#endif - struct sched_param param; - uint32_t cancel_error; -#if defined(__LP64__) - uint32_t cancel_pad; /* pad value for alignment */ -#endif - struct _pthread *joiner; -#if !defined(__LP64__) - int pad1; /* for backwards compatibility */ -#endif - void *exit_value; - semaphore_t death; /* pthread_join() uses this to wait for death's call */ - mach_port_t kernel_thread; /* kernel thread this thread is bound to */ - void *(*fun)(void*);/* Thread start routine */ - void *arg; /* Argment for thread start routine */ - int cancel_state; /* Whether thread can be cancelled */ - int err_no; /* thread-local errno */ - void *tsd[_EXTERNAL_POSIX_THREAD_KEYS_MAX + _INTERNAL_POSIX_THREAD_KEYS_MAX]; /* Thread specific data */ - void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */ - size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ - mach_port_t reply_port; /* Cached MiG reply port */ -#if defined(__LP64__) - int pad2; /* for natural alignment */ -#endif - void *cthread_self; /* cthread_self() if somebody calls cthread_set_self() */ - /* protected by list lock */ - uint32_t childrun:1, - parentcheck:1, - childexit:1, - pad3:29; -#if defined(__LP64__) - int pad4; /* for natural alignment */ -#endif - TAILQ_ENTRY(_pthread) plist; - void * freeaddr; - size_t freesize; - mach_port_t joiner_notify; - char pthread_name[MAXTHREADNAMESIZE]; /* including nulll the name */ - int max_tsd_key; - void * cur_workq; - void * cur_workitem; - uint64_t thread_id; -} *pthread_t; - -/* - * Thread attributes - */ -struct _pthread_attr_t -{ - long sig; /* Unique signature for this structure */ - pthread_lock_t lock; - uint32_t detached:8, - inherit:8, - policy:8, - freeStackOnExit:1, - fastpath:1, - schedset:1, - reserved1:5; - size_t guardsize; /* size in bytes to guard stack overflow */ - int reserved2; /* Should we free the stack when we exit? */ - struct sched_param param; - void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */ - size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ - boolean_t reserved3; -}; - -/* - * Mutex attributes - */ -#define _PTHREAD_MUTEX_POLICY_NONE 0 -#define _PTHREAD_MUTEX_POLICY_FAIRSHARE 1 -#define _PTHREAD_MUTEX_POLICY_FIRSTFIT 2 -#define _PTHREAD_MUTEX_POLICY_REALTIME 3 -#define _PTHREAD_MUTEX_POLICY_ADAPTIVE 4 -#define _PTHREAD_MUTEX_POLICY_PRIPROTECT 5 -#define _PTHREAD_MUTEX_POLICY_PRIINHERIT 6 - -#define _PTHREAD_MUTEXATTR_T -typedef struct -{ - long sig; /* Unique signature for this structure */ - int prioceiling; - uint32_t protocol:2, /* protocol attribute */ - type:2, /* mutex type */ - pshared:2, - policy:3, - rfu:23; -} pthread_mutexattr_t; - -/* - * Mutex variables - */ -struct _pthread_mutex_options { - uint32_t protocol:2, /* protocol */ - type:2, /* mutex type */ - pshared:2, /* mutex type */ - policy:3, - hold:2, - misalign:1, /* 8 byte aligned? */ - notify:1, /* CV notify field for kernel */ - mutex:1, /* used in clrprepo that it is a mutex */ - rfu:2, - lock_count:16; -}; - - -#define _PTHREAD_MTX_OPT_PSHARED 0x010 -#define _PTHREAD_MTX_OPT_HOLD 0x200 /* current owner of the mutex */ -#define _PTHREAD_MTX_OPT_NOMTX 0x400 /* no mutex refs held */ - -#define _PTHREAD_MTX_OPT_NOTIFY 0x1000 /* notify to drop mutex handling in cvwait */ -#define _PTHREAD_MTX_OPT_MUTEX 0x2000 /* this is a mutex type */ - - -#define _PTHREAD_MUTEX_T -typedef struct _pthread_mutex -{ - long sig; /* Unique signature for this structure */ - pthread_lock_t lock; /* Used for internal mutex on structure */ - union { - uint32_t value; - struct _pthread_mutex_options options; - } mtxopts; - int16_t prioceiling; - int16_t priority; /* Priority to restore when mutex unlocked */ - uint32_t waiters; /* Count of threads waiting for this mutex */ - pthread_t owner; /* Which thread has this mutex locked */ - struct _pthread_mutex *next, *prev; /* List of other mutexes he owns */ - struct _pthread_cond *busy; /* List of condition variables using this mutex */ - semaphore_t sem; /* Semaphore used for waiting */ - semaphore_t order; -} pthread_mutex_t; - - -typedef struct _npthread_mutex -{ -/* keep same as pthread_mutex_t from here to .. */ - long sig; /* Unique signature for this structure */ - pthread_lock_t lock; /* Used for static init sequencing */ - union { - uint32_t value; - struct _pthread_mutex_options options; - } mtxopts; - int16_t prioceiling; - int16_t priority; /* Priority to restore when mutex unlocked */ - uint32_t m_seq[3]; -#if defined(__LP64__) - uint64_t m_tid; /* Which thread has this mutex locked */ - uint32_t * m_lseqaddr; - uint32_t * m_useqaddr; - uint32_t reserved[2]; -#else - uint32_t * m_lseqaddr; - uint64_t m_tid; /* Which thread has this mutex locked */ - uint32_t * m_useqaddr; -#endif -} npthread_mutex_t; - - - - -/* - * Condition variable attributes - */ -#define _PTHREAD_CONDATTR_T -typedef struct -{ - long sig; /* Unique signature for this structure */ - uint32_t pshared:2, /* pshared */ - unsupported:30; -} pthread_condattr_t; - -/* - * Condition variables - */ -#define _PTHREAD_COND_T -typedef struct _pthread_cond -{ - long sig; /* Unique signature for this structure */ - pthread_lock_t lock; /* Used for internal mutex on structure */ - uint32_t waiters:15, /* Number of threads waiting */ - sigspending:15, /* Number of outstanding signals */ - pshared:2; - struct _pthread_cond *next, *prev; /* List of condition variables using mutex */ - struct _pthread_mutex *busy; /* mutex associated with variable */ - semaphore_t sem; /* Kernel semaphore */ -} pthread_cond_t; - - -typedef struct _npthread_cond -{ - long sig; /* Unique signature for this structure */ - pthread_lock_t lock; /* Used for internal mutex on structure */ - uint32_t rfu:29, /* not in use*/ - misalign: 1, /* structure is not aligned to 8 byte boundary */ - pshared:2; - struct _npthread_mutex *busy; /* mutex associated with variable */ - uint32_t c_seq[3]; -#if defined(__LP64__) - uint32_t reserved[3]; -#endif /* __LP64__ */ -} npthread_cond_t; - -/* - * Initialization control (once) variables - */ -#define _PTHREAD_ONCE_T -typedef struct -{ - long sig; /* Unique signature for this structure */ - pthread_lock_t lock; /* Used for internal mutex on structure */ -} pthread_once_t; - -#define _PTHREAD_RWLOCKATTR_T -typedef struct { - long sig; /* Unique signature for this structure */ - int pshared; - int rfu[2]; /* reserved for future use */ -} pthread_rwlockattr_t; - -#define _PTHREAD_RWLOCK_T -typedef struct { - long sig; - pthread_mutex_t lock; /* monitor lock */ - int state; - pthread_cond_t read_signal; - pthread_cond_t write_signal; - int blocked_writers; - int reserved; - pthread_t owner; - int rfu[1]; - int pshared; -} pthread_rwlock_t; - -#define PTHRW_RFU_64BIT 124 /* 31 * sizeof(uint32_t) */ -#define PTHRW_RFU_32BIT 72 /* 18 * sizeof(uint32_t) */ - -#define _PTHREAD_RWLOCK_T -typedef struct { - long sig; - pthread_lock_t lock; -#if defined(__LP64__) - int reserv; - volatile uint32_t rw_seq[4]; - pthread_t rw_owner; -#else /* __LP64__ */ - volatile uint32_t rw_seq[4]; - pthread_t rw_owner; - int reserv; -#endif /* __LP64__ */ - volatile uint32_t * rw_lcntaddr; - volatile uint32_t * rw_seqaddr; - volatile uint32_t * rw_ucntaddr; - uint32_t rw_flags; - int misalign; -#if defined(__LP64__) - char rfu[PTHRW_RFU_64BIT]; -#else /* __LP64__ */ - char rfu[PTHRW_RFU_32BIT]; -#endif /* __LP64__ */ - int pshared; -} npthread_rwlock_t; - -/* flags for rw_flags */ -#define PTHRW_KERN_PROCESS_SHARED 0x10 -#define PTHRW_KERN_PROCESS_PRIVATE 0x20 -#define PTHRW_KERN_PROCESS_FLAGS_MASK 0x30 -#define _PTHREAD_RWLOCK_UPGRADE_TRY 0x10000 - -/* New model bits on Lword */ -#define PTH_RWL_KBIT 0x01 /* users cannot acquire in user mode */ -#define PTH_RWL_EBIT 0x02 /* exclusive lock in progress */ -#define PTH_RWL_WBIT 0x04 /* write waiters pending in kernel */ -#define PTH_RWL_PBIT 0x04 /* prepost (cv) pending in kernel */ -#define PTH_RWL_YBIT 0x08 /* yielding write waiters pending in kernel */ -#define PTH_RWL_RETRYBIT 0x08 /* mutex retry wait */ -#define PTH_RWL_LBIT 0x10 /* long read in progress */ -#define PTH_RWL_MTXNONE 0x10 /* indicates the cvwait does not have mutex held */ -#define PTH_RWL_UBIT 0x20 /* upgrade request pending */ -#define PTH_RWL_MTX_WAIT 0x20 /* in cvar in mutex wait */ -#define PTH_RWL_RBIT 0x40 /* reader pending in kernel(not used) */ -#define PTH_RWL_MBIT 0x40 /* overlapping grants from kernel */ -#define PTH_RWL_TRYLKBIT 0x40 /* sets try lock attempt */ -#define PTH_RWL_IBIT 0x80 /* lock reset, held untill first succeesful unlock */ - -/* UBIT values for mutex, cvar */ -#define PTH_RWU_SBIT 0x01 -#define PTH_RWU_BBIT 0x02 - -#define PTHRW_RWL_INIT PTH_RWL_IBIT /* reset on the lock bits (U)*/ -#define PTHRW_RWLOCK_INIT (PTH_RWL_IBIT | PTH_RWL_RBIT) /* reset on the lock bits (U)*/ -#define PTH_RWLOCK_RESET_RBIT 0xffffffbf - -#define PTHRW_INC 0x100 -#define PTHRW_BIT_MASK 0x000000ff - -#define PTHRW_UN_BIT_MASK 0x000000bf /* remove overlap bit */ - - -/* New model bits on Sword */ -#define PTH_RWS_SBIT 0x01 /* kernel transition seq not set yet*/ -#define PTH_RWS_IBIT 0x02 /* Sequence is not set on return from kernel */ - -#define PTH_RWS_CV_CBIT PTH_RWS_SBIT /* kernel has cleared all info w.r.s.t CV */ -#define PTH_RWS_CV_PBIT PTH_RWS_IBIT /* kernel has prepost/fake structs only,no waiters */ -#define PTH_RWS_CV_BITSALL (PTH_RWS_CV_CBIT | PTH_RWS_CV_PBIT) -#define PTH_RWS_CV_MBIT PTH_RWL_MBIT /* to indicate prepost return from kernel */ -#define PTH_RWS_CV_RESET_PBIT 0xfffffffd - -#define PTH_RWS_WSVBIT 0x04 /* save W bit */ -#define PTH_RWS_USVBIT 0x08 /* save U bit */ -#define PTH_RWS_YSVBIT 0x10 /* save Y bit */ -#define PTHRW_RWS_INIT PTH_RWS_SBIT /* reset on the lock bits (U)*/ -#define PTHRW_RWS_SAVEMASK (PTH_RWS_WSVBIT|PTH_RWS_USVBIT|PTH_RWS_YSVBIT) /*save bits mask*/ -#define PTHRW_SW_Reset_BIT_MASK 0x000000fe /* remove S bit and get rest of the bits */ - -#define PTHRW_COUNT_SHIFT 8 -#define PTHRW_COUNT_MASK 0xffffff00 -#define PTHRW_MAX_READERS 0xffffff00 - - -#define PTHREAD_MTX_TID_SWITCHING (uint64_t)-1 - -/* new L word defns */ -#define can_rwl_readinuser(x) ((((x) & (PTH_RWL_UBIT | PTH_RWL_WBIT | PTH_RWL_KBIT)) == 0)||(((x) & PTH_RWL_LBIT) != 0)) -#define can_rwl_longreadinuser(x) (((x) & (PTH_RWL_UBIT | PTH_RWL_WBIT | PTH_RWL_KBIT | PTH_RWL_YBIT)) == 0) -#define is_rwl_ebit_set(x) (((x) & PTH_RWL_EBIT) != 0) -#define is_rwl_eubit_set(x) (((x) & (PTH_RWL_EBIT | PTH_RWL_UBIT)) != 0) -#define is_rwl_wbit_set(x) (((x) & PTH_RWL_WBIT) != 0) -#define is_rwl_lbit_set(x) (((x) & PTH_RWL_LBIT) != 0) -#define is_rwl_ebit_clear(x) (((x) & PTH_RWL_EBIT) == 0) -#define is_rwl_lbit_clear(x) (((x) & PTH_RWL_LBIT) == 0) -#define is_rwl_readoverlap(x) (((x) & PTH_RWL_MBIT) != 0) - -/* S word checks */ -#define is_rws_setseq(x) (((x) & PTH_RWS_SBIT)) -#define is_rws_setunlockinit(x) (((x) & PTH_RWS_IBIT)) - -/* is x lower than Y */ -static inline int is_seqlower(uint32_t x, uint32_t y) { - if (x < y) { - if ((y-x) < (PTHRW_MAX_READERS/2)) - return(1); - } else { - if ((x-y) > (PTHRW_MAX_READERS/2)) - return(1); - } - return(0); -} - -/* is x lower than or eq Y */ -static inline int is_seqlower_eq(uint32_t x, uint32_t y) { - if (x==y) - return(1); - else - return(is_seqlower(x,y)); -} - -/* is x greater than Y */ -static inline int is_seqhigher(uint32_t x, uint32_t y) { - if (x > y) { - if ((x-y) < (PTHRW_MAX_READERS/2)) - return(1); - } else { - if ((y-x) > (PTHRW_MAX_READERS/2)) - return(1); - } - return(0); -} - -static inline int diff_genseq(uint32_t x, uint32_t y) { - if (x == y) { - return(0); - } else if (x > y) { - return(x-y); - } else { - return((PTHRW_MAX_READERS - y) + x + PTHRW_INC); - } -} - -/* keep the size to 64bytes for both 64 and 32 */ -#define _PTHREAD_WORKQUEUE_ATTR_T -typedef struct { - uint32_t sig; - int queueprio; - int overcommit; - unsigned int resv2[13]; -} pthread_workqueue_attr_t; - -#define _PTHREAD_WORKITEM_T -typedef struct _pthread_workitem { - TAILQ_ENTRY(_pthread_workitem) item_entry; /* pthread_workitem list in prio */ - void (*func)(void *); - void * func_arg; - struct _pthread_workqueue * workq; - unsigned int flags; - unsigned int fromcache; /* padding for 64bit */ -} * pthread_workitem_t; - -#define PTH_WQITEM_INKERNEL_QUEUE 1 -#define PTH_WQITEM_RUNNING 2 -#define PTH_WQITEM_COMPLETED 4 -#define PTH_WQITEM_REMOVED 8 -#define PTH_WQITEM_BARRIER 0x10 -#define PTH_WQITEM_DESTROY 0x20 -#define PTH_WQITEM_NOTINLIST 0x40 -#define PTH_WQITEM_APPLIED 0x80 -#define PTH_WQITEM_KERN_COUNT 0x100 - -/* try to fit these within multiple of pages (8 pages for now) */ -#define WORKITEM_POOL_SIZE 680 -/* ensure some multiple of the chunk is the pool size */ -#define WORKITEM_CHUNK_SIZE 40 - -#define WORKITEM_STARTPOOL_SIZE WORKITEM_CHUNK_SIZE - -TAILQ_HEAD(__pthread_workitem_pool, _pthread_workitem); -extern struct __pthread_workitem_pool __pthread_workitem_pool_head; /* head list of workitem pool */ - -#define _PTHREAD_WORKQUEUE_HEAD_T -typedef struct _pthread_workqueue_head { - TAILQ_HEAD(, _pthread_workqueue) wqhead; - struct _pthread_workqueue * next_workq; -} * pthread_workqueue_head_t; - - -/* sized to be 128 bytes both in 32 and 64bit archs */ -#define _PTHREAD_WORKQUEUE_T -typedef struct _pthread_workqueue { - unsigned int sig; /* Unique signature for this structure */ - pthread_lock_t lock; /* Used for internal mutex on structure */ - TAILQ_ENTRY(_pthread_workqueue) wq_list; /* workqueue list in prio */ - TAILQ_HEAD(, _pthread_workitem) item_listhead; /* pthread_workitem list in prio */ - TAILQ_HEAD(, _pthread_workitem) item_kernhead; /* pthread_workitem list in prio */ - unsigned int flags; - size_t stacksize; - int istimeshare; - int importance; - int affinity; - int queueprio; - int barrier_count; - int kq_count; - void (*term_callback)(struct _pthread_workqueue *,void *); - void * term_callarg; - pthread_workqueue_head_t headp; - int overcommit; -#if !defined(__LP64__) - unsigned int rev2[12]; -#endif -} * pthread_workqueue_t; - -#define PTHREAD_WORKQ_IN_CREATION 1 -#define PTHREAD_WORKQ_IN_TERMINATE 2 -#define PTHREAD_WORKQ_BARRIER_ON 4 -#define PTHREAD_WORKQ_TERM_ON 8 -#define PTHREAD_WORKQ_DESTROYED 0x10 -#define PTHREAD_WORKQ_REQUEUED 0x20 -#define PTHREAD_WORKQ_SUSPEND 0x40 - -#define WORKQUEUE_POOL_SIZE 16 -TAILQ_HEAD(__pthread_workqueue_pool, _pthread_workqueue); -extern struct __pthread_workqueue_pool __pthread_workqueue_pool_head; /* head list of workqueue pool */ - -#include "pthread_spis.h" - -#if defined(__i386__) || defined(__ppc64__) || defined(__x86_64__) || (defined(__arm__) && (defined(_ARM_ARCH_7) || !defined(_ARM_ARCH_6) || !defined(__thumb__))) -/* - * Inside libSystem, we can use r13 or %gs directly to get access to the - * thread-specific data area. The current thread is in the first slot. - */ -inline static pthread_t __attribute__((__pure__)) -_pthread_self_direct(void) -{ - pthread_t ret; - -#if defined(__i386__) || defined(__x86_64__) - ret = _pthread_getspecific_direct(0); -#elif defined(__ppc64__) - register const pthread_t __pthread_self asm ("r13"); - ret = __pthread_self; -#elif defined(__arm__) && defined(_ARM_ARCH_6) - ret = _pthread_getspecific_direct(0); -#elif defined(__arm__) && !defined(_ARM_ARCH_6) - ret = _pthread_getspecific_direct(0); -#endif - return ret; -} -#define pthread_self() _pthread_self_direct() -#endif - -#define _PTHREAD_DEFAULT_INHERITSCHED PTHREAD_INHERIT_SCHED -#define _PTHREAD_DEFAULT_PROTOCOL PTHREAD_PRIO_NONE -#define _PTHREAD_DEFAULT_PRIOCEILING 0 -#define _PTHREAD_DEFAULT_POLICY SCHED_OTHER -#define _PTHREAD_DEFAULT_STACKSIZE 0x80000 /* 512K */ -#define _PTHREAD_DEFAULT_PSHARED PTHREAD_PROCESS_PRIVATE - -#define _PTHREAD_NO_SIG 0x00000000 -#define _PTHREAD_MUTEX_ATTR_SIG 0x4D545841 /* 'MTXA' */ -#define _PTHREAD_MUTEX_SIG 0x4D555458 /* 'MUTX' */ -#define _PTHREAD_MUTEX_SIG_init 0x32AAABA7 /* [almost] ~'MUTX' */ -#define _PTHREAD_ERRORCHECK_MUTEX_SIG_init 0x32AAABA1 -#define _PTHREAD_RECURSIVE_MUTEX_SIG_init 0x32AAABA2 -#define _PTHREAD_FIRSTFIT_MUTEX_SIG_init 0x32AAABA3 -#define _PTHREAD_MUTEX_SIG_init_MASK 0xfffffff0 -#define _PTHREAD_MUTEX_SIG_CMP 0x32AAABA0 -#define _PTHREAD_COND_ATTR_SIG 0x434E4441 /* 'CNDA' */ -#define _PTHREAD_COND_SIG 0x434F4E44 /* 'COND' */ -#define _PTHREAD_COND_SIG_init 0x3CB0B1BB /* [almost] ~'COND' */ -#define _PTHREAD_ATTR_SIG 0x54484441 /* 'THDA' */ -#define _PTHREAD_ONCE_SIG 0x4F4E4345 /* 'ONCE' */ -#define _PTHREAD_ONCE_SIG_init 0x30B1BCBA /* [almost] ~'ONCE' */ -#define _PTHREAD_SIG 0x54485244 /* 'THRD' */ -#define _PTHREAD_RWLOCK_ATTR_SIG 0x52574C41 /* 'RWLA' */ -#define _PTHREAD_RWLOCK_SIG 0x52574C4B /* 'RWLK' */ -#define _PTHREAD_RWLOCK_SIG_init 0x2DA8B3B4 /* [almost] ~'RWLK' */ - - -#define _PTHREAD_KERN_COND_SIG 0x12345678 /* */ -#define _PTHREAD_KERN_MUTEX_SIG 0x34567812 /* */ -#define _PTHREAD_KERN_RWLOCK_SIG 0x56781234 /* */ - -#define _PTHREAD_CREATE_PARENT 4 -#define _PTHREAD_EXITED 8 -// 4597450: begin -#define _PTHREAD_WASCANCEL 0x10 -// 4597450: end - -#if defined(DEBUG) -#define _PTHREAD_MUTEX_OWNER_SELF pthread_self() -#else -#define _PTHREAD_MUTEX_OWNER_SELF (pthread_t)0x12141968 -#endif -#define _PTHREAD_MUTEX_OWNER_SWITCHING (pthread_t)(~0) - -#define _PTHREAD_CANCEL_STATE_MASK 0x01 -#define _PTHREAD_CANCEL_TYPE_MASK 0x02 -#define _PTHREAD_CANCEL_PENDING 0x10 /* pthread_cancel() has been called for this thread */ - -extern boolean_t swtch_pri(int); - -#ifndef PTHREAD_MACH_CALL -#define PTHREAD_MACH_CALL(expr, ret) (ret) = (expr) -#endif - -/* Prototypes. */ - -/* Functions defined in machine-dependent files. */ -extern vm_address_t _sp(void); -extern vm_address_t _adjust_sp(vm_address_t sp); -extern void _pthread_setup(pthread_t th, void (*f)(pthread_t), void *sp, int suspended, int needresume); - -extern void _pthread_tsd_cleanup(pthread_t self); - -__private_extern__ void __mtx_holdlock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp, uint64_t *tidp); -__private_extern__ int __mtx_droplock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp); -__private_extern__ int __mtx_updatebits(npthread_mutex_t *mutex, uint32_t updateval, int firstfiti, int fromcond, uint64_t selfid); - -/* syscall interfaces */ -extern uint32_t __psynch_mutexwait(pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags); -extern uint32_t __psynch_mutexdrop(pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags); - -extern uint32_t __psynch_cvbroad(pthread_cond_t * cv, uint64_t cvlsgen, uint64_t cvudgen, uint32_t flags, pthread_mutex_t * mutex, uint64_t mugen, uint64_t tid); -extern uint32_t __psynch_cvsignal(pthread_cond_t * cv, uint64_t cvlsgen, uint32_t cvugen, int thread_port, pthread_mutex_t * mutex, uint64_t mugen, uint64_t tid, uint32_t flags); -extern uint32_t __psynch_cvwait(pthread_cond_t * cv, uint64_t cvlsgen, uint32_t cvugen, pthread_mutex_t * mutex, uint64_t mugen, uint32_t flags, int64_t sec, uint32_t nsec); -extern uint32_t __psynch_cvclrprepost(void * cv, uint32_t cvgen, uint32_t cvugen, uint32_t cvsgen, uint32_t prepocnt, uint32_t preposeq, uint32_t flags); -extern uint32_t __psynch_rw_longrdlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); -extern uint32_t __psynch_rw_yieldwrlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); -extern int __psynch_rw_downgrade(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); -extern uint32_t __psynch_rw_upgrade(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); -extern uint32_t __psynch_rw_rdlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); -extern uint32_t __psynch_rw_wrlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); -extern uint32_t __psynch_rw_unlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); -extern uint32_t __psynch_rw_unlock2(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags); - -__private_extern__ semaphore_t new_sem_from_pool(void); -__private_extern__ void restore_sem_to_pool(semaphore_t); -__private_extern__ void _pthread_atfork_queue_init(void); -int _pthread_lookup_thread(pthread_t thread, mach_port_t * port, int only_joinable); -int _pthread_join_cleanup(pthread_t thread, void ** value_ptr, int conforming); -__private_extern__ int proc_setthreadname(void * buffer, int buffersize); - -#endif /* _POSIX_PTHREAD_INTERNALS_H */ diff --git a/src/libc/pthreads/pthread_join.3 b/src/libc/pthreads/pthread_join.3 deleted file mode 100644 index 6402393e3..000000000 --- a/src/libc/pthreads/pthread_join.3 +++ /dev/null @@ -1,103 +0,0 @@ -.\" Copyright (c) 1996-1998 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_join.3,v 1.7.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_JOIN 3 -.Os -.Sh NAME -.Nm pthread_join -.Nd wait for thread termination -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_join -.Fa "pthread_t thread" -.Fa "void **value_ptr" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_join -function suspends execution of the calling thread until the target -.Fa thread -terminates, unless the target -.Fa thread -has already terminated. -.Pp -On return from a successful -.Fn pthread_join -call with a non-NULL -.Fa value_ptr -argument, the value passed to -.Fn pthread_exit -by the terminating thread is stored in the location referenced by -.Fa value_ptr . -When a -.Fn pthread_join -returns successfully, the target thread has been terminated. -The results -of multiple simultaneous calls to -.Fn pthread_join , -specifying the same target thread, are undefined. -If the thread calling -.Fn pthread_join -is cancelled, the target thread is not detached. -.Pp -.Sh RETURN VALUES -If successful, the -.Fn pthread_join -function will return zero. -Otherwise, an error number will be returned to -indicate the error. -.Sh ERRORS -.Fn pthread_join -will fail if: -.Bl -tag -width Er -.It Bq Er EDEADLK -A deadlock was detected or the value of -.Fa thread -specifies the calling thread. -.It Bq Er EINVAL -The implementation has detected that the value specified by -.Fa thread -does not refer to a joinable thread. -.It Bq Er ESRCH -No thread could be found corresponding to that specified by the given -thread ID, -.Fa thread . -.El -.Sh SEE ALSO -.Xr wait 2 , -.Xr pthread_create 3 -.Sh STANDARDS -.Fn pthread_join -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_key_create.3 b/src/libc/pthreads/pthread_key_create.3 deleted file mode 100644 index 77fae748b..000000000 --- a/src/libc/pthreads/pthread_key_create.3 +++ /dev/null @@ -1,108 +0,0 @@ -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_key_create.3,v 1.6.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_KEY_CREATE 3 -.Os -.Sh NAME -.Nm pthread_key_create -.Nd thread-specific data key creation -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_key_create -.Fa "pthread_key_t *key" -.Fa "void (*destructor)(void *)" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_key_create -function creates a thread-specific data key -that is visible to all threads in the process. -Key values provided by -.Fn pthread_key_create -are opaque objects, used to locate thread-specific data. -Although the same -key value may be used by different threads, the values bound to the key -by -.Fn pthread_setspecific -are maintained on a per-thread basis and persist for the life of the calling -thread. -.Pp -Upon key creation, the value NULL is associated with the new key in all -active threads. -Upon thread creation, the value NULL is associated with all -defined keys in the new thread. -.Pp -An optional destructor function may be associated with each key value. -At -thread exit, if a key value has a non-NULL destructor pointer, and the -thread has a non-NULL value associated with the key, the function pointed -to is called with the current associated value as its sole argument. -The -order of destructor calls is unspecified if more than one destructor exists -for a thread when it exits. -.Pp -If, after all the destructors have been called for all non-NULL values -with associated destructors, there are still some non-NULL values with -associated destructors, then the process is repeated. -If, after at least -[PTHREAD_DESTRUCTOR_ITERATIONS] iterations of destructor calls for -outstanding non-NULL values, there are still some non-NULL values with -associated destructors, the implementation stops calling destructors. -.Sh RETURN VALUES -If successful, the -.Fn pthread_key_create -function will store the newly created key value at the location specified by -.Fa key -and returns zero. -Otherwise, an error number will be returned to indicate -the error. -.Sh ERRORS -.Fn pthread_key_create -will fail if: -.Bl -tag -width Er -.It Bq Er EAGAIN -The system lacked the necessary resources to create another thread-specific -data key, or the system-imposed limit on the total number of keys per process -[PTHREAD_KEYS_MAX] would be exceeded. -.It Bq Er ENOMEM -Insufficient memory exists to create the key. -.El -.Sh SEE ALSO -.Xr pthread_getspecific 3 , -.Xr pthread_key_delete 3 , -.Xr pthread_setspecific 3 -.Sh STANDARDS -.Fn pthread_key_create -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_key_delete.3 b/src/libc/pthreads/pthread_key_delete.3 deleted file mode 100644 index 013ecd459..000000000 --- a/src/libc/pthreads/pthread_key_delete.3 +++ /dev/null @@ -1,98 +0,0 @@ -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_key_delete.3,v 1.6.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_KEY_DELETE 3 -.Os -.Sh NAME -.Nm pthread_key_delete -.Nd delete a thread-specific data key -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_key_delete -.Fa "pthread_key_t key" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_key_delete -function deletes a thread-specific data key, previously returned by -.Fn pthread_key_create . -The thread-specific data values associated with -.Fa key -need not be NULL at the time that -.Fn pthread_key_delete -is called. -It is the responsibility of the application to free any -application storage or perform any cleanup actions for data structures -related to the deleted key or associated thread-specific data in any threads; -this cleanup can be done either before or after -.Fn pthread_key_delete -is called. -Any attempt to use -.Fa key -following the call to -.Fn pthread_key_delete -results in undefined behavior. -.Pp -The -.Fn pthread_key_delete -function is callable from within destructor functions. -Destructor functions -are not invoked by -.Fn pthread_key_delete . -Any destructor function that may have been associated with -.Fa key -will no longer be called upon thread exit. -.Sh RETURN VALUES -If successful, the -.Fn pthread_key_delete -function will return zero. -Otherwise, an error number will be returned to -indicate the error. -.Sh ERRORS -.Fn pthread_key_delete -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The -.Fa key -value is invalid. -.El -.Sh SEE ALSO -.Xr pthread_getspecific 3 , -.Xr pthread_key_create 3 , -.Xr pthread_setspecific 3 -.Sh STANDARDS -.Fn pthread_key_delete -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_machdep.h b/src/libc/pthreads/pthread_machdep.h deleted file mode 100644 index 3878338a2..000000000 --- a/src/libc/pthreads/pthread_machdep.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2003-2004, 2008, 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * MkLinux - */ - -/* Machine-dependent definitions for pthread internals. */ - -#ifndef _POSIX_PTHREAD_MACHDEP_H -#define _POSIX_PTHREAD_MACHDEP_H - -#ifndef __ASSEMBLER__ - -#include -#ifdef __arm__ -#include -#endif -#include -#include - -/* -** Define macros for inline pthread_getspecific() usage. -** We reserve a number of slots for Apple internal use. -** This number can grow dynamically, no need to fix it. -*/ - -/* This header contains pre defined thread specific keys */ -/* 0 is used for pthread_self */ -#define _PTHREAD_TSD_SLOT_PTHREAD_SELF 0 -/* Keys 1- 9 for use by dyld, directly or indirectly */ -#define _PTHREAD_TSD_SLOT_DYLD_1 1 -#define _PTHREAD_TSD_SLOT_DYLD_2 2 -#define _PTHREAD_TSD_SLOT_DYLD_3 3 -#define _PTHREAD_TSD_RESERVED_SLOT_COUNT 4 -/* To mirror the usage by dyld for Unwind_SjLj */ -#define _PTHREAD_TSD_SLOT_DYLD_8 8 - -/* Keys 10 - 29 are for Libc/Libsystem internal ussage */ -/* used as __pthread_tsd_first + Num */ -#define __PTK_LIBC_LOCALE_KEY 10 -#define __PTK_LIBC_TTYNAME_KEY 11 -#define __PTK_LIBC_LOCALTIME_KEY 12 -#define __PTK_LIBC_GMTIME_KEY 13 -#define __PTK_LIBC_GDTOA_BIGINT_KEY 14 -#define __PTK_LIBC_PARSEFLOAT_KEY 15 -/* for usage by dyld */ -#define __PTK_LIBC_DYLD_Unwind_SjLj_Key 18 - -/* Keys 20-25 for libdispactch usage */ -#define __PTK_LIBDISPATCH_KEY0 20 -#define __PTK_LIBDISPATCH_KEY1 21 -#define __PTK_LIBDISPATCH_KEY2 22 -#define __PTK_LIBDISPATCH_KEY3 23 -#define __PTK_LIBDISPATCH_KEY4 24 -#define __PTK_LIBDISPATCH_KEY5 25 - -/* Keys 30-255 for Non Libsystem usage */ - -/* Keys 30-39 for Graphic frameworks usage */ -#define _PTHREAD_TSD_SLOT_OPENGL 30 /* backwards compat sake */ -#define __PTK_FRAMEWORK_OPENGL_KEY 30 -#define __PTK_FRAMEWORK_GRAPHICS_KEY1 31 -#define __PTK_FRAMEWORK_GRAPHICS_KEY2 32 -#define __PTK_FRAMEWORK_GRAPHICS_KEY3 33 -#define __PTK_FRAMEWORK_GRAPHICS_KEY4 34 -#define __PTK_FRAMEWORK_GRAPHICS_KEY5 35 -#define __PTK_FRAMEWORK_GRAPHICS_KEY6 36 -#define __PTK_FRAMEWORK_GRAPHICS_KEY7 37 -#define __PTK_FRAMEWORK_GRAPHICS_KEY8 38 -#define __PTK_FRAMEWORK_GRAPHICS_KEY9 39 - -/* Keys 40-49 for Objective-C runtime usage */ -#define __PTK_FRAMEWORK_OBJC_KEY0 40 -#define __PTK_FRAMEWORK_OBJC_KEY1 41 -#define __PTK_FRAMEWORK_OBJC_KEY2 42 -#define __PTK_FRAMEWORK_OBJC_KEY3 43 -#define __PTK_FRAMEWORK_OBJC_KEY4 44 -#define __PTK_FRAMEWORK_OBJC_KEY5 45 -#define __PTK_FRAMEWORK_OBJC_KEY6 46 -#define __PTK_FRAMEWORK_OBJC_KEY7 47 -#define __PTK_FRAMEWORK_OBJC_KEY8 48 -#define __PTK_FRAMEWORK_OBJC_KEY9 49 - -/* Keys 50-59 for Core Foundation usage */ -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY0 50 -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY1 51 -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY2 52 -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY3 53 -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY4 54 -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY5 55 -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY6 56 -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY7 57 -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY8 58 -#define __PTK_FRAMEWORK_COREFOUNDATION_KEY9 59 - -/* Keys 60-69 for Foundation usage */ -#define __PTK_FRAMEWORK_FOUNDATION_KEY0 60 -#define __PTK_FRAMEWORK_FOUNDATION_KEY1 61 -#define __PTK_FRAMEWORK_FOUNDATION_KEY2 62 -#define __PTK_FRAMEWORK_FOUNDATION_KEY3 63 -#define __PTK_FRAMEWORK_FOUNDATION_KEY4 64 -#define __PTK_FRAMEWORK_FOUNDATION_KEY5 65 -#define __PTK_FRAMEWORK_FOUNDATION_KEY6 66 -#define __PTK_FRAMEWORK_FOUNDATION_KEY7 67 -#define __PTK_FRAMEWORK_FOUNDATION_KEY8 68 -#define __PTK_FRAMEWORK_FOUNDATION_KEY9 69 - -/* Keys 70-79 for Core Animation/QuartzCore usage */ -#define __PTK_FRAMEWORK_QUARTZCORE_KEY0 70 -#define __PTK_FRAMEWORK_QUARTZCORE_KEY1 71 -#define __PTK_FRAMEWORK_QUARTZCORE_KEY2 72 -#define __PTK_FRAMEWORK_QUARTZCORE_KEY3 73 -#define __PTK_FRAMEWORK_QUARTZCORE_KEY4 74 -#define __PTK_FRAMEWORK_QUARTZCORE_KEY5 75 -#define __PTK_FRAMEWORK_QUARTZCORE_KEY6 76 -#define __PTK_FRAMEWORK_QUARTZCORE_KEY7 77 -#define __PTK_FRAMEWORK_QUARTZCORE_KEY8 78 -#define __PTK_FRAMEWORK_QUARTZCORE_KEY9 79 - - -/* Keys 80-89 for Garbage Collection */ -#define __PTK_FRAMEWORK_OLDGC_KEY0 80 -#define __PTK_FRAMEWORK_OLDGC_KEY1 81 -#define __PTK_FRAMEWORK_OLDGC_KEY2 82 -#define __PTK_FRAMEWORK_OLDGC_KEY3 83 -#define __PTK_FRAMEWORK_OLDGC_KEY4 84 -#define __PTK_FRAMEWORK_OLDGC_KEY5 85 -#define __PTK_FRAMEWORK_OLDGC_KEY6 86 -#define __PTK_FRAMEWORK_OLDGC_KEY7 87 -#define __PTK_FRAMEWORK_OLDGC_KEY8 88 -#define __PTK_FRAMEWORK_OLDGC_KEY9 89 - -/* Keys 90-94 for JavaScriptCore Collection */ -#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0 90 -#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1 91 -#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY2 92 -#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY3 93 -#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 94 -/* Keys 95 for CoreText */ -#define __PTK_FRAMEWORK_CORETEXT_KEY0 95 - -/* Keys 110-119 for Garbage Collection */ -#define __PTK_FRAMEWORK_GC_KEY0 110 -#define __PTK_FRAMEWORK_GC_KEY1 111 -#define __PTK_FRAMEWORK_GC_KEY2 112 -#define __PTK_FRAMEWORK_GC_KEY3 113 -#define __PTK_FRAMEWORK_GC_KEY4 114 -#define __PTK_FRAMEWORK_GC_KEY5 115 -#define __PTK_FRAMEWORK_GC_KEY6 116 -#define __PTK_FRAMEWORK_GC_KEY7 117 -#define __PTK_FRAMEWORK_GC_KEY8 118 -#define __PTK_FRAMEWORK_GC_KEY9 119 - -/* -** Define macros for inline pthread_getspecific() usage. -** We reserve a number of slots for Apple internal use. -** This number can grow dynamically, no need to fix it. -*/ - - -#if defined(__cplusplus) -extern "C" { -#endif - -extern void *pthread_getspecific(unsigned long); -extern int pthread_setspecific(unsigned long, const void *); -/* setup destructor function for static key as it is not created with pthread_key_create() */ -int pthread_key_init_np(int, void (*)(void *)); - -#if defined(__cplusplus) -} -#endif - -typedef int pthread_lock_t; - -__inline__ static int -_pthread_has_direct_tsd(void) -{ -#if TARGET_IPHONE_SIMULATOR - /* Simulator will use the host implementation, so bypass the macro that is in the target code */ - return 0; -#elif defined(__ppc__) - int *caps = (int *)_COMM_PAGE_CPU_CAPABILITIES; - if (*caps & kFastThreadLocalStorage) { - return 1; - } else { - return 0; - } -#else - return 1; -#endif -} - -#if TARGET_IPHONE_SIMULATOR || defined(__ppc__) || defined(__ppc64__) || \ - (defined(__arm__) && !defined(_ARM_ARCH_7) && defined(_ARM_ARCH_6) && defined(__thumb__)) - -#define _pthread_getspecific_direct(key) pthread_getspecific((key)) -#define _pthread_setspecific_direct(key, val) pthread_setspecific((key), (val)) - -#else - -/* To be used with static constant keys only */ -__inline__ static void * -_pthread_getspecific_direct(unsigned long slot) -{ - void *ret; -#if defined(__x86_64__) - __asm__("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *)))); -#elif defined(__i386__) - __asm__("mov %%fs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *)))); -#elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5))) - void **__pthread_tsd; -#if defined(__arm__) && defined(_ARM_ARCH_6) - uintptr_t __pthread_tpid; - __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid)); - __pthread_tsd = (void**)(__pthread_tpid & ~0x3ul); -#elif defined(__arm__) && defined(_ARM_ARCH_5) - register uintptr_t __pthread_tpid asm ("r9"); - __pthread_tsd = (void**)__pthread_tpid; -#endif - ret = __pthread_tsd[slot]; -#else -#error no _pthread_getspecific_direct implementation for this arch -#endif - return ret; -} - -/* To be used with static constant keys only */ -__inline__ static int -_pthread_setspecific_direct(unsigned long slot, void * val) -{ -#if defined(__i386__) -#if defined(__PIC__) - __asm__("movl %1,%%fs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val)); -#else - __asm__("movl %1,%%fs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "ri" (val)); -#endif -#elif defined(__x86_64__) - /* PIC is free and cannot be disabled, even with: gcc -mdynamic-no-pic ... */ - __asm__("movq %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val)); -#elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5))) - void **__pthread_tsd; -#if defined(__arm__) && defined(_ARM_ARCH_6) - uintptr_t __pthread_tpid; - __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid)); - __pthread_tsd = (void**)(__pthread_tpid & ~0x3ul); -#elif defined(__arm__) && defined(_ARM_ARCH_5) - register uintptr_t __pthread_tpid asm ("r9"); - __pthread_tsd = (void**)__pthread_tpid; -#endif - __pthread_tsd[slot] = val; -#else -#error no _pthread_setspecific_direct implementation for this arch -#endif - return 0; -} - -#endif - -#define LOCK_INIT(l) ((l) = 0) -#define LOCK_INITIALIZER 0 - -#endif /* ! __ASSEMBLER__ */ -#endif /* _POSIX_PTHREAD_MACHDEP_H */ diff --git a/src/libc/pthreads/pthread_mutex.c b/src/libc/pthreads/pthread_mutex.c deleted file mode 100644 index 51e46059d..000000000 --- a/src/libc/pthreads/pthread_mutex.c +++ /dev/null @@ -1,1353 +0,0 @@ -/* - * Copyright (c) 2000-2003, 2007, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * POSIX Pthread Library - * -- Mutex variable support - */ - -#include "pthread_internals.h" - -#ifdef PLOCKSTAT -#include "plockstat.h" -#else /* !PLOCKSTAT */ -#define PLOCKSTAT_MUTEX_SPIN(x) -#define PLOCKSTAT_MUTEX_SPUN(x, y, z) -#define PLOCKSTAT_MUTEX_ERROR(x, y) -#define PLOCKSTAT_MUTEX_BLOCK(x) -#define PLOCKSTAT_MUTEX_BLOCKED(x, y) -#define PLOCKSTAT_MUTEX_ACQUIRE(x, y, z) -#define PLOCKSTAT_MUTEX_RELEASE(x, y) -#endif /* PLOCKSTAT */ - -extern int __unix_conforming; -extern int __unix_conforming; - -#ifndef BUILDING_VARIANT -__private_extern__ int usenew_mtximpl = 1; -static void __pthread_mutex_set_signature(npthread_mutex_t * mutex); -int __mtx_markprepost(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit); -static int _pthread_mutex_destroy_locked(pthread_mutex_t *omutex); -#else /* BUILDING_VARIANT */ -extern int usenew_mtximpl; -#endif /* BUILDING_VARIANT */ - - -#ifdef NOTNEEDED -#define USE_COMPAGE 1 -extern int _commpage_pthread_mutex_lock(uint32_t * lvalp, int flags, uint64_t mtid, uint32_t mask, uint64_t * tidp, int *sysret); -#endif - -#include - -int _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr, uint32_t static_type); - - -#if defined(__LP64__) -#define MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr) \ -{ \ - if (mutex->mtxopts.options.misalign != 0) { \ - lseqaddr = &mutex->m_seq[0]; \ - useqaddr = &mutex->m_seq[1]; \ - } else { \ - lseqaddr = &mutex->m_seq[1]; \ - useqaddr = &mutex->m_seq[2]; \ - } \ -} -#else /* __LP64__ */ -#define MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr) \ -{ \ - if (mutex->mtxopts.options.misalign != 0) { \ - lseqaddr = &mutex->m_seq[1]; \ - useqaddr = &mutex->m_seq[2]; \ - }else { \ - lseqaddr = &mutex->m_seq[0]; \ - useqaddr = &mutex->m_seq[1]; \ - } \ -} -#endif /* __LP64__ */ - -#define _KSYN_TRACE_ 0 - -#if _KSYN_TRACE_ -/* The Function qualifiers */ -#define DBG_FUNC_START 1 -#define DBG_FUNC_END 2 -#define DBG_FUNC_NONE 0 - -int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); - -#define _KSYN_TRACE_UM_LOCK 0x9000060 -#define _KSYN_TRACE_UM_UNLOCK 0x9000064 -#define _KSYN_TRACE_UM_MHOLD 0x9000068 -#define _KSYN_TRACE_UM_MDROP 0x900006c -#define _KSYN_TRACE_UM_MUBITS 0x900007c -#define _KSYN_TRACE_UM_MARKPP 0x90000a8 - -#endif /* _KSYN_TRACE_ */ - -#ifndef BUILDING_VARIANT /* [ */ - -#define BLOCK_FAIL_PLOCKSTAT 0 -#define BLOCK_SUCCESS_PLOCKSTAT 1 - -#ifdef PR_5243343 -/* 5243343 - temporary hack to detect if we are running the conformance test */ -extern int PR_5243343_flag; -#endif /* PR_5243343 */ - -/* This function is never called and exists to provide never-fired dtrace - * probes so that user d scripts don't get errors. - */ -__private_extern__ __attribute__((used)) void -_plockstat_never_fired(void) -{ - PLOCKSTAT_MUTEX_SPIN(NULL); - PLOCKSTAT_MUTEX_SPUN(NULL, 0, 0); -} - - -/* - * Initialize a mutex variable, possibly with additional attributes. - * Public interface - so don't trust the lock - initialize it first. - */ -int -pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) -{ -#if 0 - /* conformance tests depend on not having this behavior */ - /* The test for this behavior is optional */ - if (mutex->sig == _PTHREAD_MUTEX_SIG) - return EBUSY; -#endif - LOCK_INIT(mutex->lock); - return (_pthread_mutex_init(mutex, attr, 0x7)); -} - -/* - * Fetch the priority ceiling value from a mutex variable. - * Note: written as a 'helper' function to hide implementation details. - */ -int -pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, - int *prioceiling) -{ - int res; - - LOCK(mutex->lock); - if (mutex->sig == _PTHREAD_MUTEX_SIG) - { - *prioceiling = mutex->prioceiling; - res = 0; - } else - res = EINVAL; /* Not an initialized 'attribute' structure */ - UNLOCK(mutex->lock); - return (res); -} - -/* - * Set the priority ceiling for a mutex. - * Note: written as a 'helper' function to hide implementation details. - */ -int -pthread_mutex_setprioceiling(pthread_mutex_t *mutex, - int prioceiling, - int *old_prioceiling) -{ - int res; - - LOCK(mutex->lock); - if (mutex->sig == _PTHREAD_MUTEX_SIG) - { - if ((prioceiling >= -999) || - (prioceiling <= 999)) - { - *old_prioceiling = mutex->prioceiling; - mutex->prioceiling = prioceiling; - res = 0; - } else - res = EINVAL; /* Invalid parameter */ - } else - res = EINVAL; /* Not an initialized 'attribute' structure */ - UNLOCK(mutex->lock); - return (res); -} - -/* - * Get the priority ceiling value from a mutex attribute structure. - * Note: written as a 'helper' function to hide implementation details. - */ -int -pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, - int *prioceiling) -{ - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { - *prioceiling = attr->prioceiling; - return (0); - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - -/* - * Get the mutex 'protocol' value from a mutex attribute structure. - * Note: written as a 'helper' function to hide implementation details. - */ -int -pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, - int *protocol) -{ - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { - *protocol = attr->protocol; - return (0); - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} -/* - * Get the mutex 'type' value from a mutex attribute structure. - * Note: written as a 'helper' function to hide implementation details. - */ -int -pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, - int *type) -{ - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { - *type = attr->type; - return (0); - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - -/* - * - */ -int -pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared) -{ - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { - *pshared = (int)attr->pshared; - return (0); - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - -/* - * Initialize a mutex attribute structure to system defaults. - */ -int -pthread_mutexattr_init(pthread_mutexattr_t *attr) -{ - attr->prioceiling = _PTHREAD_DEFAULT_PRIOCEILING; - attr->protocol = _PTHREAD_DEFAULT_PROTOCOL; - attr->policy = _PTHREAD_MUTEX_POLICY_FAIRSHARE; - attr->type = PTHREAD_MUTEX_DEFAULT; - attr->sig = _PTHREAD_MUTEX_ATTR_SIG; - attr->pshared = _PTHREAD_DEFAULT_PSHARED; - return (0); -} - -/* - * Set the priority ceiling value in a mutex attribute structure. - * Note: written as a 'helper' function to hide implementation details. - */ -int -pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, - int prioceiling) -{ - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { - if ((prioceiling >= -999) || - (prioceiling <= 999)) - { - attr->prioceiling = prioceiling; - return (0); - } else - { - return (EINVAL); /* Invalid parameter */ - } - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - -/* - * Set the mutex 'protocol' value in a mutex attribute structure. - * Note: written as a 'helper' function to hide implementation details. - */ -int -pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, - int protocol) -{ - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { - if ((protocol == PTHREAD_PRIO_NONE) || - (protocol == PTHREAD_PRIO_INHERIT) || - (protocol == PTHREAD_PRIO_PROTECT)) - { - attr->protocol = protocol; - return (0); - } else - { - return (EINVAL); /* Invalid parameter */ - } - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - -int -pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *attr, - int policy) -{ - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { - if ( - (policy == _PTHREAD_MUTEX_POLICY_FAIRSHARE) || - (policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT) -#if NOTYET - || - (policy == _PTHREAD_MUTEX_POLICY_REALTIME) || - (policy == _PTHREAD_MUTEX_POLICY_ADAPTIVE) || - (policy == _PTHREAD_MUTEX_POLICY_PRIPROTECT) || - (policy == _PTHREAD_MUTEX_POLICY_PRIINHERIT) -#endif /* NOTYET */ - ) - { - attr->policy = policy; - return (0); - } else - { - return (EINVAL); /* Invalid parameter */ - } - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - -/* - * Set the mutex 'type' value in a mutex attribute structure. - * Note: written as a 'helper' function to hide implementation details. - */ -int -pthread_mutexattr_settype(pthread_mutexattr_t *attr, - int type) -{ - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { - if ((type == PTHREAD_MUTEX_NORMAL) || - (type == PTHREAD_MUTEX_ERRORCHECK) || - (type == PTHREAD_MUTEX_RECURSIVE) || - (type == PTHREAD_MUTEX_DEFAULT)) - { - attr->type = type; - return (0); - } else - { - return (EINVAL); /* Invalid parameter */ - } - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - - -int mutex_try_lock(int *x) { - return _spin_lock_try((pthread_lock_t *)x); -} - -void mutex_wait_lock(int *x) { - for (;;) { - if( _spin_lock_try((pthread_lock_t *)x)) { - return; - } - swtch_pri(0); - } -} - -void -cthread_yield(void) -{ - sched_yield(); -} - -void -pthread_yield_np (void) -{ - sched_yield(); -} - - -/* - * Temp: till pshared is fixed correctly - */ -int -pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) -{ -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; -#endif /* __DARWIN_UNIX03 */ - - if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG) - { -#if __DARWIN_UNIX03 - if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED)) -#else /* __DARWIN_UNIX03 */ - if ( pshared == PTHREAD_PROCESS_PRIVATE) -#endif /* __DARWIN_UNIX03 */ - { - attr->pshared = pshared; - return (0); - } else { - return (EINVAL); /* Invalid parameter */ - } - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - -/* - * Drop the mutex unlock references(from cond wait or mutex_unlock(). - * - */ -__private_extern__ int -__mtx_droplock(npthread_mutex_t * mutex, uint32_t diffgen, uint32_t * flagsp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp) -{ - pthread_t self; - uint64_t selfid, resettid; - int firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT); - uint32_t lgenval, ugenval, nlval, ulval, morewaiters=0, flags; - volatile uint32_t * lseqaddr, *useqaddr; - uint64_t oldval64, newval64; - int numwaiters=0, clearprepost = 0; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_START, (uint32_t)mutex, diffgen, 0, 0, 0); -#endif - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - - - flags = mutex->mtxopts.value; - flags &= ~_PTHREAD_MTX_OPT_NOTIFY; /* no notification by default */ - - - if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) - { - self = pthread_self(); - (void) pthread_threadid_np(self, &selfid); - - if (mutex->m_tid != selfid) - { - //LIBC_ABORT("dropping recur or error mutex not owned by the thread\n"); - PLOCKSTAT_MUTEX_ERROR((pthread_mutex_t *)mutex, EPERM); - return(EPERM); - } else if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE && - --mutex->mtxopts.options.lock_count) - { - PLOCKSTAT_MUTEX_RELEASE((pthread_mutex_t *)mutex, 1); - goto out; - } - } - - -retry: - lgenval = *lseqaddr; - ugenval = *useqaddr; - - clearprepost = 0; - - numwaiters = diff_genseq((lgenval & PTHRW_COUNT_MASK),(ugenval & PTHRW_COUNT_MASK)); /* pendig waiters */ - - if (numwaiters == 0) { - /* spurious unlocks, do not touch tid */ - oldval64 = (((uint64_t)ugenval) << 32); - oldval64 |= lgenval; - if ((firstfit != 0) && ((lgenval & PTH_RWL_PBIT) != 0)) { - clearprepost = 1; - lgenval &= ~PTH_RWL_PBIT; - newval64 = (((uint64_t)ugenval) << 32); - newval64 |= lgenval; - } else - newval64 = oldval64; - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) - goto retry; - /* validated L & U to be same, this is spurious unlock */ - flags &= ~_PTHREAD_MTX_OPT_NOTIFY; - if (clearprepost == 1) - __psynch_cvclrprepost(mutex, lgenval, ugenval, 0, 0, lgenval, (flags | _PTHREAD_MTX_OPT_MUTEX)); - - goto out; - } - - if (numwaiters < diffgen) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, numwaiters, lgenval, ugenval, 0); -#endif - /* cannot drop more than existing number of waiters */ - diffgen = numwaiters; - } - - oldval64 = (((uint64_t)ugenval) << 32); - oldval64 |= lgenval; - ulval = ugenval + diffgen; - nlval = lgenval; - - if ((lgenval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) { - /* do not reset Ibit, just K&E */ - nlval &= ~(PTH_RWL_KBIT | PTH_RWL_EBIT); - flags &= ~_PTHREAD_MTX_OPT_NOTIFY; - if ((firstfit != 0) && ((lgenval & PTH_RWL_PBIT) != 0)) { - clearprepost = 1; - nlval &= ~PTH_RWL_PBIT; - } - } else { - /* need to signal others waiting for mutex */ - morewaiters = 1; - flags |= _PTHREAD_MTX_OPT_NOTIFY; - } - - if (((nlval & PTH_RWL_EBIT) != 0) && (firstfit != 0)) { - nlval &= ~PTH_RWL_EBIT; /* reset Ebit so another can acquire meanwhile */ - } - - newval64 = (((uint64_t)ulval) << 32); - newval64 |= nlval; - - resettid = mutex->m_tid; - - if ((lgenval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) - mutex->m_tid = 0; - else if (firstfit == 0) - mutex->m_tid = PTHREAD_MTX_TID_SWITCHING; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) { - mutex->m_tid = resettid; - goto retry; - } - - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0); - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, 2, nlval, ulval, 0); -#endif - - if (clearprepost != 0) { - __psynch_cvclrprepost(mutex, nlval, ulval, 0, 0, nlval, (flags | _PTHREAD_MTX_OPT_MUTEX)); - } - - if (mgenp != NULL) - *mgenp = nlval; - if (ugenp != NULL) - *ugenp = ulval; -#if USE_COMPAGE - if (pmtxp != NULL) - *pmtxp = lseqaddr; -#else - if (pmtxp != NULL) - *pmtxp = (uint32_t *)mutex; -#endif - -out: - if (flagsp != NULL) - *flagsp = flags; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_END, (uint32_t)mutex, flags, 0, 0, 0); -#endif - return(0); -} - -int -__mtx_updatebits(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit, int fromcond, uint64_t selfid) -{ - uint32_t updateval = oupdateval; -#if !USE_COMPAGE - pthread_mutex_t * omutex = (pthread_mutex_t *)mutex; -#endif - int isebit = 0; - uint32_t lgenval, ugenval, nval, uval, bits; - volatile uint32_t * lseqaddr, *useqaddr; - uint64_t oldval64, newval64; - - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_START, (uint32_t)mutex, oupdateval, firstfit, fromcond, 0); -#endif - -retry: - lgenval = *lseqaddr; - ugenval = *useqaddr; - bits = updateval & PTHRW_BIT_MASK; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 1, lgenval, ugenval, 0); -#endif - - - if ((updateval & PTH_RWL_MTX_WAIT) != 0) { - lgenval = (updateval & PTHRW_COUNT_MASK) | (lgenval & PTHRW_BIT_MASK); - if (fromcond == 0) { - /* if from mutex_lock(), it will handle the rewind */ - return(1); - } - /* go block in the kernel with same lgenval as returned */ - goto ml1; - } else { - /* firsfit might not have EBIT */ - if (firstfit != 0) { - if ((lgenval & PTH_RWL_EBIT) != 0) - isebit = 1; - else - isebit = 0; - } else if ((lgenval & (PTH_RWL_KBIT|PTH_RWL_EBIT)) == (PTH_RWL_KBIT|PTH_RWL_EBIT)) { - /* fairshare mutex and the bits are already set, just update tid */ - goto out; - } - } - - /* either firstfist or no E bit set */ - /* update the bits */ - oldval64 = (((uint64_t)ugenval) << 32); - oldval64 |= lgenval; - uval = ugenval; - nval = lgenval | (PTH_RWL_KBIT|PTH_RWL_EBIT); - newval64 = (((uint64_t)uval) << 32); - newval64 |= nval; - - /* set s and b bit */ - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 2, nval, uval, 0); -#endif - if ((firstfit != 0) && (isebit != 0)) - goto handleffit; - - goto out; - } else { - if (firstfit == 0) - goto retry; - else - goto handleffit; - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 4, nval, uval, 0); -#endif - -out: - /* succesful bits updation */ - mutex->m_tid = selfid; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0); -#endif - return(0); - -handleffit: - /* firstfit failure */ - lgenval = *lseqaddr; - ugenval = *useqaddr; - if ((lgenval & PTH_RWL_EBIT) == 0) - goto retry; - - if (fromcond == 0) - return(1); - else { - /* called from condition variable code block again */ -ml1: -#if USE_COMPAGE /* [ */ - updateval = __psynch_mutexwait((pthread_mutex_t *)lseqaddr, lgenval | PTH_RWL_RETRYBIT, ugenval, mutex->m_tid, - mutex->mtxopts.value); -#else /* USECOMPAGE ][ */ - updateval = __psynch_mutexwait(omutex, lgenval | PTH_RWL_RETRYBIT, ugenval, mutex->m_tid, - mutex->mtxopts.value); -#endif /* USE_COMPAGE ] */ - if (updateval == (uint32_t)-1) { - goto ml1; - } - - /* now update the bits */ - goto retry; - } - /* cannot reach */ - goto retry; -} - - -int -__mtx_markprepost(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit) -{ - uint32_t updateval = oupdateval; - int clearprepost = 0; - uint32_t lgenval, ugenval,flags; - volatile uint32_t * lseqaddr, *useqaddr; - uint64_t oldval64, newval64; - - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_START, (uint32_t)mutex, oupdateval, firstfit, 0, 0); -#endif - -retry: - - clearprepost = 0; - - if ((firstfit != 0) && ((updateval & PTH_RWL_PBIT) != 0)) { - flags = mutex->mtxopts.value; - - lgenval = *lseqaddr; - ugenval = *useqaddr; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_NONE, (uint32_t)mutex, 1, lgenval, ugenval, 0); -#endif - /* update the bits */ - oldval64 = (((uint64_t)ugenval) << 32); - oldval64 |= lgenval; - - if ((lgenval & PTHRW_COUNT_MASK) == (ugenval & PTHRW_COUNT_MASK)) { - clearprepost = 1; - lgenval &= ~PTH_RWL_PBIT; - - } else { - lgenval |= PTH_RWL_PBIT; - } - newval64 = (((uint64_t)ugenval) << 32); - newval64 |= lgenval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0); -#endif - - if (clearprepost != 0) - __psynch_cvclrprepost(mutex, lgenval, ugenval, 0, 0, lgenval, (flags | _PTHREAD_MTX_OPT_MUTEX)); - - } else { - goto retry; - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0); -#endif - } - return(0); -} - -/* - * For the new style mutex, interlocks are not held all the time. - * We needed the signature to be set in the end. And we need - * to protect against the code getting reorganized by compiler. - */ -static void -__pthread_mutex_set_signature(npthread_mutex_t * mutex) -{ - mutex->sig = _PTHREAD_MUTEX_SIG; -} - -int -pthread_mutex_lock(pthread_mutex_t *omutex) -{ - pthread_t self; - uint64_t selfid; - npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; - int sig = mutex->sig; -#if NEVERINCOMPAGE || !USE_COMPAGE - //uint32_t oldval, newval; -#endif - int retval; - int gotlock = 0, firstfit = 0; - uint32_t updateval, lgenval, ugenval, nval, uval; - volatile uint32_t * lseqaddr, *useqaddr; - uint64_t oldval64, newval64; -#if USE_COMPAGE - int sysret = 0; - uint32_t mask; -#else - int retrybit = 0; -#endif - - /* To provide backwards compat for apps using mutex incorrectly */ - if ((sig != _PTHREAD_MUTEX_SIG) && ((sig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) { - PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); - return(EINVAL); - } - if (mutex->sig != _PTHREAD_MUTEX_SIG) { - LOCK(mutex->lock); - if ((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK) == _PTHREAD_MUTEX_SIG_CMP) { - /* static initializer, init the mutex */ - if(retval = _pthread_mutex_init(omutex, NULL, (mutex->sig & 0xf)) != 0){ - UNLOCK(mutex->lock); - PLOCKSTAT_MUTEX_ERROR(omutex, retval); - return(retval); - } - } else if (mutex->sig != _PTHREAD_MUTEX_SIG) { - UNLOCK(mutex->lock); - PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); - return(EINVAL); - } - UNLOCK(mutex->lock); - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_START, (uint32_t)mutex, 0, 0, 0, 0); -#endif - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - - self = pthread_self(); - (void) pthread_threadid_np(self, &selfid); - - if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) { - if (mutex->m_tid == selfid) { - if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) - { - if (mutex->mtxopts.options.lock_count < USHRT_MAX) - { - mutex->mtxopts.options.lock_count++; - PLOCKSTAT_MUTEX_ACQUIRE(omutex, 1, 0); - retval = 0; - } else { - retval = EAGAIN; - PLOCKSTAT_MUTEX_ERROR(omutex, retval); - } - } else { /* PTHREAD_MUTEX_ERRORCHECK */ - retval = EDEADLK; - PLOCKSTAT_MUTEX_ERROR(omutex, retval); - } - return (retval); - } - } - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 1, 0, 0, 0); -#endif - -#if USE_COMPAGE /* [ */ - -ml0: - mask = PTH_RWL_EBIT; - retval = _commpage_pthread_mutex_lock(lseqaddr, mutex->mtxopts.value, selfid, mask, &mutex->m_tid, &sysret); - if (retval == 0) { - gotlock = 1; - } else if (retval == 1) { - gotlock = 1; - updateval = sysret; - /* returns 0 on succesful update */ - if (__mtx_updatebits( mutex, updateval, firstfit, 0, selfid) == 1) { - /* could not acquire, may be locked in ffit case */ -#if USE_COMPAGE - LIBC_ABORT("comapge implementatin looping in libc \n"); -#endif - goto ml0; - } - } -#if NEVERINCOMPAGE - else if (retval == 3) { - cthread_set_errno_self(sysret); - oldval = *lseqaddr; - uval = *useqaddr; - newval = oldval + PTHRW_INC; - gotlock = 0; - /* to block in the kerenl again */ - } -#endif - else { - LIBC_ABORT("comapge implementation bombed \n"); - } - - -#else /* USECOMPAGE ][ */ -retry: - lgenval = *lseqaddr; - ugenval = *useqaddr; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0); -#endif /* _KSYN_TRACE_ */ - - if((lgenval & PTH_RWL_EBIT) == 0) { - gotlock = 1; - } else { - gotlock = 0; - } - - oldval64 = (((uint64_t)ugenval) << 32); - oldval64 |= lgenval; - uval = ugenval; - nval = (lgenval + PTHRW_INC) | (PTH_RWL_EBIT|PTH_RWL_KBIT); - newval64 = (((uint64_t)uval) << 32); - newval64 |= nval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, nval, uval, 0); -#endif - if (gotlock != 0) { - mutex->m_tid = selfid; - goto out; - } - } else - goto retry; - - - retrybit = 0; - if (gotlock == 0) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 3, nval, uval, 0); -#endif - firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT); -ml1: - updateval = __psynch_mutexwait(omutex, nval | retrybit, uval, mutex->m_tid, - mutex->mtxopts.value); - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 4, updateval, 0, 0); -#endif - if (updateval == (uint32_t)-1) { - goto ml1; - } - - /* returns 0 on succesful update; in firstfit it may fail with 1 */ - if (__mtx_updatebits( mutex, PTHRW_INC | (PTH_RWL_KBIT | PTH_RWL_EBIT), firstfit, 0, selfid) == 1) { - /* could not acquire, may be locked in ffit case */ - retrybit = PTH_RWL_RETRYBIT; -#if USE_COMPAGE - LIBC_ABORT("comapge implementatin looping in libc \n"); - -#endif - goto ml1; - } - } -#endif /* USE_COMPAGE ] */ - -out: - if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) - mutex->mtxopts.options.lock_count = 1; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0); -#endif - return (0); -} - -/* - * Attempt to lock a mutex, but don't block if this isn't possible. - */ -int -pthread_mutex_trylock(pthread_mutex_t *omutex) -{ - npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; - int sig = mutex->sig; - int error = 0; - pthread_t self; - uint64_t selfid; - int gotlock = 0; - uint32_t lgenval, ugenval, nval, uval; - volatile uint32_t * lseqaddr, *useqaddr; - uint64_t oldval64, newval64; - - /* To provide backwards compat for apps using mutex incorrectly */ - if ((sig != _PTHREAD_MUTEX_SIG) && ((sig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) { - PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); - return(EINVAL); - } - - if (mutex->sig != _PTHREAD_MUTEX_SIG) { - LOCK(mutex->lock); - if ((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK) == _PTHREAD_MUTEX_SIG_CMP) { - /* static initializer, init the mutex */ - if((error = _pthread_mutex_init(omutex, NULL, (mutex->sig & 0xf))) != 0){ - UNLOCK(mutex->lock); - PLOCKSTAT_MUTEX_ERROR(omutex, error); - return(error); - } - } else if (mutex->sig != _PTHREAD_MUTEX_SIG) { - UNLOCK(mutex->lock); - PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); - return(EINVAL); - } - UNLOCK(mutex->lock); - } - - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - - self = pthread_self(); - (void) pthread_threadid_np(self, &selfid); - - if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) { - if (mutex->m_tid == selfid) { - if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) - { - if (mutex->mtxopts.options.lock_count < USHRT_MAX) - { - mutex->mtxopts.options.lock_count++; - PLOCKSTAT_MUTEX_ACQUIRE(omutex, 1, 0); - error = 0; - } else { - error = EAGAIN; - PLOCKSTAT_MUTEX_ERROR(omutex, error); - } - } else { /* PTHREAD_MUTEX_ERRORCHECK */ - error = EDEADLK; - PLOCKSTAT_MUTEX_ERROR(omutex, error); - } - return (error); - } - } -retry: - lgenval = *lseqaddr; - ugenval = *useqaddr; - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0); -#endif /* _KSYN_TRACE_ */ - - - oldval64 = (((uint64_t)ugenval) << 32); - oldval64 |= lgenval; - uval = ugenval; - - /* if we can acquire go ahead otherwise ensure it is still busy */ - if((lgenval & PTH_RWL_EBIT) == 0) { - gotlock = 1; - nval = (lgenval + PTHRW_INC) | (PTH_RWL_EBIT|PTH_RWL_KBIT); - } else { - nval = (lgenval | PTH_RWL_TRYLKBIT); - gotlock = 0; - } - - newval64 = (((uint64_t)uval) << 32); - newval64 |= nval; - - /* set s and b bit */ - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) { -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, nval, uval, 0); -#endif - if (gotlock != 0) { - mutex->m_tid = selfid; - if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE) - mutex->mtxopts.options.lock_count = 1; - PLOCKSTAT_MUTEX_ACQUIRE(omutex, 1, 0); - } else { - error = EBUSY; - PLOCKSTAT_MUTEX_ERROR(omutex, error); - } - } else - goto retry; - - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_END, (uint32_t)mutex, 0xfafafafa, 0, error, 0); -#endif - return (error); -} - -/* - * Unlock a mutex. - * TODO: Priority inheritance stuff - */ -int -pthread_mutex_unlock(pthread_mutex_t *omutex) -{ - npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; - int retval; - uint32_t mtxgen, mtxugen, flags, notify, updateval; - int sig = mutex->sig; - pthread_t self; - uint64_t selfid; - volatile uint32_t * lseqaddr, *useqaddr; - int firstfit = 0; - - /* To provide backwards compat for apps using mutex incorrectly */ - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_START, (uint32_t)mutex, 0, 0, 0, 0); -#endif - if ((sig != _PTHREAD_MUTEX_SIG) && ((sig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) { - PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); - return(EINVAL); - } - - if (mutex->sig != _PTHREAD_MUTEX_SIG) { - LOCK(mutex->lock); - if ((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK) == _PTHREAD_MUTEX_SIG_CMP) { - /* static initializer, init the mutex */ - if((retval = _pthread_mutex_init(omutex, NULL, (mutex->sig & 0xf))) != 0){ - UNLOCK(mutex->lock); - PLOCKSTAT_MUTEX_ERROR(omutex, retval); - return(retval); - } - } else if (mutex->sig != _PTHREAD_MUTEX_SIG) { - UNLOCK(mutex->lock); - PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL); - return(EINVAL); - } - UNLOCK(mutex->lock); - } - - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - - notify = 0; - retval = __mtx_droplock(mutex, PTHRW_INC, &flags, NULL, &mtxgen, &mtxugen); - if (retval != 0) - return(retval); - - if ((flags & _PTHREAD_MTX_OPT_NOTIFY) != 0) { - firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT); - - self = pthread_self(); - (void) pthread_threadid_np(self, &selfid); - -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_NONE, (uint32_t)mutex, 1, mtxgen, mtxugen, 0); -#endif -#if USE_COMPAGE /* [ */ - if ((updateval = __psynch_mutexdrop((pthread_mutex_t *)lseqaddr, mtxgen, mtxugen, mutex->m_tid, flags)) == (uint32_t)-1) -#else /* USECOMPAGE ][ */ - if ((updateval = __psynch_mutexdrop(omutex, mtxgen, mtxugen, mutex->m_tid, flags))== (uint32_t)-1) -#endif /* USE_COMPAGE ] */ - { - retval = errno; -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_END, (uint32_t)mutex, retval, 0, 0, 0); -#endif - if (retval == 0) - return(0); - else if (errno == EINTR) - return(0); - else { - LIBC_ABORT("__p_mutexdrop failed with error %d\n", retval); - return(retval); - } - } else if (firstfit == 1) { - if ((updateval & PTH_RWL_PBIT) != 0) { - __mtx_markprepost(mutex, updateval, firstfit); - } - } - } -#if _KSYN_TRACE_ - (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0); -#endif - return(0); -} - - -/* - * Initialize a mutex variable, possibly with additional attributes. - */ -int -_pthread_mutex_init(pthread_mutex_t *omutex, const pthread_mutexattr_t *attr, uint32_t static_type) -{ - npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; - - if (attr) - { - if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG) - return (EINVAL); - mutex->prioceiling = attr->prioceiling; - mutex->mtxopts.options.protocol = attr->protocol; - mutex->mtxopts.options.policy = attr->policy; - mutex->mtxopts.options.type = attr->type; - mutex->mtxopts.options.pshared = attr->pshared; - } else { - switch(static_type) { - case 1: - mutex->mtxopts.options.type = PTHREAD_MUTEX_ERRORCHECK; - break; - case 2: - mutex->mtxopts.options.type = PTHREAD_MUTEX_RECURSIVE; - break; - case 3: - /* firstfit fall thru */ - case 7: - mutex->mtxopts.options.type = PTHREAD_MUTEX_DEFAULT; - break; - default: - return(EINVAL); - } - - mutex->prioceiling = _PTHREAD_DEFAULT_PRIOCEILING; - mutex->mtxopts.options.protocol = _PTHREAD_DEFAULT_PROTOCOL; - if (static_type != 3) - mutex->mtxopts.options.policy = _PTHREAD_MUTEX_POLICY_FAIRSHARE; - else - mutex->mtxopts.options.policy = _PTHREAD_MUTEX_POLICY_FIRSTFIT; - mutex->mtxopts.options.pshared = _PTHREAD_DEFAULT_PSHARED; - } - - mutex->mtxopts.options.notify = 0; - mutex->mtxopts.options.rfu = 0; - mutex->mtxopts.options.hold = 0; - mutex->mtxopts.options.mutex = 1; - mutex->mtxopts.options.lock_count = 0; - /* address 8byte aligned? */ - if (((uintptr_t)mutex & 0x07) != 0) { - /* 4byte alinged */ - mutex->mtxopts.options.misalign = 1; -#if defined(__LP64__) - mutex->m_lseqaddr = &mutex->m_seq[0]; - mutex->m_useqaddr = &mutex->m_seq[1]; -#else /* __LP64__ */ - mutex->m_lseqaddr = &mutex->m_seq[1]; - mutex->m_useqaddr = &mutex->m_seq[2]; -#endif /* __LP64__ */ - } else { - /* 8byte alinged */ - mutex->mtxopts.options.misalign = 0; -#if defined(__LP64__) - mutex->m_lseqaddr = &mutex->m_seq[1]; - mutex->m_useqaddr = &mutex->m_seq[2]; -#else /* __LP64__ */ - mutex->m_lseqaddr = &mutex->m_seq[0]; - mutex->m_useqaddr = &mutex->m_seq[1]; -#endif /* __LP64__ */ - } - mutex->m_tid = 0; - mutex->m_seq[0] = 0; - mutex->m_seq[1] = 0; - mutex->m_seq[2] = 0; - mutex->prioceiling = 0; - mutex->priority = 0; - /* - * For the new style mutex, interlocks are not held all the time. - * We needed the signature to be set in the end. And we need - * to protect against the code getting reorganized by compiler. - * mutex->sig = _PTHREAD_MUTEX_SIG; - */ - __pthread_mutex_set_signature(mutex); - return (0); -} - - -/* - * Destroy a mutex variable. - */ -int -pthread_mutex_destroy(pthread_mutex_t *omutex) -{ - int res; - npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; - - LOCK(mutex->lock); - res = _pthread_mutex_destroy_locked(omutex); - UNLOCK(mutex->lock); - - return(res); -} - - -static int -_pthread_mutex_destroy_locked(pthread_mutex_t *omutex) -{ - int res; - npthread_mutex_t * mutex = (npthread_mutex_t *)omutex; - uint32_t lgenval, ugenval; - volatile uint32_t * lseqaddr, *useqaddr; - - - if (mutex->sig == _PTHREAD_MUTEX_SIG) - { - MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr); - - lgenval = *(lseqaddr); - ugenval = *(useqaddr); - if ((mutex->m_tid == (uint64_t)0) && - ((lgenval & PTHRW_COUNT_MASK) == (ugenval & PTHRW_COUNT_MASK))) - { - mutex->sig = _PTHREAD_NO_SIG; - res = 0; - } - else - res = EBUSY; - } else if((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK )== _PTHREAD_MUTEX_SIG_CMP) { - mutex->sig = _PTHREAD_NO_SIG; - res = 0; - } else - res = EINVAL; - - return (res); -} - - -#endif /* !BUILDING_VARIANT ] */ - -/* - * Destroy a mutex attribute structure. - */ -int -pthread_mutexattr_destroy(pthread_mutexattr_t *attr) -{ -#if __DARWIN_UNIX03 - if (__unix_conforming == 0) - __unix_conforming = 1; - if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG) - return (EINVAL); -#endif /* __DARWIN_UNIX03 */ - - attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */ - return (0); -} - - diff --git a/src/libc/pthreads/pthread_mutex_destroy.3 b/src/libc/pthreads/pthread_mutex_destroy.3 deleted file mode 100644 index 17207f32e..000000000 --- a/src/libc/pthreads/pthread_mutex_destroy.3 +++ /dev/null @@ -1,72 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_destroy.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 29, 1998 -.Dt PTHREAD_MUTEX_DESTROY 3 -.Os -.Sh NAME -.Nm pthread_mutex_destroy -.Nd free resources allocated for a mutex -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_mutex_destroy -.Fa "pthread_mutex_t *mutex" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_mutex_destroy -function frees the resources allocated for -.Fa mutex . -.Sh RETURN VALUES -If successful, -.Fn pthread_mutex_destroy -will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -.Fn pthread_mutex_destroy -will fail if: -.Bl -tag -width Er -.It Bq Er EBUSY -.Fa Mutex -is locked by a thread. -.It Bq Er EINVAL -The value specified by -.Fa mutex -is invalid. -.El -.Sh SEE ALSO -.Xr pthread_mutex_init 3 , -.Xr pthread_mutex_lock 3 , -.Xr pthread_mutex_trylock 3 , -.Xr pthread_mutex_unlock 3 -.Sh STANDARDS -.Fn pthread_mutex_destroy -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_mutex_init.3 b/src/libc/pthreads/pthread_mutex_init.3 deleted file mode 100644 index bebe8a27e..000000000 --- a/src/libc/pthreads/pthread_mutex_init.3 +++ /dev/null @@ -1,78 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_init.3,v 1.6.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 29, 1998 -.Dt PTHREAD_MUTEX_INIT 3 -.Os -.Sh NAME -.Nm pthread_mutex_init -.Nd create a mutex -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_mutex_init -.Fa "pthread_mutex_t *restrict mutex" -.Fa "const pthread_mutexattr_t *restrict attr" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_mutex_init -function creates a new mutex, with attributes specified with -.Fa attr . -If -.Fa attr -is NULL, the default attributes are used. -.Sh RETURN VALUES -If successful, -.Fn pthread_mutex_init -will return zero and put the new mutex id into -.Fa mutex . -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -.Fn pthread_mutex_init -will fail if: -.Bl -tag -width Er -.It Bq Er EAGAIN -The system temporarily lacks the resources to create another mutex. -.It Bq Er EINVAL -The value specified by -.Fa attr -is invalid. -.It Bq Er ENOMEM -The process cannot allocate enough memory to create another mutex. -.El -.Sh SEE ALSO -.Xr pthread_mutex_destroy 3 , -.Xr pthread_mutex_lock 3 , -.Xr pthread_mutex_trylock 3 , -.Xr pthread_mutex_unlock 3 -.Sh STANDARDS -.Fn pthread_mutex_init -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_mutex_lock.3 b/src/libc/pthreads/pthread_mutex_lock.3 deleted file mode 100644 index e0a4fadc6..000000000 --- a/src/libc/pthreads/pthread_mutex_lock.3 +++ /dev/null @@ -1,74 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_lock.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 30, 1998 -.Dt PTHREAD_MUTEX_LOCK 3 -.Os -.Sh NAME -.Nm pthread_mutex_lock -.Nd lock a mutex -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_mutex_lock -.Fa "pthread_mutex_t *mutex" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_mutex_lock -function locks -.Fa mutex . -If the mutex is already locked, the calling thread will block until the -mutex becomes available. -.Sh RETURN VALUES -If successful, -.Fn pthread_mutex_lock -will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -.Fn pthread_mutex_lock -will fail if: -.Bl -tag -width Er -.It Bq Er EDEADLK -A deadlock would occur if the thread blocked waiting for -.Fa mutex . -.It Bq Er EINVAL -The value specified by -.Fa mutex -is invalid. -.El -.Sh SEE ALSO -.Xr pthread_mutex_destroy 3 , -.Xr pthread_mutex_init 3 , -.Xr pthread_mutex_trylock 3 , -.Xr pthread_mutex_unlock 3 -.Sh STANDARDS -.Fn pthread_mutex_lock -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_mutex_trylock.3 b/src/libc/pthreads/pthread_mutex_trylock.3 deleted file mode 100644 index 345a01447..000000000 --- a/src/libc/pthreads/pthread_mutex_trylock.3 +++ /dev/null @@ -1,75 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_trylock.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 30, 1998 -.Dt PTHREAD_MUTEX_TRYLOCK 3 -.Os -.Sh NAME -.Nm pthread_mutex_trylock -.Nd attempt to lock a mutex without blocking -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_mutex_trylock -.Fa "pthread_mutex_t *mutex" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_mutex_trylock -function locks -.Fa mutex . -If the mutex is already locked, -.Fn pthread_mutex_trylock -will not block waiting for the mutex, but will return an error condition. -.Sh RETURN VALUES -If successful, -.Fn pthread_mutex_trylock -will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -.Fn pthread_mutex_trylock -will fail if: -.Bl -tag -width Er -.It Bq Er EBUSY -.Fa Mutex -is already locked. -.It Bq Er EINVAL -The value specified by -.Fa mutex -is invalid. -.El -.Sh SEE ALSO -.Xr pthread_mutex_destroy 3 , -.Xr pthread_mutex_init 3 , -.Xr pthread_mutex_lock 3 , -.Xr pthread_mutex_unlock 3 -.Sh STANDARDS -.Fn pthread_mutex_trylock -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_mutex_unlock.3 b/src/libc/pthreads/pthread_mutex_unlock.3 deleted file mode 100644 index ae29010a7..000000000 --- a/src/libc/pthreads/pthread_mutex_unlock.3 +++ /dev/null @@ -1,81 +0,0 @@ -.\" Copyright (c) 1997 Brian Cully -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_unlock.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $ -.\" -.Dd July 30, 1998 -.Dt PTHREAD_MUTEX_UNLOCK 3 -.Os -.Sh NAME -.Nm pthread_mutex_unlock -.Nd unlock a mutex -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_mutex_unlock -.Fa "pthread_mutex_t *mutex" -.Fc -.Sh DESCRIPTION -If the current thread holds the lock on -.Fa mutex , -then the -.Fn pthread_mutex_unlock -function unlocks -.Fa mutex . -.Pp -Calling -.Fn pthread_mutex_unlock -with a -.Fa mutex -that the calling thread does not hold will result -in undefined behavior. -.Sh RETURN VALUES -If successful, -.Fn pthread_mutex_unlock -will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -.Fn pthread_mutex_unlock -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa mutex -is invalid. -.It Bq Er EPERM -The current thread does not hold a lock on -.Fa mutex . -.El -.Sh SEE ALSO -.Xr pthread_mutex_destroy 3 , -.Xr pthread_mutex_init 3 , -.Xr pthread_mutex_lock 3 , -.Xr pthread_mutex_trylock 3 -.Sh STANDARDS -.Fn pthread_mutex_unlock -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_mutexattr.3 b/src/libc/pthreads/pthread_mutexattr.3 deleted file mode 100644 index 9f6ac0cbc..000000000 --- a/src/libc/pthreads/pthread_mutexattr.3 +++ /dev/null @@ -1,302 +0,0 @@ -.\" $NetBSD: pthread_mutexattr.3,v 1.3 2003/07/04 08:36:06 wiz Exp $ -.\" -.\" Copyright (c) 2002 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. -.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -.\" POSSIBILITY OF SUCH DAMAGE. -.\" -.\" Copyright (C) 2000 Jason Evans . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice(s), this list of conditions and the following disclaimer as -.\" the first lines of this file unmodified other than the possible -.\" addition of one or more copyright notices. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice(s), this list of conditions and the following disclaimer in -.\" the documentation and/or other materials provided with the -.\" distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY -.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE -.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libpthread/man/pthread_mutexattr.3,v 1.8 2002/09/16 19:29:29 mini Exp $ -.Dd January 30, 2003 -.Dt PTHREAD_MUTEXATTR 3 -.Os -.Sh NAME -.Nm pthread_mutexattr_destroy , -.Nm pthread_mutexattr_getprioceiling , -.Nm pthread_mutexattr_getprotocol , -.Nm pthread_mutexattr_gettype , -.Nm pthread_mutexattr_init , -.Nm pthread_mutexattr_setprioceiling , -.Nm pthread_mutexattr_setprotocol , -.Nm pthread_mutexattr_settype -.Nd mutex attribute operations -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_mutexattr_destroy -.Fa "pthread_mutexattr_t *attr" -.Fc -.Ft int -.Fo pthread_mutexattr_getprioceiling -.Fa "const pthread_mutexattr_t *restrict attr" -.Fa "int *restrict prioceiling" -.Fc -.\" To match the SUS, this should be: -.\" .Ft int -.\" .Fo pthread_mutexattr_getprioceiling -.\" .Fa "pthread_mutexattr_t *restrict attr" -.\" .Fa "int *restrict prioceiling" -.\" .Fc -.Ft int -.Fo pthread_mutexattr_getprotocol -.Fa "const pthread_mutexattr_t *restrict attr" -.Fa "int *restrict protocol" -.Fc -.\" To match the SUS, this should be: -.\" .Ft int -.\" .Fo pthread_mutexattr_getprotocol -.\" .Fa "pthread_mutexattr_t *restrict attr" -.\" .Fa "int *restrict protocol" -.\" .Fc -.Ft int -.Fo pthread_mutexattr_gettype -.Fa "const pthread_mutexattr_t *restrict attr" -.Fa "int *restrict type" -.Fc -.\" To match the SUS, this should be: -.\" .Ft int -.\" .Fo pthread_mutexattr_gettype -.\" .Fa "pthread_mutexattr_t *restrict attr" -.\" .Fa "int *restrict type" -.\" .Fc -.Ft int -.Fo pthread_mutexattr_init -.Fa "pthread_mutexattr_t *attr" -.Fc -.Ft int -.Fo pthread_mutexattr_setprioceiling -.Fa "pthread_mutexattr_t *attr" -.Fa "int prioceiling" -.Fc -.Ft int -.Fo pthread_mutexattr_setprotocol -.Fa "pthread_mutexattr_t *attr" -.Fa "int protocol" -.Fc -.Ft int -.Fo pthread_mutexattr_settype -.Fa "pthread_mutexattr_t *attr" -.Fa "int type" -.Fc -.Sh DESCRIPTION -Mutex attributes are used to specify parameters to -.Fn pthread_mutex_init . -One attribute object can be used in multiple calls to -.Fn pthread_mutex_init , -with or without modifications between calls. -.Pp -The -.Fn pthread_mutexattr_init -function initializes -.Fa attr -with all of the default mutex attributes. -.Pp -The -.Fn pthread_mutexattr_destroy -function destroys -.Fa attr . -.Pp -The -.Fn pthread_mutexattr_settype -function sets the mutex type value of the attribute. Valid mutex types are: -.Dv PTHREAD_MUTEX_NORMAL , -.Dv PTHREAD_MUTEX_ERRORCHECK , -.Dv PTHREAD_MUTEX_RECURSIVE , -and -.Dv PTHREAD_MUTEX_DEFAULT . -The default mutex type for -.Fn pthread_mutexattr_init -is -.Dv PTHREAD_MUTEX_DEFAULT . -.Pp -.Dv PTHREAD_MUTEX_NORMAL -mutexes do not check for usage errors. -.Dv PTHREAD_MUTEX_NORMAL -mutexes will deadlock if reentered, and result in undefined behavior if a -locked mutex is unlocked by another thread. Attempts to unlock an already -unlocked -.Dv PTHREAD_MUTEX_NORMAL -mutex will result in undefined behavior. -.Pp -.Dv PTHREAD_MUTEX_ERRORCHECK -mutexes do check for usage errors. -If an attempt is made to relock a -.Dv PTHREAD_MUTEX_ERRORCHECK -mutex without first dropping the lock, an error will be returned. -If a thread attempts to unlock a -.Dv PTHREAD_MUTEX_ERRORCHECK -mutex that is locked by another thread, an error will be returned. If a -thread attempts to unlock a -.Dv PTHREAD_MUTEX_ERRORCHECK -thread that is unlocked, an error will be returned. -.Pp -.Dv PTHREAD_MUTEX_RECURSIVE -mutexes allow recursive locking. -An attempt to relock a -.Dv PTHREAD_MUTEX_RECURSIVE -mutex that is already locked by the same thread succeeds. An equivalent -number of -.Xr pthread_mutex_unlock 3 -calls are needed before the mutex will wake another thread waiting on this -lock. If a thread attempts to unlock a -.Dv PTHREAD_MUTEX_RECURSIVE -mutex that is locked by another thread, an error will be returned. If a thread attemps to unlock a -.Dv PTHREAD_MUTEX_RECURSIVE -thread that is unlocked, an error will be returned. -.Pp -.Dv PTHREAD_MUTEX_DEFAULT -mutexes result in undefined behavior if reentered. -Unlocking a -.Dv PTHREAD_MUTEX_DEFAULT -mutex locked by another thread will result in undefined behavior. Attempts to unlock an already -unlocked -.Dv PTHREAD_MUTEX_DEFAULT -mutex will result in undefined behavior. -.Pp -.Fn pthread_mutexattr_gettype -functions copy the type value of the attribute to the location pointed to by the second parameter. -.Pp -The -.Fn pthread_mutexattr_set* -functions set the attribute that corresponds to each function name. -.Pp -The -.Fn pthread_mutexattr_get* -functions copy the value of the attribute that corresponds to each function name -to the location pointed to by the second function parameter. -.Sh RETURN VALUES -If successful, these functions return 0. -Otherwise, an error number is returned to indicate the error. -.Sh ERRORS -.Fn pthread_mutexattr_init -will fail if: -.Bl -tag -width Er -.It Bq Er ENOMEM -Out of memory. -.El -.Pp -.Fn pthread_mutexattr_destroy -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Fn pthread_mutexattr_setprioceiling -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Fa attr , -or invalid value for -.Fa prioceiling . -.El -.Pp -.Fn pthread_mutexattr_getprioceiling -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Fn pthread_mutexattr_setprotocol -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Fa attr , -or invalid value for -.Fa protocol . -.El -.Pp -.Fn pthread_mutexattr_getprotocol -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Pp -.Fn pthread_mutexattr_settype -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Fa attr , -or invalid value for -.Fa type . -.El -.Pp -.Fn pthread_mutexattr_gettype -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Invalid value for -.Fa attr . -.El -.Sh SEE ALSO -.Xr pthread_mutex_init 3 -.Sh STANDARDS -.Fn pthread_mutexattr_init -and -.Fn pthread_mutexattr_destroy -conform to -.St -p1003.1-96 -.Pp -.Fn pthread_mutexattr_setprioceiling , -.Fn pthread_mutexattr_getprioceiling , -.Fn pthread_mutexattr_setprotocol , -.Fn pthread_mutexattr_getprotocol , -.Fn pthread_mutexattr_settype , -and -.Fn pthread_mutexattr_gettype -conform to -.St -susv2 diff --git a/src/libc/pthreads/pthread_once.3 b/src/libc/pthreads/pthread_once.3 deleted file mode 100644 index 1a843202e..000000000 --- a/src/libc/pthreads/pthread_once.3 +++ /dev/null @@ -1,102 +0,0 @@ -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_once.3,v 1.6.2.6 2001/08/17 15:42:52 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_ONCE 3 -.Os -.Sh NAME -.Nm pthread_once -.Nd dynamic package initialization -.Sh SYNOPSIS -.Fd #include -.Pp -pthread_once_t -.Fa once_control -= PTHREAD_ONCE_INIT; -.Ft int -.Fn pthread_once "pthread_once_t *once_control" "void (*init_routine)(void)" -.Sh DESCRIPTION -The first call to -.Fn pthread_once -by any thread in a process, with a given -.Fa once_control , -will call the -.Fn init_routine -with no arguments. -Subsequent calls to -.Fn pthread_once -with the same -.Fa once_control -will not call the -.Fn init_routine . -On return from -.Fn pthread_once , -it is guaranteed that -.Fn init_routine -has completed. -The -.Fa once_control -parameter is used to determine whether the associated initialization -routine has been called. -.Pp -The function -.Fn pthread_once -is not a cancellation point. -However, if -.Fn init_routine -is a cancellation point and is cancelled, the effect on -.Fa once_control is as if -.Fn pthread_once -was never called. -.Pp -The constant -.Fa PTHREAD_ONCE_INIT -is defined by header -.Aq Pa pthread.h . -.Pp -The behavior of -.Fn pthread_once -is undefined if -.Fa once_control -has automatic storage duration or is not initialized by -.Fa PTHREAD_ONCE_INIT . -.Sh RETURN VALUES -If successful, the -.Fn pthread_once -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -None. -.Sh STANDARDS -.Fn pthread_once -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_rwlock.c b/src/libc/pthreads/pthread_rwlock.c deleted file mode 100644 index 75c6a39db..000000000 --- a/src/libc/pthreads/pthread_rwlock.c +++ /dev/null @@ -1,1880 +0,0 @@ -/* - * Copyright (c) 2000-2003, 2007, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/*- - * Copyright (c) 1998 Alex Nash - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/lib/libc_r/uthread/uthread_rwlock.c,v 1.6 2001/04/10 04:19:20 deischen Exp $ - */ - -/* - * POSIX Pthread Library - * -- Read Write Lock support - * 4/24/02: A. Ramesh - * Ported from FreeBSD - */ - -#include "pthread_internals.h" -#include /* For printf(). */ - -extern int __unix_conforming; - -#ifdef PLOCKSTAT -#include "plockstat.h" -#else /* !PLOCKSTAT */ -#define PLOCKSTAT_RW_ERROR(x, y, z) -#define PLOCKSTAT_RW_BLOCK(x, y) -#define PLOCKSTAT_RW_BLOCKED(x, y, z) -#define PLOCKSTAT_RW_ACQUIRE(x, y) -#define PLOCKSTAT_RW_RELEASE(x, y) -#endif /* PLOCKSTAT */ - -#define READ_LOCK_PLOCKSTAT 0 -#define WRITE_LOCK_PLOCKSTAT 1 - -#define BLOCK_FAIL_PLOCKSTAT 0 -#define BLOCK_SUCCESS_PLOCKSTAT 1 - -/* maximum number of times a read lock may be obtained */ -#define MAX_READ_LOCKS (INT_MAX - 1) - - -#ifndef BUILDING_VARIANT /* [ */ -__private_extern__ int usenew_impl = 1; -#else /* BUILDING_VARIANT */ -extern int usenew_impl; -#endif /* BUILDING_VARIANT */ - -extern int PR_5243343_flag; - -#if defined(__LP64__) -#define RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr) \ -{ \ - if (rwlock->misalign != 0) { \ - lcntaddr = &rwlock->rw_seq[1]; \ - seqaddr = &rwlock->rw_seq[2]; \ - ucntaddr = &rwlock->rw_seq[3]; \ - } else { \ - lcntaddr = &rwlock->rw_seq[0]; \ - seqaddr = &rwlock->rw_seq[1]; \ - ucntaddr = &rwlock->rw_seq[2]; \ - } \ -} -#else /* __LP64__ */ -#define RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr) \ -{ \ - if (rwlock->misalign != 0) { \ - lcntaddr = &rwlock->rw_seq[1]; \ - seqaddr = &rwlock->rw_seq[2]; \ - ucntaddr = &rwlock->rw_seq[3]; \ - } else { \ - lcntaddr = &rwlock->rw_seq[0]; \ - seqaddr = &rwlock->rw_seq[1]; \ - ucntaddr = &rwlock->rw_seq[2]; \ - } \ -} -#endif /* __LP64__ */ - -__private_extern__ int __pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); - - -#define _KSYN_TRACE_ 0 - -#if _KSYN_TRACE_ -#include -#ifndef BUILDING_VARIANT /* [ */ -static void set_enable(int); -#endif /* !BUILDING_VARIANT ] */ - -/* The Function qualifiers */ -#define DBG_FUNC_START 1 -#define DBG_FUNC_END 2 -#define DBG_FUNC_NONE 0 - -int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); - -#define _KSYN_TRACE_RW_RDLOCK 0x9000080 -#define _KSYN_TRACE_RW_WRLOCK 0x9000084 -#define _KSYN_TRACE_RW_UNLOCK 0x9000088 -#define _KSYN_TRACE_RW_UNACT1 0x900808c -#define _KSYN_TRACE_RW_UNACT2 0x9008090 -#define _KSYN_TRACE_RW_UNACTK 0x9008094 -#define _KSYN_TRACE_RW_UNACTE 0x9008098 -#define _KSYN_TRACE_RW_UNACTR 0x900809c -#define _KSYN_TRACE_RW_TOOMANY 0x90080a0 -#define _KSYN_TRACE_RW_TRYWRLOCK 0x90080a4 -#define _KSYN_TRACE_RW_TRYRDLOCK 0x90080a8 -#endif /* _KSYN_TRACE_ */ - -__private_extern__ void rwlock_action_onreturn(pthread_rwlock_t * rwlock, uint32_t updateval); -__private_extern__ int rw_diffgenseq(uint32_t x, uint32_t y); - -#ifndef BUILDING_VARIANT /* [ */ -static uint32_t modbits(uint32_t lgenval, uint32_t updateval, uint32_t savebits); - -int -pthread_rwlockattr_init(pthread_rwlockattr_t *attr) -{ - attr->sig = _PTHREAD_RWLOCK_ATTR_SIG; - attr->pshared = _PTHREAD_DEFAULT_PSHARED; - return (0); -} - -int -pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr) -{ - attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */ - attr->pshared = 0; - return (0); -} - -int -pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, - int *pshared) -{ - if (attr->sig == _PTHREAD_RWLOCK_ATTR_SIG) - { - *pshared = (int)attr->pshared; - return (0); - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } -} - - -int -pthread_rwlockattr_setpshared(pthread_rwlockattr_t * attr, int pshared) -{ - if (attr->sig == _PTHREAD_RWLOCK_ATTR_SIG) - { -#if __DARWIN_UNIX03 - if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED)) -#else /* __DARWIN_UNIX03 */ - if ( pshared == PTHREAD_PROCESS_PRIVATE) -#endif /* __DARWIN_UNIX03 */ - { - attr->pshared = pshared ; - return (0); - } else - { - return (EINVAL); /* Invalid parameter */ - } - } else - { - return (EINVAL); /* Not an initialized 'attribute' structure */ - } - -} - -__private_extern__ int -__pthread_rwlock_init(pthread_rwlock_t * orwlock, const pthread_rwlockattr_t *attr) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - - if ((attr != NULL) && (attr->pshared == PTHREAD_PROCESS_SHARED)) { - rwlock->pshared = PTHREAD_PROCESS_SHARED; - rwlock->rw_flags = PTHRW_KERN_PROCESS_SHARED; - } else { - rwlock->pshared = _PTHREAD_DEFAULT_PSHARED; - rwlock->rw_flags = PTHRW_KERN_PROCESS_PRIVATE; - } - - if (((uintptr_t)rwlock & 0x07) != 0) { - rwlock->misalign = 1; -#if defined(__LP64__) - rwlock->rw_lcntaddr = &rwlock->rw_seq[1]; - rwlock->rw_seqaddr = &rwlock->rw_seq[2]; - rwlock->rw_ucntaddr = &rwlock->rw_seq[3]; - rwlock->rw_seq[1]= PTHRW_RWLOCK_INIT; - rwlock->rw_seq[2]= PTHRW_RWS_INIT; - rwlock->rw_seq[3]= 0; -#else /* __LP64__ */ - rwlock->rw_lcntaddr = &rwlock->rw_seq[1]; - rwlock->rw_seqaddr = &rwlock->rw_seq[2]; - rwlock->rw_ucntaddr = &rwlock->rw_seq[3]; - rwlock->rw_seq[1]= PTHRW_RWLOCK_INIT; - rwlock->rw_seq[2]= PTHRW_RWS_INIT; - rwlock->rw_seq[3]= 0; -#endif /* __LP64__ */ - - } else { - rwlock->misalign = 0; -#if defined(__LP64__) - rwlock->rw_lcntaddr = &rwlock->rw_seq[0]; - rwlock->rw_seqaddr = &rwlock->rw_seq[1]; - rwlock->rw_ucntaddr = &rwlock->rw_seq[2]; - rwlock->rw_seq[0]= PTHRW_RWLOCK_INIT; - rwlock->rw_seq[1]= PTHRW_RWS_INIT; - rwlock->rw_seq[2]= 0; -#else /* __LP64__ */ - rwlock->rw_lcntaddr = &rwlock->rw_seq[0]; - rwlock->rw_seqaddr = &rwlock->rw_seq[1]; - rwlock->rw_ucntaddr = &rwlock->rw_seq[2]; - rwlock->rw_seq[0]= PTHRW_RWLOCK_INIT; - rwlock->rw_seq[1]= PTHRW_RWS_INIT; - rwlock->rw_seq[2]= 0; -#endif /* __LP64__ */ - - } - - rwlock->reserv = 0; - rwlock->rw_owner = NULL; -#if defined(__LP64__) - memset(rwlock->rfu, 0, PTHRW_RFU_64BIT); -#else - memset(rwlock->rfu, 0, PTHRW_RFU_32BIT); -#endif - - rwlock->sig = _PTHREAD_RWLOCK_SIG; - - return(0); -} - -#if _KSYN_TRACE_ -static void -set_enable(int val) -{ - int mib[6]; - size_t needed = 0; - - mib[0] = CTL_KERN; - mib[1] = KERN_KDEBUG; - mib[2] = KERN_KDENABLE; - mib[3] = val; - mib[4] = 0; - mib[5] = 0; - /* best effort to stop the trace */ - (void)sysctl(mib, 4, NULL, &needed, NULL, 0); -} -#endif - -static uint32_t -modbits(uint32_t lgenval, uint32_t updateval, uint32_t savebits) -{ - uint32_t lval = lgenval & PTHRW_BIT_MASK; - uint32_t uval = updateval & PTHRW_BIT_MASK; - uint32_t rval, nlval; - - nlval = (lval | uval) & ~(PTH_RWL_MBIT); - - /* reconcile bits on the lock with what kernel needs to set */ - if ((uval & PTH_RWL_LBIT) != 0) - nlval &= ~PTH_RWL_KBIT; - else if (((uval & PTH_RWL_KBIT) == 0) && ((lval & PTH_RWL_WBIT) == 0)) - nlval &= ~PTH_RWL_KBIT; - - if (savebits !=0 ) { - if (((savebits & PTH_RWS_WSVBIT) != 0) && ((nlval & PTH_RWL_WBIT) == 0) && - ((nlval & PTH_RWL_EBIT) == 0)) { - if ((nlval & PTH_RWL_LBIT) == 0) - nlval |= (PTH_RWL_WBIT | PTH_RWL_KBIT); - else - nlval |= PTH_RWL_WBIT; - } - if (((savebits & PTH_RWS_YSVBIT) != 0) && ((nlval & PTH_RWL_YBIT) == 0) && - ((nlval & PTH_RWL_EBIT) == 0)) { - nlval |= PTH_RWL_YBIT; - } - if (((savebits & PTH_RWS_USVBIT) != 0) && ((nlval & PTH_RWL_EBIT) == 0)) { - if ((nlval & PTH_RWL_LBIT) == 0) - nlval |= (PTH_RWL_UBIT | PTH_RWL_KBIT); - else - nlval |= PTH_RWL_UBIT; - } - } - rval = (lgenval & PTHRW_COUNT_MASK) | nlval; - return(rval); -} - - -__private_extern__ void -rwlock_action_onreturn(pthread_rwlock_t * orwlock, uint32_t updateval) -{ - - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lcntval, rw_seq, newval = 0, newsval, lval, uval; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - uint64_t oldval64, newval64; - int setbits = 0; - int overlap = 0; - uint32_t savebits = 0; - int isoverlap = 0; - - /* TBD: restore U bit */ - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_START, updateval, 0, 0, 0, 0); -#endif - - isoverlap = updateval & PTH_RWL_MBIT; - -loop: - setbits = 0; - lcntval = *lcntaddr; - rw_seq = *seqaddr; - savebits = 0; - - if (isoverlap != 0) { - /* overlap return, just increment and inspect bits */ - setbits = 1; - overlap = 1; - /* set s word, increment by specified value */ - newsval = rw_seq + (updateval & PTHRW_COUNT_MASK); - if ((newsval & PTHRW_RWS_SAVEMASK) != 0) { - savebits = newsval & PTHRW_RWS_SAVEMASK; - newsval &= ~PTHRW_RWS_SAVEMASK; - } - } else { - /* normal return */ - if (is_rws_setunlockinit(rw_seq) != 0) { - setbits = 1; - /* set s word to passed in value */ - newsval = (rw_seq & PTHRW_COUNT_MASK) + (updateval & PTHRW_COUNT_MASK); - if ((rw_seq & PTHRW_RWS_SAVEMASK) != 0) { - savebits = rw_seq & PTHRW_RWS_SAVEMASK; - newsval &= ~PTHRW_RWS_SAVEMASK; - } - } else { - newval = lcntval; - newsval = rw_seq; - } - } - if (setbits != 0) { - newval = modbits(lcntval, updateval, savebits); - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_NONE, rw_seq, newsval, 0xeeeeeeee, updateval, 0); - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_NONE, lcntval, newval, 0xeeeeeeee, updateval, 0); -#endif - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; - /* Check for consistency */ - lval = lcntval & PTHRW_BIT_MASK; - uval = updateval & PTHRW_BIT_MASK; - } - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_END, rw_seq, newsval, 0xffffffff, 0, 0); -#endif - return; -} - -/* returns are not bit shifted */ -__private_extern__ int -rw_diffgenseq(uint32_t x, uint32_t y) -{ - uint32_t lx = (x & PTHRW_COUNT_MASK); - uint32_t ly = (y &PTHRW_COUNT_MASK); - - if (lx > ly) { - return(lx-ly); - } else { - return((PTHRW_MAX_READERS - y) + lx + PTHRW_INC); - } - -} - -#ifdef NOTYET -/********************************************************** */ -static int pthread_rwlock_upgrade_internal(pthread_rwlock_t * orwlock, int trylock); - -int -pthread_rwlock_longrdlock_np(pthread_rwlock_t * orwlock) -{ - pthread_t self; - uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; - int error = 0, retry_count = 0; - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint64_t oldval64, newval64; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - uint64_t myid = 0; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); - return(error); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } - UNLOCK(rwlock->lock); - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -loop: - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; - - if (can_rwl_longreadinuser(lcntval)) - goto gotlock; - -#if __DARWIN_UNIX03 - if (is_rwl_ebit_set(lcntval)) { - self = pthread_self(); - if(rwlock->rw_owner == self) { - error = EDEADLK; - goto out; - } - } -#endif /* __DARWIN_UNIX03 */ - - /* need to block in kernel */ - newval = (lcntval + PTHRW_INC); - - newsval = rw_seq; - if (is_rws_setseq(rw_seq)) { - newsval &= PTHRW_SW_Reset_BIT_MASK; - newsval |= (newval & PTHRW_COUNT_MASK); - } - - /* update lock seq and block in kernel */ - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)(newsval)) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; -kblock: - updateval = __psynch_rw_longrdlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags); - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - if (error == EINTR) - goto kblock; - - if (error == 0) { - rwlock_action_onreturn(orwlock, updateval); - if ( is_rwl_lbit_clear(updateval)) { -#if _KSYN_TRACE_ - set_enable(2); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("yieldwrlock from kernel without EBit %x: tid %x\n", updateval, (uint32_t)myid); - /* kernel cannot wakeup without granting E bit */ - } - goto successout; - } else { -#if _KSYN_TRACE_ - set_enable(2); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("yieldwrlock from kernel with unknown error %x: tid %x\n", updateval, (uint32_t)myid); - goto out; - } - -gotlock: - if (rw_diffgenseq(lcntval, ucntval) >= PTHRW_MAX_READERS) { - /* since ucntval may be newer, just redo */ - retry_count++; - if (retry_count > 1024) { - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_TOOMANY | DBG_FUNC_NONE, (uint32_t)rwlock, 0XEEEEEEEE, lcntval, ucntval, 0); -#endif - error = EAGAIN; - goto out; - } else { - sched_yield(); - goto loop; - } - } - - /* Need to update L and S word */ - newval = (lcntval + PTHRW_INC) | PTH_RWL_LBIT; - newsval = (rw_seq + PTHRW_INC); - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; - -successout: - PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); - return(0); -out: - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); - return(error); -} - -int -pthread_rwlock_yieldwrlock_np(pthread_rwlock_t * orwlock) -{ - uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; - int error = 0; -#if __DARWIN_UNIX03 - pthread_t self = pthread_self(); -#endif /* __DARWIN_UNIX03 */ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint64_t oldval64, newval64; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - uint64_t myid = 0; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); - return(error); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } - UNLOCK(rwlock->lock); - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -loop: - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; - -#if __DARWIN_UNIX03 - if (is_rwl_ebit_set(lcntval)) { - if (rwlock->rw_owner == self) { - error = EDEADLK; - goto out; - } - } -#endif /* __DARWIN_UNIX03 */ - - if (lcntval == PTHRW_RWL_INIT) { - /* if we can acquire set L and S word */ - lcntval = PTHRW_RWL_INIT; - newval = PTHRW_RWL_INIT | PTHRW_INC | PTH_RWL_KBIT| PTH_RWL_EBIT; - newsval = rw_seq + PTHRW_INC; - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) == TRUE) { - goto gotit; - } else - goto loop; - } - - newval = (lcntval + PTHRW_INC)| PTH_RWL_YBIT; - - newsval = rw_seq; - if (is_rws_setseq(rw_seq)) { - newsval &= PTHRW_SW_Reset_BIT_MASK; - newsval |= (newval & PTHRW_COUNT_MASK); - } - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)(newsval)) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; - - PLOCKSTAT_RW_BLOCK(orwlock, WRITE_LOCK_PLOCKSTAT); -retry: - updateval = __psynch_rw_yieldwrlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags); - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - if (error == EINTR) - goto retry; - - - PLOCKSTAT_RW_BLOCKED(orwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); - if (error != 0) { -#if _KSYN_TRACE_ - set_enable(2); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("yieldwrlock from kernel with unknown error %x: tid %x\n", updateval, (uint32_t)myid); - } - - -out: - if (error == 0) { -gotit: - rwlock_action_onreturn(orwlock, updateval); - if ( is_rwl_ebit_clear(updateval)) { -#if _KSYN_TRACE_ - set_enable(2); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("yieldwrlock from kernel without EBit %x: tid %x\n", updateval, (uint32_t)myid); - } -#if __DARWIN_UNIX03 - rwlock->rw_owner = self; -#endif /* __DARWIN_UNIX03 */ - PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); - return(0); - } else { - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); - return(error); - } -} -int -pthread_rwlock_downgrade_np(pthread_rwlock_t * orwlock) -{ - uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; - int error = 0, haswbit = 0, hasubit = 0, hasybit = 0; -#if __DARWIN_UNIX03 - pthread_t self = pthread_self(); -#endif /* __DARWIN_UNIX03 */ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint64_t oldval64, newval64; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - uint64_t myid = 0; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); - return(error); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } - UNLOCK(rwlock->lock); - } - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -loop: - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; - - - /* if not holding exclusive lock, return */ - if ((is_rwl_ebit_set(lcntval )== 0) || (rwlock->rw_owner != self)) { - return(EINVAL); - } - - /* no other waiters and be granted in user space? ? */ - if ((lcntval & PTHRW_COUNT_MASK) == (ucntval + PTHRW_INC)) { -#if 0 - /* should have no write waiters pending */ - if (is_rwl_wbit_set(lcntval) != 0) { -#if _KSYN_TRACE_ - set_enable(2); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("downgrade in user mode but W bit set %x: tid %x\n", lcntval, (uint32_t)myid); - } -#endif - /* preserve count and remove ke bits */ - newval = lcntval & ~(PTH_RWL_EBIT | PTH_RWL_KBIT); - /* if we can acquire set L and S word */ - newsval = rw_seq; - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) == TRUE) { -#if __DARWIN_UNIX03 - rwlock->rw_owner = (pthread_t)0; -#endif /* __DARWIN_UNIX03 */ - return(0); - } else - goto loop; - } else { - - haswbit = lcntval & PTH_RWL_WBIT; - hasubit = lcntval & PTH_RWL_UBIT; - hasybit = lcntval & PTH_RWL_YBIT; - - /* reset all bits and set k */ - newval = (lcntval & PTHRW_COUNT_MASK) | PTH_RWL_KBIT; - /* set I bit on S word */ - newsval = rw_seq | PTH_RWS_IBIT; - if (haswbit != 0) - newsval |= PTH_RWS_WSVBIT; - if (hasubit != 0) - newsval |= PTH_RWS_USVBIT; - if (hasybit != 0) - newsval |= PTH_RWS_YSVBIT; - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; - -#if __DARWIN_UNIX03 - rwlock->rw_owner = 0; -#endif /* __DARWIN_UNIX03 */ - -retry: - updateval = __psynch_rw_downgrade(orwlock, newval, ucntval, newsval, rwlock->rw_flags); - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - /* TBD: what to do with the error, EINTR ?? */ - if (error == EINTR) - goto retry; - - if (error == 0) { - rwlock_action_onreturn(orwlock, updateval); - return(0); - } else { -#if _KSYN_TRACE_ - set_enable(1); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("downgrade from kernel with unknown error %x with tid %x\n", updateval, (uint32_t)myid); - } - /* Not reached */ - } - return(EINVAL); -} - -int -pthread_rwlock_upgrade_np(pthread_rwlock_t * orwlock) -{ - return(pthread_rwlock_upgrade_internal(orwlock, 0)); -} - -int -pthread_rwlock_tryupgrade_np(pthread_rwlock_t *orwlock) -{ - return(pthread_rwlock_upgrade_internal(orwlock, 1)); -} - -static int -pthread_rwlock_upgrade_internal(pthread_rwlock_t * orwlock, int trylock) -{ - uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; - int error = 0, flags ; -#if __DARWIN_UNIX03 - pthread_t self = pthread_self(); -#endif /* __DARWIN_UNIX03 */ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint64_t oldval64, newval64; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - uint64_t myid = 0; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - /* check for static initialization */ - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - return(error); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - return(EINVAL); - } - UNLOCK(rwlock->lock); - } - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -loop: - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; - - if (is_rwl_eubit_set(lcntval) !=0) { - return(EBUSY); - } - - /* set U and K bit and go to kernel */ - newval = (lcntval | (PTH_RWL_UBIT | PTH_RWL_KBIT)); - newsval = rw_seq; -#if 0 - if (is_rws_setseq(rw_seq)) { - newsval &= PTHRW_SW_Reset_BIT_MASK; - newsval |= (newval & PTHRW_COUNT_MASK); - } -#endif - - /* update lock seq and block in kernel */ - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)(newsval)) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; - flags = rwlock->rw_flags; - if (trylock != 0) { - flags |= _PTHREAD_RWLOCK_UPGRADE_TRY; - } -retry: - updateval = __psynch_rw_upgrade(orwlock, newval, ucntval, newsval, rwlock->rw_flags); - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - if (error == EINTR) - goto retry; - - - if (error == 0) { - rwlock_action_onreturn(orwlock, updateval); - if ( is_rwl_ebit_clear(updateval)) { -#if _KSYN_TRACE_ - set_enable(2); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("upgrade from kernel without EBit %x: tid %x\n", updateval, (uint32_t)myid); - } -#if __DARWIN_UNIX03 - rwlock->rw_owner = self; -#endif /* __DARWIN_UNIX03 */ - return(0); - } else { - if (trylock != 0) { - return (EBUSY); - } - } - - return(error); -} - -/* Returns true if the rwlock is held for reading by any thread or held for writing by the current thread */ -int -pthread_rwlock_held_np(pthread_rwlock_t * orwlock) -{ - uint32_t lcntval, ucntval, rw_seq; - int error = 0; - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - return(0); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - return(-1); - } - UNLOCK(rwlock->lock); - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; - - if ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK)) - return(0); - - return(1); -} - -/* Returns true if the rwlock is held for reading by any thread */ -int -pthread_rwlock_rdheld_np(pthread_rwlock_t * orwlock) -{ - uint32_t lcntval, ucntval, rw_seq; - int error = 0; - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - return(0); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - return(-1); - } - UNLOCK(rwlock->lock); - } - - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; - - if ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK)) - return(0); - - if (is_rwl_ebit_set(lcntval) !=0) { - return(0); - } - return(1); -} - -/* Returns true if the rwlock is held for writing by the current thread */ -int -pthread_rwlock_wrheld_np(pthread_rwlock_t * orwlock) -{ - uint32_t lcntval, ucntval, rw_seq; - pthread_t self = pthread_self(); - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - int error = 0; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - return(0); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - return(-1); - } - UNLOCK(rwlock->lock); - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; - - if ((is_rwl_ebit_set(lcntval)) && (rwlock->rw_owner == self)) { - return(1); - } - return(0); -} -/******************************************************/ -#endif /* NOTYET */ - - -#endif /* !BUILDING_VARIANT ] */ - -int -pthread_rwlock_destroy(pthread_rwlock_t *orwlock) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; -#if __DARWIN_UNIX03 - uint32_t rw_lcnt, rw_ucnt; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; -#endif /* __DARWIN_UNIX03 */ - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG && rwlock->sig != _PTHREAD_RWLOCK_SIG_init) - return(EINVAL); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG) { -#if __DARWIN_UNIX03 - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - - rw_lcnt = *lcntaddr; - rw_ucnt = *ucntaddr; - - if((rw_lcnt & PTHRW_COUNT_MASK) != rw_ucnt) - return(EBUSY); - -#endif /* __DARWIN_UNIX03 */ - //bzero(rwlock, sizeof(npthread_rwlock_t)); - rwlock->sig = _PTHREAD_NO_SIG; - return(0); - } else if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - rwlock->sig = _PTHREAD_NO_SIG; - return(0); - } else - return(EINVAL); -} - - -int -pthread_rwlock_init(pthread_rwlock_t * orwlock, const pthread_rwlockattr_t *attr) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; -#if __DARWIN_UNIX03 - uint32_t rw_lcnt, rw_ucnt; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; -#endif /* __DARWIN_UNIX03 */ - -#if __DARWIN_UNIX03 - if (attr && (attr->sig != _PTHREAD_RWLOCK_ATTR_SIG)) { - return(EINVAL); - } - - if (rwlock->sig == _PTHREAD_RWLOCK_SIG) { - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - - rw_lcnt = *lcntaddr; - rw_ucnt = *ucntaddr; - - if ((rw_lcnt & PTHRW_COUNT_MASK) != rw_ucnt) - return(EBUSY); - - } -#endif - LOCK_INIT(rwlock->lock); - return(__pthread_rwlock_init(orwlock, attr)); - -} - -int -pthread_rwlock_rdlock(pthread_rwlock_t * orwlock) -{ -#if __DARWIN_UNIX03 - pthread_t self; -#endif /* __DARWIN_UNIX03 */ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; - int error = 0, retry_count = 0; - uint64_t oldval64, newval64; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - uint64_t myid = 0; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); - return(error); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } - UNLOCK(rwlock->lock); - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); -#endif -loop: - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lcntval, (ucntval | 0xee), rw_seq, 0); -#endif - - /* if l bit is on or u and k bit is clear, acquire lock in userland */ - if (can_rwl_readinuser(lcntval)) - goto gotlock; - -#if __DARWIN_UNIX03 - if (is_rwl_ebit_set(lcntval)) { - self = pthread_self(); - if(rwlock->rw_owner == self) { - error = EDEADLK; - goto out; - } - } -#endif /* __DARWIN_UNIX03 */ - - - /* Need to block in kernel , remove Rbit */ - newval = (lcntval + PTHRW_INC) & PTH_RWLOCK_RESET_RBIT; - - newsval = rw_seq; - if (is_rws_setseq(rw_seq)) { - newsval &= PTHRW_SW_Reset_BIT_MASK; - newsval |= (newval & PTHRW_COUNT_MASK); - } - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; - - /* give writers priority over readers */ - PLOCKSTAT_RW_BLOCK(orwlock, READ_LOCK_PLOCKSTAT); - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lcntval, newval, newsval, 0); -#endif - -retry: - updateval = __psynch_rw_rdlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags); - - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - if (error == EINTR) - goto retry; - - if (error == 0) { - rwlock_action_onreturn(orwlock, updateval); - PLOCKSTAT_RW_BLOCKED(orwlock, READ_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); - PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); - return(0); - } else { - PLOCKSTAT_RW_BLOCKED(orwlock, READ_LOCK_PLOCKSTAT, BLOCK_FAIL_PLOCKSTAT); -#if _KSYN_TRACE_ - set_enable(1); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("rdlock from kernel with unknown error %x with tid %x\n", updateval, (uint32_t)myid); - goto out; - } - /* Not reached */ - -gotlock: - if (rw_diffgenseq(lcntval, ucntval) >= PTHRW_MAX_READERS) { - /* since ucntval may be newer, just redo */ - retry_count++; - if (retry_count > 1024) { - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_TOOMANY | DBG_FUNC_NONE, (uint32_t)rwlock, 0XEEEEEEEE, lcntval, ucntval, 0); -#endif - error = EAGAIN; - goto out; - } else { - sched_yield(); - goto loop; - } - } - - /* Need to update L (remove R bit) and S word */ - newval = (lcntval + PTHRW_INC) & PTH_RWLOCK_RESET_RBIT; - newsval = (rw_seq + PTHRW_INC); - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lcntval, newval, 0); -#endif - - PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, 0, 0, 0); -#endif - return(0); -out: - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); -#endif - return(error); -} - -int -pthread_rwlock_tryrdlock(pthread_rwlock_t * orwlock) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lcntval, ucntval, rw_seq, newval, newsval; - int error = 0, retry_count = 0; - uint64_t oldval64, newval64; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); - return(error); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } - UNLOCK(rwlock->lock); - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -loop: - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_TRYRDLOCK | DBG_FUNC_START, (uint32_t)rwlock, lcntval, ucntval, rw_seq, 0); -#endif - - /* if l bit is on or u and k bit is clear, acquire lock in userland */ - if (can_rwl_readinuser(lcntval)) - goto gotlock; - - error = EBUSY; - goto out; - -gotlock: - if (rw_diffgenseq(lcntval, ucntval) >= PTHRW_MAX_READERS) { - /* since ucntval may be newer, just redo */ - retry_count++; - if (retry_count > 1024) { - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_TOOMANY | DBG_FUNC_NONE, (uint32_t)rwlock, 0XEEEEEEEE, lcntval, ucntval, 0); -#endif - error = EAGAIN; - goto out; - } else { - sched_yield(); - goto loop; - } - } - - /* Need to update L(remove Rbit ) and S word */ - newval = (lcntval + PTHRW_INC) & PTH_RWLOCK_RESET_RBIT; - newsval = (rw_seq + PTHRW_INC); - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_TRYRDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lcntval, newval, 0); -#endif - - PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT); - return(0); - -out: - PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error); -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_TRYRDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, error, 0, 0); -#endif - return(error); -} - -int -pthread_rwlock_trywrlock(pthread_rwlock_t * orwlock) -{ -#if __DARWIN_UNIX03 - pthread_t self = pthread_self(); -#endif /* __DARWIN_UNIX03 */ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lcntval, rw_seq, newval, newsval; - int error = 0, gotlock = 0; - uint64_t oldval64, newval64; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); - return(error); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } - UNLOCK(rwlock->lock); - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_TRYWRLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); -#endif -loop: - lcntval = *lcntaddr; - rw_seq = *seqaddr; - - /* can we acquire in userland? */ - if ((lcntval & PTH_RWL_RBIT) != 0) { - newval = ((lcntval + PTHRW_INC) & PTHRW_COUNT_MASK) | PTH_RWL_IBIT | PTH_RWL_KBIT| PTH_RWL_EBIT; - newsval = rw_seq + PTHRW_INC; - gotlock = 1; - } else - gotlock = 0; - - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - if (gotlock != 0) { - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - } else - newval64 = oldval64; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) { - goto loop; - } - if (gotlock == 1) { -#if __DARWIN_UNIX03 - rwlock->rw_owner = self; -#endif /* __DARWIN_UNIX03 */ - PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_TRYWRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0, 0, 0, 0); -#endif - return(0); - } else { -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_TRYWRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, EBUSY, 0, 0); -#endif - - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EBUSY); - return(EBUSY); - } -} - -int -pthread_rwlock_wrlock(pthread_rwlock_t * orwlock) -{ -#if __DARWIN_UNIX03 - pthread_t self = pthread_self(); -#endif /* __DARWIN_UNIX03 */ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval; - int error = 0, gotlock = 0; - uint64_t oldval64, newval64; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - uint64_t myid = 0; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); - return(error); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL); - return(EINVAL); - } - UNLOCK(rwlock->lock); - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); -#endif -loop: - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lcntval, ucntval, rw_seq, 0); -#endif - -#if __DARWIN_UNIX03 - if (is_rwl_ebit_set(lcntval)) { - if(rwlock->rw_owner == self) { - error = EDEADLK; - goto out; - } - } -#endif /* __DARWIN_UNIX03 */ - - - if ((lcntval & PTH_RWL_RBIT) != 0) { - /* lock is restart state, writer can acquire the lock */ - newval = ((lcntval + PTHRW_INC) & PTHRW_COUNT_MASK) | PTH_RWL_IBIT | PTH_RWL_KBIT| PTH_RWL_EBIT; - - newsval = rw_seq + PTHRW_INC; - gotlock = 1; - - } else { - if (is_rwl_lbit_set(lcntval)) - newval = (lcntval + PTHRW_INC)| PTH_RWL_WBIT; - else - newval = (lcntval + PTHRW_INC) | PTH_RWL_KBIT| PTH_RWL_WBIT; - - newsval = rw_seq; - if (is_rws_setseq(rw_seq)) { - newsval &= PTHRW_SW_Reset_BIT_MASK; - newsval |= (newval & PTHRW_COUNT_MASK); - } - gotlock = 0; - } - - /* update lock seq */ - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lcntval, newval, 0); -#endif - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto loop; - - /* lock acquired in userland itself? */ - if (gotlock != 0) - goto gotit; - - /* unable to acquire in userland, transition to kernel */ - - PLOCKSTAT_RW_BLOCK(orwlock, WRITE_LOCK_PLOCKSTAT); -retry: - updateval = __psynch_rw_wrlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags); - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - if (error == EINTR) { - goto retry; - } - - if (error != 0) { -#if _KSYN_TRACE_ - set_enable(2); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("wrlock from kernel with unknown error %x: tid %x\n", updateval, (uint32_t)myid); - } - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x33333333, newval, updateval, 0); -#endif - PLOCKSTAT_RW_BLOCKED(orwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT); - if (error == 0) { - rwlock_action_onreturn(orwlock, updateval); -gotit: -#if __DARWIN_UNIX03 - rwlock->rw_owner = self; -#endif /* __DARWIN_UNIX03 */ - PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT); -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); -#endif - return(0); - } -#if __DARWIN_UNIX03 -out: -#endif /* __DARWIN_UNIX03 */ - PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error); -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); -#endif - return(error); -} - - -int -pthread_rwlock_unlock(pthread_rwlock_t * orwlock) -{ - npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock; - uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval, ulval; - int error = 0, wrlock = 0, haswbit = 0, hasubit = 0, hasybit = 0; - uint64_t oldval64, newval64; - volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr; - uint64_t myid = 0; - - if (rwlock->sig != _PTHREAD_RWLOCK_SIG) { - LOCK(rwlock->lock); - if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) { - if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) { - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, wrlock, error); - return(error); - } - } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){ - UNLOCK(rwlock->lock); - PLOCKSTAT_RW_ERROR(orwlock, wrlock, EINVAL); - return(EINVAL); - } - UNLOCK(rwlock->lock); - } - - if (rwlock->pshared == PTHREAD_PROCESS_SHARED) { - RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr); - } else { - lcntaddr = rwlock->rw_lcntaddr; - ucntaddr = rwlock->rw_ucntaddr; - seqaddr = rwlock->rw_seqaddr; - } - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0); -#endif -loop: - lcntval = *lcntaddr; - ucntval = *ucntaddr; - rw_seq = *seqaddr; - - - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x51515151, lcntval, ucntval, 0); - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x51515151, rw_seq, 0, 0); -#endif - /* check for spurious unlocks */ - if ((lcntval & PTH_RWL_RBIT) != 0) { - newval = lcntval ; - newsval = rw_seq; - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) == TRUE) { - /* spurious unlock, return */ - error = EINVAL; -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x1a1b1c1d, lcntval, ucntval, 0); -#endif - goto succout; - } else - goto loop; - } - - if (is_rwl_ebit_set(lcntval)) { - wrlock = 1; -#if __DARWIN_UNIX03 - rwlock->rw_owner = (pthread_t)0; -#endif /* __DARWIN_UNIX03 */ - } - - /* update U */ - - ulval = (ucntval + PTHRW_INC); - - if (OSAtomicCompareAndSwap32Barrier(ucntval, ulval, (volatile int32_t *)ucntaddr) != TRUE) - goto loop; - -lp11: - /* just validate the l and S values */ - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = oldval64; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) { - lcntval = *lcntaddr; - rw_seq = *seqaddr; - goto lp11; - } - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xd1d2d3d4, lcntval, rw_seq, 0); - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xd1d2d3d4, ulval, 0, 0); -#endif - - /* last unlock, note U is already updated ? */ - if((lcntval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) { - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xbbbbbbbb, lcntval, ucntval, 0); -#endif - /* Set L with R and init bits and set S to L */ - newval = (lcntval & PTHRW_COUNT_MASK)| PTHRW_RWLOCK_INIT; - newsval = (lcntval & PTHRW_COUNT_MASK)| PTHRW_RWS_INIT; - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) { -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xcccccccc, 0, 0, 0); -#endif - lcntval = *lcntaddr; - rw_seq = *seqaddr; - goto lp11; - } -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xdddddddd, lcntval, ucntval, 0); -#endif - goto succout; - } - - /* if it is not exclusive or no Writer/yield pending, skip */ - if ((lcntval & (PTH_RWL_EBIT | PTH_RWL_WBIT | PTH_RWL_YBIT | PTH_RWL_KBIT)) == 0) { - goto succout; - } - - /* kernel transition needed? */ - /* U+1 == S? */ - if ((ulval + PTHRW_INC) != (rw_seq & PTHRW_COUNT_MASK)) { - if ((lcntval & PTH_RWL_UBIT) != 0) { - /* if U bit is set U + 2 == S ? */ - if ((ulval + PTHRW_INC + PTHRW_INC) != (rw_seq & PTHRW_COUNT_MASK)) - goto succout; - } else - goto succout; - } - - haswbit = lcntval & PTH_RWL_WBIT; - hasubit = lcntval & PTH_RWL_UBIT; - hasybit = lcntval & PTH_RWL_YBIT; - - /* reset all bits and set k */ - newval = (lcntval & PTHRW_COUNT_MASK) | PTH_RWL_KBIT; - /* set I bit on S word */ - newsval = rw_seq | PTH_RWS_IBIT; - if (haswbit != 0) - newsval |= PTH_RWS_WSVBIT; - if (hasubit != 0) - newsval |= PTH_RWS_USVBIT; - if (hasybit != 0) - newsval |= PTH_RWS_YSVBIT; - - oldval64 = (((uint64_t)rw_seq) << 32); - oldval64 |= lcntval; - - newval64 = (((uint64_t)newsval) << 32); - newval64 |= newval; - - if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) - goto lp11; - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555511, 1, ulval, 0); -#endif - updateval = __psynch_rw_unlock(orwlock, lcntval, ulval, newsval, rwlock->rw_flags); - if (updateval == (uint32_t)-1) { - error = errno; - } else - error = 0; - - if(error != 0) { - - /* not sure what is the scenario */ - if(error != EINTR) { -#if _KSYN_TRACE_ - set_enable(4); -#endif /* _KSYN_TRACE_ */ - (void)pthread_threadid_np(pthread_self(), &myid); - LIBC_ABORT("rwunlock from kernel with unknown error %x: tid %x\n", error, (uint32_t)myid); - goto succout; - } - error = 0; - } - -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555522, 3, lcntval, 0); -#endif - -succout: - PLOCKSTAT_RW_RELEASE(orwlock, wrlock); -#if _KSYN_TRACE_ - if (__pthread_lock_debug != 0) - (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0); -#endif - return(0); -} - diff --git a/src/libc/pthreads/pthread_rwlock_destroy.3 b/src/libc/pthreads/pthread_rwlock_destroy.3 deleted file mode 100644 index 47beb62ed..000000000 --- a/src/libc/pthreads/pthread_rwlock_destroy.3 +++ /dev/null @@ -1,82 +0,0 @@ -.\" Copyright (c) 1998 Alex Nash -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_destroy.3,v 1.6 2001/10/01 16:09:09 ru Exp $ -.\" -.Dd August 4, 1998 -.Dt PTHREAD_RWLOCK_DESTROY 3 -.Os -.Sh NAME -.Nm pthread_rwlock_destroy -.Nd destroy a read/write lock -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_rwlock_destroy -.Fa "pthread_rwlock_t *rwlock" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_rwlock_destroy -function is used to destroy a read/write lock previously created with -.Fn pthread_rwlock_init . -.Sh RETURN VALUES -If successful, the -.Fn pthread_rwlock_destroy -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh SEE ALSO -.Xr pthread_rwlock_init 3 -.Sh STANDARDS -The -.Fn pthread_rwlock_destroy -function is expected to conform to -.St -susv2 . -.Sh ERRORS -The -.Fn pthread_rwlock_destroy -function will fail if: -.Bl -tag -width Er -.It Bq Er EPERM -The caller does not have the privilege to perform the operation. -.El -.Pp -The -.Fn pthread_rwlock_destroy -function may fail if: -.Bl -tag -width Er -.It Bq Er EBUSY -The system has detected an attempt to destroy the object referenced by -.Fa rwlock -while it is locked. -.It Bq Er EINVAL -The value specified by -.Fa rwlock -is invalid. -.El -.Sh HISTORY -The -.Fn pthread_rwlock_destroy -function first appeared in -.Fx 3.0 . diff --git a/src/libc/pthreads/pthread_rwlock_init.3 b/src/libc/pthreads/pthread_rwlock_init.3 deleted file mode 100644 index 507317ac6..000000000 --- a/src/libc/pthreads/pthread_rwlock_init.3 +++ /dev/null @@ -1,102 +0,0 @@ -.\" Copyright (c) 1998 Alex Nash -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_init.3,v 1.5 2001/10/01 16:09:09 ru Exp $ -.\" -.Dd August 4, 1998 -.Dt PTHREAD_RWLOCK_INIT 3 -.Os -.Sh NAME -.Nm pthread_rwlock_init -.Nd initialize a read/write lock -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_rwlock_init -.Fa "pthread_rwlock_t *restrict rwlock" -.Fa "const pthread_rwlockattr_t *restrict attr" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_rwlock_init -function is used to initialize a read/write lock, with attributes -specified by -.Fa attr . -If -.Fa attr -is NULL, the default read/write lock attributes are used. -.Pp -The results of calling -.Fn pthread_rwlock_init -with an already initialized lock are undefined. -.Sh RETURN VALUES -If successful, the -.Fn pthread_rwlock_init -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh SEE ALSO -.Xr pthread_rwlock_destroy 3 , -.Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 -.Sh STANDARDS -The -.Fn pthread_rwlock_init -function is expected to conform to -.St -susv2 . -.Sh ERRORS -The -.Fn pthread_rwlock_init -function will fail if: -.Bl -tag -width Er -.It Bq Er EAGAIN -The system lacked the necessary resources (other than memory) to -initialize the lock. -.It Bq Er ENOMEM -Insufficient memory exists to initialize the lock. -.It Bq Er EPERM -The caller does not have sufficient privilege to perform the -operation. -.El -.Pp -The -.Fn pthread_rwlock_init -function may fail if: -.Bl -tag -width Er -.It Bq Er EBUSY -The system has detected an attempt to re-initialize the object -referenced by -.Fa rwlock , -a previously initialized but not yet destroyed read/write lock. -.It Bq Er EINVAL -The value specified by -.Fa attr -is invalid. -.El -.Sh HISTORY -The -.Fn pthread_rwlock_init -function first appeared in -.Fx 3.0 . -.Sh BUGS -The PTHREAD_PROCESS_SHARED attribute is not supported. diff --git a/src/libc/pthreads/pthread_rwlock_rdlock.3 b/src/libc/pthreads/pthread_rwlock_rdlock.3 deleted file mode 100644 index 815da8c55..000000000 --- a/src/libc/pthreads/pthread_rwlock_rdlock.3 +++ /dev/null @@ -1,126 +0,0 @@ -.\" Copyright (c) 1998 Alex Nash -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_rdlock.3,v 1.4 2001/10/01 16:09:09 ru Exp $ -.\" -.Dd August 4, 1998 -.Dt PTHREAD_RWLOCK_RDLOCK 3 -.Os -.Sh NAME -.Nm pthread_rwlock_rdlock , -.Nm pthread_rwlock_tryrdlock -.Nd acquire a read/write lock for reading -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_rwlock_rdlock -.Fa "pthread_rwlock_t *rwlock" -.Fc -.Ft int -.Fo pthread_rwlock_tryrdlock -.Fa "pthread_rwlock_t *rwlock" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_rwlock_rdlock -function acquires a read lock on -.Fa rwlock , -provided that -.Fa rwlock -is not presently held for writing and no writer threads are -presently blocked on the lock. If the read lock cannot be -immediately acquired, the calling thread blocks until it can -acquire the lock. -.Pp -The -.Fn pthread_rwlock_tryrdlock -function performs the same action, but does not block if the lock -cannot be immediately obtained (i.e., the lock is held for writing -or there are waiting writers). -.Pp -A thread may hold multiple concurrent read locks. If so, -.Fn pthread_rwlock_unlock -must be called once for each lock obtained. -.Pp -The results of acquiring a read lock while the calling thread holds -a write lock are undefined. -.Sh IMPLEMENTATION NOTES -To prevent writer starvation, writers are favored over readers. -.Sh RETURN VALUES -If successful, the -.Fn pthread_rwlock_rdlock -and -.Fn pthread_rwlock_tryrdlock -functions will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh SEE ALSO -.Xr pthread_rwlock_init 3 , -.Xr pthread_rwlock_trywrlock 3 , -.Xr pthread_rwlock_unlock 3 , -.Xr pthread_rwlock_wrlock 3 -.Sh STANDARDS -The -.Fn pthread_rwlock_rdlock -and -.Fn pthread_rwlock_tryrdlock -functions are expected to conform to -.St -susv2 . -.Sh ERRORS -The -.Fn pthread_rwlock_tryrdlock -function will fail if: -.Bl -tag -width Er -.It Bq Er EBUSY -The lock could not be acquired, because a writer holds the lock or -was blocked on it. -.El -.Pp -The -.Fn pthread_rwlock_rdlock -and -.Fn pthread_rwlock_tryrdlock -functions may fail if: -.Bl -tag -width Er -.It Bq Er EAGAIN -The lock could not be acquired, because the maximum number of read locks -against -.Fa lock -has been exceeded. -.It Bq Er EDEADLK -The current thread already owns -.Fa rwlock -for writing. -.It Bq Er EINVAL -The value specified by -.Fa rwlock -is invalid. -.It Bq Er ENOMEM -Insufficient memory exists to initialize the lock (applies to -statically initialized locks only). -.El -.Sh HISTORY -The -.Fn pthread_rwlock_rdlock -function first appeared in -.Fx 3.0 . diff --git a/src/libc/pthreads/pthread_rwlock_unlock.3 b/src/libc/pthreads/pthread_rwlock_unlock.3 deleted file mode 100644 index def7aaf6a..000000000 --- a/src/libc/pthreads/pthread_rwlock_unlock.3 +++ /dev/null @@ -1,81 +0,0 @@ -.\" Copyright (c) 1998 Alex Nash -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_unlock.3,v 1.4 2001/10/01 16:09:09 ru Exp $ -.\" -.Dd August 4, 1998 -.Dt PTHREAD_RWLOCK_UNLOCK 3 -.Os -.Sh NAME -.Nm pthread_rwlock_unlock -.Nd release a read/write lock -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_rwlock_unlock -.Fa "pthread_rwlock_t *rwlock" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_rwlock_unlock -function is used to release the read/write lock previously obtained by -.Fn pthread_rwlock_rdlock , -.Fn pthread_rwlock_wrlock , -.Fn pthread_rwlock_tryrdlock , -or -.Fn pthread_rwlock_trywrlock . -.Sh RETURN VALUES -If successful, the -.Fn pthread_rwlock_unlock -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Pp -The results are undefined if -.Fa rwlock -is not held by the calling thread. -.Sh SEE ALSO -.Xr pthread_rwlock_rdlock 3 , -.Xr pthread_rwlock_wrlock 3 -.Sh STANDARDS -The -.Fn pthread_rwlock_unlock -function is expected to conform to -.St -susv2 . -.Sh ERRORS -The -.Fn pthread_rwlock_unlock -function may fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa rwlock -is invalid. -.It Bq Er EPERM -The current thread does not own the read/write lock. -.El -.Sh HISTORY -The -.Fn pthread_rwlock_unlock -function first appeared in -.Fx 3.0 . diff --git a/src/libc/pthreads/pthread_rwlock_wrlock.3 b/src/libc/pthreads/pthread_rwlock_wrlock.3 deleted file mode 100644 index 5906e4b94..000000000 --- a/src/libc/pthreads/pthread_rwlock_wrlock.3 +++ /dev/null @@ -1,106 +0,0 @@ -.\" Copyright (c) 1998 Alex Nash -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_wrlock.3,v 1.4 2001/10/01 16:09:09 ru Exp $ -.\" -.Dd August 4, 1998 -.Dt PTHREAD_RWLOCK_WRLOCK 3 -.Os -.Sh NAME -.Nm pthread_rwlock_trywrlock , -.Nm pthread_rwlock_wrlock -.Nd acquire a read/write lock for writing -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_rwlock_trywrlock -.Fa "pthread_rwlock_t *rwlock" -.Fc -.Ft int -.Fo pthread_rwlock_wrlock -.Fa "pthread_rwlock_t *rwlock" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_rwlock_wrlock -function blocks until a write lock can be acquired against -.Fa rwlock . -The -.Fn pthread_rwlock_trywrlock -function performs the same action, but does not block if the lock -cannot be immediately obtained. -.Pp -The results are undefined if the calling thread already holds the -lock at the time the call is made. -.Sh IMPLEMENTATION NOTES -To prevent writer starvation, writers are favored over readers. -.Sh RETURN VALUES -If successful, the -.Fn pthread_rwlock_wrlock -and -.Fn pthread_rwlock_trywrlock -functions will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh SEE ALSO -.Xr pthread_rwlock_trywrlock 3 , -.Xr pthread_rwlock_unlock 3 , -.Xr pthread_rwlock_wrlock 3 -.Sh STANDARDS -The -.Fn pthread_rwlock_wrlock -and -.Fn pthread_rwlock_trywrlock -functions are expected to conform to -.St -susv2 . -.Sh ERRORS -The -.Fn pthread_rwlock_trywrlock -function will fail if: -.Bl -tag -width Er -.It Bq Er EBUSY -The calling thread is not able to acquire the lock without blocking. -.El -.Pp -The -.Fn pthread_rwlock_wrlock -and -.Fn pthread_rwlock_trywrlock -functions may fail if: -.Bl -tag -width Er -.It Bq Er EDEADLK -The calling thread already owns the read/write lock (for reading -or writing). -.It Bq Er EINVAL -The value specified by -.Fa rwlock -is invalid. -.It Bq Er ENOMEM -Insufficient memory exists to initialize the lock (applies to -statically initialized locks only). -.El -.Sh HISTORY -The -.Fn pthread_rwlock_wrlock -function first appeared in -.Fx 3.0 . diff --git a/src/libc/pthreads/pthread_rwlockattr_destroy.3 b/src/libc/pthreads/pthread_rwlockattr_destroy.3 deleted file mode 100644 index 3d4522856..000000000 --- a/src/libc/pthreads/pthread_rwlockattr_destroy.3 +++ /dev/null @@ -1,70 +0,0 @@ -.\" Copyright (c) 1998 Alex Nash -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlockattr_destroy.3,v 1.6 2001/10/01 16:09:09 ru Exp $ -.\" -.Dd August 4, 1998 -.Dt PTHREAD_RWLOCKATTR_DESTROY 3 -.Os -.Sh NAME -.Nm pthread_rwlockattr_destroy -.Nd destroy a read/write lock -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_rwlockattr_destroy -.Fa "pthread_rwlockattr_t *attr" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_rwlockattr_destroy -function is used to destroy a read/write lock attribute object, -previously created with -.Fn pthread_rwlockattr_init . -.Sh RETURN VALUES -If successful, the -.Fn pthread_rwlockattr_destroy -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh SEE ALSO -.Xr pthread_rwlockattr_init 3 -.Sh STANDARDS -The -.Fn pthread_rwlockattr_destroy -function is expected to conform to -.St -susv2 . -.Sh ERRORS -.Fn pthread_rwlockattr_destroy -may fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa attr -is invalid. -.El -.Sh HISTORY -The -.Fn pthread_rwlockattr_destroy -function first appeared in -.Fx 3.0 . diff --git a/src/libc/pthreads/pthread_rwlockattr_getpshared.3 b/src/libc/pthreads/pthread_rwlockattr_getpshared.3 deleted file mode 100644 index 61dcc733a..000000000 --- a/src/libc/pthreads/pthread_rwlockattr_getpshared.3 +++ /dev/null @@ -1,83 +0,0 @@ -.\" Copyright (c) 1998 Alex Nash -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlockattr_getpshared.3,v 1.8 2001/10/01 16:09:09 ru Exp $ -.\" -.Dd March 22, 1999 -.Dt PTHREAD_RWLOCKATTR_GETPSHARED 3 -.Os -.Sh NAME -.Nm pthread_rwlockattr_getpshared -.Nd get the process shared attribute -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_rwlockattr_getpshared -.Fa "const pthread_rwlockattr_t *restrict attr" -.Fa "int *restrict pshared" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_rwlockattr_getpshared -function is used to get the process-shared setting of a read/write -lock attribute object. The setting is returned via -.Fa pshared , -and may be one of two values: -.Bl -tag -width PTHREAD_PROCESS_PRIVATE -.It Dv PTHREAD_PROCESS_SHARED -Any thread of any process that has access to the memory where the -read/write lock resides can manipulate the lock. -.It Dv PTHREAD_PROCESS_PRIVATE -Only threads created within the same process as the thread that -initialized the read/write lock can manipulate the lock. This is -the default value. -.El -.Sh RETURN VALUES -If successful, the -.Fn pthread_rwlockattr_getpshared -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh SEE ALSO -.Xr pthread_rwlock_init 3 , -.Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 -.Sh STANDARDS -The -.Fn pthread_rwlockattr_getpshared -function is expected to conform to -.St -susv2 . -.Sh ERRORS -.Fn pthread_rwlockattr_getpshared -may fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa attr -is invalid. -.El -.Sh HISTORY -The -.Fn pthread_rwlockattr_getpshared -function first appeared in -.Fx 3.0 . diff --git a/src/libc/pthreads/pthread_rwlockattr_init.3 b/src/libc/pthreads/pthread_rwlockattr_init.3 deleted file mode 100644 index 1d75a3cbe..000000000 --- a/src/libc/pthreads/pthread_rwlockattr_init.3 +++ /dev/null @@ -1,69 +0,0 @@ -.\" Copyright (c) 1998 Alex Nash -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlockattr_init.3,v 1.6 2001/10/01 16:09:09 ru Exp $ -.\" -.Dd August 4, 1998 -.Dt PTHREAD_RWLOCKATTR_INIT 3 -.Os -.Sh NAME -.Nm pthread_rwlockattr_init -.Nd initialize a read/write lock -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_rwlockattr_init -.Fa "pthread_rwlockattr_t *attr" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_rwlockattr_init -function is used to initialize a read/write lock attribute object. -.Sh RETURN VALUES -If successful, the -.Fn pthread_rwlockattr_init -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh SEE ALSO -.Xr pthread_rwlock_init 3 , -.Xr pthread_rwlockattr_destroy 3 , -.Xr pthread_rwlockattr_getpshared 3 , -.Xr pthread_rwlockattr_setpshared 3 -.Sh STANDARDS -The -.Fn pthread_rwlockattr_init -function is expected to conform to -.St -susv2 . -.Sh ERRORS -.Fn pthread_rwlockattr_init -will fail if: -.Bl -tag -width Er -.It Bq Er ENOMEM -Insufficient memory exists to initialize the attribute object. -.El -.Sh HISTORY -The -.Fn pthread_rwlockattr_init -function first appeared in -.Fx 3.0 . diff --git a/src/libc/pthreads/pthread_rwlockattr_setpshared.3 b/src/libc/pthreads/pthread_rwlockattr_setpshared.3 deleted file mode 100644 index d8702b9ff..000000000 --- a/src/libc/pthreads/pthread_rwlockattr_setpshared.3 +++ /dev/null @@ -1,91 +0,0 @@ -.\" Copyright (c) 1998 Alex Nash -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlockattr_setpshared.3,v 1.7 2001/10/01 16:09:09 ru Exp $ -.\" -.Dd August 4, 1998 -.Dt PTHREAD_RWLOCKATTR_SETPSHARED 3 -.Os -.Sh NAME -.Nm pthread_rwlockattr_setpshared -.Nd set the process shared attribute -.Sh SYNOPSIS -.In pthread.h -.Ft int -.Fo pthread_rwlockattr_setpshared -.Fa "pthread_rwlockattr_t *attr" -.Fa "int pshared" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_rwlockattr_setpshared -function sets the process-shared attribute of -.Fa attr -to the value referenced by -.Fa pshared . -.Fa pshared -may be one of two values: -.Bl -tag -width PTHREAD_PROCESS_PRIVATE -.It Dv PTHREAD_PROCESS_SHARED -Any thread of any process that has access to the memory where the -read/write lock resides can manipulate the lock. -.It Dv PTHREAD_PROCESS_PRIVATE -Only threads created within the same process as the thread that -initialized the read/write lock can manipulate the lock. This is -the default value. -.El -.Sh RETURN VALUES -If successful, the -.Fn pthread_rwlockattr_setpshared -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh SEE ALSO -.Xr pthread_rwlock_init 3 , -.Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 -.Sh STANDARDS -The -.Fn pthread_rwlockattr_setpshared -function is expected to conform to -.St -susv2 . -.Sh ERRORS -.Fn pthread_rwlockattr_setpshared -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The value specified by -.Fa attr -or -.Fa pshared -is invalid. -.El -.Sh HISTORY -The -.Fn pthread_rwlockattr_setpshared -function first appeared in -.Fx 3.0 . -.Sh BUGS -The -.Dv PTHREAD_PROCESS_SHARED -attribute is not supported. diff --git a/src/libc/pthreads/pthread_self.3 b/src/libc/pthreads/pthread_self.3 deleted file mode 100644 index d7c2bcd54..000000000 --- a/src/libc/pthreads/pthread_self.3 +++ /dev/null @@ -1,59 +0,0 @@ -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_self.3,v 1.4.2.4 2001/08/17 15:42:52 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_SELF 3 -.Os -.Sh NAME -.Nm pthread_self -.Nd get the calling thread's ID -.Sh SYNOPSIS -.Fd #include -.Ft pthread_t -.Fn pthread_self "void" -.Sh DESCRIPTION -The -.Fn pthread_self -function returns the thread ID of the calling thread. -.Sh RETURN VALUES -The -.Fn pthread_self -function returns the thread ID of the calling thread. -.Sh ERRORS -None. -.Sh SEE ALSO -.Xr pthread_create 3 , -.Xr pthread_equal 3 -.Sh STANDARDS -.Fn pthread_self -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_setcancelstate.3 b/src/libc/pthreads/pthread_setcancelstate.3 deleted file mode 100644 index f8f5ba04d..000000000 --- a/src/libc/pthreads/pthread_setcancelstate.3 +++ /dev/null @@ -1,207 +0,0 @@ -.\" $FreeBSD: src/lib/libc_r/man/pthread_testcancel.3,v 1.2.2.3 2001/08/17 15:42:52 ru Exp $ -.Dd January 17, 1999 -.Dt PTHREAD_TESTCANCEL 3 -.Os -.Sh NAME -.Nm pthread_setcancelstate , -.Nm pthread_setcanceltype , -.Nm pthread_testcancel -.Nd set cancelability state -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_setcancelstate -.Fa "int state" -.Fa "int *oldstate" -.Fc -.Ft int -.Fo pthread_setcanceltype -.Fa "int type" -.Fa "int *oldtype" -.Fc -.Ft void -.Fo pthread_testcancel -.Fa "void" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_setcancelstate -function atomically both sets the calling thread's cancelability state -to the indicated -.Fa state -and returns the previous cancelability state at the location referenced by -.Fa oldstate . -Legal values for -.Fa state -are -.Dv PTHREAD_CANCEL_ENABLE -and -.Dv PTHREAD_CANCEL_DISABLE . -.Pp -The -.Fn pthread_setcanceltype -function atomically both sets the calling thread's cancelability type -to the indicated -.Fa type -and returns the previous cancelability type at the location referenced by -.Fa oldtype . -Legal values for -.Fa type -are -.Dv PTHREAD_CANCEL_DEFERRED -and -.Dv PTHREAD_CANCEL_ASYNCHRONOUS . -.Pp -The cancelability state and type of any newly created threads, including the -thread in which -.Fn main -was first invoked, are -.Dv PTHREAD_CANCEL_ENABLE -and -.Dv PTHREAD_CANCEL_DEFERRED -respectively. -.Pp -The -.Fn pthread_testcancel -function creates a cancellation point in the calling thread. -The -.Fn pthread_testcancel -function has no effect if cancelability is disabled. -.Pp -.Ss Cancelability States -The cancelability state of a thread determines the action taken upon -receipt of a cancellation request. -The thread may control cancellation in -a number of ways. -.Pp -Each thread maintains its own -.Dq cancelability state -which may be encoded in two bits: -.Bl -hang -.It Em Cancelability Enable -When cancelability is -.Dv PTHREAD_CANCEL_DISABLE , -cancellation requests against the target thread are held pending. -.It Em Cancelability Type -When cancelability is enabled and the cancelability type is -.Dv PTHREAD_CANCEL_ASYNCHRONOUS , -new or pending cancellation requests may be acted upon at any time. -When cancelability is enabled and the cancelability type is -.Dv PTHREAD_CANCEL_DEFERRED , -cancellation requests are held pending until a cancellation point (see -below) is reached. -If cancelability is disabled, the setting of the -cancelability type has no immediate effect as all cancellation requests -are held pending; however, once cancelability is enabled again the new -type will be in effect. -.El -.Ss Cancellation Points -Cancellation points will occur when a thread is executing the following -functions: -.Fn close , -.Fn creat , -.Fn fcntl , -.Fn fsync , -.Fn msync , -.Fn nanosleep , -.Fn open , -.Fn pause , -.Fn pthread_cond_timedwait , -.Fn pthread_cond_wait , -.Fn pthread_join , -.Fn pthread_testcancel , -.Fn read , -.Fn sigwaitinfo , -.Fn sigsuspend , -.Fn sigwait , -.Fn sleep , -.Fn system , -.Fn tcdrain , -.Fn wait , -.Fn waitpid , -.Fn write . -.Sh RETURN VALUES -If successful, the -.Fn pthread_setcancelstate -and -.Fn pthread_setcanceltype -functions will return zero. -Otherwise, an error number shall be returned to -indicate the error. -.Pp -The -.Fn pthread_setcancelstate -and -.Fn pthread_setcanceltype -functions are used to control the points at which a thread may be -asynchronously canceled. -For cancellation control to be usable in modular -fashion, some rules must be followed. -.Pp -For purposes of this discussion, consider an object to be a generalization -of a procedure. -It is a set of procedures and global variables written as -a unit and called by clients not known by the object. -Objects may depend -on other objects. -.Pp -First, cancelability should only be disabled on entry to an object, never -explicitly enabled. -On exit from an object, the cancelability state should -always be restored to its value on entry to the object. -.Pp -This follows from a modularity argument: if the client of an object (or the -client of an object that uses that object) has disabled cancelability, it is -because the client doesn't want to have to worry about how to clean up if the -thread is canceled while executing some sequence of actions. -If an object -is called in such a state and it enables cancelability and a cancellation -request is pending for that thread, then the thread will be canceled, -contrary to the wish of the client that disabled. -.Pp -Second, the cancelability type may be explicitly set to either -.Em deferred -or -.Em asynchronous -upon entry to an object. -But, as with the cancelability state, on exit from -an object that cancelability type should always be restored to its value on -entry to the object. -.Pp -Finally, only functions that are cancel-safe may be called from a thread that -is asynchronously cancelable. -.Sh ERRORS -The function -.Fn pthread_setcancelstate -may fail with: -.Bl -tag -width Er -.It Bq Er EINVAL -The specified state is not -.Dv PTHREAD_CANCEL_ENABLE -or -.Dv PTHREAD_CANCEL_DISABLE . -.El -.Pp -The function -.Fn pthread_setcanceltype -may fail with: -.Bl -tag -width Er -.It Bq Er EINVAL -The specified state is not -.Dv PTHREAD_CANCEL_DEFERRED -or -.Dv PTHREAD_CANCEL_ASYNCHRONOUS . -.El -.Sh SEE ALSO -.Xr pthread_cancel 3 -.Sh STANDARDS -.Fn pthread_testcancel -conforms to -.St -p1003.1-96 . -.Sh AUTHORS -This man page was written by -.An David Leonard Aq d@openbsd.org -for the -.Ox -implementation of -.Xr pthread_cancel 3 . diff --git a/src/libc/pthreads/pthread_setspecific.3 b/src/libc/pthreads/pthread_setspecific.3 deleted file mode 100644 index 96104b49e..000000000 --- a/src/libc/pthreads/pthread_setspecific.3 +++ /dev/null @@ -1,95 +0,0 @@ -.\" Copyright (c) 1996 John Birrell . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by John Birrell. -.\" 4. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_setspecific.3,v 1.6.2.4 2001/08/17 15:42:52 ru Exp $ -.\" -.Dd April 4, 1996 -.Dt PTHREAD_SETSPECIFIC 3 -.Os -.Sh NAME -.Nm pthread_setspecific -.Nd set a thread-specific data value -.Sh SYNOPSIS -.Fd #include -.Ft int -.Fo pthread_setspecific -.Fa "pthread_key_t key" -.Fa "const void *value" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_setspecific -function associates a thread-specific value with a -.Fa key -obtained via a previous call to -.Fn pthread_key_create . -Different threads may bind different values to the same key. -These values are -typically pointers to blocks of dynamically allocated memory that have been -reserved for use by the calling thread. -.Pp -The effect of calling -.Fn pthread_setspecific -with a key value not obtained from -.Fn pthread_key_create , -or after -.Fa key -has been deleted with -.Fn pthread_key_delete , -is undefined. -.Pp -.Fn pthread_setspecific -may be called from a thread-specific data destructor function; -however, this may result in lost storage or infinite loops. -.Sh RETURN VALUES -If successful, the -.Fn pthread_setspecific -function will return zero. -Otherwise, an error number will be returned to indicate the error. -.Sh ERRORS -.Fn pthread_setspecific -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The -.Fa key -value is invalid. -.It Bq Er ENOMEM -Insufficient memory exists to associate the value with the -.Fa key . -.El -.Sh SEE ALSO -.Xr pthread_getspecific 3 , -.Xr pthread_key_create 3 , -.Xr pthread_key_delete 3 -.Sh STANDARDS -.Fn pthread_setspecific -conforms to -.St -p1003.1-96 . diff --git a/src/libc/pthreads/pthread_spinlock.h b/src/libc/pthreads/pthread_spinlock.h deleted file mode 100644 index 40fa601aa..000000000 --- a/src/libc/pthreads/pthread_spinlock.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * POSIX Threads - IEEE 1003.1c - */ - -#ifndef _POSIX_PTHREAD_SPINLOCK_H -#define _POSIX_PTHREAD_SPINLOCK_H - -#include -#define __APPLE_API_PRIVATE -#include - -#ifndef __POSIX_LIB__ -#define __POSIX_LIB__ -#endif - -#include "pthread_machdep.h" /* Machine-dependent definitions. */ - -/* Number of times to spin when the lock is unavailable and we are on a - multiprocessor. On a uniprocessor we yield the processor immediately. */ -#define MP_SPIN_TRIES 1000 -extern int _spin_tries; -extern int __is_threaded; - -/* Internal mutex locks for data structures */ -#define TRY_LOCK(v) (!__is_threaded || _spin_lock_try((pthread_lock_t *)&(v))) - -/* _DO_SPINLOCK_LOCK() takes a (pthread_lock_t *) */ -#define _DO_SPINLOCK_LOCK(v) _spin_lock(v) - -/* _DO_SPINLOCK_UNLOCK() takes a (pthread_lock_t *) */ -#define _DO_SPINLOCK_UNLOCK(v) _spin_unlock(v) - -/* LOCK() takes a (pthread_lock_t) */ -#define LOCK(v) \ - do { \ - if (__is_threaded) { \ - _DO_SPINLOCK_LOCK((pthread_lock_t *)&(v)); \ - } \ - } while (0) - -/* UNLOCK() takes a (pthread_lock_t) */ -#define UNLOCK(v) \ - do { \ - if (__is_threaded) { \ - _DO_SPINLOCK_UNLOCK((pthread_lock_t *)&(v)); \ - } \ - } while (0) - -/* Prototypes. */ - -/* Functions defined in machine-dependent files. */ -extern void _spin_lock(pthread_lock_t *lockp); -extern int _spin_lock_try(pthread_lock_t *lockp); -extern void _spin_unlock(pthread_lock_t *lockp); - -#endif /* _POSIX_PTHREAD_SPINLOCK_H */ diff --git a/src/libc/pthreads/pthread_spis.h b/src/libc/pthreads/pthread_spis.h deleted file mode 100644 index a9b365963..000000000 --- a/src/libc/pthreads/pthread_spis.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2000-2011 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * Extension SPIs. - */ - -#ifndef _PTHREAD_SPIS_H -#define _PTHREAD_SPIS_H - - -#include - -__BEGIN_DECLS - -#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE) -/* firstfit */ -#define PTHREAD_FIRSTFIT_MUTEX_INITIALIZER {_PTHREAD_FIRSTFIT_MUTEX_SIG_init, {0}} -/* - * Mutex attributes - */ -#define _PTHREAD_MUTEX_POLICY_NONE 0 -#define _PTHREAD_MUTEX_POLICY_FAIRSHARE 1 -#define _PTHREAD_MUTEX_POLICY_FIRSTFIT 2 - -/* sets the mutex policy attributes */ -int pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *, int ); - -#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */ - -__END_DECLS - -#endif /* _PTHREAD_SPIS_H */ diff --git a/src/libc/pthreads/pthread_tsd.c b/src/libc/pthreads/pthread_tsd.c deleted file mode 100644 index b801c9c4b..000000000 --- a/src/libc/pthreads/pthread_tsd.c +++ /dev/null @@ -1,256 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * POSIX Pthread Library - * Thread Specific Data support - * NB: pthread_getspecific() is in a separate assembly file - */ - -#include "pthread_internals.h" - -static struct -{ - int created; /* Set TRUE if 'create_key' used this slot */ - void (*destructor)(void *); -} _pthread_keys[_INTERNAL_POSIX_THREAD_KEYS_END]; -static pthread_lock_t tds_lock = LOCK_INITIALIZER; - -/* - * Partition _pthread_keys in a lower part that dyld can use, and an upper - * part for libSystem. The libSystem part starts at __pthread_tsd_first = 4. - * dyld will set this value to 1. - * LEFT OVER TILL DYLD changes to using static (1-3) numbers - */ - -#ifdef DYLD_STATIC_LIBC_BUILD -__private_extern__ int __pthread_tsd_first = 1; -__private_extern__ int __pthread_tsd_start = 5; -__private_extern__ int __pthread_tsd_end = 10; -__private_extern__ int __pthread_tsd_max = 10; -#else -__private_extern__ int __pthread_tsd_first = 10; -__private_extern__ int __pthread_tsd_start = _INTERNAL_POSIX_THREAD_KEYS_MAX; -__private_extern__ int __pthread_tsd_end = _INTERNAL_POSIX_THREAD_KEYS_END; -__private_extern__ int __pthread_tsd_max = 10; -#endif -/* - * Create a new key for thread specific data - */ -int -pthread_key_create(pthread_key_t *key, - void (*destructor)(void *)) -{ - int res, i; - LOCK(tds_lock); - res = EAGAIN; /* No 'free' keys, return EAGAIN (as per standard) */ - /* The first slot is reserved for pthread_self() */ - for (i = __pthread_tsd_start; i < __pthread_tsd_end; i++) - { - if (_pthread_keys[i].created == FALSE) - { - _pthread_keys[i].created = TRUE; - _pthread_keys[i].destructor = destructor; - *key = i; - res = 0; - break; - } - } - UNLOCK(tds_lock); - return (res); -} - -/* - * Destroy a thread specific data key - */ -int -pthread_key_delete(pthread_key_t key) -{ - int res; - LOCK(tds_lock); - /* The first slot is reserved for pthread_self() */ - if ((key >= __pthread_tsd_start) && (key < __pthread_tsd_end)) - { - if (_pthread_keys[key].created) - { - struct _pthread * p; - - _pthread_keys[key].created = FALSE; - LOCK(_pthread_list_lock); - TAILQ_FOREACH(p, &__pthread_head, plist) { - /* It is an 32bit value no lock needed */ - p->tsd[key] = 0; - } - UNLOCK(_pthread_list_lock); - res = 0; - } else - { - res = EINVAL; - } - } else - { /* Invalid key */ - res = EINVAL; - } - UNLOCK(tds_lock); - return (res); -} - -/* - * Set the thread private value for a given key. - * We do not take the spinlock for this or pthread_getspecific. - * The assignment to self->tsd[] is thread-safe because we never - * refer to the tsd[] of a thread other than pthread_self(). - * The reference to _pthread_keys[...].created could race with a - * pthread_key_delete() but in this case the behaviour is allowed - * to be undefined. - */ -int -pthread_setspecific(pthread_key_t key, - const void *value) -{ - int res; - pthread_t self; - /* The first slot is reserved for pthread_self() */ - if ((key >= __pthread_tsd_first) && (key < __pthread_tsd_end)) - { - if ((key < __pthread_tsd_start) || _pthread_keys[key].created) - { - self = pthread_self(); - self->tsd[key] = (void *) value; - res = 0; - if ((key < __pthread_tsd_start) && (_pthread_keys[key].created == FALSE)) - _pthread_keys[key].created = TRUE; - - if (key > self->max_tsd_key) - self->max_tsd_key = key; - } else - { - res = EINVAL; - } - } else - { /* Invalid key */ - res = EINVAL; - } - return (res); -} - -/* - * Clean up thread specific data as thread 'dies' - */ -void -_pthread_tsd_cleanup(pthread_t self) -{ - int i, j; - void *param; - - /* destroy dynamic keys first */ - for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++) - { - for (i = __pthread_tsd_start; i <= self->max_tsd_key; i++) - { - if (_pthread_keys[i].created && (param = self->tsd[i])) - { - self->tsd[i] = (void *)NULL; - if (_pthread_keys[i].destructor) - { - (_pthread_keys[i].destructor)(param); - } - } - } - } - - self->max_tsd_key = 0; - - /* - * The first slot is reserved for pthread_self() and there is no cleanup on it. - * Destroy rest of the static keys next only if any destructors registered. - */ - for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++) { - for (i = __pthread_tsd_first; i <= __pthread_tsd_max; i++) - { - if (_pthread_keys[i].created && (param = self->tsd[i])) - { - self->tsd[i] = (void *)NULL; - if (_pthread_keys[i].destructor) - { - (_pthread_keys[i].destructor)(param); - } - } - } - } -} - -int -pthread_key_init_np(int key, void (*destructor)(void *)) -{ - if ((key >= __pthread_tsd_first) && (key < __pthread_tsd_start)) { - LOCK(tds_lock); - _pthread_keys[key].created = TRUE; - _pthread_keys[key].destructor = destructor; - - if (key > __pthread_tsd_max) - __pthread_tsd_max = key; - UNLOCK(tds_lock); - return (0); - } else - return(EINVAL); -} - -/* we need this till the switchover happens for the dyld. It get 1- 10 slot */ -void -_pthread_keys_init() -{ - if (__pthread_tsd_first == 1) { - __pthread_tsd_start = 5; - __pthread_tsd_end = 10; - __pthread_tsd_max = 10; - } - -} - - diff --git a/src/libc/pthreads/pthread_workqueue.h b/src/libc/pthreads/pthread_workqueue.h deleted file mode 100644 index 20edf50b8..000000000 --- a/src/libc/pthreads/pthread_workqueue.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2007 Apple, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* pthread workqueue defns */ - -#ifndef _POSIX_PTHREAD_WORKQUEUE_H -#define _POSIX_PTHREAD_WORKQUEUE_H - -#include -#include -#include - -#define __PTHREAD_WORKQ_SIZE__ 128 -#define __PTHREAD_WORKQ_ATTR_SIZE__ 60 - -#define PTHREAD_WORKQUEUE_SIG 0xBEBEBEBE -#define PTHREAD_WORKQUEUE_ATTR_SIG 0xBEBEBEBE - -#ifndef __POSIX_LIB__ -typedef struct { unsigned int sig; char opaque[__PTHREAD_WORKQ_SIZE__];} *pthread_workqueue_t; -typedef struct { unsigned int sig; char opaque[__PTHREAD_WORKQ_ATTR_SIZE__]; } pthread_workqueue_attr_t; -#endif -typedef void * pthread_workitem_handle_t; -/* Kernel expected target concurrency of the workqueue clients for the three priority queues */ - -#define WORKQ_HIGH_PRIOQUEUE 0 /* high priority queue */ -#define WORKQ_DEFAULT_PRIOQUEUE 1 /* default priority queue */ -#define WORKQ_LOW_PRIOQUEUE 2 /* low priority queue */ -#define WORKQ_BG_PRIOQUEUE 3 /* background priority queue */ - -#define WORKQ_NUM_PRIOQUEUE 4 - -extern __int32_t workq_targetconc[WORKQ_NUM_PRIOQUEUE]; - -__BEGIN_DECLS -int pthread_workqueue_init_np(void) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int pthread_workqueue_attr_init_np(pthread_workqueue_attr_t * attr) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int pthread_workqueue_attr_destroy_np(pthread_workqueue_attr_t * attr) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int pthread_workqueue_attr_getqueuepriority_np(const pthread_workqueue_attr_t * attr, int * qprio) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -/* WORKQ_HIGH/DEFAULT/LOW_PRIOQUEUE are the only valid values */ -int pthread_workqueue_attr_setqueuepriority_np(pthread_workqueue_attr_t * attr, int qprio) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int pthread_workqueue_attr_getovercommit_np(const pthread_workqueue_attr_t * attr, int * ocommp) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); -int pthread_workqueue_attr_setovercommit_np(pthread_workqueue_attr_t * attr, int ocomm) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); - - -int pthread_workqueue_create_np(pthread_workqueue_t * workqp, const pthread_workqueue_attr_t * attr) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -int pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0); -/* If the queue value is WORKQ_NUM_PRIOQUEUE, the request for concurrency is for all queues */ -int pthread_workqueue_requestconcurrency_np(int queue, int concurrency) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); -int pthread_workqueue_getovercommit_np(pthread_workqueue_t workq, unsigned int *ocommp) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); -/* - * If the arg is non zero, it enables kill on current thread. - * If the arg of zero, it disables kill on current thread. - */ -int __pthread_workqueue_setkill(int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); - -/* =================================================================================================== - * NEW SPIs for 10.8 onwards - * - * =================================================================================================== - */ - -typedef void (*pthread_workqueue_function_t)(int queue_priority, int options, void *ctxt); -int pthread_workqueue_setdispatch_np(pthread_workqueue_function_t worker_func) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); - -#define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x00000001 -int pthread_workqueue_addthreads_np(int queue_priority, int options, int numthreads) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0); -__END_DECLS - -#endif /* _POSIX_PTHREAD_WORKQUEUE_H */ - diff --git a/src/libc/pthreads/sched.h b/src/libc/pthreads/sched.h deleted file mode 100644 index df1fc51e9..000000000 --- a/src/libc/pthreads/sched.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _SCHED_H_ -#define _SCHED_H_ - -#include -#include - -__BEGIN_DECLS -/* - * Scheduling paramters - */ -#ifndef __POSIX_LIB__ -struct sched_param { int sched_priority; char __opaque[__SCHED_PARAM_SIZE__]; }; -#endif - -extern int sched_yield(void); -extern int sched_get_priority_min(int); -extern int sched_get_priority_max(int); -__END_DECLS - -#endif /* _SCHED_H_ */ - diff --git a/src/libc/pthreads/stack.s b/src/libc/pthreads/stack.s deleted file mode 100644 index 1d1cbc26d..000000000 --- a/src/libc/pthreads/stack.s +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -.text - -#if defined(__ppc__) || defined(__ppc64__) -#import -#import - -/* - * void *_sp(void) - */ - -LEAF(__sp) - mr r3,r1 - blr - -/* - * void *_adjust_sp(void *sp) - */ -LEAF(__adjust_sp) - subi r3,r3,0x100 /* Stack frame padding */ - blr - -#elif defined(__i386__) - -#import -/* - * void *_sp(void) - */ - -LEAF(__sp,0) - movl %esp,%eax - ret - -/* - * void *_adjust_sp(void *sp) - */ -LEAF(__adjust_sp,0) - movl 4(%esp),%eax - subl $0x100,%eax - ret - -#elif defined(__x86_64__) - -#import -/* - * void *_sp(void) - */ - -LEAF(__sp,0) - movq %rsp,%rax - ret - -/* - * void *_adjust_sp(void *sp) - */ -LEAF(__adjust_sp,0) - movq %rdi,%rax - subq $0x100,%rax - ret - -#elif defined(__arm__) - -#import - -LEAF(__sp,0) - mov r0,sp - bx lr - -/* - * void *_adjust_sp(void *sp) - */ -LEAF(__adjust_sp,0) - sub r0, r0, #0x100 - bx lr - -#else -#error sp functions not defined for this architecture -#endif - diff --git a/src/libc/pthreads/tests/Makefile b/src/libc/pthreads/tests/Makefile deleted file mode 100644 index d9c33a9a7..000000000 --- a/src/libc/pthreads/tests/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -MACHINE:=`arch` -MAKEOBJDIR:=../../obj.`arch` - -TESTS = pthread_atfork_test -LDFLAGS = -nostdlib -lcrt1.o -LDLIBS = $(MAKEOBJDIR)/libc.a /usr/local/lib/system/libnotify.a \ - /usr/local/lib/system/libm.a /usr/local/lib/system/libmCommon.a \ - -lgcc /usr/local/lib/system/libkeymgr.a \ - /usr/local/lib/system/libdyld.a /usr/local/lib/system/libmacho.a \ - $(MAKEOBJDIR)/libc.a -CFLAGS = -I.. - -.SUFFIXES: -.SUFFIXES: .c - -.PHONY: tests - -tests: $(TESTS) - @for i in $(TESTS); do \ - $$i && echo $$i passed; \ - done - -clean: - rm -f $(TESTS) - -Makefile pthread_atfork_test.c : ; diff --git a/src/libc/pthreads/tests/pthread_atfork_test.c b/src/libc/pthreads/tests/pthread_atfork_test.c deleted file mode 100644 index 7303db2d6..000000000 --- a/src/libc/pthreads/tests/pthread_atfork_test.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include - -/* - * Parent and child handlers are called in the order they were registered - * prepare handlers are called in reverse order. The non-commutative - * operations will ensure that we are calling them in the proper order. - */ - -static int parentval = 0; -static int childval = 0; - -static void prepare1(void) -{ - parentval *= 2; -} - -static void prepare2(void) -{ - parentval = 3; -} - -static void parent1(void) -{ - parentval += 4; -} - -static void parent2(void) -{ - parentval *= 3; -} - -static void child1(void) -{ - childval = 5; -} - -static void child2(void) -{ - childval *= 3; -} - -int -main(void) -{ - pid_t pid, child; - int status; - - assert(!pthread_atfork(prepare1, parent1, child1)); - assert(!pthread_atfork(prepare2, parent2, child2)); - pid = fork(); - assert(pid >= 0); - if (pid == 0) { - _exit(childval); - } else { - child = waitpid(pid, &status, 0); - assert(child == pid); - assert(WIFEXITED(status)); - assert(WEXITSTATUS(status) == 15); - assert(parentval == 30); - } - return 0; -} diff --git a/src/libc/pthreads/thread_setup.c b/src/libc/pthreads/thread_setup.c deleted file mode 100644 index d2985df43..000000000 --- a/src/libc/pthreads/thread_setup.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2000-2003, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, - * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ -/* - * MkLinux - */ - -/* - * Machine specific support for thread initialization - */ - -#if defined(__ppc__) || defined(__ppc64__) -#include -#elif defined(__arm__) -#include -#endif - -#include "pthread_internals.h" - -/* - * Set up the initial state of a MACH thread - */ -void -_pthread_setup(pthread_t thread, - void (*routine)(pthread_t), - void *vsp, int suspended, - int needresume) -{ - kern_return_t r; - unsigned int count; -#if defined(__ppc__) || defined(__ppc64__) -#if defined(__ppc__) - ppc_thread_state_t state = {0}; - ppc_thread_state_t *ts = &state; - thread_state_flavor_t flavor = PPC_THREAD_STATE; - count = PPC_THREAD_STATE_COUNT; -#elif defined(__ppc64__) - ppc_thread_state64_t state = {0}; - ppc_thread_state64_t *ts = &state; - thread_state_flavor_t flavor = PPC_THREAD_STATE64; - count = PPC_THREAD_STATE64_COUNT; -#endif - /* - * Set up PowerPC registers. - */ - if (suspended) { - PTHREAD_MACH_CALL(thread_get_state(thread->kernel_thread, - flavor, - (thread_state_t) &state, - &count), - r); - } - ts->srr0 = (uintptr_t)routine; - ts->r1 = (uintptr_t)vsp - C_ARGSAVE_LEN - C_RED_ZONE; - ts->r3 = (uintptr_t)thread; - /* Incase of needresume, suspend is always set */ - if (suspended) { - PTHREAD_MACH_CALL(thread_set_state(thread->kernel_thread, - flavor, - (thread_state_t) &state, - count), - r); - if (needresume) - PTHREAD_MACH_CALL(thread_resume(thread->kernel_thread), - r); - } else { - PTHREAD_MACH_CALL(thread_create_running(mach_task_self(), - flavor, - (thread_state_t) ts, - count, - &thread->kernel_thread), - r); - } -#elif defined(__i386__) - i386_thread_state_t state = {0}; - i386_thread_state_t *ts = &state; - int *sp = vsp; - - /* - * Set up i386 registers & function call. - */ - count = i386_THREAD_STATE_COUNT; - if (suspended) { - PTHREAD_MACH_CALL(thread_get_state(thread->kernel_thread, - i386_THREAD_STATE, - (thread_state_t) &state, - &count), - r); - } - ts->eip = (int) routine; - - /* - ** We need to simulate a 16-byte aligned stack frame as if we had - ** executed a call instruction. Since we're "pushing" one argument, - ** we need to adjust the pointer by 12 bytes (3 * sizeof (int *)) - */ - - sp -= 3; /* make sure stack is aligned */ - *--sp = (int) thread; /* argument to function */ - *--sp = 0; /* fake return address */ - ts->esp = (int) sp; /* set stack pointer */ - /* Incase of needresume, suspend is always set */ - if (suspended) { - PTHREAD_MACH_CALL(thread_set_state(thread->kernel_thread, - i386_THREAD_STATE, - (thread_state_t) &state, - i386_THREAD_STATE_COUNT), - r); - if (needresume) - PTHREAD_MACH_CALL(thread_resume(thread->kernel_thread), - r); - } else { - PTHREAD_MACH_CALL(thread_create_running(mach_task_self(), - i386_THREAD_STATE, - (thread_state_t) ts, - i386_THREAD_STATE_COUNT, - &thread->kernel_thread), - r); - } - -#elif defined(__x86_64__) - x86_thread_state64_t state = {0}; - x86_thread_state64_t *ts = &state; - uintptr_t *sp = vsp; - - /* - * Set up x86-64 registers & function call. - */ - count = x86_THREAD_STATE64_COUNT; - if (suspended) { - PTHREAD_MACH_CALL(thread_get_state(thread->kernel_thread, - x86_THREAD_STATE64, - (thread_state_t) &state, - &count), - r); - } - ts->rip = (uintptr_t) routine; - - /* - ** We need to simulate a 16-byte aligned stack frame as if we had - ** executed a call instruction. The stack should already be aligned - ** before it comes to us and we don't need to push any arguments, - ** so we shouldn't need to change it. - */ - - ts->rdi = (uintptr_t) thread; /* argument to function */ - *--sp = 0; /* fake return address */ - ts->rsp = (uintptr_t) sp; /* set stack pointer */ - /* Incase of needresume, suspend is always set */ - if (suspended) { - PTHREAD_MACH_CALL(thread_set_state(thread->kernel_thread, - x86_THREAD_STATE64, - (thread_state_t) &state, - x86_THREAD_STATE64_COUNT), - r); - if (needresume) - PTHREAD_MACH_CALL(thread_resume(thread->kernel_thread), - r); - } else { - PTHREAD_MACH_CALL(thread_create_running(mach_task_self(), - x86_THREAD_STATE64, - (thread_state_t) ts, - x86_THREAD_STATE64_COUNT, - &thread->kernel_thread), - r); - } - -#elif defined(__arm__) - arm_thread_state_t state = {0}; - arm_thread_state_t *ts = &state; - thread_state_flavor_t flavor = ARM_THREAD_STATE; - count = ARM_THREAD_STATE_COUNT; - - if (suspended) { - PTHREAD_MACH_CALL(thread_get_state(thread->kernel_thread, - flavor, - (thread_state_t) &state, - &count), - r); - } - - ts->pc = (uintptr_t)routine; - - if (ts->pc & 1) { - ts->pc &= ~1; - ts->cpsr |= 0x20; /* PSR_THUMB */ - } - - ts->sp = (uintptr_t)vsp - C_ARGSAVE_LEN - C_RED_ZONE; - ts->r[0] = (uintptr_t)thread; - - /* Incase of needresume, suspend is always set */ - if (suspended) { - PTHREAD_MACH_CALL(thread_set_state(thread->kernel_thread, - flavor, - (thread_state_t) &state, - count), - r); - if (needresume) - PTHREAD_MACH_CALL(thread_resume(thread->kernel_thread), - r); - } else { - PTHREAD_MACH_CALL(thread_create_running(mach_task_self(), - flavor, - (thread_state_t) ts, - count, - &thread->kernel_thread), - r); - } -#else -#error _pthread_setup not defined for this architecture -#endif -} diff --git a/src/libc/regex/TRE/lib/regexec.c b/src/libc/regex/TRE/lib/regexec.c index 89229feef..174f6b609 100644 --- a/src/libc/regex/TRE/lib/regexec.c +++ b/src/libc/regex/TRE/lib/regexec.c @@ -10,6 +10,10 @@ #include #endif /* HAVE_CONFIG_H */ +/* Unset TRE_USE_ALLOCA to avoid using the stack to hold all the state + info while running */ +#undef TRE_USE_ALLOCA + #ifdef TRE_USE_ALLOCA /* AIX requires this to be the first thing in the file. */ #ifndef __GNUC__ @@ -201,7 +205,7 @@ tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags, i++; } #ifndef TRE_USE_ALLOCA - if (tags != intags) xfree(tags); + if (tags != intags) xfree((void*)tags); #endif /* !TRE_USE_ALLOCA */ } @@ -247,16 +251,6 @@ tre_match(const tre_tnfa_t *tnfa, const void *string, size_t len, tre_tag_t *tags = NULL; int eo; size_t offset = 0, count = 0; - if (tnfa->num_tags > 0 && nmatch > 0) - { -#ifdef TRE_USE_ALLOCA - tags = alloca(sizeof(*tags) * tnfa->num_tags); -#else /* !TRE_USE_ALLOCA */ - tags = xmalloc(sizeof(*tags) * tnfa->num_tags); -#endif /* !TRE_USE_ALLOCA */ - if (tags == NULL) - return REG_ESPACE; - } if ( #ifdef TRE_STR_USER @@ -276,6 +270,17 @@ tre_match(const tre_tnfa_t *tnfa, const void *string, size_t len, if (type == STR_WIDE) offset *= sizeof(wchar_t); } + if (tnfa->num_tags > 0 && nmatch > 0) + { +#ifdef TRE_USE_ALLOCA + tags = alloca(sizeof(*tags) * tnfa->num_tags); +#else /* !TRE_USE_ALLOCA */ + tags = xmalloc(sizeof(*tags) * tnfa->num_tags); +#endif /* !TRE_USE_ALLOCA */ + if (tags == NULL) + return REG_ESPACE; + } + /* Dispatch to the appropriate matcher. */ if (tnfa->have_backrefs || eflags & REG_BACKTRACKING_MATCHER) { @@ -287,8 +292,8 @@ tre_match(const tre_tnfa_t *tnfa, const void *string, size_t len, if (source->rewind == NULL || source->compare == NULL) /* The backtracking matcher requires rewind and compare capabilities from the input stream. */ - return REG_BADPAT; - } + status = REG_BADPAT; + } else #endif /* TRE_STR_USER */ status = tre_tnfa_run_backtrack(tnfa, string + offset, (int)len, type, tags, eflags, &eo); diff --git a/src/libc/regex/TRE/lib/tre-compile.c b/src/libc/regex/TRE/lib/tre-compile.c index f9ee7d980..f8741a098 100644 --- a/src/libc/regex/TRE/lib/tre-compile.c +++ b/src/libc/regex/TRE/lib/tre-compile.c @@ -931,7 +931,7 @@ do_addtags_recurse: u = tre_mem_calloc(mem, sizeof(tre_last_matched_pre_t) + sizeof(tre_last_matched_branch_pre_t) - + bitstr_size(num_tags)); + + bitstr_size(tnfa->num_tags)); if (!u) { status = REG_ESPACE; @@ -1234,7 +1234,7 @@ do_addtags_recurse: node = tre_stack_pop_voidptr(stack); start_tag = tre_stack_pop_int(stack); b = tre_mem_calloc(mem, sizeof(tre_last_matched_branch_pre_t) - + bitstr_size(num_tags)); + + bitstr_size(tnfa->num_tags)); if (!b) { status = REG_ESPACE; @@ -1379,7 +1379,7 @@ do_addtags_recurse: #endif /* TRE_DEBUG */ DPRINT(("Reordering submatch_data\n")); - for (i = 0; i < tnfa->num_submatches; i++) + for (i = 0; i < (int)tnfa->num_submatches; i++) { #if TRE_DEBUG int so = tnfa->submatch_data[i].so_tag; @@ -1810,7 +1810,7 @@ typedef enum { static reg_errcode_t tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast, int *position, tre_tag_direction_t *tag_directions, - int *max_depth) + int __unused *max_depth) { reg_errcode_t status = REG_OK; int bottom = tre_stack_num_objects(stack); @@ -3050,7 +3050,7 @@ tre_compile(regex_t *preg, const tre_char_t *regex, size_t n, int cflags, sizeof(*tag_directions) * (tnfa->num_tags + 1)); } tnfa->minimal_tags = xcalloc((unsigned)tnfa->num_tags * 2 + 3, - sizeof(tnfa->minimal_tags)); + sizeof(*tnfa->minimal_tags)); if (tnfa->minimal_tags == NULL) ERROR_EXIT(REG_ESPACE); @@ -3144,6 +3144,7 @@ tre_compile(regex_t *preg, const tre_char_t *regex, size_t n, int cflags, if (errcode != REG_OK) ERROR_EXIT(errcode); +#ifdef USE_FIRSTPOS_CHARS /* not defined */ /* If in eight bit mode, compute a table of characters that can be the first character of a match. */ tnfa->first_char = -1; @@ -3189,7 +3190,38 @@ tre_compile(regex_t *preg, const tre_char_t *regex, size_t n, int cflags, } else tnfa->firstpos_chars = NULL; +#else /* !USE_FIRSTPOS_CHARS */ + /* Set first_char only if there is only one character that can be the + first character of a match */ + tnfa->first_char = -1; + if (!tmp_ast_l->nullable) + { + int scanning = 1; + for (p = tree->firstpos; scanning && p->position >= 0; p++) + { + tre_tnfa_transition_t *j = transitions + offs[p->position]; + while (j->state != NULL) + { + if (j->code_min <= j->code_max) + { + if (j->code_max != j->code_min || j->code_min == -1 || tnfa->first_char != -1) + { + tnfa->first_char = -1; + scanning = 0; + break; + } + tnfa->first_char = j->code_min; + } + j++; + } + } +#ifdef TRE_DEBUG + if (tnfa->first_char >= 0) + DPRINT(("first char must be %d\n", tnfa->first_char)); +#endif /* TRE_DEBUG */ + } +#endif /* !USE_FIRSTPOS_CHARS */ p = tree->firstpos; i = 0; @@ -3359,8 +3391,10 @@ tre_free(regex_t *preg) if (tnfa->tag_directions) xfree(tnfa->tag_directions); +#ifdef USE_FIRSTPOS_CHARS /* not defined */ if (tnfa->firstpos_chars) xfree(tnfa->firstpos_chars); +#endif /* USE_FIRSTPOS_CHARS */ if (tnfa->minimal_tags) xfree(tnfa->minimal_tags); diff --git a/src/libc/regex/TRE/lib/tre-internal.h b/src/libc/regex/TRE/lib/tre-internal.h index 86e93d217..aa6748459 100644 --- a/src/libc/regex/TRE/lib/tre-internal.h +++ b/src/libc/regex/TRE/lib/tre-internal.h @@ -300,7 +300,9 @@ struct tnfa { tre_tnfa_transition_t *initial; tre_tnfa_transition_t *final; tre_submatch_data_t *submatch_data; +#ifdef USE_FIRSTPOS_CHARS /* not defined */ char *firstpos_chars; +#endif /* USE_FIRSTPOS_CHARS */ tre_tag_direction_t *tag_directions; int *minimal_tags; tre_last_matched_branch_t *last_matched_branch; diff --git a/src/libc/regex/TRE/lib/tre-match-backtrack.c b/src/libc/regex/TRE/lib/tre-match-backtrack.c index 734f088b0..a03d1c68b 100644 --- a/src/libc/regex/TRE/lib/tre-match-backtrack.c +++ b/src/libc/regex/TRE/lib/tre-match-backtrack.c @@ -274,7 +274,7 @@ tre_tnfa_run_backtrack(const tre_tnfa_t *tnfa, const void *string, int num_tags = tnfa->num_tags; int touch = 1; - char *buf; + char *buf = NULL; int tbytes; #ifdef TRE_MBSTATE diff --git a/src/libc/regex/TRE/lib/tre-match-parallel.c b/src/libc/regex/TRE/lib/tre-match-parallel.c index c6ce364cb..c6ce76f27 100644 --- a/src/libc/regex/TRE/lib/tre-match-parallel.c +++ b/src/libc/regex/TRE/lib/tre-match-parallel.c @@ -143,7 +143,7 @@ tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len, #endif /* TRE_DEBUG */ tre_tag_t *tmp_tags = NULL; tre_tag_t *tmp_iptr; - int tbytes; + size_t tbytes; int touch = 1; #ifdef TRE_MBSTATE @@ -162,7 +162,7 @@ tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len, everything in a single large block from the stack frame using alloca() or with malloc() if alloca is unavailable. */ { - int rbytes, pbytes, total_bytes; + size_t rbytes, pbytes, total_bytes; char *tmp_buf; /* Compute the length of the block we need. */ tbytes = sizeof(*tmp_tags) * num_tags; @@ -177,11 +177,11 @@ tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len, #ifdef TRE_USE_ALLOCA buf = alloca(total_bytes); #else /* !TRE_USE_ALLOCA */ - buf = xmalloc((unsigned)total_bytes); + buf = xmalloc(total_bytes); #endif /* !TRE_USE_ALLOCA */ if (buf == NULL) return REG_ESPACE; - memset(buf, 0, (size_t)total_bytes); + memset(buf, 0, total_bytes); /* Get the various pointers within tmp_buf (properly aligned). */ tmp_tags = (void *)buf; @@ -209,15 +209,103 @@ tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len, reach_pos[i].pos = -1; /* If only one character can start a match, find it first. */ - if (tnfa->first_char >= 0 && type == STR_BYTE && str_byte) + if (tnfa->first_char >= 0 && str_byte) { const char *orig_str = str_byte; int first = tnfa->first_char; + int found_high_bit = 0; - if (len >= 0) - str_byte = memchr(orig_str, first, (size_t)len); - else - str_byte = strchr(orig_str, first); + + if (type == STR_BYTE) + { + if (len >= 0) + str_byte = memchr(orig_str, first, (size_t)len); + else + str_byte = strchr(orig_str, first); + } + else if (type == STR_MBS) + { + /* + * If the match character is ASCII, try to match the character + * directly, but if a high bit character is found, we stop there. + */ + if (first < 0x80) + { + if (len >= 0) + { + int i; + for (i = 0; ; str_byte++, i++) + { + if (i >= len) + { + str_byte = NULL; + break; + } + if (*str_byte == first) + break; + if (*str_byte & 0x80) + { + found_high_bit = 1; + break; + } + } + } + else + { + for (; ; str_byte++) + { + if (!*str_byte) + { + str_byte = NULL; + break; + } + if (*str_byte == first) + break; + if (*str_byte & 0x80) + { + found_high_bit = 1; + break; + } + } + } + } + else + { + if (len >= 0) + { + int i; + for (i = 0; ; str_byte++, i++) + { + if (i >= len) + { + str_byte = NULL; + break; + } + if (*str_byte & 0x80) + { + found_high_bit = 1; + break; + } + } + } + else + { + for (; ; str_byte++) + { + if (!*str_byte) + { + str_byte = NULL; + break; + } + if (*str_byte & 0x80) + { + found_high_bit = 1; + break; + } + } + } + } + } if (str_byte == NULL) { #ifndef TRE_USE_ALLOCA @@ -227,20 +315,37 @@ tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len, return REG_NOMATCH; } DPRINT(("skipped %lu chars\n", (unsigned long)(str_byte - orig_str))); - if (str_byte >= orig_str + 1) - prev_c = (unsigned char)*(str_byte - 1); - next_c = (unsigned char)*str_byte; - pos = str_byte - orig_str; - if (len < 0 || pos < len) - str_byte++; + if (!found_high_bit) + { + if (str_byte >= orig_str + 1) + prev_c = (unsigned char)*(str_byte - 1); + next_c = (unsigned char)*str_byte; + pos = str_byte - orig_str; + if (len < 0 || pos < len) + str_byte++; + } + else + { + if (str_byte == orig_str) + goto no_first_optimization; + /* + * Back up one character, fix up the position, then call + * GET_NEXT_WCHAR() to process the multibyte character. + */ + /* no need to set prev_c, since GET_NEXT_WCHAR will overwrite */ + next_c = (unsigned char)*(str_byte - 1); + pos = (str_byte - 1) - orig_str; + GET_NEXT_WCHAR(); + } } else { +no_first_optimization: GET_NEXT_WCHAR(); pos = 0; } -#if 0 +#ifdef USE_FIRSTPOS_CHARS /* not defined */ /* Skip over characters that cannot possibly be the first character of a match. */ if (tnfa->firstpos_chars != NULL) @@ -271,7 +376,7 @@ tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string, int len, } } } -#endif +#endif /* USE_FIRSTPOS_CHARS */ DPRINT(("length: %d\n", len)); DPRINT(("pos:chr/code | states and tags\n")); diff --git a/src/libc/regex/TRE/lib/tre-match-utils.h b/src/libc/regex/TRE/lib/tre-match-utils.h index 83258e806..5d4cd223d 100644 --- a/src/libc/regex/TRE/lib/tre-match-utils.h +++ b/src/libc/regex/TRE/lib/tre-match-utils.h @@ -17,6 +17,7 @@ /* Wide character and multibyte support. */ #ifdef TRE_STR_USER +#error TRE_STR_USER defined #define GET_NEXT_WCHAR() \ do { \ prev_c = next_c; \ @@ -82,30 +83,43 @@ } \ } while(/*CONSTCOND*/0) #else /* !TRE_STR_USER */ +/* + * Because all multibyte encodings are exclusively single-shift encoding, + * with the shift codes having the high bit set, we can make an optimization + * for STR_MBS that only calls tre_mbrtowc_l() when a high-bit character + * is detected, and just do a direct copy for ASCII characters. + */ #define GET_NEXT_WCHAR() \ do { \ prev_c = next_c; \ - if (type == STR_BYTE) \ + switch (type) \ { \ + case STR_BYTE: \ pos++; \ if (len >= 0 && pos >= len) \ next_c = '\0'; \ else \ next_c = (unsigned char)(*str_byte++); \ - } \ - else if (type == STR_WIDE) \ - { \ + break; \ + case STR_WIDE: \ pos++; \ if (len >= 0 && pos >= len) \ next_c = L'\0'; \ else \ next_c = *str_wide++; \ - } \ - else if (type == STR_MBS) \ - { \ - pos += pos_add_next; \ - if (str_byte == NULL) \ - next_c = L'\0'; \ + break; \ + case STR_MBS: \ + pos += pos_add_next; \ + if (__builtin_expect(len >= 0 && pos >= len, 0)) \ + { \ + next_c = L'\0'; \ + pos_add_next = 1; \ + } \ + else if (__builtin_expect(!(*str_byte & 0x80), 1)) \ + { \ + next_c = (unsigned char)(*str_byte++); \ + pos_add_next = 1; \ + } \ else \ { \ size_t w; \ @@ -114,30 +128,23 @@ max = len - pos; \ else \ max = 32; \ - if (max <= 0) \ + w = tre_mbrtowc_l(&next_c, str_byte, (size_t)max, &mbstate, \ + tnfa->loc); \ + if (w == (size_t)-1 || w == (size_t)-2) \ + return REG_ILLSEQ; \ + if (w == 0 && len >= 0) \ { \ - next_c = L'\0'; \ pos_add_next = 1; \ + next_c = 0; \ + str_byte++; \ } \ else \ { \ - w = tre_mbrtowc_l(&next_c, str_byte, (size_t)max, &mbstate, \ - tnfa->loc); \ - if (w == (size_t)-1 || w == (size_t)-2) \ - return REG_ILLSEQ; \ - if (w == 0 && len >= 0) \ - { \ - pos_add_next = 1; \ - next_c = 0; \ - str_byte++; \ - } \ - else \ - { \ - pos_add_next = w; \ - str_byte += w; \ - } \ + pos_add_next = w; \ + str_byte += w; \ } \ } \ + break; \ } \ } while(/*CONSTCOND*/0) #endif /* !TRE_STR_USER */ @@ -145,6 +152,7 @@ #else /* !TRE_MULTIBYTE */ /* Wide character support, no multibyte support. */ +#error TRE_MULTIBYTE undefined #ifdef TRE_STR_USER #define GET_NEXT_WCHAR() \ @@ -201,6 +209,7 @@ #else /* !TRE_WCHAR */ /* No wide character or multibyte support. */ +#error TRE_WCHAR undefined #ifdef TRE_STR_USER #define GET_NEXT_WCHAR() \ @@ -614,7 +623,9 @@ tre_bracket_match(tre_bracket_match_list_t * __restrict list, tre_cint_t wc, break; } error: - if (list->flags & TRE_BRACKET_MATCH_FLAG_NEGATE) + if (list->flags & TRE_BRACKET_MATCH_FLAG_NEGATE) { + if ((tnfa->cflags & REG_NEWLINE) && wc == '\n') return 0; match = !match; + } return match; } diff --git a/src/libc/regex/TRE/lib/tre-mem.c b/src/libc/regex/TRE/lib/tre-mem.c index b5fb2768d..21aa79323 100644 --- a/src/libc/regex/TRE/lib/tre-mem.c +++ b/src/libc/regex/TRE/lib/tre-mem.c @@ -106,12 +106,12 @@ tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block, } else { - int block_size; + size_t block_size; if (size * 8 > TRE_MEM_BLOCK_SIZE) block_size = size * 8; else block_size = TRE_MEM_BLOCK_SIZE; - DPRINT(("tre_mem_alloc: allocating new %d byte block\n", + DPRINT(("tre_mem_alloc: allocating new %ld byte block\n", block_size)); l = xmalloc(sizeof(*l)); if (l == NULL) diff --git a/src/libc/regex/TRE/lib/tre-parse.c b/src/libc/regex/TRE/lib/tre-parse.c index ad09c2620..fa0b34a98 100644 --- a/src/libc/regex/TRE/lib/tre-parse.c +++ b/src/libc/regex/TRE/lib/tre-parse.c @@ -107,7 +107,7 @@ tre_expand_macro(const tre_char_t *regex, const tre_char_t *regex_end, } static reg_errcode_t -tre_new_item(tre_mem_t mem, int type, int val, int *max_i, +tre_new_item(tre_mem_t __unused mem, int type, int val, int *max_i, tre_bracket_match_list_t **items) { reg_errcode_t status = REG_OK; @@ -717,7 +717,7 @@ static const char *bracket_match_type_str[] = { static reg_errcode_t tre_parse_bracket(tre_parse_ctx_t *ctx, tre_ast_node_t **result) { - tre_ast_node_t *node; + tre_ast_node_t *node = NULL; reg_errcode_t status = REG_OK; tre_bracket_match_list_t *items; int max_i = 32; @@ -2016,6 +2016,8 @@ tre_parse(tre_parse_ctx_t *ctx) ctx->re++; while (ctx->re_end - ctx->re >= 0) { + if (i == sizeof(tmp)) + return REG_EBRACE; if (ctx->re[0] == CHAR_RBRACE) break; if (tre_isxdigit_l(ctx->re[0], ctx->loc)) diff --git a/src/libc/regex/TRE/tre-0.8.0.tar.bz2 b/src/libc/regex/TRE/tre-0.8.0.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..cfcde9e6b90a69d74c3e93414018899e352bc787 GIT binary patch literal 380714 zcmZ>Y%CIzaj8qGbWZ0!{$JTzi{{R2~|Fu8_42#IPFxQt?@ur0@4mV?9^hiEhUB30Z z&G#L0-JyFKV1Rc6^I8T5hM(p4zVd!s`zA3yeVu2?<(Jd%$Cs~P=F6+}`{uhn=6Rbs z*WD@d@}1$5V!NhL_Oq4fwMqOkua?_p#bqSE+fem=4ZkaMncU}ghKXkBJ?yaz%M2TS zG4OI9`}#e3;k)O_`OEzGsONnVOL$?Ioj2`w>bmBAANSn(eSm?lq1JZhX)BOpm>QTL zF)%Px?7sJai}3Yz4zI@wt8RtecwAjKfnDJd~@IL(i=-R zEOuP3d$)YvhRm}3q>Y=ycgsmVpSQQX`rZ2Mooq!_U%yqqx7%C1^X2T(duJnt0dn2-uu0}YpPekuM@wnJ?;G_d*he+`NI3%XPzm3~i?kS^oZu|D#?@E|YT-IQ)-DSn8v5@uFttnG-eVF#%J-}Zs z`|<+c-o5vo_a$C_`bzP1T;J>W>psof^u2cOtF03_rYuqn-#Bsm_5Ms(ecynk@&4?F zAqxe(e!nZN-TH;u(Q;}ItJduN+VbFQYBMe@U=Cb1?NkPL0;Afy2UfPc!f*07SjxJ% zZ}#xgtUh4(`2Yj61B2ZSE5GNZIn2SkZTDJbOR{D={IqVH+Y_F={Pw-?@wqw7?+(R8 zZeU>GwUQ70@-CrBzkz{qeR6FB^NUNqDh1s4o?npr+`z!_EA;y%`TX+RyllIxi*M!1 zy=WwUO!TxpHS~=e+%X?QXEI9RuUrrjF0ocf7n{_x;f8mz!tryq&wa z>}l=XGTq+yWeg0=uU{{BV066uJ%E9s?Bjv*y$2W=-u-ZHeD}G+_TG2a8((;t-(G$= zzu4}=tw(HcrytIfcPRZ5eM-Fi^v$p03;g#SuwrS|;AklQ`aB`*x$(C3``*3VzI(^c zC;GgvUtiU`^Rz8Q%U|JIb7xl*i@caXgXjji73XWrPwmOynjpTI@%g6j`*QVkua|yc z-gxRY(=J8ZWb3`(Zdcb{_#C&l{Nl^(`{g(HeS1{J$s)yWfH#QkVHU-zIR(+tXsC}UCEQX$IGL)@4H|9c3tsC+j84opKVXf zo^5%bi$CM#+qGuTZ|**KqrBwqi92f^2c0^5;okS@<+Hb4HP(EV)c4Nry{+7v+uXUY zV^=O*ee2x1+v2gO%tEfOskmQWdv|Zd#JT0uR~}`%_~vC;`o6bc-hDoy`PD3QtzPu& z>Q(P%P1;~4+IS-%zxMX~qSU(=_nnQMQN30A@`cn}?;4-)?zj8BF8k%`1gWI8>a};> zyzk}L{JwhoYVEu3+8x#JQasOZ_E}+`{kqDwJmcN>dGpp=Z@nG!cITyAC%zrtzUF+z z{p#hnt8DMy+r4V9>hq$V^UQZQ+|Av-Tm1SC-pzNXH~cPN@P5^L3&y)MZ-YKIY17?n_XKDJ-@Em;JMrW3@N}Fd{T{ATz4?)SjvgLZH3^;Cp?=3|hRxyE2F758RxeEI4()2Gh%uijVvZi3j++=`-o zZ?8=2QFK}*_x;?bt}5}n?t6E>VJv2L&#Im`Rr`G0v-A7fw`@FLa^vUCZx{1k@B6;z z=dD_+nhDFV->=?#yIXB@dD&g2h5$xaSUweMLyYk#63=G>&Fx-4s6tw%@?^{*x zi*3u>zV9e=-@B*MyzJfXz2ClwIDPv4`n=umdz`PU_srWqNuyS_D(&s=ODp%?`~803 z?d!XrFW{++2>bPY?~Vl7GO2A>atoxaM86ll`2D8pyK(K?vstrm#g?!Iy_35_M8wwi;;dp*(W|#!vn%c{U7>h+;Z#ebyp5YzUbH&hQt~o1 zz4-0xw-2h{)!Z|6;8n?}UBJCs{O$o~Z-xteXL6@3V2Uf-+rEuEAuUy~;>+Ya9~EEC z%iUeGw^#b8tbfFp?6}%_zXR`Hzjy8Z_C2z?{d034@9pUu1>s=B(lHU&j1?U-1Qon#*?ISkF5xWeWCCU})fA@HJszVPN59 zm}zo>!%fv@nZM8St`vq0P*u;MYQmw&BH-*~a)FV_UnFN%Mh53fTbqey^Oi7Y@tQC@ zn1EF=FgYqIIB`y3n5CBCuWGh@S+ASgtQpH^32Q!@VQQ?o%vWyKtc=UT4iGaLT9p)8 zE-*2uaR@URF}qwAR+v?l8T{AZ^Ho+=hLq-HUy}>GCYK$+CUZWuA{rlIFFXTsBj1RkfBRn*d|yQ@Q0UE-qYf#N^AxMH~|ama#DOGKBn<;%qbt zwZADG@>kV9kOKW8MFwXYZZ-r)MlY{bcO0^b;UoNVPUw1!r)whEW_is!8 z9eV3XjAumUF}>GeUqA$mD`Umc&=tELaEYB*Jfmy*PY?E)LXDQqsz(|6Ji{+3REr3)Fdsgv5bWsaV8~E) zX>DXy;l=d<_F*eyZ2eA0&bad}PuTbAa+yS*M`u6!CK@(gD0}d_D6Z`5O4C-snQFmD zL$3Pxo;5vlPi@ihIj&mMb$VhF0`r63UuiMbP}Mb(cGR56z;)LtS?DsyS`z`Mg9=&V zVh)q0E=ZlUl*Rx3aly7Iwv-^PWooH5i`6e{*-evj;0kq{$Wl4gaiMs@g7u$H&6f$=Rgn^48{Mc1z1E2rLI*Qb5`kp+F zQ+^U1`my1~7O(D0%)6Y|w{PR=(YPi*J|Cj$yA~Ib5dre_#a1JxLrudhYS7+JO!UHSRf@W!` zC>1a_zkSZD?yX_?FzSetXP`{(MMsme#Dh9ChigAapCP^)5~#*{TD4LlN?C$TEHOj+#dWn!YM zaAC?qhf6`Ky1XizrYL$G^2+H+SSsbk)aBOHxa5B#_oOW$!QT2d60;Ue<>ZhG@?=@S z737iW)+N}v)Qe>yha#6s$E+nvk{v5LGVMQk8nJo0ENl{7lBAc`wekOo|6y!Tmn_Ig zXmR4usK2W{!ASM6vW}#pTcAK)QB~Cc&FBB-HRKA|7A~q1$Q^1ACMN~xPvY{Zet7d?q zz!65DL#NJ6n!?I#(lTWVt7$NEpi0OQ0Y?m~EV~azGl1NC1k%Pz)Mb|wBGiEJla?)D1N})(5NMMnc z@-*2E85$8yot`2}3uk0?C@j)Yoit&Z;v}}VhE6rnX#tv%6Sx*EO6ppeCdD*Mbm^j% zQbL_gE7&|TxHP$#G`qN#HGlSOxhSCG;w-9j$i+m+N7#pDGAGZJD+exmxdw(@5pZ!8 z3=*2q;c`;M!GYz(Ny8-u$2e9hEa_Opw#c(Ba$%BRvFgg+Fv;7y|22L5pZf3a&&rbi zE3$nrI~L4bv@(gQVdkp8|Krc^ZK;v;o+uI&;t&wPDl)~SQ=rq!WTlr2uSUp)13gQ8 zTm@ZRH9f07$V|xa=n|Ts_<#L>{lnW+Hio){iUf!{ItEv5{8G5tSwU4mASBqB*O*5~ zS<%!e`s?E*UCnnTIRZ5tOn4bCxG)-BTB>z6I3&bt!jz3V0*2aacm$U&k(3O0%ay|7 z%E}_dEy`=mab!(PgRqjwk|19ZKChIGfdVFidroRH8E&p zu4;avgRN2zK=FtdKw2wqWW)u8xIG63ZGr z+b}<4Vs-m$=>w75>M4aLv<+>v}qt zs3i5I7Dfn6;NZ#J7U&`zxHjXGWLvcXyYj&^jwcUg%=B`aG_`AGhSx%`1=`;hT(p{^ zDXe&EWd_HDD-0?6e->O2I$+?a$Ho`Lk<8-C<#ecOvz3@P3(Ezszc=SD*R0sjo}%-MY_aUky;ob3ut<|dLLi`R8v7ch z%BR1N&tY#V)f5foi8#UAaNx4nR`uzb-42XjE;Ps;-_W)A>7&=%Q$yEqF)aGc!`x?E zzcAwEt>>SUjl5*nonz7L0ID^VWC5F^S zk7-OyDjFI6cDyq^eH9&CnhF^b8PBN+coj=PG~bw^O7{_W%0VSG{|R*P9*1q zLld}J0}WV|9WE^vax`#eX*BRuV9#JJsx2ta=*;j8YE*OJJ(Q@b$ZO~^Q7fNsQ{sX{ zB1=|DCW`~AGM_AL!B}=51a&#y+4tk#^n6|{eRx|>yc8|{{_vl4OUnF;#2qhGXIx= z-}k3Yo_sg`#hmFjb-ww>oG&eYe^K9_E%E%t&3pcD<<0Yx_exkP7ilT8YtyCq4~3rp zT541?(RBZ#_kTkwgp<@hIP>c;OX?UJ@n6^3sz1B?W5mUonW5RHybm3#jjnI{nsE8& znY#7e=hECZUS8n*SXlSmFAj(OmLLC#|64lkVKdJ;8LNYpdotGaRQ4!Yd#*M8oF7#^ zQ_HNc&nY&)z||y;ai?LV@)zCt<)wR#RIX&0+cC?0UJLl?C^L)cNEj-0h`* z<-9z*T)%B<<_WEK1;%N8stotPDjfQJ{9?G@PLt1$yqBNMjEH;u;ErC6QX1d$4 zKhsP_TI38~sPl#&W3TaKc~UDj;p(DG;(MkU9R9cCWN+m4Mf0sM9!=Z!anszd`?><0 zHvjAUmonp(wX#ava-(@CCLEd6rE^FhyGWVm`;yEr9AKw@}x9Oe) zd*bx9m0xbH)a;Ggw=~~!Wyr(@$IKkJ1RXgcdU9)(;=$U|$p@1cZBACvoRr#e>!^C+ zrRPWYWVB4pvnutBp3%-UDQRod^_7kshmzjk{{!2NB-acHG z%zHj9Pr>wUpS{?-{KvmM`%cTcRDHUudjHt(ZNCny@aD{j6Z7a#=a?=q&s2TUtNQ7E zf*Nlh_nBCfyuQzG%hRd;a`C0px}i?9?>vg0*8QMUN5D}iP{A(KXcET;nH4tQUTq39 z(@azgc%=MEsZ-X!S-|1vdx?F#GR}Vj|8@JwE>^Vj{Mpst^s4x!qGm{A(%YIv_j{|a zJ??9>R%QtltM-j~v20Sh`5LVc>)Uuw%wl>H(7dniTv2$@WzNgn9h^Nn{T6aIF|pnY zs4nFf{uQ6MGRfuPQ=PZ-?j2bqs{LZ&>Vxc=!V}9wg^Uj>YOJn}oB4ZBzwVrixm)UQ z+MlkOKYx;Nul={!A2-eaN}YKVQ)(PIZ(X(aznlM?ef4N z1WwI)HK*XZ#M4D0npayZel2Ax+H!IJ`9(9cF9mdedCv4^LFC$J&b@7tasT6&-m2q% zyoXa|(~d_ERVLMBZ~MpZE1|u8?dkQUQZ>J9y^mP$sybxkUVlun@N41Y+rA$IU(fsZ z_2~QUhKH4Q<+ttHvf6SN%Uyvd-2rEnm+{RrKjYz^;Jeacib>%NnJbUi6m?oP6o2&- zs(tTcx1~%xNb(o!&(&|DFZ?d8mr1tVSd}L6R@lHe*MV2(ZuggEo?F##%33XuR_^I~ zuQZ`3j`PloJ`o}E=S6bH`KE99r=;mb=DU-LXdHd}y+m7;w zx92JNZ8R29oOjBZ>Gfa1dq?w53oquAe)jY8gf>6!NdY#x7Z=L%{hlY;m%;BnIcC1U zO+A>-Z zXM>*TE?6)1!gB>zxX86IPQ#$LK2FlVBX+M!{Ox0Y%kh()zf$hvC$oKY6`q>E4M{vL z>N4?H@^=$fjm3d~IydqKY;R}3E)X_{C*=6GcWu58X018tFSAdQebc$+Pisu+ zYVG6sxmhVRK&c0DlX)o;E zuGAzHT$U4{u0 zS4dnpmilTVHR-#^#ZT^+&*ppyygAuolH%RNd}R}_bnNyJ>PeV?_DAp@*3y~N4_@(= zIQpg2ZdS@sZN=mS>&%z_X_k_^R2zG_6WN0_Cd#N3J6)J{XuU<1-M#&lZ(MT2GuO{v zS|?F_jpgXB;)FL1Z*==a!?`$`S`4~`1JY)!urvF(K;m*;(3*fIz2+6~Z=|p6SmxO^ zdFwTMrDPMXA%~=K_GLDKBJR*R znsc}>2kUM~lDO=sTRP1@^}gK;LvuB&|2!N1STANOQJK0j>{IW$$~BYiF8^nJw65w% z?VTxCLe1wd{dP0fgxmKp=a%aqf2Q&TRxR7w`rUha&P$e+Vso8Xv(jDlx6JD@+O{L( z(9DeeQkfqg2^&rgUSLyvCxGqINssN3uWC{pG+)H7IC!IWjrz5JF;QRs+#*B>vcxq5oL(VlfB|8C6T+w?e7AY8Xu&f+c?YtXFyo!P#Von|i#_jqyD zq=u$FbFSa~`t9bD1H0x52xa`3yV_G1*st2Vt&c?)a_g_U$Kv)-!NbFd|1QfS ziT*RW^35ykRdy;m3QT05&%;?g+bES|)0MZqSx4VE7B5=q#<^X&IU?l!Nxu4=Qy6q3n5JiIG}kM>ve@r4HDd9MJ7LjgRkittlj~b2edXWq z!!=y zSa|%4Sj;w7Ix3+=C5 zxv02cV$kH|lfsqDoR`Ok*vS69AGv9b%u>1KH}aEGCZ$_lnWP;5)4qkRv~cS~{W%A_ zZ(L>$Q~Po6LzUXB$mgXu)!!dkx@A>r49DEG0}V%nx?5kEh%`Tx_Ia`4%xbL{HN6v; zzSVnX)Uv+L__E9=z5n_vA9)_!c5T9}cS#wq7&O&N9tn)Hdx9k*SYrD!!dtw=0wHrn4XG+|1MOOx<0nsA-0RNw&F;DUUH<&Mi|o7V6!TALE%bUV^R@B3 z-j&s-9*YXsRv&9!c)I4-|Gg{nH~5H5=vce`^oDkYFAf{|4Ymk+3iSj{Il;=gx}S0G zynPejzm{0M>2IjSnl`WK#h3c@UR=D+?05ZC=Azw!tSbUix)j_v0%wVcga!B=##})l%D#7)9mO(@iYE<+Z8VQeX(#iSfea9$0k5+_Oi4Mt;@J|j`IXXY&2dHv%iE> zsPV!i;fnIs#e3TsPgL*zip!3EBZP_ zw!UXC4w7PW(@wRyu=qx2^u(|=RUeMqxlZAAIkZSTeQwFqoVY`iSoM?5CSF?Ba>~gp zo+CT<>k&mmoo#17`*H`-6;FJn{kaZZod@9y4z$fMsl*#Av; z#I9NC;mPaQigm`TSGex(UpeP@wAaiXJ6oq3E?4H4_+9xz`tdK@muZVRYZtoEyQun4xY(&rk1Tc6Ytki!Or#A~ zJm0Wl;bL*QbD^BQT}Cchi++8ax$O9%>1o^6t5!y?oUtfd$tpx^!<6MGUF+;J^LP7x z-{7$FN8-Z89p{>ly>r-~a_g-2w8K{x%?c_@>Abu{F5miVwA<4XqnpuD*HuH#vTxj{ zqH^qGy|87!FWYX(?;k?T*LvPKc|2$46txcjZiUKsb06>gy6?vCo%hTCZgETBp1z5A1QpXS;> zA9BA+U%0a(ZLNE9a_7`iH&(gK?Cxso9TBd^etTZ==i8bGXMJ{dvv-^Sdz;LrQ`_@O zF0sd)Iwz39xnORVyNdccgD_hW^%v_ZdnW!VP@M4o&2#sw>pU~A-+nafqlx{=ub1OY zZOX15@^w6(T32vC@7kP?&C6u^r|%V5_luu%S9IQ+kT2$P+@8xS$>in2m;-72hTQ21D|68tnc)|bjkV=!1KF9U0ub!>>8!#azGC!Fy z@Y83u4wqjpFVzxf>PPIdsrwwU;Ip%$LBT~1^O7K=>EDC3(mWm8J}in}m9%gA-HM78 zn|x&XLasW@zWrv4szy+F4zudw>jEz(w;%ttOLA6oA8)(6ME8Wi#sjkcg|2;7+RRy{ z>t>X+haIyzt$jQ?zGd<87sq%b4Q-oi3od2$Eo*q_<=MFTqN12d!Kx6yqp_Uf=D|OX z?=otzyy;@fx^RUV6BnaEa#1PEgh@{_l^A=&1bDVAd2`gzy!+0c>3+P2W@PVq-I;vU z;JaPC?vK5S{SD7%Gd!85{{HK6BY6#-ujlg3KFB8boY^mQ`cK4xdOn`>xA&UZwQ#O_ z#Cz&(xSVN!*Vk{gm&8q9OAE-=nw|SFS%t|rWXCe8-I`~V8y+mpu9Q2Saja8pOT~)o zVU_zYEA2Z}q~62$+$8rpd!=Zq_Txpfw4*JHPh2>zm2jik^EAV4q04@jf46woUKjD$ z!u6D6&!g>;t2X@)krMOb5|D}tQTv(U^Gr5RE_PF#|MU~435(h8KX14tB=stbSHAyf z-;0$|K^`Y{Ls!Q(*aVaxDQM~P-O?)H?eOk+@!_sM#ZPZc&R^YDBXiX^YI!_ zlN3+JOB@W`KFjdliD^>Ok!trEXDA$4)%f6c&Zl?Wel8N{?KUduy_Wnay7Y?A&FRYx zw;Z1QEpElPdk?p5{NJ)aO*3%n&uc&SZ(p+ibg$XLpDX@c?D(>GruD)*KQvZpuHx`< z(%bO$u+(GbMG?2!g@W%}FZ-2oWubLf=E)D+eH8xwS{ys|;PEd`CTqP#oh~jjcfHbS zJ!SW5##?J;=J|#e{n#aW^-TP>S01nCsP)7}Ol;Sc$Oyi=F68nJ%Z0XmFY~@QJyCIU zTIj@aN?Y*9D)W!$MDG4Ay~n$@rrlmE$>NUljPkGvZf1(w%TCa8|eH&$~0$il|L#YR^)g8^hbtvn^xYLbjKZVYippKk`_{oZK7O z%ecIfiRaAanz<*Y@YQ>7KDV%cQtpy@qUnk&T~DkqJk#KC_*I)mZ(7b7MI&bwm!Nga-Uu@%J68yZWOKuPS^_2YEWXid+ilaVR+~9e-7`Z~pAd6_sbN3kDV*es%BO z%np~B^B1g4zQ6sg$5tZo>!jkR{i|=9USw9m6mHZ4;>z5CV2W7n!5 zis`Mf*?wBa=EHm&#UzCrmpxNXrOO=H{cYv#B`XRm>oz@TJ$=P0Ix0=zSN-EJJ6_#> z9W~#;^`#?Mqe70_zjIHvEDhkTV zt$;_`qqY~{qF23U+j;23+m@)AX^W-2Tt0N~xx)Is$6?mH%V$De0|h?+$^R8z+EZI^ zDi}IWC)*>Lfp!GV$lsq7tQU_JjXS_Oc4Qgt(=deYak|Bf!aybNT&!rdgIV z`cLo3^*&;F-Ns?E%ANQ7{4L5-W?RedET3{j+eNMS{UyFXf6L7h?>1h4lfwEcW@+ll zf@%GKw#Ir{xXGOR^2s`_iPDt9^D9e^u1P3VZ9MMU{x|;||KIt`6yE)v@ap~EfTyX`AAdA#dOzpP z;m?VWD_2>}lGz-uzUB5~#vKdwj5(g2b~);EQmE=r?aue#zsFk1rYPeqv@mhHFubYCv|`GTOzeJ5Ui^jN-3-+%e4Q;H$R+q_myE&TOx?sDTpb7lW% zO!bRB_*3bbYHJ}Bt=9b6^p(K+8}tINLi;$7aKUN>>*ui8-*7WDJt$cJ<@)cW z%-fNrJB~(cH~)BEs3~}ML;Ba^riF*Acl;_}rS>Q#er;>UeW^FK7dwjD)9T%ymZ#mV zH~;u^*NeqVHB(5o4|J5fw;buwRA&V0w4gn%_Z`EuFdTaZo z?(O?azvf2YW%yg7>1Y4#;-h6o4pRivKUOS$_RrI+a8h~vsn*2ySbLk~sr7dLeWj+~ zLpgJNGOt((d1hNZu}}H4qF2bzYSH%o^Ox;g&HhsR z@3fWf_SiSYnROYVZ=d}T_;S!s;Hy_pqGG%)?}9F2hRK}l6T0PRf3Z8~H#=E=>sfoV zsn0EU{M*HRrmBLge!9~7n@i7zhOXsnIJ|J-jp-L_e?1S?U2){bB^CjnTb{2%R|MAI z&-PT+RGD;r!QIeZtF~s8u=TF^FX|lXrSEH6e?9V>>nUq_W0f*%vzEIWyC*N3YhgRt zpY_FWJJGoww=cU`2a9xArY?IYp13Y{V%wMeX+O^MpUpL0KPfyKB~>tqPt zSyYf!Yn_^EyLR>LCCUYU-IjGPE@%eDJGRbyDbgN$^kF#96)CHvsS{eCeU&)!zT;TX zso?ARFItTkTy+&PWW63Id2M^-h4(A%-n3it+f7{f`}frv<>OZkj%zEe$*WmY)|ArJ zWm#Ev)b+em-jbvR9f}|KPbjc!xpH}p0e?yEwd6?}W;ail9^7>5RNT+7YcVoAe?C?_ zVYkXZtSfJKkU@Uhs^xAe=j|i|mo7b|~ zhi~6Gx8}pqwcGAoUbN7*i__Y9uV=-DS9*Vi>!t2V^`*L9_B_e-X-aEGOXJ%$((NE3b-JOj+|&tKTVW(ZhuS+E-s0$j-R%yH>ET(ns;P`kPgu=cBJrc%p7E z`t$vtZRgWFOfO7$KTTWcQ08*(z8ME6_UbcrdzaUKuDtfJi#;vF@zQ5OuRym4b~k-J zrVIC#TYRYES@<`}J7T$_mhHZuYW6YL_^-DeB#wst4#9LJYR4=cS_`ZzFXGIb9BllwT9%Df44q(_p!^DdfqFy zCkI>?xhf`G<^AjRFWpOxw;Vn!woLr=LHtGk#n-=bFIrh;T|8vg@twnGMW5A7nTL~a z{4L71SgLK8{n_S(osPNMldHuwr|fR8?=#_2V}dPM^N3dQblvvxVP#eRjE? z`el82dYWO-tFD>LExQ7Ji=~$Daf#aFd;X*I>0SPnueA6TzpB|!m1i}{_Ph3Rm1u?i z#gkladGYKvTk2*Qo?jO5>g!MS%h6kowLEm+>ACn-g?4zI;QCmVhcT}bI)6wVm)=#> z5PxX3tytBv8|&3fj?KwxUKRj8}jkm|kU&4VXvv|Bz*y^^K1*@atoLy@S1ZN@6I znMZa$x-G@+H!+D*CHC~f#b3@<6&sv7mEIFreCcPeR!oxEIe{JBlh1wEk3FT7V{|jT zWYHFT!FjhoTszicaOI&=fV%h*w`XRruef$i_FUh0@q2pJm%G*HUO%)GaeLHz<6!=3 zi9M4qy>I$5NmHzSiovo|6(W@(5)U@-nx9rP<&=mt?~D62kz9L!Z@zh3(rEu=d5uZa z9%{Ud+-vwct&V$|)CR8DxifwT9FAMZ@11|Jc5C?4f4AyxpV|ED$K-P_qEnoAYCN0z z>x*CUn%aqtfi2$`H0hP^j^4GpQL#y?FgNk>&DSr+SP5SmIu~~gQ+!L!ZX=%Z{dm(j~tlNF2h6L!OJLev*IoDG3dhIHg5491O z=O{T%y~xH>e(sRYF{`&1Yu9f*ZrNCJ{qTBS!(F$3FR-5M^l$$pkIJ>jS66?xwd0>x zz3T?|+()HdO>gbjm$w*f-S<{zan#Qz-yR*~Q(w@yLBWH|`4G#g6&V3bj1A=5AOE+g z+@F^DYVRJe-J3O*tx)n(m?fl;wDijf2~kBMLq)fJ`Tp$XY`e~PioZE~&a$t#Xn)9k z&y$|}k9qVQ-<5a!^mNzsn3LPftQ6DC4(H!vd%sNT<+tK#$L>mS*FWu%H+dV%Yq;_L zA;T{A^2BRLi%b`)%rdd$e!OjFxH+RhW#`2^?^LF;>0J;!$SSmW?(sW;o0d2Jj}tpK zb8p4VuRk?bz0!Jqf7x!%G^O1uBhGJ1-z;%iN+;0&?TdY0)kV)%)E=AdZ2Q;ACvcsQ z%A_6+bLrofPZMMLGiEM0C8O}MtM^{M&!6b`A3vVEac5o0yT(dqa)0?tYD{kLEI z*38P?d^&u``{O15{N|s!bg*~6vS~`%Ep4w&DH_)^+S5wjKWT7K*!Snh?{~&;4?Nl{ zWb$jpGtFQBM6{z9to$cq|M-4ijr7Cc^H*GcTk>AkdZJwNn^_ezIzxO+R;*aAxyd(X zEqYuLf>9> zPj%PrJ(`&5*1qYU=Y_LNLuOpc+?oDn&+X2#O3o$LS7#ry30|p~RaN5s#AwU1ips^I zpKmUxeOIMyWmt7`g5Yk={>hh*^m`}Xs-wISW@^Q}aJtflfAI3YuJ&h+Q)4R-TLxr&+A2-;|3kGdJFBx*w_H$irfC{;+sdmac4( z=xnXdg=#`9+1sU))%L!7vP|{dkC!)-z1IFN`(Dwdaqx*&l)i*ld`#`OsUqKH&(kPN7eM~npFD2 z?BB|lDYd`W#c%n1o#*T3$a9l>AZPlHw4b5TxYqy!_Y&|2mB<=5TZ zUfx)^RrgY7z~0VDhD+yqP4}C7^}5m-#gvtfzb90&oK2W@AoAeR*lZh>-| zgg>+5h!m(XGk$(r;bUde_P$$I##hd)ykh!t(bnvzW^S`2nU*zl^IW-Lv-wA{la4~j z-_)`RQ~2tdPCUN4$>Zm%g1JjOH@j=5{Z0;jcVT_{xqVxf+je%Yy;xFV&Bn#ilKFh! z{Pbx-?s4vSjq;Zm6&!c{;uEN~a9=R%(WY6i)a?%OxXL|hbVz~ z79ZYPX`X)TYI1H{ccQC^yOhR)U80XxnOr-2`lVLdl3li^)>Kc*7x8`~8rf#H@%^42 zt;M!1?vf!FlapI#T4`l|%jA{q{TuNTYP0g7mzB7Upg`scif%5$xSp78&vnd&ZEepT*`>g?N9Z&*XP z`kRj}4XrZ$dh7E+;n4g?zi<70m7RTvT}R$2Pw2ya>7LtDY7OKyWp+%L;@uG})NyE$ z>VnKyZKYnP|5eva{9WQbeO<-xJu9l-EHKJtp5^mmbNp3K3*$qJ6nxo!XvJ;Xaw*GX zx%|6L0v|u$jr54Peg7z5M{275w>^b#W{2s;oSgR+X|lMnBx{O6@;mnHM#?t%|floi=T>_fEEro9XO$a&_9tD@iXbsy^JV zQTiUB_3HZ}xyd2N@3Q56&R>>$Le9+YuaVvV!{uYHV)Cl$^~wjAofqsin0n&1-?rcT{w#hK^t7<(_=ml+ zW_sBlPn!DGWk28Q%YWm6ujKFZQN3#Xb1WTQgrD*`1`0Vpm2i$%OE!O>rvC9+Kz7A0 zm8+NBUw!*_@l4T-YuYBFChQKUu4Kn`ivCu4I^mhc>4fc7@v~1)uFbwR!}7w!yRT!E z@9s`7kWev6ZkAZ@KF{aZ&$Ic9=gj-M@V``P$>}4t{GkGUJn3b62R`C7P>mNmyB^qr~C%D&K-D1YGqGdm?tDvuE zaii}!t9`l8Zj0pYt;&}Yka5zScs1Zr$dq!Yqqo;jl6e2>@sx$hQ;V-l?YnpO`pH=b ztsb*XS}SlRn{WPv-65ZsUXAYF{pG}rlMEAG#aA)K^2M&4CX_JKZ`r|L?{`i0Dl|^( zTJyZ>k!^R+;Y&VJf6q-6?OiVNXT^iRHfMa7c|>undh_t@;;@+_hIfudd6>>`>y`MH z6S`hf{i!8ji~R(xSf)h3cFMb8~0Ak3k=y+o?u=u zZysB{=X0Yd#n>q(o!U>lwRR*)ofmr%(P*;M%vnx$()~l9x_5qg{NYzg;gvTkGs@FF z74MX&w60OC&6f-Oeox@T^L_PJ&sM**JgNI}pWV&AfEP;n-7@h<)x>jh4sq31em|?{ zccLKIUH!5+KU=b*?lk7q!d1sS%w{VUBul-YpnYw}-cl*)rxqExo(EN1M3|raxzNm; zy!ocYmgO-6HoCsWkqB~$);bLZYWM zGA3SDO_7vt$=0t^<(cF&Swp1seT!g#?#G3-o;FLv+A~aNdH%?G`Q+)TU#q1}Chwjb zkXiZISN!HaS8d-26)oj#b(Qb$D~%t_a=NIkG^a-K&FzMwpHg!}m-V`Nty0lmb>p?p zi8VSaI*ufsS$3vK$6(oUE~OJn|6QJXyjT%q%-M6CY14wFg+-@~HI^({uBddTC#YH5 zAm>oWnqyrutpes+?J7;%el<+57e!n|%2gyV->~ z9VdkD-#)Q^QP)jt5$k0k%L~u$^o})JDZ4B`u1ZGBKXTGc6!!)jUZol&xiE&F2rCW>Y5Z(0G?|E5zkV?Ct&9NzPuIZq>~d zVLTOhddG`*D}D-_v;Inb^yAk_t+`E8*w)1!omy(+Iqfp@eTfs#pIuC^;y7UwXJcLT zd3yM_c?H`pDavj)yd-q-T2Io5L4 z?%jktv&yoo%zyugoNC{*D)Dp_pTOJS?;i5+s^|O}H1FVJw+WxrOR~C@{L}ZEyxm?K zV0&@J_W#k26U%Riy(~PjSiw-KPTQ?NGNnBI=D|%C6Q5i%n>TG$?$)NLuzMk8(x z6T3e#@ow^oWpf#RTtE2H%r-o$Y_Iqs$Jp?5Ch?m;R-F2{<z@l!SFQN1_OkBBZLWe#x6*|SUtDZ5J*Vn$_KxDr236$=X|F%LZ@;;!reU%0FSY*N zJf-5jt(8wdWk+P4I{)zauTaBof%bDYQuPv+#ryATRQ)<~-~PU=$jLgb_lNm)r;2P{ zYBl}7#9{Y+P3%g2KTjDS{bR?eb?pb=q~PgqzMKqwzc2kvoy?N6>T_P$rYW~3&+5`~ zI?rt3``}lS^%g;kzT8?{dGq$`b8YAIMJzq7zUg>IMvtzKo8YDb6*qm3Nw$Ujxk9Zc z3RP5YeBNpIePj<7IJ5A>zE^SC1@9P_CO_&vXTWL0^Ef2> zqM4jdsikUKg#78-;ghEAI)AV9TuGpr;>+faV+$wr@P1^=vbgYU%`E0Ge{aaHQ(0(r zTqj`Pv6bHw{Pm|9lnJn@U5Hp9_pSYTK~xsAy$1UlUH#Kv&OYi$`SIxK^+T_JEUdHc z6;qs$I{A{-vG2$F?kFD@QkKtcF#P#t&%K@L(&AH;-`@W1D$%(6so(2|inlN4ui|~t zyurP=UekEL(em#5!v6j;ho6hTn0!5A!%x*!fhxzA-g(em`2BqO!oNT4GQRCT(KLC^ zktK;A*e1-lwCke%q5A8Lhp%t9e)Lly?y9`I&AfYSi}qygypu3Tt9**mAGa%lEF2Bh zKNVz8ExC331AedauL zq3`#dz{*TCeEI~ zBYTjs{T;tzO3I}Cx1EPg?mvCOe|!VW$wP`$!!MPuu(gd!Q`@9gb@IZLX+m-bmh8DS zcfybKc81EWnc8>rBL93Z(CwJhy3cE8)nYTY-M6xQuiZSVcS%K|B}Aa}-Sz&|o|-vd z=dV`Z-6zZMR`>H;tq9Y!3ta9D(tRQgEMW@Dy^Jymg2x(K6cqJmUrV;WpV?$B`dLup z$oEfX6&pUq_0OHxE3~LmNa5Xh8=6r2SuzdrwXYxDQoGZQy#d+#enE*;U<7RRpDi4Sug#NWNJE!nMmCpCVQ`@|k+<*@Fh$|bL#cbm;GHD~WCFWFo&SEMG-{KfG+do}a#ww(cd z2XxC~FS-Uli78{gl$#|Y^LXR^V}Jfno7{DV+v$bVmdNy)oSN>xPohIr^Phb@u}NpQ z-uK++ac_3}ItMgZ{=V%~ZSgLdO_nz?ehKjJAmzVp^wJNMuWSQi#cB^7e@%rW)m6jV^ zgS6)st@EGBZkb~e=xCQv!uCYwWut>lLleW^x%VZClvoQI!n!}0I|-D@8VT++{_siI zG~@Eul%oy`efJO9E~yLRk$HRQ1|wT5zc zY0vG4dn=|to8vG$`2N#)nS#$>F1{-+W;|cMc9A!)k0lCCkP%UNB-9yWeLadXTBByZa?au0$--Ka(R+nLjw`R@3rkROP7M|Mt^71h$tCyPGOR@qIvQ{+56h|G}5%6qsZt$Wj z7dJkQQLO&Kui10uTKYQ1XDdH4>zjPbe)B?j>Fp!lLfuSTcPkt)41G9@*^|Y|Meoca z!)qUS<#K-rA30k0FIC9Z(=oh6ex9xLugI$7ThA8*RWDD?M?p{aX-5thkYMU?s&0O&F5u}c}({E6Afox zWN@cHcp%`sv+n<{C?>@}iUKu_@AzNwHveosptWj`L(`#-O*1-Ie`!lCS8vjAVF+Yu ztE?5TzjswX#CF5d=f1A$S}R!{9UciZa0;?IwES-i3R{q{NK3Qh*P7I2tGYB+bj|AW z($L~qmbEHvnTBSYf|8b-LZ?#KtW^tUajfdToN~rdRnS#1*pp`|kB3W8kkMq;U{OyO zPZv*5@n5I4fAJKon9`V-sim<{OD$ljkj65t6&;LCTpFEPE0b1eO;haDP!mvUTDhu4 zGOR^H!ZkzUzh`sTRF+`nAg8WL0zwlmoiRTUyXHd0t(j4Y3p-b7WlZdxn5ZzREp@_- z4vjXBPAMlQMTsdLlQPXQE(EGRZ!r*3 zX_8ttL*aG8sb`6%LIKQLWpgC5jAcR^I3wCJIhdSU7By*Uv2p~cHYs*-t}rk-p|YT9 z(WGUQn3gSKQfv}yQfgT!G3m5c8bik-j|ECBOFL&QOWJI(Op0TX634Qx427nqX$x9A zva&q1JTx+zI+tEE32`GtJ;PF#m@JKnWjyd)xoq< zN{vZHDr@B`m97=5GLtg)Mz)Ih__8#r201D^TUrg(Xa2qRc#ibiVkOat^~OX3b;518#8#yJZ=h6QDF(; z5%O?V`O?$0vQ4FRiIS2^m&7y$rG${iur3YHMT#0TT@^wXESk{p!g{68uCS=ayQOwc z)6M<~?p^(-JYbT*+#6wzfhXKo$4|Q6*%odwL(u10$|aY8kSQX?iEI_=Q`jEtJ1x{N zfBx0qvpH|vb%Gf!9#1yN5;*3S+3~UARKubqHPr-aJ@CO2yfuJ!1NN}JABxJXL-R<+M#ttUUX@=eGVSMq4e;+&+V(3G^4O`vOrQqWQ* z&o<5^C#kH2MV*`qD;9c1v}!C|(8;A0pZXz6O+&SfvB`^R66XZYkZF-!PL3^{Ge6%H zRd8t(ax@k(VASdj2^8`)GIH`%5jv<8z#8Jz;vmS%E6Q>(SkTbaFl32oV88)aP{0Ve z@~|2l7IF;o3UM_QIdoCzOrR^PqQFHKokJU3nY=@MS+0ZxGV<~$is}do8!HAHni>WK zi13KAIC}?~c(P12m=q%7;xk21#K3*SWX_}xCbrBKQVW`t+BnnP92#dPbu7`~Q0Z`3 z!I8A6rD2NHj3pgXntPOm6cp52G@E8fG5y#q)RCmgw5-#kLv7|VhE)rcf>c!97&@kS zatgL;bnxvhfJ=)a6h<6mC&amTYKLNfOCa-^L2m=chB+p*CxMD2IB&r(f86%nJ; z4p)8Td7kjs-@CX#tGVb2qm#Uh;zW-l(^lPO>j+5+o+Wg?J8VXrwK~%m@&2<*HLvm( zvd62kKkeMUY(nnouMxI}ep24IyDe9pyHS+tep&3#6`MaAPdmOZ{_c2A>Vf{RMMdQ= zh5lEIew?~=l4+Z&OF$j}*|kLE_dkUu?SoV{1 z`LZxm)mBHN$i9TMwT^GLOZCs@Go5{0Y5I%f&rF+*M6dBM74vv0H~FkzcVG6`o$Sz~ zcQ0JOUbMfDXGz14H4EzYe0}LZ>+*uhB9C{!x%W<~WzB5EBA-oM%XCg0*3jb6TA<;z zWKl%NW`j*UT$^O96xfwZj$X1H})S+ zz5=!BzKRzbH5N_D(DbbO@!D;pf{KzeTjL)ggAL!*1S45$jI0(;m&o2<7i}0hVX2b> z=S#LwC7*(24l^e4N^*QDU1GRy=Bzo3%+wbATP!1~#HF-^xky=%B_L1SC)V4XG#z`rX#5Sg0NFUs3kh!Y;cGwwR0A9_#_B zo!gFeD#>s>vF!~zE#)#%{_&Zl75rfd(%0BL-8%mo&i!^mmf}RmE$4rt+OQnqp++u*zF9;6#(e#!X2A&1s1N7uOUkJUF;% zGfzl@)gzG>c1e!9{f7g4c~lziNG@g;Ne_@%;^O5g>MA*-L*@}H)5|q77fe)*3|AbF z^30W5He-PhL(dsubp;JSpVGw=LCZQ-l!F(sJ8CVHXw^yzFbtZSSkaP|w1`P)nbagM z&W<+CrPmS+XXKfjHVMCUQ`Av!?X1IwTpt@Quk^`C@|d)6WmD3EMU9h$G}GL)S{89| zDy>jb@=EJc(okF_ku;^TLro=VnVQ0sR#l}Wt&nq#vy`|Tr$=bFd3Q@DTyo_04ph}m zYw}f7>#^9h_O(O3+z0cH6lQ@-M_L6HJwz57iFAfAT?hzONO{^DY4Rj3at7nXT&dgY-^5~@M>VO%6u9n@cRz2Om!mSnw5(2Caj*2t8LXCWuuzIFV zj!L*DIk|hrLEg@(Z3zOC(mPt1U&k;Tbqr4eJ0_fDP_T{&|UW)-LyugOr_A~4C-`|hk> z0qHYNs$b5XO>}vXP*XPJU(YFXK5@$)))1+UsdJQ?T5OU|O-{;Y6Eb2hPz+nU#g0C68>iMpiNz|ff_kJfq;evoO&2WoxgZka%4*pc+3qdD%d$n_ zBDWzEi&nrjVU_3WBbX^idkHcDageU`wj`EOsBg@Bi{;XB^AXAi2*M@~`9 zQCxq@ORpM|ZdJ=B(k1`nyE(hz<)wo^}58j-Tqk>*r7Zo~rXYL62t_hlE?hk-u9a5?p#F z{95cH^Q%9c;V^ULeS@!d^=GpMo>^_xRaLb*aq$ng77*vNoR5 z$ejIXnVOo*xmMTbaw0Puel1GL&Q=ay@BhZu^4+?}tXt1LYP$3@pd`Gb=J)aW;?GQV z-h8uN*LXbFIc9p9t5%0b<>FnBqz$f}J;=B<=#6Y!;}UPXl_x)K@@dpiyaQvT;xH%m5drdzSS zh|VLyG{p@!d>2l*|0PeM?x}=o-~Bwcg**DBTQvVi=|?#;#kKH>jbAOO! zbm_Wrf?ZQ_TZ7*Mx%QUpbz3G0Iq$w~w))!h7`~%My>IrYWw*Zipy08`prByF(*Wy* z4QIQjEy};WUR~GZPVAN0?pcx239*7X7Hxcoe(avc7v!XzyYQIKU-22?3w%1)q?!c; zL>)BEG}yyu{o|**sN$BhCH^cn##X|WU;Fz$ILA+(Jmu_7CXc%OX-vhhCtul|v*C<7 z`}_)x$ssYE#+-eJrhTbzo)~xU+VK@D94A(J`QD%Utg5nL%MS(N0*>is+@6ZZrUo2d zCVFzdSjB_am(87?nQb{TGrgI;ChAFj0f*R&yQ2tF=wl6 zzCNgGXZM@8YKnz#ry~o$5u=3EnSvz?H%wVHSt*@^>jc|z8I`7%Ne&Yo@=T>#1GFSo z2`rm<`mS_ov!ddZ#i^>l&;4~?aN~6Yc#P&`8lc(|uRrt;e7daxTvOLg}e>c;vq{AQM zZmkk4_c-?Jd;RjoQY&Y?`^on*`BL&^nf5Nr>mGJp6*s~@&*0h=bSY?+LiU9%UMzdG*86%z;!n5E+Iw{Q{TlG-Bv=daJT_dZH>U0l$<<*T^2 zgp1V!sgpB9KKn)FwJxf7kZ^Pb+l@I(tb;%PaDDP~v+Z90p1ZMPyc?`{?zc#Y$xBnx zU-QIr_fdi0%v-FSCOi-*^jWgRx{dj*jG5xTE7Fp)yv=o9n`}Bf`RlwMyZ(Ld&O7)& z2x$ItNSM&d|NQIKQ2q;*3`cUsLEINOH`Ol*X$I=3}2)A*%w%vHPQne_iUH7Tfx~70@yFC-q zzZY-0S9iD1jjv(LmnrSfn2tVHa1JSHoy7ETnfSNT+WZ%Th(6 z^!1b@CW{h0p7SMKGL8BDGl%Q&l?cv7AJ`K%G-*pFmb_p3wp4E#$Gi`!M|ABj&pQ10 z(X-lJkY6b2l(J!Y5m+;c;w$N|Okvuqdh{P|K}^7a0O!o1m$>8dGR2PTX1oH^pT zIj<^%<<-yM$UQr=;PClvIVBr7yV$%M za{5(I+-z=Y|9)5SS#8&}RYXn6PR zjMJ48wuoJPcQjV+XkEC@F6+qqXM1*9-JQdC+f#1k&Kv4{?1#6{lS=tz#J}dj*NYZ; zJ34b^Z+_!H{ZM;9`{hG>?jC!0<-;?%ZcAxGE z%ch8)FUy^<+i!Qu7U%h`zw2kJY?l1CD0!D%!tCV+g&(q#n;1VNOuE^z#m}g0mZ!?C zy@g6*fp?c~XgrsFf93ix)vDK(vwywWAZ}oBgU8n`b1Y7Be7B}ETs8D?fv&A^azWILmBH%A9emg>08yKK7r%}e*G~19ppUu=Ygy+fk18?*Bx9HwCG2ysT zCSOoA@AtJG@1DhZDxSHvPSGZPLfsYzpFe4^+%yk=QuYGZ?{8ZN=3sXUzW!K+f+;`!+{Jq!i{90jBELY?fdX77E zZ>RgafOV=W8o75Xp1N4RU3#y}>2UP44`(MkZFqlb^JUk9)7kq&T&re>eXKlct~Osg zE?nPfy^c(q>cQi8rGEHE9n!54$XECs{AsbvzKRF4Zaz3%sC)Kbdf%_^)4FS~?0(;Q zVA+g)Y>RgN-QwzKwrysPv~FM6oXCZ1@9VW3IJ?r|>L&ZUe@o@-W(IQwf3{iDF8c0O z=aG(&pJnyWvnlF7TUw+3!+-VpbdHUC{=L$8H(92MO`uIM( z1gY0Qi)2ihS16^aPuZQhqVKUyaBkoJ`+t_(ZFxG+(uVEyy3JOOpCx%De}29*_sP!! zVGZUss~*W+rClqIc3S=@58Qkv*kP7Q<1#&AQ;szb580PI6x?6Up=dB=flhzriYZ1+ z%sMgCIi*w^7Ze$IOp|-(6d&lo09ctm>_Mm^AnqdZrk}Ua|aLT*Nia=Vb@0*}+9BEuo8M+`C%O zKlcq+_WF+kA#Kn zt9FCrp<3&`vGZmvFE;*NU3JHrf3k1X>->X%rk(xgb(pMAJ9af9L|k2jBV zE5G0D{F^g#t@-0gM&D}hzS{cu&6*P~PYo9^uG6T^xH!R&(c@p&3Qkw)$%PNj-Evg9 zZgPWhF3-#_xoTcd1fJh7JhVOc=zQkg^S3D;75sSY;&DeQb= z!PdB?u;G5?Ce^uFv8NR|PJX-fd*V^1Pgm3A1#i!-UQz9|>_Yb>pGPc;3duo#?lNyk zR(Z)9yt?sOW39|q10mb=O%2z76lY~QSWNJ4DmM4t$m%d_72{v6fcvKxIh!3}Uaf83 zS2yWLFTcOr%oh%~S(BNHgEQKz)BBDW%JBUPP)m`$wm;mlx8L7z=8nc)%9qavOlWx8 z5wP=UW^;hhwG*mw!J>&Ti9qyx<-GGOwk_EflvL z+To+3ZsyUlYVpa}`<87|Nt{y`!E;r4$(3BY>&g3rC$6$BzQOo7cWt2rjX^*FU{+&X3lg@>{pN?7wt7uONmy|80)${5}t9-tSu` z8O3k+UvuuhZ{X*0*1wnK*F{$u&65*)eg1Lt)#{&zpEq~-rF?Ue+aV=>@8l&v<(v7F zxAn6vd|lGt#Bil1Xm_vUBvlQ@i>K#Kc&75kTuRRC%E1$hmaO!xUA$dq#j=2`^t$|b zou+kZDmLt9i|2YM+_=x6%rarZgq5e+PqOVg)gshav`2VZ;TbFENrwZ=O9EOo*G}%S zN;}GyVfyM2WBKi4n?yHM)*tKF38>n)Fm6wtQGkOY%lj|vI+D>Tja}>h$BIcFV$V`* zo4#~jqPK~He6^ab-K7T;oPri?UA1bK`mKk%(pl8H4++bbC%WJH`f^R;L@CV=}#GV*432Pt!hkL{;27Cu}(a6f|(D$!PhUnQ(h^Ti0#xX|8OgKd#C0 z%<)o>X;Z$r(&zTv53|kNLV_nX{wR2EvSp>>VwHF88c~K5f7abhs%1H5vuVLkx0dMN zYtkmnf2NvKdy8?^nfZpQ+X~Lv{gnQ9HS)Lp`s**hRsAW=*Sy?140sY_1jBNcIWSZ zeBXIV?WC#&i`9Q{bm{c$^VmO`*U>p&rrY4(N&eY=I*<4Kd-poy%jE5U;y?PmNWZ;r z>&jqm-y;`)?LQw_n`anrb?o!q+Zlax>eziIs2DGk&EI{mbnzt^WXS% z{B7q;HoIJ==E%F>{ZWwnb<4tKi?s4Q&IVjmy71%A#jxv(zuNHxKVMSsuJ}Fi`?6Kd z+*%t#;6O!TQcS8uUDoBG7&l7``dRXS%bGjvHRXm%}s`l@!x(${S= z?=Eh--XXfxIOB3h{um)Zaa3pZQ2>*{W4d zKMa3P%n7drBTm1Zss7^KhWE@}d*7D{{xm!5{)zwV zuSIK*f4RK%@b$Cb-Cl*S|90h%$-mUw1>5D5hLcPOR~XXSuA)J}kTWjPWS{PNCyZUrc9K z-fw;Qk^2Wv^*HITsaJnaNURf4c5mRl;&OiJ_jOs)lf7>U`_zlCS@xar8t2Bad+LIB zUo(qeu`SkG1qQ3{y_@2eZd7oReZm4AiA8x~pB?I)oE6mzZ=~LTW#6{=T>bXXNt#cS z=6zht@xSPw?{n*@%kO(!gC8b+G}e0ivBx#|YLa1};(Up7g>zhO)+9Za{$|Zy|K&lB z;f{iBE_)?a)y)It7kRKcYB5Uh|8`j5hf3L-!v-sL@9SxvXPV=WQ_1PM?1cw%uLx~ICoy-il^@N3m)!j}cY;*CIvM<{{n`C@-+%Efu_jwsl z#*~&Ti&yc*>v}}5GkMQ^mDT!0c<1@=KZ`P#98;)wx_x+ym0T=e@y2UMB{Iq;*(^*i zWBlwsZNGkJgVLh8heZ-(JmxW2cX+S8lY8dO-6AF>H4YAibMs%v^(h})l#sfi@RD`P z+3qTimmQbyoZZ43HKW>>)y#ZZ>`~J#j8{5xpY7(C2t2-K_5-Vex9|OC9rBvexnIy) zZVGdo^s6YLn3~f3n}HnXZ%Utd@O3S-b@kDkPXqiMcp2X`EHQE@FACkf=!l4rQTxm8 znac$(pFL3$@~q=oxtcun6{{Hskr>na)3#He5ik@-y z%|b<$Nhyy?Eas}-IG!O>@N(tB7h4OS{7atF@2udlq^GCh?7ZsRPlX-`Db1MF?ege| ziJ>m9iO5n@-=LsNQ?{5~b`ZI6;lJpl02jvf)Fs(3zw*OR9^*sA$!! zfQ3pNE0f=DN^9PgGWXzJNwLaZ{D!+{o=yIizN}`_Dlb3x3}?@RXJ=Ntod5Wl9namR z-~Ptezd65q^O^Sm2PQeK=xS4#(b+XgX_?oWO&eMN>!@vgys)IpVY2mHr>Fjz z3+_uOwl$t{`gdnJg9n4kqX3N=1rNF+dg7nX|8#3t>BS58-e0PpY|geI_DxvhDcP6e zqQ5S<*>BwWTYl=fF1xTZTenUx__mqr`mTe``+pw(e5F?KZmY!Q@6Tr6-T$rJuTeVV z)!&~pgqJ*?@cg~oPQJx|*xR-$Em>7oVic>x_hk91^ZcQ?fzzXIZ$EtP-}c8h^;#$E zsIIufs4-FHP|2gPWY(~VNQuXiY~}~8vevq#I_vhxdbu3jklY;KGr98bx)}*)3qrRE ziZ=>8Dv(Jv;0P3dJ~dG9x9QC`)t9UP&X~kl`@iOVMDx$uzFH$srAd}wf7ng_`1`R< z(ZBWQ-_JkD{cqMfcLRTpej`q$?nw)qMeoSlvqiDW_XS?b@ja$|$oJCkn)>aF`(JS` zI_7@kOXsS2_Wb+P^S)f?;eGrr z%BC&#OnObqr&HP!)eD_JpD;0-=;6qd5u_FvU@~QnPiA??ik68J9?Q=!R|)Ue-}7O? zY}t=#tK`>z`8#XoqPW9sHD>~+bvj@1UZ}M#p!#Lq=L@sH@%hinsY|oaMl+I)F7r%Xd(Khqa@y&c$x-&fH zig?&;zWbV;_uQjI`3Eyh)RNfzcpv*1GIi(PE?XnGV%x;#t-9-8mRcNgWMnvRlpHeA z@M*)7T){`4Gmb7gXkdGyGNOZh@5`_`Cg&UynLRo`f67@Dw)nXA>^l`x=iIR{_c!J) zXylo>*UYRmzAX3Y`;W3;LYJ&P5%xMDH@V+YbX%EDZRP*jYxajvJ#>Cnk(i}SQrt;{r@o&m zGv2n(*}QA;*yqaL&Gv~IUqtK-n z@$2uNX3I26a?0neb}nC6@U_&ru{->H_TP7{3)6#q+dzpEsZZC+%#bX^Xg&F29BboIp*_hWo& z{z_T-Jd9_5a&hr5w~C{m#80L!HsoD2VbAKK!}b2UH+IT+#uoEjShgqaZ&m7|==mpS zE!;D^;KoxX*FOd&q8necOYPy{6}uTKxA@0oE@`WJ`_sY~Y9+t9FaNy##!dFSc{%s| zjM|U(Eu7`cTySzv-P$?(R@TdjPbnl(#vHbgHh7k*Q_dm2Td6l*D zU|m$n#-mf?^ZA#TN?+%x)>&pTFaG8Vp^yh($`od%%icA3 zR{d`G62Hvjd_CVw)A!f;i=_Bzq`670T&a+kU?pMTbKx#~x9iMy<(S=SU*3JSvwP2@ zxck|~mrqx1KiOc=d_s_K5(Ddwm67}7{!cDF#=7(`E7RbMexU>n>8y!)ihpI zsC96Bh%j$DD0AEQ!`vgk1p*Y!_tvCyyU+c`mu`Q3a;UGVqic}K<=ln68+(gt=g;3f z$&(X2_U-exN~>els1gOH4!mS{Y-z!L+cPurWizNzW-`7u9n%u}dy;OA91b?w9%S4@WZI>PSR(+CNKIwsM z+LIICE(J*kxqMsxWqG51Vb4ePQ__>4`wE>txAN`H%`^WBJUq*K#dU?qiwuq}2O0xz z_m!1Nn;baW>fTt}{xl~hSJFfOg{7#J@M*=DOKPMhuAWiiKZnEk@Pvymmi4=HC#UBg zjryQ=ezR_elk~+qA{H*YT@t=c&7WOS?!LEr>BnO?dhE{rQSZ2L(?FUxnNQ}=dx85G zPh=eq&JVxemlpE2GB5bCRK~yW_Bzu;*IAr1+~0oOq+ojFj7r`)4l)b>m7eEbKd1Qq z?vK;sS5LR8%yHNg{`{)O+sgaPmYiR5CTq^VLN@uxxvz@kG0Gv<6gzw5fk^MKMjJ%2a*bXA^h_i^Yo2Vo{je|E`0^yS2^MSj+_Doq zd$;EA-a~r>ZB9ND-e}(yRJ=T?CeyR2?n>w1PGOM?{_lMzZ?!o&%VkODH`U1^x8@x= zsFW4{OPFP$%4A_-;hk3MnpbR`nH||!1nL$zCKTP1*N|gW*rLV7bipwqLV$OHtm6S& zN2Y_{S(i_!?@&l!KVi_?#>9HSW+9`^L53s7TknMS^oXm**m4{ z-C21yOm`>^+jH+sKvd?fxmH_p*cbL`$p{_#z2fY>rvbO}n=`~(Zd}&gnEhg9r*NCa z-}G+A&p$^GHkt-pjXWHF%6?OjS0Gn-Q~C3K*7C>Sirg zFH6#0xN3LY%BqZq%n3n@1@zOTmAs4J`Av~&c;EVE!t<{o=F2CivA&)Ywz%o;W`>q| z1%GyKN@!bV8P!z1zb5&agqzE?$;(O}IrO_OD?Q2Gb@S1iTSg~sUe2BP;8ftXgxL#M z<~TjdX0*8{q|`FS>q6hpW87MwBi@-FF1kOJc}nZW(g^j#Az$9jx7{5!drrijkfcYw zt}Jd(qV~?2Fpq7so+_FnF>~GBU6*T~ zG4XDEt84s}^D}!_Mn=KHznAugtlcl&TzS)nKjg*|<sR5^t6M(( z6!KJDB&x8%AoE1#oHb?so&G*|MP{joPFg$n;<=fxRcyCN*Bw2yIrRHyyXke))(K4Q zyLso=HIJkdwq1LCr8Y1mK3Q}^@*u~&(~HU?zTUSgW&6bMN5+;CfVO=QCN&iC5;`t6tXFP~DAbA9uYK-PP|=IuVYQo_UF zu)yUjjJI}_S3b{6@qeyTbEVgBh2rTu{T!!8*Zzqk@-<^#b>c8ulygr#yVy+H&$;?}iD> zOy-?74gT}DcHTO_+S?WLFRqqawYjcAheZK_?U+nf>*DcyWiO;I|Qcaj?; zrrPX&;e06Bd7|A`eL-$vP9N#_i;|UeY**eC%2_8}_}61jy5{S*Et>K$w0{0!hkuehX)EHB6mnMHXlL2u^t_{+tv2@n4X_y|p&)-@NL7`bz8Y>4F*a8l4UqSsPC%Ox~?>NJ&j` zf`i4ESi6{)Nr%oTa&1eku`&PAd$%5RwEw1@5A(QA79<;+0c%ZFzt^PKUi z`@P}Vrm*X4j*1H>N*oa2IpoClMDJ(i&HGQ1FNr+nxjkcw$hEikWoGGB)tmqLfA;78 ztMYd~|93wBCx80tntSTv#s9*3{7PQ4DGF`aa^=I1bA|kd7RTnToF8>otL6RlYo%Ob zLOjv0vL%mMkex9JZxn*x)|i>?8+M5vA)q+v*9MM&CCyt z5o&7s;hW!xzfG`Pv{ipqOv%+~)7Nw2{{4Pt@kli1o)723>2-7S?;cbYHdAp2{?YobrP+G%Db45=IlHt1-9T-}$s}h%zsMQO98RlmTg5E&txo^y9a)_vQ6dtP<%M=E6Fs@4-IHfU z`Mn3Peopu|d(PDVjR*3Lw%qpg*V>R0uD;M@iNzOpi&-02w5`@s$Xu6p=}ui|z~TC0 zhIKLXw5}^YDstW4ZZGhg$!-ImZSgGYbFndQseji9W%!*b_Yr@$;Z5AhbCFuB1m|Ba z>^akuxhr*PPot5x$C6ILv<+8Yol%mX{(|@It&2B1nBCq^a(0nh6H*%~JagxSaL!Gv zNhK<6fv?v({^D!Xy|zC^VqII->$+dHvwqDwS~!ub?!>#!Z02nXjSqOLr#mxUvv|}n zN#M=ooyszm=aMI!URGek+dN(L@y#FMdk%M0{I+}T84-4sb;G-lMou1{zHM1Qs&*M4 ztX%Bgx2IO!v{5WtYm$Fx)>FF+GIKT^Tgsjh_jKa>Z@IGG%~!%=+fTbXMcqH}A=0$J zIBzzStE)>j-zp#VSK)`&8n!FnG}l@cU=iN9a)Ok=B~#W1EgV2MH$6wsuva`@ICg}LvTjCp356{^6@K!~$bIx^_S%NE;`krv@DB5XQd+WQN z$%DC<_ub&-hp7RJE$-fEy>oj1kf3mE9ESGuL$U1dczQ%Oo!s)bgJ))b=^tv&?wC06%3&wW^O%icd^ z&n@%AC!d$5EM$KWl~w*}R_&z?R+{I#%Wh29O>b)Zp691`gr((p2-Aj#N8UcTuk$P| zMI|CLRN5$TL*b_vA(4tIK~5e*t|}^%EQCBx+V3f7Yy9-lD*La&s*P_HfBoLwVs=WQ zG$H$YwvF04vFCk_f4r}*^fNnA`uLef-)-4@=PlPfTD$0QiD2&jc(I#5&qe8n=`BhS zzjt=R3=dD;lhYobzBp0FBzn8_7Y#2>18R_k6Q-}7VU{pmbbKCdel zS^pNyT~yZS$G6$ws&05$$ChoEF6_*RIdiz$^!MLi<|ii_T?)`u@wu|bq43eS z%d5KnUbEX@l2$N&%=xIfR?*1E+wriJ&Zj#+7q%H0s2ChJ+)z^Tz~Z!e=tcyUtmbg6Vwn^0o)^!z0+t8Mm1{jKFaWGiP|@t zdE3?VjkAPwR8ovI+E$l-yk0x|eywDirnkanr6&$mv*sG@-8S!r#e@|P4c=eA-OKa% zrr*UsbAEHrZ8>vO!D&X!Vi)f#&jez{OQyG-yPP`)3{!iJM zN7y?3;_~^=+S@ODTJw$L#l;iVJ5>bde0P7I7xX6mvTfC$xeJA-PRVTd>fb1&nAH$B zx20=!)iTf34+@xli_dO9ocn3Zqi~Z+bNk!A@4KnGYRRNlleKAS31*7&C3Ss%7WWl@ z2X5hQJNYY3bDP8$zK*sG`wLl&&QU_qSMxL#^OHRn@-CV9>~QCuj$Gzo)tO&YAh? z*1c@u4G!u2Z|;0ozBSA6Nz0_klO`Y4;`4nPQ}W4g+NAQ7cQ+2GawG?DA`*Gp#(+_L-n z%e`V<^bgA;FXC)Z$ItE8O1rso$LxLnw>~=GDm=08A%EQ`1^%Ki*Kd)kGpDL8Jk|Vm zQ*P?-v|eFx$%)%<+o`#K{CKQaY@3xw)Kf|I;*T{Nu3vu4b+Vtc79-w(@(u$&MouLg)0~5e-U9l{9Eeg z(UQ8uyCkYC_D63`^5NgS=V|fYcjp(UuRr+sY52|q{I?x{+n)K@{rBC!AB!AU*!kE? zEL7om$D-hV+lQl#k#VPEt7w9K4u4R<)?-J-elD00@k}~1;o#@DiGO!5__H|Sp(;DW z!-G5*Ya7fjTO_9FbM$(I%>LskIU%h>R^eHKqCggNn^K8`i4Wg$C549bQhEy~>bwxp zTsYz4#x1NFH~uz$=a9O+I(|KO%iqLTbtg(>1ny7oH`w&o=#xV25eK=v<4d=m=;7ph zo9eDUEr?(LF7LDrH*8%v#BW-eGm`TuJ9IlKJx%c}Ap>@5ui0Tq4c3zPJg-t`RVtGnT-(z5o(+peya=2p*Cx1YSU zYr@~m<1dbHFHu^t(pb((E4vE! z${yXlrOP1gsI|JCzb*1V|PeD}h2ewmGv`ev#6ws7Tg?0vSd zA$0R zd7*;myki$y2@^O$L#=5a2zpICSB!A{?t-Rq{S z$tz{Xyj;b2aY?H5_2;jPxNA7HPH8L`5$*cFPD<&KXy*sll^a_3Hc#I7MpJ87|MGb& zz1>%-iM?ER;$+p~ZCUrM6|#(`eEl2$%wm6ja=W_ioOxarMIVmKCq4B3ZLmma@`V+1 zMZAJS0zNP5@bY(BR3iVdt7}Dd8xOGBar@4?^9aDqD55>6)CGxap zx^i|OS2Nkd?_!n9Ibq?6J8zx`t~#;NZSk*(s+YeNaCNUee1p|P@z2zY?3=y?KbG%2 zYF-+yd~DK>{+?igU$5VMKRf;9&R1W5G1gd5379V|^D%3S<*&o+>z+y1{#bWcVp4v> zwa*UhqQ$%9t1eGH^kkc_xAjWxvr}A-K6E|h6tK4HHOKkuFaOGjEq-?6lCS=bjFKsG z@iSZ;<+q%Ex&2e|Dr*^IV}-}MZx$~BWIRXSL@8<#bsN(XF1N=n$x?Vm$$I>pNNz}+|M&HM+*98 zY8i`cS9$d?Jx29x_2TZx)aGV`S=V+x2r*kNlc1RQJL%)vb@MYk?q*i+j9Fvprdh}y zUZ#F$`kWNk(nU&sGCN*hE{%B}WxQZ%{ASy{_E`tjFIp=Hy=+OeZ@=D`wBhB^`R*p& z#&jgp1WtAzUtl~o6tE?cixOQ-s$@HMRSyP`{%V?w?5jhlljc_{O+k` zF;07V{>QUd&*PN}owjeo-rZrDsS@X1N|sko%9niHC9S=CpY92dL+5Vyh&SGkIPJ`G zR>vj!%(J?Mu@86k*vUR*IUQIcblP`U$m@`(>w0F{r^45{ls?(Vdp7gbwLhDbjtdBe ztv_U$R_%3KQzbl9NiM%;G3!dtp1obpaqTbn&gIdvv3+^p@AtA5lin0(+Xnx&yBAv{ zx349Cb?PkLwF@$r&&(IO7QAd{$gM@EdNl5aGk%zxdo|(Hs!B$^r@2B4H78Zf&D~(< zp*=JC^?|Cp>5MO<Y&V?mQREy~Tb}3wPMHCCgX+m45S6E=uDmgDFQ^{;PKkXYTdh3M+f{ z?4s$ZxqR2Z_?|d;R^m`!h4r(OOOh4MPWO4ra^w7LCFTjmepV-qg{JL!-93BmHztQWN$mOc&wsjCU%2akD_F5l`S#g>i>2&e zUhZ;PYqy|2N}y?(8zYIP0!{5)uP}cV1qAoiVL$A38O&d=ynS9&aaOdM_J$bXAerIIY7_2K_B|1l= zB||6Tmx$Sqb1LtC>8-r%`($yL8va<8*-~K4A zzxyJ&Df!VHpOdAs#cSR@3cOd*QLt#`1Yg0@xp&NdKCQfb{MAgMzWt6VpZf2X9{sRz z%BD0)j`-EGj#q8hKV-_v4N=ipHSZCZ-;U%fAN!Y;)+%k53bD?a`0QNx^o(skwU+-{ zu}$JHwJ7IG zt-yV2g>{wpSMe9!KOIuIs%h;s@!PZgoqAu)s$kXJetaI^=`6M051SZYn=|M0%|8=j zpK|?Pe|z>3`}wAk2eO+xUqwd0$(C-vasB!2PqR*!r`D7m)X1*!m%sn?rT98&zB212 zVZSrp-m3_|UwF@7+dH=X;PkCGrNo!1AAYnwkZbuu1%V2m@;UR9r?(ZW+0Q=D8n?mC zYVpBGH;V3YmQ9U3DERMde9GtbXL-+>J^p!SPQ}xYKhIAME_kKL8}y}7y=UgWr%k*@ zJ&Aofm%3-(D|_^|iDU8dRn<$5KRxzLk$?{8)&We0iKE%`aKq}uPve~~GR4bJmd zR3=_OE4Ef-?O}HNkH^>komD9;c}69nBvq2V_qW~s(|grdindHqy}x@3=l!jQX~z?e z)z(Ju>$`gG;Hh5o%{4ns531j6*OmU^vn{{Ml*NCkmwv2uwc5ddCfyac-_7beE74X| zwN0ScU#I&*>8utO{}~$FL%&5@oq=plnt46a@nsYJr>wFzq9=I+F92(D(9#F<+8KqS?6~C^)`i+JLhx1I;`SN zJo2RX%dSP;zFiBK=cxJJ^KjGO=6UN54R-AgxVC!o^~ck;cAIQTNX>S- z^76um7P+9V4vWhfS4}>LOqYFhbk=Oyn{Kxj2i&2z~_WSiW$t<}! z-+B5nuA@Q$TOzk~c%RHON)>8Zvcs#Dnej|c#rEg!`cAwyr*Z`goEIJ1?tALao_^LO z8*^tT%@ez9TO3zTWzp@?u6THSnNX{W#J6elKF0nNNKrZcHeg#v#(r*-$F1?bf3{7` zWWE`Dk1J@I^rE6e`|_OjOjF)_@)p~R*c5qltqmU+Esin4s_3bOPCm^Meg1*p!Cr1}rj*kxA^!7pUFPL-Z7QC^?j7=Rx_pgX?CTqX zEH}4J_ZN^j>Z#j(f&x zFZ{)}=-13ubIu!Guc+sGoZ2US_UI=a)6{;y?t6=!lxB8kpL2;is>}Cw&7l*FoHK%@ zl}kRPC1uEO~x?^6%$sJR-+-n(&&tF?8_<0iE^Gp8#aFL`%Q{zK>6Kgz)mH~q3c{r;4q_j{XX>tCNd?Dp^E z%tIYn@9J%?$H!TGUw=uccFukM?6Xrmzwqn+efwp%&DN>WOkYpB%=&AV5YVV5nWb~+ zyv)K(=dVROcekE1UAb>*qvGTCl9Q3IbtZ(=HFg*r$q?GruIN8udDz`|SNDa7Y;D|d zsl8D87LzKs@#WI6=a2N3sATA_ySCY;gy(v5$f2Y~|CcOU^LYD0!I{U;?%MU`WBj>? zm!D|ctau-FxkL2pt-H=ZPhzOU%1Nh&5%#KZuz3h?CpV%6B7SPG+*_1{@7Sp z-RDrA{AY9PeDB*WiqoRXS#?+bT(K$Hvzv}U+h{Q^gHKn+N*1?%d_*|AgQ5Ozs z+MMxnqiVdL#nJ@fBW^b%D+6ZrMU{vb8+^MRb}@WCXV;CoY;!Z4D(l|Ma;Ea-qIWOc z<`XchSJSJTpSvuReLv)L}DcrGYq6PHYB{?xi_!JC#v z$9foc=R|h-_T5%o%=094wZkh`gY%Ke$Gn;j={fH2WSDSK@~2`y?~zwp4wEz8v}T91 zrb>j}*>Nu0Z5!vYSF6-2w(iNAYVlR@(uu{*_ou6vs64yh>bftB@dzi+?Uu`1Pqg_* zE>{0F_koIvib;&Li^A`#_uFPj<@?Rx7hD?UA#`P5=Wf|8mnP>;Razn(^sdoJpha!z zi#oo$vf;O1ym)-}^y5b#FQ2T8`I?$)nzL?h`zeQ)SzTY6ti4uo@&}(Rx^(X6!Q1oZ z6|Z@gw*TJmnrjYIL#KsKi%dBi;oBA#DLFG#GSuX%WMo*xT$PvVPGbLkEkfTcvHtmg z*8b$e={Y*<4&I+%qIgK>-N%)GCU^XBwiDaK6vB$3wB$~-o~BMii|ZsHk;wb z(^VOt7j*4C-uu;2PDpci3NPPlZp|Kk89t+3mw75rT@+h)>4jC5MtgEg!WZM>7G~xp z%G%pvy4shWQo>ZulN==mL(v@ef zlvq2hQhv2~>;BtoZ!CZF)B8nJT-D4!^A^88|HwVp)cw3|&a;j3x1I-`=fCJ{w)^Ad zq_?{d^_ofwtX+SanaQ`fR5~F@Fa3vkO|5vG-R%?U0`FAzwY4r<>!rgJnfQZWwFlrEWc)pQZd;Uo7uRvhNt z@M2v+~-{_NY9s>;7>EFbQ*U$49Q8}F+Q-DxUJMlQ-i z{4cLBcWY0xi_OESs+lL32|u@A zr2b)1ptAQAzIRst{?6x}bLDQS(G zubGr)+eTBaAh~x!%Sr_1tL_qDyw*_55|)v<;=@e2W=5HXO6ehI!xbX71o%`22ncf= zowY4==iWU(q!mnV?5gKg`TJ+#s`}DOg%Th8=HoFx4EJ>8d}@~W%#qA~ka2L$b>8eN zvo3sG|GJ{+Z1QxTUk84d&-fZ1_^|X_jdN?W)Ty0s|IYH(o0z!m%o$+aUF?RjRnR6B5W?)K{E z+tM>*ORvY~UXPh}Jt7>$EWH;0saR*zX{}S6PV0bC+0$a9Rhv$A8*`m0n60#3l2uA; z)sZ)IPv`c2xSp4O*>#myb8&tV>$RG#TXvSj%*b|H{m$iL|N7U4*TUv^T6H>^SRdYU z=*<)Tndx8CFIW92jb^^IcYcnYr+rtIh_KWI6Jbt8oR)2Qm=L0u|X@B20xOA2OtGH69cbh8q4HDI&En@JQrq7~Ny|@T;eGW@a?AdM z3rgQjHearv$~o!45~o!c&i4DvT$b(|@x#p|ra$mk_;tA~l`jpYPS>}%FMsplM#g^c zcYDo_3GQ5f@nVQm%o!(E9c_89X1jo_M`xF_Pm`;>rr0d$Kf86dT}7o6zx3xNO-9=# zrk`3RH%o1@^dgJq2s_a&IcH8uhq9c0FICtXQlID?ufDhB`GWk1oBFbJcRRJrNjGOZ zxn`zuU}mw2hFVwL3}dV4x~i>D%ceZ>`uOQ?O76YK7M%-woy-=w<}VcVNy*){ZENOa zzi0EWtySbOEIRth=je2Yix(o_t(t$;zipC`)YdN=hl9Tf9TGdA%%62UW`XXhfNPh7 zMVFcgx-+hP$Z=Wb5YN%7%D)Sb{q%GFVkxA#(&58Zzj0q( z6F+tzz8WUawO-U@!^ZC8^`Xa7^=h!_9I<#^*ym z5_b-K7IwMxPQ~oe%xzW%SHgc=cIT?yIJf)4#2bgr_%7^v@#X%LZM&OlLt`sTKE=Gu z;-1|5yWrQsOtoVjeOf({)e8@EioBJo2r%nE%IndZDjF$u{o4D`O&pDm{K@RyzP7uH z);!s`e&Z<*U9~&=m&FMeoxQVh?^{KCqoRFrg8I`ouDr=#|9w|~viHr;vF~_Q3uGr+ zSOr?W;yyjisHQH0Q>gIX`E}-8w{E31bnNXbh}vPdv|RbcdY#8+MR(g<1t-b&Ry~~5 zZ)N1}5;Id)p!HMhuigzUE+UU50ys4m`8^ckIF)+)bcbo??0flUt!iDT_f)?*zq={m*In+uIn$Ky^&1xVrDrB}zgiyl$M z*~-LYI}fSdDqq1r_sE2don1u_3Le~1^jn(zNw++Bs-;Nb<<6N~qdP84mdm&(#eT?Q z?>FZ!7s6I9b@;jH_M(5mw-WDd_V_aGrQxLOi+>mY&36miQPX{Cxl4R~3E%D&ZnG_X z*ZI9mluXu?^xofhu6s$y(JAk(RM$WH`$}B8t5kH|>3`+oir;FK`07hDt`?n@+Yr3- z^50!blN6OXoXqxa`YNxRdU*b+vge%5$>wHwzz&6B4j z7EQgZ_vytX^O`{4h`BF+eOkF#R5d0kxAsC6_lvVG#|rML&sq3I_mtUl7v7m?w5Q$N z%)cx8-LexG9#7QTuN^tNOD9br&U)s%;@r5y`AmBoUsM=8Y}DW1etY**wO^s%1RPc< zeQdZfxt77kt^0%dTm$CRC1EdTGDcV*v98YGkMp~?uI3BRj(c+hj_>c0Q2q7xS%++DSAS%2#Ji@wjy4{M+C4#_%I zc*v~Iv;XcKy}Pq#RtMSE*ce^YZe8o*u{ZvJ^2v|Vch@D(EjaE`xtTLU>rMaT?koo$ zsgJMsG#%4Tt$612GhIBXySBdOYhq!t!p-YxpNyJHy64|)mPocp`D3Gb)9MbdI+G;B zksr>bogZYTwDZlMYaEm&B(Q^LJ{vLC))WN#yrwqeVXHQTq{IB%7f zXuarg7(XLt*sjMn+hO#e=9 z{GuwA+xhX0%A$#`u|gT?yLLaWGOM>%PJME-I?lKIj_1`)JR&KopW;5$$ZV_&eWWdv zcy8r3zw?LmAM1r?%`?atprKV7+a@~yY6Vg5L0Vt2vUY2OXX@4Tuy zd&t%O&5l|7TSeXVW}S*tUlm(6#jCye+-k8G`y1kN1%d?FzxO@4<0LQmY3}09!MppW z3-?E9Kbv`Fe^rmx&Aif6M(HVw7FQqJ6(h&@FDdKs`nOZ14Aw3FxbLpXUiS;>3*AHR z%2d_uJl%TkQ8<5aqERGoXxKZ|IWIXBE;oxzxOOtcwCAZj7yG{AUrEXHv){Q|r2myra58?5RYV@KedlQx2_fIdJ6U%k6b;vkbPLS#sq` z#+;j5pZ#*Vxc4y2A-|Owo0)@(ERU>Tbw+<%$t~5}54I}4EBXHB$Ir)`lfG`;(r?SK z(E7{O`>AJRrL))FN>)?e)pF6md8@P9+f-BjohI=C53VzQZn?)2)5lxN-t%1KUBup% zk9<2cmtI`tlYL%cX3E`d?^mwQ<5|OMmAAz7n7Q?em}uS;3l1)154rNz&-o(zlSLv? zOGQ^(Bo!X#Ym~Wr_nzF>7YCJX-!G0Rui4pjhGn~&q%r5SGgfJwE;?xzzAbt(Xhb$&d%KC&V^8H(X64?W9|hdh zSG_s0&*WL-j=&ndO&gy1h+gp8`Pk?7o%f4f1uR}xluX+m%U`SW%gn{(>UH%^Jsad$ z_gDQ{_3oqP)!wr^SDl(HI6F=9SE=XA|M@wmmj4Xp^4x2aBCTUyYAJ2J$UIWNO}Oum z{$}mMW5QEnW7o}HeRa!=W$Um0pZRdrO|yMRSGe_c%KlA_I&s}QUfnWT^H{1??8;d; z%@%K{6yGcL_;U1w{^u`0c%2uO>0P{j@+OOn1y{FT?B0-id-c)lo9gG6&YQjQwe`c0 zYHf=>8xQ?Te|pa{^s6O%@vMNGSD(w4zCYWz&;7X39s6qqvH#Vl=dAiO?dC_j1+TFI>?N&y{x~>hnD_d{QpIbL$p;-9MkWZUlzSzyJ*(w%e zaVDv*Dkn8firKmU#jI%WC$*1^Z)F|nFP^^H+KE$Ta^dNu%1`b4lAZ4|KIM53-MU!J zV`7hD(v0?ozs9~-O1@58Ve+x))2D~ivU;=4r;FUWUF+<$+G78%i)V9}vY&}K8`3Pv z`?M`zgTIDz#;4396B9VjsGYmL)n&`;2M-xvoE8l&43kSJc=POero;x~sVImwwUQ>UZ?7fU29Qh~epaGv~mPd)o4IcIeln%Y5lLW^;I* zvgn&V!P_q{yseQJvwq690>8ugg@5acp4ZD?nNquF)d#~OOIw{g1>ZuKt#00Np_E+gwFH{fUd6KkrK39iEeR zR{0yA-)gOqxg7j1FtDgwne&H@sG@kd6K_z{q*EI?wNE%S%s1V2ahv3RMne&{;Di+{ z8GX%KC!=HkZ}qBu0X;o2VE^UwAfA6>n0 zYpBLP1CNT$`;Wcg@LeAA^68>S%?C{vcCQwSddON;!Es^BirK6#FB;xGwGH1M5abqG zq-%Ei#7P;!a>bRWel#U9@s#a8dRo?wVa37?4S!`_^7UdQJg&Wv(dS#SGtB>b^Xyc1 zvjFgbLS|NY3Ws+{lv3-?{4HH*RyIsXFbKaN7juRc)18dZN&Z*fN&-A@( zDtFhLfHm6f^DpbNty<;lVlYqg9P5*W+r?aWXCDn(zNEWq%4CC?jYiC^SGH97nkKJi zF3Ef*t$y*!Q|l^S-D?LTyF~fa3#QnV8axSneBP{JPh}X#fn<-{ch4U8ov^LyfuZb~ zoLzhOPQ4p6=hQBB4ZA&+Cv$HfV*3{JHfL7EW^=yoLamIm_68gFetBK9L244PkN4y0}(BTk&YTi?}V=v*w=Ud#1qBisUI}1Zio$w+z!H+gnLIVD3okhk7>-fZ`U1+(woJyzs;O|3J<&iAV5)%J2Bji?n0Wj1C1dME8T zn_6S!!`s|2cUp^sX>^gk<(;rH(MgNz7p?02a?|2Vkz+^HJGBWiMhmW~=hbj6U4FQA zks7~qM$wu4me;4PmnQu<`EgBMQr;uq{K@%|%L4=1m+=a5l$_KQ;pI_Pd-~)iuTW8+ zepK%!j<)XJ58JqUD}>pc7pkSDG;mwwuD5!<+{z+=%R!CYv|BYZZm;*B-aL2h zf%ReGZ@6?H8PjBAO z^2J-tXfZ=l|L2FB%tFq`g^zE0l&96E9%cdTQ*Rbc3zPGVH`HXs%wa=|f zbAlG_(rj7k^>fsaj7zqI4|^4lz*+seMJspZqV z{`=MP=ijylZ)HkVoZ`g)a_RbjKYuRFmla7~mO3l)c7YnxZ=F`JJPXS(gQleES=EX@ znf_K~I+c>M9j}}1>(=i4YgFyAPuwc>>4!%Tt}OiWJaupP0)D0b7gHxre?H^Hp`9`B zt?&GJ&8n)pLiBX4pVRf@YT0ayW9FSx%sza4aqyLo>k|^L->>Ugec^nNoPf@C*MhF{ zj0x#NE_yb+A6D)Xy|U@j=ek$PESm4y_<~kFQC?#<+uXDI)DG`E$9UiUEq?a;c(mfG zFXuG_9^dYe@hMu|VSf5*$m8kxTv5BPc4X%KmML~QbMx2kk_%j1Rmx9yCM>;V9sYLv zs{A?ok2`$i`xO}+S+bZ<_4ab9w7_E$8`vd3m@>LDE!-2T#g?6R*+9MUru?2M)%T*0 z?Yn8rqg>bs74$()(w3{FsscRxt2< z5qH#?#~QMxacTKee23@u-V?TLVPA&b z`9|MM*BAS24iPCnc+*{N;ev~@PK@W5ehvyW4czSdEz~ox#J!;~&L*B?%heTTyM2w? zr$3x#U$vWmUM)k;{eu~wt)jl{ZZa2rXCAk)S%2L^SwP*g-H=1`VL?~#KFOu;-mQ53 z>tpwdV#%OSlegvCh^cBe1s{3+>F$YlKOJSg+mxnUnR|KL#*9uirN3WSJ%}}T`E`87 zV#~L;qrE4~=iEJhZ1e1_%?b;Sf4}9mQ<++*Qv}_IlB^dTtijV%x2bImlvD-x$gR`%hoGQ)jF)7l^(y*aokkga!KovqQ}Q; zT~0rgjX9v{ZJO!6Fi*=pU-mIm=-YSfPm^bv&Ab#*B{{t#qU-I7Q^yiM&bpK@{lQt< z=jG~4iE6)6>%u$VKJ=(L8oSeZ#>ZR5?*nZ=OMIH6`z6w%Ts5gwg8cuf5^rbm^&ky8Pjf{Y|D_hnCx?+5UTPn;v@D;?~)UGcx~^A3uFO z>*76g`K))_H*UOkJi5Or?S778%bb)S!4Fh# z2xVwJkC(iAxon=|qWT=ezQ5_$+vQ}s=Ki{Gp__d8-3T3+(dZFj;^4oC0gtyid)w{ z?p-stb?Iw&`?BBq*Zt)bKE6D1>#ta4*72!t&($pXBwbhE{b+`ge#bBQF7G2#S6q=l z_xk6lC&B`(XX6YOu35Y{Ybs}RnYz8OP4dy~mXZ|*`zJn_{r1?OTity!W!GPomAmJf zqzi35#&}dv5K!3UgoBa4xsimIOIflcyWL2Aw|}z1VNNNp;S}`|E2{+2wTeRZ4Bx%$<%e z{r&aF*~C+K7Od!8krMLG_!Dc=RIW!h783859^14{Yw`_0%e>nWvpVJ3s>N3yNt+YaC!YnU7hi!jKk9vmk@~-PLOZXvM!gH@!>CxGX&AgEjEdgIYedyOu zZZ)yyyP(M%{df`cp>L69OD=RxYkYENy~dkjmSB~KQ@$Kdb9{U{vFcYCm(vf!?@w2z zl-zWzD3mEHR9eH5> z>)I(>FETW%Oul-&Xr9@X!_(4=rF*#)R5&L|a+FBET(xRdjXd9iK7;aZk2t}fk)rO5 zj;5+98ymD;NNhhe+4oKK z?%CN=tx*ZZ+kWR18h5OmIr+t_L(DEmzS!=Pb5!X%B2y6}`S3 znY`Pf|4G%h0JqbplvCav{k0?fSB*@h6+pwkax0MwXv^Z?a^j`CGpkH_pve zN<8j#GyS1;-qVZm-G+*9#e5?Ab|s$JkQtogn84k6_O)tw@xmALYtC=C>$|xoOSrvz z&++f?LfjSyb}UMix^4X2=-~C!fsbCYN*Rf)m> zRwgCile}41Bqwt6k>^`=`S`t=;ak6)H#~IBHv5p(kDz<}M@61Cm92LAcSiJ!$)D+` zzvr4sA4*Wqjg!yXa&BJmVa>YtX+JHu1^xH_8F+H1AJeWK=5ua+W0-ZuHTB$)Hp|!j ztM~=CF`Rq3MeD2j(wouBK9L{mH=bI!`K)g}r=;4lo1b-qUb;M(V`lN@^40BDtCuhP zHSMD0CL`zO%$C^aT5#s`@A`t%LAwAH|@*M$`aQG()lTuf zKeF5`=)wFIl^bkhSykWOw+cF)TyW#&giC8LGrl~x>%r!eFFUvC{nz;+{q=OMzW0^S zJMH3Z4tlg18l0P6_T<#0@LB6`t(NOcugk7F{O)FPY})BZIV&rCdSA8W*9J%|^u6%g zK|t`P!!2>26|!5leNI`jvHFT)#??@D-yo;CE1!J4c}#u2pyKTnf~lIjmd2m@cKCsB zBO70eT8gc}-7da>GXnXWdN16RShnO&-um8$pRcMez1E#;GN<6K-po%OiyQmqY&fKs zU|+CkN&B>SRu4oc$#LX)-O_$)6VoPkviRdegVS*-7min@*#t>GW~hOdmRKn0~#fbL9Goo&H9B_wH|f^SqWVqNn>+zkd4V z%b#EUo%5=s=DFdQi>g_bb`#$9cd}_p{7ApKb#Yy9@TO+1drLzYrOuV}%rqB$bfoCW z>wWri!GZkBJDhhkJiWRzxgr0k{Nb+~-B^$8E|0RCb=g2_!foywa+{7d8)R}!SWt7! zb7i^A-Ee!ucPI4j`~4TLTO+f6`R%Tk#~OT zii$4kyl>%U)v}8ha?H>mtp6dk`a7@sj0uyL|!xeQ!xI+v8^wdZ@SRT z$xEf;ZhsSdu$N`tEv8OoQ^}OivzDzEykt>+{H)T<*OTNq9y9HF%G-TH+1);deT9Hw zj>eMB%RGPUmhbeMWOT=Il17b){_f{eX1CvO7dxUJDfZ^j>?I2_GlU=RE|`>Zrq?jz zR_vi!&whN!%d2@c@AUqu6D^vGi|;PKtoK^|kZt!QGl%e`ttE!yd4`uz=g!gfj!O!JN0g!P3!(r zX7=)P;qGd_yh)CXH%;yDhL&8sAn@^a(w&`(E?*C4+G@M4S!3~b<}bF-_x*s!nK>)gqiCnrA)n2Fu!r`-Q~A0CALPt zIs94w(ck^i(`I`gU%6;rP@}B%g6ZE6AK4Wl*6zK}#-9^z_BTJd{p0q|P0`BS zY}VFmH_ga;tl?es)$OcddZAg~uO)v@+!qhE)43KlQ_aac(NQC0x52K*UClo~pWA1i z`Xu9nr|hN66Aw%*S{N32C?s3^v8RvZ$(*#GX44Pu)M)K>3p^LJ_L22{Ek%#;$>yIu z&5L;tU0KZi_;PJM*Yo|G?))|K>96Pc{6Tl~w8FeK6TPceh#$TkTRrG9?ljf z$%8)~6I9fEj@wlyUs?COUO-{a4uoa#_UJGo^krKXz~N<<}AM z(d52)=%Dp?xdfkHl^T|wJ>@#BA~kL%a%V1w{qA}=C9yE)anPw%w}bfE0ygfL;?g!R z{iGtNPOyqG_jLAVw*XJ~=Sh!Ol-%olZMQrk?X7``{M@@W zw_kNMD#-p_R%Muk2&E9yagR@@QO^~x)b414Sp+wt}+V<(4 zlVXI(qYnL>+gS8tl)kc_;}8qiQ5FU?(<2=yxn}h zv2OdBi^8@N2WK(NI%xLfNUgm2eW{82?z#NRUH5fT)!bJ-vV9SMc0Ea*J9+*?gH?0+ z<`z2|FY3Q2yNiGF3B8rxo)afOdGxqU@OWcQ+4su0PuGfXne3}H=1G31o@4%O#qq_) z-9PHKKi9nI!g#x5!qr_z+TZo~pQ|nt{C0cAI$y<8zvo@_lGXVu|&O zr=2aSv#O{p5`I-XuYJ;z$SGT>#n@@3B{9{srnufran6F!b~Z>Vo}pQ51u~mxe;WQx+*tqU3!s7me0NJnh#mQP0j`E zLeeYEJPM+fb3R@9An|Y~@3{vT93(s^9!Xh!^x!d@(=BaFlbBT>DFv%qs;exxyEaw8 z`Bm?+Ma@A^Uh{-CEJ|2-Zbstg_q=+sR?G61+~GROwCi%FU~A&xv#zt%jQJbxGPhN& zdU$YtsAS&M$P0n-yBDo4H_e)`$ZggANgBF_lEwxGK{1aF4x3ysW%;-<=;Wg{vjV16 zZoJudXVZhFQR43E8E@Zk?q|)quKQBxrAhzY4-KmtdAGzG{c^vj#3{b%qji(E)eM70 zac(UW>RE31de+45y1u1cn*X@f^P~KycZVA9J{)KyTeh=s&9(iu%(C2-zc;hvNTD|)z z?|!*EADrIIKl-M&@NvYW^(!qN?Rxs`bx(HRow-}vKF`fBzqLC~@7ogNW^GreZ+G3; zbG3iX>*o(yob)&U=*#5FFIPTZm0F)4`Cy8P>2Z~^_FGAdSCynQpPXK9czMRlgF8BN zd=*;HxzCS%yslgJPubh)_tdw3I{TgXoq3NW+ro+0yPv5T+WtNr{^F*4`mE&Ldauvv zi&#JSutDv_tlfL=>ipc3Eb#W+GOi~Ze{VbA{NsM_<4w$`p7OmH{?B8O#dnW4EUW7A zhNUlEYwoFie0{Ae-uAx2a^vdh*Vmku$d~B&wcO(LoSQ3r<(jA7D5@-qd#5g!&41P} z*;+h_*U9WcdePZ04?iAw{CJLkU3HbzzUP;vuI^9n@R>8?(a)w8u^$#pmHQJ{?$pb* zGb!P5@#+=lAFQAFo;_GfREbt&CBGgK#E)YIT>w`}V13B?z_JiokM;=HlJ zw5fM0E4wP%j9*SFSzWFulVtwX@^mFIszE15xX0aUtX-i(6 zms}%~Epo$bY2ZzJr^!|tll)XW z@oM9hJ7-NY`x5X;M@LKSdBo-P>k`Kd?K;-p&JE&Ic-}cT;q1p5hx?;T0;g&p|MpC~@W#V~*K*hXyesiE$VzBF5N z=eCME*@fkTFHH7{Ra-yK`7UrP{Cd97-RsG_pX(vkuPO+?=QFazPtAAPr;9K z-w{5o;xt-VRC%ct-A^Gv7r8K>zqlaIFpuJg&|@3FtP=i&Ok^mTVzOwX?<;t^R(9*gsCi35otJ6( z>relqck^P$Z3(`bkPzP~3A@V*Q(xcLUtE^O6lR>8Z=~2Bd-LwDx8dFGKb&8!)_=Cn zwzMy0<=M|}U*3M&c~5`OjQ9Rac3fmJ=!nXJ>~DO z!y&OIzyCaVE&saMsw{Q&bxCfm$iMf#zdGl1;ns!hN87(yf1JVLs^>A!R!MyJll;T# zYrmgQxl;A|;pZ?j!*i>4eo=Pxt_>4h6tzq4;MSOF!cBM?TLmk;v`p zU-8KBp;v9uubCnyRtliP?;Vzx&$_4n4mm z|MXLO|9Xj|JMUXeswi7;qO{G)r|a3oR33aROO*ir{ z_q(%3hVSCqx|N6cznncY*ZaR~^`VqYYh^^cD;BTc6}A52^_qoQt9E3{x}QkgBz`zI z&S^bsNLjKJch2rMVO2Z98+KhspYE*p;decP{vKL2E|)fwQt=Ifb`# z{Oxky?Bl``9*aU;YLw^fsw{qt56mQKrNol_f7CY8W zJY#2IcBxaY{9sg=_V3!ymR~=fDa>Df$Gq`x+2P$6*)xBcJ<(tdSi5ZJ%oGX{4Irw-*Og zqN=x^S@Ple9WVR&=}#UPSlS-nZOmiLb4bY9UEoa1gwvTSDlHQx36;1t&+g?OwLNUB%Rc)(kzw@>S0++QqefS*e$vy6mH0B0fFkN3Y&V zT`lBcsH^SIc3aH+%(6DsuSXwChnd-}nUS?4ts|W!%i;pMg^mlCgfOXj_|UuRO= ze)am^W7bZ{AZ!7p{R%JauCdp4dAaqO6wIzFY z2`{tu-<$QAeZ^j>3*E7AeEvneU3b(d(eaDx#ug>uu?5b8aSXrFv5}}cC<-M(ehTy@NlfM^;WG*=( zEtVlNEmK`lUb1a5Ph8;1OY6;jX5Z`jTz9pWC9o#)meN)2h)K!I9oHYNjkxz?*?QyS zJ8pRVo;)>~UDEN(m0O&Ar#&*3=zZty&u!hEy`k`Uc-qs$F>@boT$r))KzT@Z?l*^U z7`G|?uv=gsoDZj3Dp!%W&vKNI!6@T>hclm040;{%h| zK0G$>-CzCBx0u#1zG|B$ueZnkYTlE|xM3vS=BX#OSn zH^J@q)Xxg8j!!EL3EgS*si)@Zb@AK}rw_!wRPoyB5` zyEJ`X#zM>Wf@igZ=ZK%ysp+|r+FSgLYkB;Inj`^vmSc*Q6{%kpAFKM$yZd-O*XCzO zUtCr?Yx8~JvvYnf_1^fv9sAmlzCDta$KSTy z*_HF__2P#gzpbh8I4xJM5o=+epJAi7^@#MBy-EIEr*f?3ecw@8+M@mb^z|JJ@62DN zf5J6|>E`E1>mRCtk8hPPc~!gR_4PSxZ`MxQcI~R?su{-&n~&_;5nX&tt7&JI-H*46 z+LGo>j6T0_`{L72u7<3h$UZ!@hHmHu@ zN3%BeU|nmJk)uj*=tRYo1(UDV_dV{aE41f1wqE(Mi07H_$2fGIiiD@He7$>)vf|@_ zt@?!qYG0n-5-Y0~{$?N0wV!RqI_L12yF&%=x&YRzO`S|h2_cp69oGPjbe`>uaC1Cb`#*`_Vx$9D#SM8cCc|272b<3NZ zFShJobRul!WPv=9b1cQ~s|2^S`|LKkxa{rQ>Wj}GeYw3}>#@Y7RlKFT(su5AhW$;4 z^hB~BGGCuD(d@48*@R0iW+~SX?o^)hWVZ3^Jt-aaO}r)ZC8wCR%O*eJ`n4ll$Msg_ zPUlwbY#jyD)4dBfR;PP&_^?bkv5-Hz^YY3a_x_vYwZGVBa=+qR*YV~i$#}slJR7Zx z#V5WxH7!j;K&t%Bq97K|v({~ed)6M0{93B}Bl(G6NY)Yd9&7e3+4D9#pX^?7rbs5M z!~DYJC3F1a?tV2*30p9E&AbZTH>cCt7S-GS-eP2zA=!U;Q{h4$C&q*NmaAN!O8Jm@4J}>h)8O@TF*nL8PH)Q7lr-yT2KZ)9NG~j3LokZ3v#&w_9 zKYRYE`2PJyF^_+T{ucGIsCXUl7TP4xq;`3G+N)j8O1-mw|K41E;bnu}7lzO4j^54w zpfo4nj=g-IvROv5=#$wScRUf=dVWst3p2@UH)gp{t5RM+sojJ1se2Ch@f_cchxBcp zZkY1OoZsW`oAZ1#s#L#Buzx$h&*Z#-)Wj&MgS_X>lRt=QwZ2dM&^oa!SMNbJ-vXN+ zm5G-)CV0PaW)CQBzG4{nf+fGGz;VMAXVIo#Q-lH{HL{zY^v(Snadf4{WrnqR{U*Os z|5o|UFymC&uuDMd{qhv9urCRA9Y>lpeLePgCrvsl_wU~tNws&Ezx}OwT&$~p`f+FL zbFWA8-aEs;?|Aq5u7-xX!?~78cCK5^Uw^i)U8!Js?cWXOsI|HN?Jf!nIh>xpaF6BN zVQt=7x+=(1HRTu%MydMaF*?mCmf0 z8n>#8HBP8{hg5bn%wdf5&WR<*2jHQ-4pfWN(qvR6m#@8u4~!($a)& ztCrt!o)f}#_|)IOde=Hsmd)5$`fz{c^q^;p_MMg4$niQ@A#33`w+H8xT(!&mqwbo2 ztn7;1+35aa)4fgy!S$zoqVIfcZvAm|Nx;^*%Q8+owlAx@bb1@#|H;}(!WT}Stg}{_P2c#cO?7$_b)%C zZdb7SxBm6t%khQJS21PG*)-QbJBX+3>6hqli)HNEl=-)({axibr$$MCl1=LQN5%=< z%*}uJKGrYoe;?$eYWa5A^ZIvxqCT^R|1?;5M5URj_JV-j|Nidde-}J`QKKul(KO4O zIko1<;(cwb(ux{VQHjd&Z;q5QKYrd(;{8N@|LxwNu1~hT{k$qRHsR~k>#=40CnA$? za)w^ddAO=+@l=rshfXK9ZO?GfR)2fqM8Us>TGG#bL)YuGzZP5YwJs}X@`Kf4M%EsQ z=VhhdT{Qdd^ysbG+NCC+Sl8-GtqJ;A^Z8y?a`f|$Cws#rZWd;&x%uw?szUesnO;B6 zId$iRD@=Vh+hfY*Hx(wrtJZ3U9_!jSBiMP@li#uZQ&wv)X0f$6m{`N4Qg}HsW_oP-@wR}T<=v(Fwc@^~If9M|OFflO@u}*1 zm=^syBqCy_SYPy$DIB{heS)48Rr*~zu<5quCU;-URc#mReLuEdHjD0gZ&iA*=fc%f zF{^#**X;;;HtqSL&dkFyw>C;WZVcJ@?Ea7Q+^bv_PY4|n6XQP>*e^Qg#;k>Fi|2E^ z*nP5IwQ6_uZ>6jib9)|%luW#P-==eaR#lm8mhrV~;Xj|zOUG_&-KTmuW2?vOTlQVr<$PVG;i;OdLm#tjcT7y0E_!iS-|pV7xxDMW?=pTVFZ;M-+UhR{e^q5JOnA2PRn1pX*;7pop|x=p5|DcO{?7Q3*x?r^h6vi)w%Twpt?M+jq?}_v?2S)!CD*w^ar^YkPU0 zd&lEquxZvR-5=*IH*$%umpHp1e8sLq?pB{;EL~&Hy>$B2;XdKnm*;W4Q!g^lY`N^5 z{*XDcE&9jf?}i8X_KIx$BKj^zOTF_Vzy76@HHx#U9x}1++&#PVR8jrj6YkfVf;?|N z6s`R$>2<|Lb;@_+)u(nIc+d8!ELLrE!%FrR{%x=AO4hc1<-HudGS1kW^xJ@<5J7(4D;GKu4`4jf^L4Dy-lX{+WXIP zVcWM)m*t*mVw#vg&)MAS606AB8S&9m{`#HG)&0W$_FLYM6S`l%KIeVPH76molu0t_ zsDSe9XRh0$j>p;C+&{Iy#YAg zXZExAD<93@W-H z>^Qa}*+1y-3Axi(SUe~A8_XImCKSo8sgE@epWx1PTsv+GAnIoLu}Dj7lTc$ z^^bD9(`rR3B|9#*aoQh0y11m|$G`a2nt4(7ZX5fj8VhDmm?ODy?=h`O%`&pLm{h}s zr!4uo)$ZKm?=`RG{^f_=w>-1QzUK2Q{g)Rvf4KerZtUjV#OJoLyEpIK(l>Y6z5KAI z%;=vj6ItH1)$INyVs&QG5F33EHZ{kuYjL&!H@SBl&<_^gF(>53)d3<_E{Ks1Ted5dU(1- zotZF6GF5HW#vBeV#bbw}7@Al#qSy^*9(0<>#W`)Fv(g#KDN8vR|NLl3X5=ZnjS(%7`w;N9F=GL4fq9ayw#*=!Xa)eaApq&v?q&kPD?;S`c8JT$?;@WiyB z487agJRxCp4M3v8eem8u+V-q@{T} zy=dlC3Q9WgK~`rA8{>?VH{>m6mv_AWe4xe4dfmr$yV+kZpQ-Uy*pZn{BDo=pX~N~k zDXJBzeZDh2#NsY2J=yeVxqbM~i2iT>$Ly!q`nT)VKQUf@`daOys$Yi>%UaHAlFy&G z(swOS=pVVOmpcBfoRB7ztD;ePB-^+u)9;{`BGZwBlRmw^dBU;g&ySQV>*w#XpZ~;Q z;kqYvuKlkHXWZGoCgqvP-un9ye(GCeH{XQqB~w=eQml+*iN-pS|nzW9yD>PGom(I?R1~j{U04 zu%B;@bJk8}N?KtMc#`j2cbV5opEtd+qW-TROjkK|wQR3vk4cHgV#{;YI*tDgJRcvr z=l`caUP@`-&;REi)=bh(uXJuQdg3m=;qmc&IaAi{_Wx%eXuQ*RF8onbh4RA5ffK4_ z>NzI7ws|&b_cQ-(ul`<@$eXCut<>l3DSBM~Tix!bF=sqW1X|bCpMAPG<$jvM|Jl1_ z?c;y06Sx+BIL2zz;=Z3>U;Ru@(G#B~u(1BU%&(1Bz3byLxl8ANUs!v`-!^rcTlcNH@$T$1E7=aYX@#343XMO{O`CTzC3b^tFMo~_Aoh((7Vh%%|H;1wRpGN{IIaj-dX?qB-}~$5% z9v4om40x9@(e-ZdNAFZoPtp08ee{-dPCGc~54XWv<$nDDsurnNht*}wf|lJn_zoy+~e@NMjh|I{A8_|Ikh z>Zj3v`RhMFuG{xJ^;P~`yPo>T|BmcDtmzhS3ie?6yF9m zM~9#(DU!inUUPbS^yW6Cv~@5Xau!dBOklip=0E{Q#Dz99Mn0o7O&N{_oA1Aw;qy92 zL11ZHSxVHLl-9@@JASeMym;TRd0l;-uOUzH*Z8=ZdzKo0NIs{we9pQ1M`SGRU4z$Y zF3A2~eCxS0^Tgm8%`U!L0S!(DLd}zOoLIL_Jm%_juE03Bqjh4(l|%`XNEhcBi9Q{d zO%*2GbL|aWu+cqHVsS*!<{-sziIuY$QV#z*Q_m=M=c2D$TI#&y#myU+cD|lze2_QU zSa8jW6F&35MTk8+ZfvmjhKqoU)YdgBT31>Y>jch-`%`LjdxEKs^Motj;mPu!^962~ z>`JqGJ@ff}Yu76mX7hUWePH3a^d!;9CDdvY6Bkp{r8GN6rkRS&8ZYn8se1CD=HA8n zDT}ULdjGv6Q26iNd%AX?7ysQeS8(0-Y(4&ST8j66*zWaw*mNeSvt@#c-jb87Df4%2 zo^19~%yokNtK+ZFDNlYXt>ARFesiF=VNcfHemT)LZ>z_O@k;;o{%>z%=40=9pe=66 zG0W(VYuU-aYkf`}H*qpKW_2~(Xl}}xE2}yW*)7QGjfsgl_U-()qCIy_V@{_^9Xs9k zl;cyM#wE*%kGfJm)qFI+B=k{T@Mc?7%)!1%W|!LpCix!XH(K`PVUcaO>eY(^!OGJT zQzku~EULoJmOB6SIjeN(24hE-N)?}{hq;%S9hc4twLGdT$JWz#aCMwS*y+UBh1_vo z9|P}XY3qf~cq!R0SrzOxf!Ezj+cT~^<>0xFNjofOF+G=BADMi`{zBD`o2A-n0-2xQ z3*4I*ow!H$WWN%($CQoH($0D*eV2qbCl+KF@!&H@@@cITcMF!ePe?wt zy8hNhuCKh3dorK?W(#)vD(NOX*XOJ!r}VDP#?Jjx$73J6Eiqi>bLMqXuk?zBdN;8{ zJSn$5OlJDzeRwl<_e#qw>C017_G}J$T=Zk#!Iv-B<~EnCGH0J~W+BrgF1e^zRuXxF zllCk*yD^~Us?wFnM{Kq>syDlN-Y)63O6$qfEiO7Uxy`-BF}nFu+nW=Y0{6aid?vvY ztZVi;$k2>Uu6kuy+gD%zp8;2S4Z~Jz@#)?0c6Xv!3+IsZzUSre6)iPC6FCCX&=PkYQ zqnl#S_QI2r>x`b|{olDH-p)T=E$hsOhn$*AK5Y1I`ld^wGwhMqO?yVOlnL+kB&Kaj z%MZ2neXG69CqFz-Vv@9w^_7)VP0Uw6+Om1VsY`}>OX|*VGMEwYZDa3C)x;WGRf#vj zo_pj==)dRg`3RvBxbs)h%sn5J!V;?6s6M8A#1OcFwvg&6`e=7XD zubQxajlDVJ&K(Yx4;GwIk|_^++CC>qS!|(OqC+{uV?~dX8deSBDoX`4M3C)^&7R}g3-%iUuQ&vrXh;?EG%VcUkZ}Hn zacX>Yh9=`8h6Nrn0S(7H%Gfp}UhQPbY^_zX{Oj`0^5U9IqX`#1f4((evZZ^m&-yc! zGR$i14oiOe$D4{=I8hpx{%-odCrv#DuQzc#?f%sLW3SY6yIbXQ_FlD$584D6CJ3^0 z1avYgJ`i}wF~j+QQ|CRo1u_DsW@Rn|qXi3QESS*6+nzN^QQ<(7kn&m9`OB|gxuPW; zz3G{Qvx0-~N%3ta%o>7<0tODAUvF^6wkn;sq&d!OSTiTk0 z-RBfCFZH>WY z&p1ynabc~W*uZzBhr98Df!spHB@Zl2X0c52RGH+dsCuF+MEycyvgi|mPjh7to|!Aq z%Ub8&y5Xc<%=5Z&-E8JF>d$#z z8)^oIidZC8b|%>v(_t)a}F+jobF4qk_$=OIZ(lP#^Hj%X zqvECqMG7*Nsvi8aZ@D|Em2{t*@c6}2leZ0v<0Nd7%u8DeyG8f#eS4U7!B=SVI?Il? z-OGatFCBl>({YdU6>nwFiT5Ad+Jw(4?*k384UB|MBRJgCSqRq@dYZOuND7Z;ZZOjfDj*SoMK`pP|>=C2X;HfscAOV0bvxGZIdM*l?ADl{ z`CPN!-Lo;0)W7icQfB3$Al?UOqv`wDaE+`frB%-MxEObS<-GNo`z(3(}R)(GAX*sc+P!VHfbpHOPs$(m5s5rkn%ABK=!Eb-B zp+G{X^sl94#B3L{zdQ9*Lh|J|bR6)Ju-!O;chw{XtMAnUIvxvydU?)%X8N4)K<3b? z2?|FzTfU3*Zesj$v8^Wfqh#Yld7c7i`<|{E6N&SNx424J4tN?1g_rOuwtPvrEp3(| zZ74sDDSz*>=OTPN^1D)w%)M}6LKkzxbY_;vj!oCE-#@nY$PO0wD@OZEntXpPw@L7F zJKW^BwS9@^zFTM5uBh>>T#&iEciV+Tub{5AOdHJ%__O^lidak3HytyuP-3^;9c_91 zbM%%23e#mDnJ?yu;7|6k|NbSCed1h$KQF2pe7^9MNZvS+eLgeE&*YG=gzM+o1`m5U zs*=}Q20BFNW+d?_T1j}NsjPHz76@M$UL_t96f}EPJ6wIf<6#=VR>fr3v(LUiTh#ol^TC^mSsqrNwvl(P3En+w?x{bzlN3%zaDe)y>%^pvF8NYBBe!z z?~m+yHY{@8j)(mmqx zt{XKE)MSOe{rqzH;0K4bTT)!Oc^7{>W8v1TvgbofqHyjv=h?Q~Hzd`UIbP7^Jm53? z$^up%Cy%~wav$#P$dgx$-jJ~Ag~m#c8n3kp`(Dg>w0h;NdsAIG&mBK+F2Sx5{YXG3 zRVw9`!|HPaw(WEI>aD6)T<~Z!YkTbxcks8<88v4Q$@1f7`vMn#eHpvlLp()9V(<5i z`>i@*qSl}0s`sqZoa6qbC(-z`V7;=S_|?xU4iCSj_p=#>TE6sJ)6&Ssnx#1ZYLX+{ ze#`>3Nc3{D%MLAKkiNPpo7P36?r8{=ILv=-+z#^RkbBY9C&< z|BQKWjm(^-D;H^GWhG_I|NMEy6Gi7k=Pg!FUMKFa4aQSUUgRW9Abo8s_OsdFxP=AZXc}v%cAV&cYoihssx-OVBwQ&5)e|#kW{>ue!E1Y8&%FQ{m zj6snxca{lqu_tsRN>4{8lrUZ4lT5LZiS*%nq`uz1@dEp!U zFBruq{?|W0=~b7i*RQF~fjYOp@okvvls@gz-1PSI7cLx8FRrgzmF1t?8llONV|G#a zmXF`ghND6%t%f43K?=@HQUAAmsWY4JHM@9s$iBbMOP&Zu<byzW(o*)wcJitR7w6`kpZ~e|fBfTTuYT6boxfVfd(G6& z?Ea3cn&w;Q=KAkn{QbZ9eC>mY zrS5V6A`ZobJ1xy?pYeA3do#1iE57`)t^TKYb?teT+T)E9Ztw2(+jW`0eRFpG_68}X zDQd;JioezTWmez*xBjy?NB;NhRr7yYYWij+OMNoBvU=A#E~SgV*IvpL&YZPo+N#W_ z<~6^5zW?7_t~cQ$^B&7ev0XQp1te?ut6vPStu^tg&ZvFwYuL48TBYj^uaD2T+* zOp0G2BPm;wu{bG8ch#zgY5te)+&`WEllP24aBtE-vsa()e|;PD@yn;kZ)J04y#D0B zGjh@HNelkF-Pfu9^8VAqRXZ|eKY!(V zEN9;nseb%7;lxDF^PW$*+tPfppP$Z*>~yItu9t5=@_o|EknLPt0_An04o^BQ&IOz* zDL(z-e)`mX4g0g+f6co%pIu9gzxl<_NegB>HVQNfHnsgbTeQxcNpk6-V+Yx~m|Lm6@{&r*+!@YI>_V&fz&;PIfyU}jR&Yj6jGJ9rU*V*=I?zD5zCBh`4&}4I+js7rMPZ?$qN1Wwm&T$lZN>A4 zoA$*|wo+$P@k%~?v;6G0x_|vYoPM3(+#BzAvXry6JDKh8J~h5ILVkBTB)=`UbgmHQ zXk%#nW4++=qoBzid;u?I_R4W&Z1=eK_eJ3%!*k7%j4L-xyL>qE#*PUxcfB)@9=rSR zo0#Pco9tezA5%ByxEg+Z|2`l~U<-uAA`cSb?A9xrJ`` z&tCLC$a&*+hIP{CGKpAj4grn#&3DSe_S$}6U#0mu>g7Qtg`;j7tsVbXtVmnLsbs=a zP@f~EV<2Vs{rrt9y1KT-_vRmqlYjR1#FpQgKX)E@&rowOg8Qq(yikU}FT}N2V;LBa zrR?JO%IDQL5V`2u6#O;&m;UOAs@?l1JIM+03otsg^grZuYFUzU{><+aoDEFj=TdSF zL?*|2U2s-ek`b)_Uu4R+2!VGmk2Ndt-PhAxIK!f&cH(01y=lv5968bSt?a^!n}6o) z;5m5iiq25D?2G>rTG>2(Tgk*t3Vg>{|2~=8+L+UHqFwI#2i0i(^#`~7J)m?k z`l0&E_H8HQ&99Y2D|5011$Nqbvjp5OmgUG%`h7$|{7Xt^kdM?^y`s5%Os={j=Uf$4 z^Pk+)K5;&ON0W1%ZOY;k-!2ROTebA}JcSRro)f0$O}@U&*Y!fPbOSLb*=$D?A@FEv=1G2_`=|+Y<`L<=h5eX@9!=spV4{$ zrqHDGZ6QGytL-0LTadBmlf+SG#xE_81SauJxT(ncW96Bb4{ve*yT`|7Z1OTiDd`t~ zu}XCHZ;_>qEb520wePc=zpvMHZRV1Xf^pH6iPhfdKIpI)5H!GAJ=RObYz+O!em$iH!M)9euwSc&s;Ta5;L&Y03)r zYmXoHZ}02A$h#=zvG7A-yZ`I!*e}{BUlO=u`=w;{tCf7-3;g1IXC$6jX1%{%lHuY> zw%C~YPvd@eaBaKI@$8NF!Uu~2)>$@w=fBeSpY3a&*}o@BK4+aApS=6{CV1Z5=RYT} zJU+wBe;S{npv(Mk3jc1Yo;@YxI^mLtijuMRvCu$@@!+{3nDp~wrn>r3t5M4xeT8XXPL;;MDkt{Yv+{Va^H#lh(@??u&_i7C*@2Jc+1pnuK5)2I z`%+*phwkP(7dC9vxG14f6R__`zXDs&!J7%kyj#l!_-D+Lv^g_*g6h45Yg48@f4g~8 z?9C&Ab>9}uwJZ|Xv`qT4#;ln+Sb9lIu72!8hU#LW_Ji9h+7~MEudcG-;ZM62&%=A* z;G=#O)8}rTSMR?sE5H4)+w4+tr%9XQ$NqUXHP1`Goj$mB`ueXyykqx+ zdY!*jKhFs7FDd3PRIV)x5&m5JhWV_buLyJQ4N32v8F$arGJLpnG&R*v>QCN{g)75% zTlg+Ncjiva`ty%J|9tiS!%Wx1o`3TWJ7&dJyEw_SE}8wK?Wb4F-(5F$|91UT{BURA zrzVjp;r|=1zDhp#%-1_}oBU}F<+(p=KK_$Gz4-M*hXOmfXS%)eJOADOQ)Q8S-kHaB zcD_#;J4fKjUYp(%^E%}Zv0MF{K3hHV(}N?et`ok+)wcJqf8NNQ8O689EGp~ziOq+# zUYzr3_chzO>)aw%BX^rOYu^~oDYyG^;<(=o!M(nBj+sw&oGi9d9rS zr4y`ESFJ4EHknIDPUQsm+hgJn-A&y*Yj(>qbrm(#ZJLoIJ~_taABEku|@Ki_}$b{VaJtclI8gM%IOe(jHn zqQ}l&v+nLp_POF#Gx<}>W0?xe_a7EKd#!pl#w&f7)UR``&lWXX%-Wig(dX57?6_0w zYrVf_XC5xtcDEwy+QGGoCM7$9mrvhs>!cbVn``vnb?LLNUbdG>iSr^p>m1#z|N7ZF z4v#Mq35y&0F4g&N4=A{A%(UuOik-lQ`^!XM-_HmO-}WN^F2}3N#m=*ea~E;1Kb-w@ zW#>Gr>(kmF?BeT~vMS(_>YBPrjURujdOvDBGdEaR*6_l5iV_V(R{{04q8i3_7UFRwFu=OrgPoA2!O>yO%m_~Q0-SDn)5 zyEiXvX4t7MGeX7GQkQoG8Z3Hl`m6kUl4sH9i-EjW>26*IlLPOZ`QvNn^_DH!@Ymn1 zMqgjwp7yw+^z-$m%XS}M?RmYa)nCIdboYwFei#3_PB$-m6uiG;uw3$)P-bV$_U)Wzt0Px;*hJjlWu-Y`>iV<1Ugz3RA74JO0?WmNyl*3w>cuZ#`|&w&TEEFb zDes;udYy`$?_F-^EPeg%bB}}cxfwf6Lw83`SJ4a660B;?Q|-R`;-=aY7Yi?2yI$?1 zH}7-I`KIgMeRyZ2eER->YkgxrRH?pxSZDC=A^(>j&S`z|YP)yVicIrd_p@s8!PyVj z*KPY#ce^gy;NvImXFk=Br%yed>3wghG=Jyh7oE4Z#r&6_ym3-|FsfpU$NB z@~+CdcQdBt9$$W9^7D_${H(8n_id?3O4(BP#KI}y=+tPfmxcEX-y_ zriahkSNHFJ@_x?wNsFHbeLPhdBP;MA+&!lxuvc(p`i;nxB_iwX_a653FG^b(oFg@J zcj(R5l1b~IPT%(<=5tM1kYmfH#nKnw-nE*0UVit)S>ku~Z`vi5J1%I|z4-g-%dnum z?72q2YlXQ?CiTw}NH(pXeIj!63kz{M_6wCJ$9SABD9E|Ul{uUVkUExdjX5!Rrb1Ko z1NB2wm>xN+cBwToyl3)z^mk&U>;r?^iC-LSlRtP*_%fAkv0CiuZegjf-(}fzzkl(Y zwEIhd^?Cgn8@`1;H!G=lb${A?)2&hRc9S+)%FNl{aO{cM!(HXSq9^WoE8EijFs%Gr zQ0c-_iMgS?y1&#Cr@y{^_Vahi%M-G?i$u+{{;*kjyE1+jpVs?>E+i~)2jbk{dDq*tJKR2%To6J zkg&wpX8qUl^$X4mSMXkcboKSmdcL{$Z4NJ=fB)^35|cv?EwU$M9Nx{`+IQyc`}-Rn z`1|kCdci;Um{Ps9MB=Z1_ijCs>AD@0b31!d>jsxM*YERrn$L(ix%kE7PuF!1>9}cR zCB*Z7JG{(Xp})8#;HHriBk$Qyq2U)d{gOI;N89nK!*98wjkUTDmv;VI^W#doa@D{4 zAA9!vnB`jR9LSb$dC#uSHETw4)%-O_|JYt`X5+AY^ZIj3@$Bidtp5J%@bZva_({4n z{A}MDjZb^FpL^mO7Vtdv?hV)3v%Q1Ay*FoB_1HVv^Xh)?Wg-_J3(IcQNeU7Du=v3` z(W0jZUw-~t>aMSMqf-CkcyRY6h`yZut^i3Uu{o(8R`zNu? z$hJ9LQN6+a*0jCzW(fYf8EO@pdT5(zJ9r%?uH-kj4wIO zI%gTGJ4iP*&ybv8Xd|`YrA@o3s#r_SLAxHA9_IxWtO{p6s=do4+Ey8~*l%33K;zZ& zrvia5)+(wVf8Fa9TqT&byx>yGwclG0cc0=v(trDj_O<2C^SL<8x7Ox;{%h{|`qk;% zpXO_sgvB@Wr%m~N{9E98^=Ru_mh8>WrxO32_q`sct8Efjc4pgzPgP#BvNyk6mAmt5 z`_<*C>6Txg_pP|iVkH+ewPnft(6_afd4K+An*S<>|lD`y@<{rb$emmK0I* zD(zQ$z{!i-4R!v{>(5ud>d*UkPQ3Asx~s=cyg1#N9$M$#xzS&-?cI|l$N5~W0!n^4 zCzh>s`uFc^sQ$t5<5_U$`y=beF*@5`tt)zQ?#sf~jRy|?5uKZ_W_O@w zU0nA=sqZgNyVRBVYu$6rOKD%4{yS0DBQir{+N~2a*Ltpa?0oQUsMhP?DZ1U8-ah$S zXBWHi+V{irtKTblI{uy5BU|G9bZ)>Tui%N!JAbS?v-3+u)t3#oZb!>}mYe^_^IgV- z^AoI|YAu*sUMTB^neq*avCiR zd(AZj-kp|y^!Hjce_KtQoYm{B2Va6ih1b9PclEc;^4Z~h&h1n4Hyrx?^klADY3+|+ zRd4>>wRm&6FY?l>|Ham*?WWjZ3-j#6UK|Pj++MpG}3->iqmVax=zraxNt5f&%1|TjAVUYdVadDdC^LxY1;EOwJVO>zLz-7 z!(nP%E5(~C;?-hmCHiuK>+U}vRxFvwB~uk!Q`j8V$+}PdXTa~RTbEtQzNNa;Y5I|m zE01zKb6lDywDN{S&uZDdm6lu0HV3@P3%Kw&KIpK-_Nxcaa_MC)b&JkSirSeo?c}Aq zrK&3`m|smXQA@n$ugA0cdK7uuXIT6Zl*o`{3P0?7!>^>Y_><#f$@Gqw;g^18=+{~)V$V0NnQE|VMzGKKl{Y5` z#pkU09vgh?>Vs>_CY-i;j_fyPluQK8u zJzIDv=F7Qtd;8peWJ&aMCm5PVGPVV6KWe@9Po-RijN;?vB67%$h z+$qa*=izBVX-rZwT;e9I#GM@&7P{APv8EuTXUr6d$4%f{iQFa zy`Gh@`)X0yg1mixEXGrrcVs+~QMuFW+*`d@lo>Jn-_upsEirTV zs*|n4youiu-blRDXT9%y6vh?o&)2 zMFGp2ttA(*U{7ZC~5+ASC?kk|@tmucIM9BFh~gE|ZqOpda(2ys8)j+gyKJnXX5L^=TKKR<0FW1E%FyO$?kp!NVydFm3gz zjBU?XHy)I?;`X0=%zVS8u**H#*I&KQitK7MxnRw4Z%en|q7}xfwkr?HEe?94(q8j@ z?^&6<_d@&qd>06xGf|vTzE?!f_j&bNw(7E{+kvL>!a36yo?JLvMaQ-INUm5KIQfIL(8%>)s7$XyqzBSVpZvW zE2$gC$7faksq;;=eo zw>kUwi(GPc?wl5wP;&o{^Wr&{=i*#v_f1HC`o&pPEhJaxZtT0)+oDb$iST{h8GQZi z^!C+9H7crKebyA+z4%gd)*i<$(~ivTlh?@>ZVxG*xcq!`@X{Aa{KcOhD($j(ytJ^| z;`c)CX}2HeYQFpGaX;R1`=qyB>oVpw-^lEDYdjn#YkTeYro|I{4^OuE`;LD_&FY2C zBK1w0N*fvjFaFZI>zkH%DW_2JLU!B?3+=OCKAqrck$Y-=C&BLPrTtMQrgFY$SvQ{S5v+14iCZuiM6pA(vP{_U!j$3lPn z>oO^d-q9Og?zp)5+%4rck&;qtub1JU(qm#HJT-5hmAc0EpC@BZcy3<3>aN!>!lK*q z-T89k%&h`WCvA+W`MmSKLI0ilCH3p&cih@@*Iah@=1czq&F5CFoL$kk{HOCXiDgNm z>mC-|YdLeI!kRa`@5tnPuNQm?DDHKrUFaR5d}Vif%-WT!n*X0zV{&f<9y9idS>6tv~?OUY<(mb({e?^qb#aZ zMgN_N=z_Wp3syKTP)OlO;7pO?S~M%b`E`TvZ6)4*3Q^{@|NGnx%!)GnV%RR?yHw~Og{Ww>$>nNnMd-6u5D@!$(&Gc zKCOqd=2CI7B;()vpA!8Xr24O(znUR;w|=qXl*m68`-FD&y)#&(CGb1%&yg$ak{^HD z7k`yEEjc{%{NaiBHxxem5M@?h-myB}l$D7~@z8alW10`vw;TN3qIu8c;w8D7^Xt=M zBhRb~oASl|X8*FYEbE$`716c&-)?o>7&(a zXE+z0^B5^M*-6J`)<=1X^kRN>QnL82i|K+X@X%!`b0nCwaaKI{lYFukNfW z{_$K!`yyV!6U&ph7`aYPo2a7vrP?;y?v~z?C9BQSCcK>N;}qz~;vFDzw`vaO=2zF> zS6w~Bb^J}|Wu6n;IL?V!b($D#b^g5ho8$Y#b0t1YO}|;qXJGx|sP&Vgv@VUMNk7lp zr(RF3o%7KmU9YUVj|Ob zk%r7!5iZsXcW?M8&1~SQayQv9MY8-#B8ThUnV0x3WPNq~nag8n;8A=o%lr2RgO*=< z_D>B%-nUq&Ds)a#NaC_zWn`+|^0zVT?Zd!B<@wEy%>uTIZQ0a}f?HBFy^i~Y9N1gL zxUPJ8$JIp~`bve8vVN|jE9z||l@|&A*m!iwk}kP4nGGA6m-KD^QDxKhv^YNg@xi$I z^WUHUtS{diDf~Zwf4XDiFU4s)<<6(QKffiV&*iX6l$wM@L-ZSkoc0t$ZeJ}K=Xv~d z>NW@d;atq||DgDn*UM+=I=|@kv2V{mx}Lv|ZNuM)Xa)!C6&h~Fvj67C|4RJzH~!_O zyt~Vf%-3;WAIhkhB(!R&aJ*>h%(q8N#gdPu)t0H>@B8ucapTcTcYoI%Z^<=(8UOI! zJBO!}i#Xc@W_@0L|M#}cwJoW4{!7VDIPo(^^mxWio6R$)%~6;3T5`xVCQbYMmGt+vJbJq5=*ahA+*qvv0e*M>a z&4+eRu1IjP|8&tvSWx_SLuiEP-W9^pyf4F<1e$_4Jvih7Tz6zuet+`-!v`={nwRi67^(($?B={m-0*>S$i($f9~*kxAX)R)613rO&xC7uBB&=r#B>Ptx*9BU{+J`X?Xrv`^~4 z?-jdQXZg4<nATZ?eVhu{r9}& zto-a9#R55A(Z}XUd@G+H6v5T9U1mk@!!2L+MGTY|`ppv9vUQ>7@~`Uzh5xP5exFnO z`Re^dE zIZMBLM^D^)o!PWA^3Tsh>)U7N$L`(ZbLFb7;m7%9Hg)&nn#&)Q^zX7(Qk`L-$i$)~ zHnl}iQo>c`NSd0*#A%U@ZyOdz9X04S%(P<)xVG@*vhdT7e{w!!PWk0uIHSVaLH-zP zlaavW8g|Px7E?!2@te6<0z^cGgXiz4x%2g5<(XrS9ZUEpoZ*~cvCWmoW3q|pHeZ(a z%dP4%EfnrNLi)do0hNSy!M)}b5VljzA`rVzHc&550+)wcU4wksrG@BO&DoW1s$WP$gA+ehwf(OojpKXdb{K9@&(+&nk? zFF26f{PUDkiRJ-6Cf{G5wM#lKa`oKZdxm>a@8x~W^OVvWJGIsoJvR8j{^5n6Sf{M< zuG75Jq?u)U51fk#wf$uIHQvJ9Zzg9m&yxwKlcz6P7}ZJLih{n$}6y>Y1`%18rupvfX06YU_a&6hF4z>ca_-EMTc2Lu zo|n1R$9A2x&+OK)5 zdJ1b&o^-nL{3>&et-4#i`(8e$XVfB*bmOIw&T)d%t0S*Iijx=dNV*rWWvipP(e?Lp zPPRth8e{#>GGu$C-wwX_sy1w}^8;{OOMUl%K zu1B8D=nJu&bLxrQ4U^jWn=1B7pHr1}zkc_*F7K_s%5UyfD7d6_oH%B<(X!z~qu|#M zavckna&|d3b#SccQskJckixGdB`8wBC-sw0I>Fg-&c`1YV@-Rm9LY_w7rRuy-9G$g z|GG(SuU76*)}16Da?-G~Ivi>YlIXxc)^r ziT$xkt?9~glVcT9-*A2B`e`?&9aP!!u=DLzj+}+3WJ|P~bre;)HHz=1%sO`Yg5Rmz z(~gQaCUr`zD%~1 z%0C}3uc)?6?<~m7y2+KPwm>ks&Gb~K#JM#uHV2=0k$ZHx^oqx+r=RwwneFSo$C({6 zy;W>twzQtXO7G&E&dr(oLR>d5oBfo_)H`S2|4Dmp{j=_fm^Gu=v0JRPsProH1nbHK z<8`ObT5m9&`kcKhce~`rSDSWR5jRdt=gs!H$~9{_Je8IBo?keqFv&?^66djf ze`+3lJ-%7in?)*J<+#o52{-zeC7fL3q92gPc{gsJ@8o^^a?8){lhM%HK=b@Q#ONfgj`(j*^x-j>}Qkgv=`n^+MUo+fZXb}|gr|{g(&?OodK3*?w z-}XDFbJ>eis@~`1Zp`Ps^RW1J{NW4N@B7d1`t|*^x#(n}`&Q+@;{BO>4bQ#M+`Zye zAoDq6*Gmd+UItk|3R}N~pSmf0JjZa??yKK-<``!>?f&v5d#ahrl|4K{J<0tBlWZ!! zOv`5u{yS6o^~D(%JM?B>7dtlN*Yu)hP1XymF7uf$;+<4t`}SOj+eX1;Esx+cZiabj zHRm_Ycy=bnVaJoO<=_ay6Gm!8ygr z6<@=0_BJba-_UzFPxxf)lojT&IVP9CBy!$d8Sfii?ZJ8X?6SL-R-T;dck}`evE*D& z_cV%%)4u$F(dU z`&^nB7WjHvR2RpqYA)rvlrmy$eEBr_ir>$dlqRm5$ago$e#IOm-J@${kIU`(WBcEzujNlp`InvV?=F8e|In^; zT-J3J7PFf6#$WV5e^FfG=p&<7@pXsaxioZinMh0%csb>hoJi(5;}8j_FISYj*ICSJ zUmobGW%{zAr*h`csccOJ(Mkq=LF~$r6O^NUZ@b)%7yl|!J)<`C>WVPAvMASxS!PG7-uxOr9i8Ei@66-#rTDvDo^m;9BO^SV85fA8f(u}`Oe z+|T)K;-NOtjdJ3l`MbO4+%!9vb}`^;{4?q6+YY~v)9p=krKrCufw_M!cwIR zYdMAczdfiw^!Df@Ur|Fg=kp?`bRU*gCuT^+tYmrNm3a1h$;BTEl}k_cNvSTBwy%7@ z{=&?C6J~$eTobwW!)tA|>OzO=`kfJPPaQk-E_nIj2Z>MKPTT9fkNt{%YsS}4JU1^} zz4-F!>b|_7eR4A{#zsDVysB6Brc?Xb<4a%Y_L&D4JAdA;*7f|-lC|BdjvIZO87a0l z*8ct!CE@)#t2AP#zWx3%G6Z11z~*_*c3S0Qo7mYgvt zw0GXR%{94I{?aQhrso%*Y<+O-`MjokZvBP7y!&UdxZW(f{^-iB-BQy`e%3GS@!}I$Li2;s&O|BOl#A1$w^H3!l}+pTf4*d4g84tIQ+D+xz$b{ASfJe~QiE z@Je@vGtLZ6@}CZOG=3NUGxwggzn-;^K`r-{4ZiQL{q6|((K~-r(6L_58Cm-BS)cXd zwYRm#uWGan^j&f*N>^>=@}>t58FxRK65S&u%m1N%frVYcjY20&^A!j9Iha?RIc?}> z_)EV{QbbZM_#74=J>8pXR@Ch*0-H18ozhCw7v0PYQUwHY6eO;MGwxXwK;k*csm5CusJT@nv|7M#m+tR4~D|UC!U(@C-GOCwLmK2#N z%-LcToNDoJ&8F=pHz!Y*VLB53h~W_5JEb7MPv`jq|0KS)SSu{pw#mq2iK3TeQE6OU z+(VIfjSE=>DjY6JAAFa5#lu6m@W=#B9_R1RFPrPkSReM*_XYD;!_7V>l?wtc^++|Y zNL{z=qthvaj)p}OzP$J&ZQ#+SeDV6_%Lz$KP9$$-UevO0yV;`ZE!P&zP~=TyRB-HQ z;pF7xWNKP9^Zsm`&4o8@txOv^FU@E;b7kpe>=2KWLuqnJA+I z!>_8+?pNQ)t7~>IPL^bt#HIEjd#(1FC}pKK>4}j6hjfIQLY11j=ahw=Q_}hVZ+-Na ztu^m1@f*)u=`ri?7yW?wKjlxX>tdYaBd_&ONAA9)l7gy(R6`_`!+PTY`<1J?Y2m)#j$TjO*>Az#93^(ztfoa*Uzlnww&pg_-gLw?^*G! zIs31GY)`MX*iqYFx1*n!=5O40|11A3SZ|`o`pWSdo>CgKMH!^$eo!{>{*qwH+H}^xzxobC?mE`#w91|yO zXxQfFtf<@~bTd6?ChLR=MSe3SdDwc*niZ!R2sD~CuDjeaNp{Dl;QvuA{a>uUNgR~3 z_t#b5vd62u+T;xTmwcOGgJZr5E7zqg@2&ZtaOG;rwf)OogkNMNF-ydkwI$q8U^Gxv zRC5V*6`5cv66hM}tMZ}Z$D}2@CbwM<{PgM3ej|=q#rw7U)lZ70eU!~qi0LzTmGZeO zAKs^b_)O?dTf4<)Lmycm{OlNh$06cp?Q?&|3C{0sU17Z$HhYsr{E~~E;Z`jZ?%&8= z&F;?{ndT9Gyr%H+i;KL5pFSQ9i|%;!=8yG(XATK9vnrk*lYFy#;ZD8tF?MI$!($7S zB~}Pj=i9JO4eP{G3gXTqYI3EV4L76?C`tharp zw$$?u*}gr>w~~%p2E4sjkaq9d31+kTW*skAzA-hh&z)zx)qdXF2Ld8dhCym8`|d_t z)&^G0c=%4Ac|nOF-_|V-`fu+A6}-2e-D>>s&)xg_r&rJU_$_mbX@ku?nO*r$95_GocjFQzP_n@N zoU!(YZfusU$tPd;MY7+lMHfuD^I-LY%4G~64Ju}y6A6)#XreY_|61Bxq8uE zKRHg66}LA<=rPZ5u(9>esH(M|e4x5|=hu5%_a$jo2-#@1+pA`FZ(RN0huL-Au>NEL z>6bqDQdp|)csvhr*N8o;^sO#$BH!*x%bv!tLgAB@D!VjqJ7n2Ln{2gi{k!aIrb3g$ zriNeVO9NIWF&n+{nIg3C^yxow9aj~ewiyavnZkYI-(qc`03^CP3PWlZkkXbn35u@aA;1Rg31fg$ffTx9tSUS zyE1iCrfJ2~RT^r^juNv{Qs;lWEyTL`PSl;Mo{#&4Z2yPyG&yno$zr?czIalHRKI$! z_qU4=Y)k@92niV}rR7dbIiP$rx05q>L%q9J0`szWP5YMDrKsoyUpRJ2Ibz=3$4(U~ z2i&Z$C9*e~weuw|UAj8qOto6|Ket;}TM~PWlN+0R{cT=vcKW;Lz{~%Wug$$z7hOKT z$>{6sv-{!=Bdb?!w|gid<*#t;U`Lb0W`|S%4&0RLxsfozY_dW1wY3I%97kv5tEmcp zDcbO`A>ro{*^h~*CyCbtOjemFB)PD02?tY4#fqYwyc#a4XJsXiO1IelJnLO6D2+t zR`4T(CyNc|FRNC1`O5Bm?=rh&A>J>|Z?6`3{q%o$+&baWYuS67X6S776?4kwyztyu zVc+XxFMLmLNbEkg+)J}acu&o0$O5Zt9-H;&nywhG zoa)mh%GCUtU!v0``%vc954SI7I^C|@ckZ0U50BS3{&{?I|6UY5?V9)59GxKHpILKv zm2j>Kzx4RZ&%>(B{TJT)&2*gd<)T>2tD~1XuHSmLN-ppAw;w;#cC#M)xuj0O?#D_F zP9^;>5f4eXD?q|&Q_j2;h-<*EBEp9ln!0)+48b^cp=~lbA^_v;Klowr=cT&8WfAQIr z<-4|R-~OfG^YPsKC91QwNhZ!o)ya}6ZGADPdQ+pF&&y@OH@4p^7YTTAFVyGh6&zv^pu#5vpR#x)5C z|D69Y{josdzAwM`pXRSTUt_XAS3Ks+b+;M2jQ0K4FS!?Y%Sz)u&&_)7<44@4*K_Q> z_uQuX^P$>V8{Zu7&-K+axtaO%JjXnj=})HpsNKF&|47ghZx_WZ*>}(Poo`9abUc6J z>4uiIYpTOv7A+6>CcUdtWA~?a-fy9@A&+Ojx%l^Iyx#iiX(unH{E<@(XI;hX`tJIH zIf=p(1>%=2&-1HF4D4@{xO%9WF*)2M@$~7(i)<|;FDgZ?zAnTmXq|ZR*NSOk@~LAJXMGEt(T&?z88!*{O`aw_gu=2}rT--8yq|Zf=+4N{2}88#|Ud zFYT!RBD_PZ@AS6+Y0KSYuFw6vJ^k_fPxeI{`s-xdV;>Z%?f8_Gnt%A{=X14N&*%I4 z7neCbIDgpYS9q>p|LvbYdX)CR+WjXKascEv#b~-ea*$bE8GvtMz-tLycbA z{y)xp?taVFf1MfUYL#bNE!BAYE%e!g<`pG={14YooKf^)XM6vt|MS0osQm2q`^uxO zmw$*G-rRkEY1Owm`;zun&3zc%SMzoM+jD2^R$2Bx`7&42)P2|Ujf*8WN6Z%Qyyzmz zUmCFLRrXZjA6Xl)=C@kfH^z=-)^beCVK8~aYfXWc}kD97s{nRxIBf|Ykr-v^r6mk z8#c*Ktd0o3YLyvK0{(r??!r^|hKTX<0M2=fw!!sAjrE^GoVA`%@u ziX0F+AW6ZXMPb1aheQrX$Bu?W0!__=j4g_+Y)Z@=PCSn!iguUWbJmTR`0ne&oZ869 zFSqY)>vg;FxTVzb#jRk=^`%9X4evZ6+VvFv<;Pw6MuAKgr#9{y9&ZGJD^WSv1ANaLduHs;G@xS}o%a)7RO^RLHF%bL$yZMi+t>dVWYreQi?D-G72>MF0) zZWa1`pEqmm=9}wQ2iuCqycDSU?J2?0w z{KpK>uDEiV!cMs_^n#`xzdKWH}+Ll9FB|MVz;Yz z=3MLRQYUZTn>}~tt1RE}S2IO+cgoy<{&Ml`y~+8;S32Xx!}D+b_IbU=Va3|dF$elT zmCu~>w&L`Ww=a&fOH|0u4Uc&HBJBOde78>@rOwpd=|5-nm^GrgZu5ByUA4Dsr+&XE zQ&#b5cj1cvN$)xTeEuCG5&gURSVVn`&6THYtEbQ6jg2@gcyC_&T{)?Zw{++BdamM^ zdd_LI@`Yl1uc3y6yG1H@P>rb8pg5OY&JNb>sT4V|E7u-b+vZ5Oqtfxbe%Ukd>Be zGdYv<1rMz4S^T2ON?E6yWk)afj`LrqzLmZZeKCAOta7H0$pni@j6IB5uYQF8DbkF+ zckzqtC38O)?J^FfuU?skUn<@%xvIHv|D?s=4R=ac?C~{K7%abEy(n*&kTf9{^y0{v+ z3T^ZebeZVW>d5M&^=CqZ^j4S7f8X!^u>1eLvajBi<$vWb_OpL?EBv@ClT#FNE7?Du zEq|rXfkXSh_%W_Y^EvWA-eO(K-^gT%vj^+Xg}ZDxbg?yA=!m3W`}Ti48^eD->pYh( zdEfqZsYXe>9gvY6uA9rWc&73 zZ{ddt-KOCuACZc|Og?8<*cYZS_4>&#y_0-d?(%m1>3;J0 zXZvqT_#R(2dboavr&o1uV(wtIDK#98M9=;!pL)3 zhUa$PtogKfbM?fFI+AaXWbJ%=E9vv}vuU4ac5mC)UL^aX=JZ>&yKVt7rl;23ocpo2 zVD5(AOv`NLGv`*V`?g*)PAl)R#fm-Y)d#yGuQ<&-leM*DkDX!FndC^7d-r6@OWvs( z{Eqh4Hy0G(d-p7f)9H@atAy>F^nSc}kr7vvKJUVZpO1@IZWliKvG0b~ip8t6wxsd> zzxey{`qi(W@6X%#`u6tB?rr&>^3zUf9NesSc9LUi@2kprDG9&2;x2xW>U!C`Ek0-c zzQEl+O1q-Dz9&uSP?P!f`riqjTR)@B;`0|?J@);@SDBBmno}KIJ$z(OEuXz1=Ejwy z9@pMA?t4&N(b7Eo#fIc1>)hosoIV=)Oz>v<7WLKSl6G=F|AU-Or#A@BXnQf~W8-8_ zfusv37-w%@lbNiQk+#-6a&dp}?6dREdHI$U$8YmfO67}euAiE5ZR6hO#d}_vZho7| zB<1q5uzK!$Ve1v;P1<5{1{*`WjwExvX9-h|kJ8Sm>%U$5zj@Bb$MZhkZx<63Xta8_ z(U3pysq+4;-Dhn0_c+IRHD^Y-ED}xNHtAH7Y~B+RTyg#F)FR*1h()1x=dTFgZk{_+ zIzjs1x-;26*N$tmEUPHpp0nyj&DH3>lZw`y!u{os(tdrMXJsF@Jak9#y5klC%`f+_ zeW-F$(eQ8O><`Tk{xu&}a5}M|Gyd6^o8=pseD1DfjF_b0P|oY|W=Fy$`|7|~f_0Z0 z53$tw9!`#2y?)-#&uc`j6OQe1Utn-xo(;>!l}`<~U!B%@pII@&KIQwbRr~(S*BpIu zbJeb`5>abs=uGOJX_PXF+vM0{ujIfvIWKn}+q$NB?`Oj*i-gH{Cij-E=dH@VUY)%8 zxA{}kA6p}Ky!KY>EG_g2dimDx$dPZ$LoVJvGTrvx;|1l7_d5f5(6}R&uTeep76Fa`7z4`v*drtAM ze#zd>x7%J#xm@n)A(?h>zx9^>nd|7~BM0k=y=M)xc2Uos7A$}7s8Ps`cZ2uJb zZ_DX-+rK_ZD9qcsMeLVU7Tck)9G+(X+1jk1wk#8_?&!I@Kp~5nne|S|Py2ZcRyj`c zCP`8T&%FLh1jWy5&~ht1RX%0Er{M0-Q3i?Mb3`UgYSer%W&Jc}<;^es1unInk6PYP z_V@??mg=j5FPfFUeo>qDDY5qY-MPiVyToc`9FIy)QN8-fvH8j}4#Ac09VWB?R4BP; zSM#cSQIgHm6=uHk1f+y`9~85%PqO!a-&N~n>v~1-C;w~nh0_ElRJX9Lvng|XC&U`z z*phQ3wK+$nF*bL_rDUD0y)4PTn>C`RPLjXhxGdqqO+6bHrH5Thwpk=bb?d+7(oYe3?B^w2(^;jjEt=IfJGb+p zAbVfmc4sZ8wXFUs#rEqL7`|4~Tro||J?da@?}R>;WP>9eD#t0iTnseoocZJR(FNHZLXsoz2E#b1l zRZ|he-8=kl{!}P9uGh1EdZ7E2H0R&-v-Z!3jpBE^cj@;2=~3kta)KW(d-56IZk_zT zqxQMs#HAnOxZBLBtVPP|MWf|c=pG*Ii7<2!c@@D>h&8YZUCwU!SEOC*( zGS8`_Bk=TWfzGPcjVsJ6_pw!F7p$GkcktWgXMg1{`BeUMUi|InZoNAD+f_G~bsbpT z{^JktxuT-dk1|`Y8N3Sr^Y`z@pY{9aKUa!1&+osI;-+}6mgUzEQQ11C;xp~7rF%3h z&m6wdBz^D8ynMeHH6d&1YYU4rV*4stUp@UT82)`qY^B?9_v=4r z?rc^bHRcQKFYK*0&XwKQdm^hLO)jR6Gw5zxh_2&SR+Hq0%3q68Tw6m0kLXlC@J+wJ zz}}YQO7cFZ^!sP+a&%e*TA8UMJbxA@Qz%*}qn|=N>=)Nd4lGpZ2coE-F$Q{$Kn>3a1~b zQNKPTxwv6kv*gno4u@anp9u>xII`#U+zj;>xel#QIyHD63uv=PK0M6O63>r8$REG#o>MPPOhZclh}J(Zm)`6-j9>%f~Y>^Gtet^z%36 znv1U1kN)ZWw2mwOQon-7R%-sW@9K)rTYr>%E)eN`A!5JatRa6Gn|;bb#XVMYm|f$J z&(3f8;V=7r^~cW+E{qN$j7|Zp%AOumWSI@Pq#TxbIV@e0q2bolpqa5W)531vXPf@k zh!+gM`rq2jbG~?I&QeuX4r6}b4+(Xf^ww|M`^QgZ`}N-<0l)s2-mU$7dEwX9g|9z# za+Ep=tFjxvzkd4kUdslaDWAlA+pm-+oj7q~w%(WamFf$b9O511Uff-fvb1A@?aCD= z3_cafeXpB`Czvf@5TZR(ECtvKJ<{eKYqqvZKSpRXRjtygfY?3%SoYgN-M zhDA+{n*O_=+t!M_vzz*MgBOGC#l$IgD~kjcdI>ISX<%nv<#;0X5@)XU_fIlElR3+N z%CNXtu21C`@P7H~{fA$90zV%0BJK8^NnVc*V=VfyEa55z)G#WgUnAtla zw~zbU?R}cOadDn@m(O2*%)jy)YtjU}|MUBA{yqA|KL7Sc1=lN&BYy0(*j*yTQYCkB zMY``>k=j#_CVcRc{rC7qpVEg(|J~vwxmCU8PX+(=G?@HhQgEk){FECdQk(8iTARCr zab02lnzkaDwyT-lK_NST-dZa;NZEtyfirEi84kIn9huP>+n z&R};`{G)bqw{BPR@>yn&mVejOXq?%QwER|d%ld3BhAR#etQd>eReW4LyTsOTUDUk; z%Puf~kkk*i>ufOI;~cx@%n~`J1ydK_QA+Jxs-h*K$q>o3(RS`GNvX{|Yni7VO;MQt zx*>JH&f9X1?G1_wOTD(Y1u=gQX%eyUo-FK{IB&{B?w<=3JaTv{R?NC|tI1?ua_-Xf zl!IqmulY+XNZgr~^L0&vLhXbvF-MR5uKHB^plCs+Nr2D3%>@BR8YbBHZ((T^$opjF zRvq7E_E+WOwDbO26-Qk^d{>%Y>bar6F76t8%|VHUA!?Gki`PB#ymaeE%H=a6nR*f` z9M8pVCIfTkJQ#{!@Qn`**JW^gnj{ug{Y_?;C&kbCt)$ zfB!fBKlXf1{GT(F*6@z3Zvnf^gQfWiM*JeY}^Pd0Z*SsC34&6A}kjFjf@&Y6{wS_b5ZA zL%p=}kxqu2@4M$6%#_mI?C5A-G-o$s^qwip&TN0)HMipK?YjpG7(~nX^SgO`Vc$X>_vn>-ueECY)BRa6 z$MKbN{MC-p3nv@gb;2_Ai{^5kxmi2gJ0tNw?%iyJR* zdpPsNw1>yj_ln(^U!0}(>gvzqkJJ)Hf5y4C*~yYKXUu*4Smy8VFSBmS z8v1<;xWW*k-O1;j7JhHT|BYQ=geznWd~6&iNkqy?u6=gbAw`%W*^P)IEZl;LsZn}u!;=D zb?mI+)70+n7f$Ai)mZASZu-A;&$hx%x8x?AIdeG0`Ild!Nn61Gkno3h%K8phF}^L( zU-Rw$`N;+!X2x%J+#0GTA<86mw?%5nSzR49)rOz`D?SA53vfw@a=h%NZo0kn)Qh&*7DA?RFwSVAD*}KWBP{JnakGxercIM zTgbKW`)Zrl>VFhhDE!^8o5|x@&yhdF)=0(My44v%NR~;-LLf~Wv2K&PTq=O zfy1`mRi?|1ozPyf%J46bL&uTWzQ;Cyk3Ua-oO|2s28+>Df6G&RcI~oiB`;4$d>7=O zajYpxX^DR23}HtHVL`(XQGtuRzU2oJMK%QrUAQW;{*0g89QkXzIwo_ZzT!Gym;G6? zs7~-l_V1p9EbYAh8|UyvzYX}~c*X9(m$xr({#xV0e>hNuQ}D5ZS`~EE#Ow1e@^-gkN7D$o&(7*9ga93n|(fh#)_lo^A9gi_o!GLmeYal zppe^>8-K&ot^_@jad^{KUZ^HueM8jRwzYL%VJ?dz%a`ylzNFtvE&aA`Tz`(;Ezbuxk>l`&`1hmA_oxnBn_iu~pREt7^QF zWvPMcPySx^zIQCI+>&o`q)t2k@nxUXzfIJBxQIpKB75_$)Gyj1>96LrS7$6JyRh?5 z-5aZj)6W&drl(3z`Eaqp`AeImtk5C1E^E*Ea#}twoDyV@r_I%ytaN|*C84g@vFXvX z*KLk`x3%TyOSzXmW+F0?-(R|XTyyo|$J&e-iTV4~#GK<}bvxWVS4B=+d)v;qRq2QC z<0qxgzPAn>3E=B8eHe03Z94bbes#S)Nr$6Fza17dmR&Qmdr|8V=Z{^S5~gf>+jm{y zDa+jdH~nGKownK8o@uQ<=k{t@N97nguDP$O z=3k2bu$9k41n z==rkw%S@3Vy__*>FLw&^%batjO2UtG0mk`Tw|e85{ii>*fcpp8n&@3-#rGtuu~n zRm$8clJe%#k~I_R0}ink^UtbL3cl|1V_NKdxyw)O{bJjfFZlLn@x;Rp#;);}EDNlv z>P{V1f6e&2rT%z9+q}M}-FxFoHe?%cGEZbL6h4?)v@iW+VGZN<*Jt$D);~2Bsx8$2 zJV_#ONs7C`zc*noR~~!y+rNkB!hS2YzuU_`8^2NZn4fPJ-+c41lWlxYhxPtlC4T*; zg0Z_k##fx=yQTHx>j_ikO#z{mjemYE{T+BrCc|k~;{}2FM@_Ha{T+8?>at|kiJIoK zR!-gOR+80Ha->J;(yqDw@e=o{`V}G_zEu7BclK?1>e^Qi^job`=Or%7c^*Ewv38e| z#)@N)`Fy1dk}oJdVPCn}XM)|SZLP0=BVZM{-L{c>}BsP4GMX>Rm!k0Z1aL}^Ub&a zE;w`f-S&EW_uC?efAQsAHvX1)!Ha!es%@AJ>!#P;>EVC1l->M1jf?IUtln18C@np$ zNKbOs+_l?}^Kl2?T(WCN(KMdxtZAxG_cf~d9EoD+6_Kv=KAN4jOx<|G%FF+4G?%3_ zM}Fd5Q@5#jTIIug6V1I$l7pCK%CE(yoteDt`OT-xE>~q5o4-6C*R>=@z_@fm>A7Ri z_sp~qQ%(-GGk%(r zuJB7=LW+Igb;$)*+l@nwW-{^$7R@tW)a`lgpo@GZUwe5xpYrYcvN!QX;UzMU8RvW7 z_!;-EKL6_Rr4@VFrD`vQsR!@Ky?<&?jnqbmFN)SDe!Z{}6qxAT?N{xq;;1yAaSo5q zrNXVtc-2<@i+Y+iP36Ch^z!VUOH=Hx-IToY?BL!leTSNwH_Q~hAm?d%W!rLwjn)9{p{D?L4iLEj#Y;?PlhEhD{#IGliZUj+<2y$~iVD_YZdIv+M1ld-#)@H?Tp;=$e{_15gy`4%kPZgD2- zQ>Ti`>PFcgyG<`o{av=?b;&%#XLA~=Tbt4z%hj?A@xM>Lxz?VqHuLI~xdodfZcZ_j z-yFZ`V}mnK@3KWgPkC;e_c-k;dFONaesX!av$m?Q()-VM+;2|39`d!-p<#Q9ZKldP zu4BXxPD+;Y02gPb$U}j9Bb}5{(hUb=+B zppwEj-$m3cumfK%8AGX{)VXjYmu)CGZtl0fz_nJNI=C)dE^fk27_+DOL^LoQ#_F1dfT>Eobh{aGL?$3{}({eVx@p;vy z;G}2Vk@9wp^w%w~la}^BTkV-r`s!)hsk@grUH?5&@~-+C$oWw;Zo!P*YkW*!iYIul z|IL2!A;-L*29EnT`D=;i7nS_C4Eb;T()hIdv_sqH*{w8v^-Fa6?lo-_ELqjlnPx^*oywXocQ9(r=Nb-vHkUz-k2yo z2xB|HW0Pu!=E{3~DrbyCx^uVfW4OnYtZyIsZMvRhum=m9W#ac*>%(8#Y9wATZk9Ou z?1^&!!R#-8)8`*4mY?f=`Gr{H<~=86@64Wg?fsW4({9C=xM@_^?#lgg-H&hXa_LPE z6DJn!(pheD{c()ymkiG8Z%d!nD4l(iW+3^|M>{5oSH#XLR^>qEhE^%D_M;iX-0qdX z_J&_LEE=@H>CL9e%Rkl}tm%^9)+J{BQ}}YOt43P;zMpc-1iwT?pWb^cA^BH$5AU?p z+duby-S_L=&s&vKJi~);&0NgzUviG}+S4=F9ZUW`|7eHo-hEC?EdJA_7kS+AbD886 znbBgRWH>KF%IL-UuklTLmI$k;lo_v@l(05W{{Bweo115|$ZK!Q6u2r7v#I>uE4PW+ zUmjoa{af{1wszXh>c6%j(f_8{vCH1w9oA;Ju*E`%xyJDK&*#PWPv`q`sb%gpulT*~ z=+#rlPcD@?`gen6aQ^+-nO&)^b`Mu~W@#u%&FR(Aba!4Ok}P#{NoN1!7U$Hjm!*FO znI1fU=0%aao}|a86_XoN7b{I>zR)F#cFryiu56j)so|(5$o_;+{E@A|b_A}Z&C?EAYGF=d~dTeE37pZK=4gu7{L zdoCaUQD;B>=C|5;PilPCF7zZly*O2ir$O;yIop$C9y^)!KHh#V{H=QLw3^t}uVd!R z&k}aOadm;u!t=oke)w(uXlHY(|I4ra)pq-;mge%h|2g-e>fL{jqW`}8O_i$Jem1gu zo%;Obub{cO;d+hho>SKapEM6!HtA>HGv3@k2W9*+*ryoraUTA|etij-hp5QTKUPa} z4*ciV<#G{B+!e_jm@;Q=?oa(!eP!d%|5 z#<|_@pe4Hths#@~V5Ro!k8A6k7Rjk?vt&6vd(yrp-hd09xz3hN?Wd$}Z4fKrH(wjc zXHk6W<5|Vv2<~@WofrG~#Ele`G#33nJk4qYvbNcmR){N_SoUX zm#TRc;SxOWPHYs3|J%Ih!?NW2_3Px;)~%gwamG+5b^6bG`NI=mHuAzY|I(mNWf+V5%c57Zo3#ueRE1Ifs(*>YtGgukSO>at-F%ANa}fREm6%jmxJw zKT7YcKW=j@|3?-f*plv!=cyNK_{f>@5$o%osfeAg_a1~-_e=qFI4^Gec_$~9p1CH$Y_xb$E2?kaF6aEFy|6F;`#=KJN^NCe_ zT^fs)yz<@?`tVkZkN`*Fac)Ky7BTa;f8}n?)%ox`%D=|m)Hm|kd<*}TOa0f{|FB*% zDgMIpFLl#C_5FO^%)RA&)>h8nm(o{tzm5I0xpk%W+?EObr}x&q_mFt^$8zm;nRWBZ zXH_1&rxw3w-^Mw%e#Up+sZ8>4y=5cgvq9kHjONdd*TXX+uXf)``*}p>Yf;kb%U7>2 z)4%#rEtzd&##jD;uhRF`_IDe~+NZ=Op9^UH;`J({BEa!;>*8rI^WQvsExADL*9G$% z?_u6Hd8-+{yXPMvU6o|-PRXADTTYl6^>6z zT^%){sm#l zFLDV?T9wG~?swnD9kuT+3cvdEAT>?*U z-+cAd>YMN0R99{ORaM}ApUY&;n_Gns#4?dZ7o5yo`@nZXnyz?$H_9y=~pOj_0bLxxjQE5$cBzC@g z@O9hr`w5R9a)=7ow|^)wKFkqXy>Wd^Y1*`2uW#F217~mB;Q~-(-fe%;BGqu- zGS2CO7xwHCe8SOoect!4Q!HE$-JW|yXqNxs8A)7i4-Ed4_C6`>_Yi(}cez@~`IBbL zkM8j~ywL2(jaTKj&OF#Cv^Dg|93PDc#osyZoas-?y0!`*NcPQ2K7H3kx^!Q*(t+!0 zO^KY%&M#Vyi0PO_h+fnQJ7aR#fJ02V^%L8s@7zi6PMGpna!;Rf_DHSve^9zA$Nfx>!$Bo!YZM?--AUyuQ!#z#Q&PIu&moYra`~_T#xV z85)bOZe#h>7c%2OgVNT`u)+bX5btn~a= z(=5run>ypgG~7j3ZJ#BxujIJ)ob%CdgadZ{2;Fp6pwU?E$tmf*1&vNmBOX|%IG*s{ z9BNQk;m>FmRQJBm;`_Fz<-hLjDEJlW$z{N;AFuhIbQ(d`h~7;>m)1 zRy)h5y$+m_pKk}SoZGAKCVlJ1g_hcwto8ZZCp~t!!7!ohz3e8Rv$=U^E#j-1cz3O7 zJkEJIH^RhK(z)(SYFf|V-(P3!$^K`-zuiP5>wZQ@?c0-wzm>-&@$S<*+x1|>v*M8Z zUXOR%EZDH&HOr^P3oj5*t?b9k|Ol1B6M z;JNP}o=rK{bn1pgr>v%$kPbsbdC>POMJ$}1+OiE7W-zfy&$)Uz?A*${sW!7z`}BF& z*W6{8u_fH~2(y~0wrJ*TFSC+;bA{WqjxLMIc&t4^w6gMDzf#gQ_VO!#I?_Dyr1dVk ztbDQS`?^`{mQQufVcC1iwK|igO5b6`v9J?ta%8rFmz|jYSzzf@fxJF|0CZo_eH4(D#_=lr?NjIjr6#^IZ*!ctn2JY*;P* zz>Fi$JC1X4&bf>?d(SyaDo(L{-FW(>#j@m#_lv4m9scaw^+8LV#bVKofVo#zpFc9a z?WyGBKXyqa^e8N`w z@}c<#6-m17tC!dx_>h#jtVAY?@$Mu`J?~Y#BC41B=Y3N4_ScKN^sF~VwI%b#)pfJB zE9t*#Nxiu0mil?gtD6E}UU-$1rnRWR%3F4kTHc$L*KFLbbV!{x4VZVLpJREC#?#M< z+E3579SN=U@3weyUi`&=t{0&)8)|ujuS7lMa{u68d#PHHQ!eU&?CP!js%{HUOK;bY zjCs~ouOoZxmfQ(Z=2h9xG&UNPEP7#`<63GH%8_<&wg$uhoynJ;oyZF*DxCA=&YuYv zYq`?RCj0Xmxu`|2^XE-@%zdXKn%7!&e%G6hXZ;6@t-sE=Zt?N)x!q@zGR&KJ_d*yB99w#BYt++S8;fLD-Y+-1 zyr{HTB>L_8lj409H!i+wUc0XBQ?&GHi_em$UcKyifA#ue+3@FFCqgyX{K#HJWNH1L+cHAnKBfkkEM$^)rO(&TQ-IxqI)FgXSW)*7_U#sqdC!Yv zH?)X{t$G;nD$x1MSG7sLJ$ILiKr8OH0fhs@mDp4fzhK2WhArIj+lcwnb!a-A7k3<`C8o}R8xL#W2pS)Hw86#uiF$L#orfH|!jy#P-Z+uL8}Yrg zGUGzpnegp?+hY8WG1q2fsQjLw_^UkV)nlIAg}dILXSQy?-L}M+va{V&)dL^$ZG2T?@y+(%RNv6`lg>U}QZPS< zEjZq{K!1`)=Y?SZ<|qEWmc~jAQ*+dxey{Ow(bbTzb2-aa&nA%;JT+0WM>@C0KIO+7 zbEaD9_ublmgrt5|-~D*|`@7Q26W3OpV&R{XF70#tv3ufi;r!jnoXe)wF5_Eypzhh) z?RPVcl;0-#pX@vp`(^I(X63&UY%^OHzIkWl@yGVg*JkB{Y~IB`LlhrgQuNZ8Xl>JR zr0RBM)SG{6lh)7QzbI8MXwKdl3s;@{^(Q7>rk^$BwW0iprpt9D_j4af>p!xxy}Q5g z@Tr_7Exmgzlk24F3ifgA{J8sYP~K|g{29AUzdqb`OW;NDmuKl3M+{z0uk2aN@k;s@ z(*|qp9oKj#$}Qj4cQ*N*NkNV5Ds7Xa5et5ww>fZfxp(k)cIe0iDO3Fix}lzXKN{;vNGAjedpKqZ^=Blrf`?7 z0khDX7!4oEiPA2&l6&8ss&UHS>b$Cm@A8r8yX%vSDtZf)A5du|8+%Pzv|YM7V8Q7ij;LE z@F_fY_{Xa+w(QAaW{yK$s}?qF^>m!kzb?4!YC^Arq}GuI7cN{i%9CdW5+KhHV8<=Wfs(AK!PUq0~JbARAhA>XOw@jqBbTVvG=xsTnG9OG{I92U@V_|j#^ROiX~qr=-+!l2`i zm_k;7t@`20$U2=v`}6E(hkfRfW_oRvna?MDrI6hyeWg{XELUIT`u3~0CATH>ZPI@; z$**Ehwe#}win2E|3>U9@UUlfvJoiJ^x&j~9?T)K1xR52&Cu}FUySU|NvFvWYg;xLK zi<86FIPuTtU&8e9@7%{{_h>53)629zx7{Fl>9nX_*EpLlG70r&-HkJtxMpjB&bRUp zw@e+QSB1x3IXS_4Vv9qy*+L(sy4EkB_Gr`}{+t-1|Eu`)r{9+UpIfl> zlb1h#Ag})HUzhKW$#s3sr%x;PKeW%2t2}3OJydwzsqD0_G|gDuyrOmcWAE?(_ATK4 zuE<#7-#VLES4G6X>Gw*S645j9vD*#nvU-2NvOD|lZuiZ(`cM6EYL->xotrLBV!IDl zZ(M!1WwD7%^ZO^ZDv#LT{)?BZfB37y?fsYHA6?r*G7^9Mn?LXUhl@7Kx1T+Hyr@h3 z(6bNu+n-6lN-1*{Kl`;Q__@QPDF$Jj&zttM{9C@YBiSiMDZaX1ok_n`KKU@O!ND6W zsSHP^b2qEHTzh5EF=Nuy1P)a-O{Ncp%t}nG>hEqgvYcbI6q68b2?;b+oUq&MZlSi% zx=@bWWz4xJ1b3{kc(rQl4DYN%m$MossX4I+JBTH;vl!&09XxV^MN*gHfJ7uy#AU%^ zu2qvZtQ89imOAS2KV&8QPmz9^Nd`rlGR=X@44xiqFI3xK%p4G9cnW7s4(6W2VX(jg`}sR&=hIvB-=qv3Fa{)iiGBsTwzx9d$Sp zV}*TJD_nRIklAM>Xeim17W6Davgs$w z%TL`FTe(Rpa)*-Df7Km{8~@$d;x}LFdHk2IUH8BH>ulHi|Jctq*57l-#p@AuQ$H$i zo1Ss@!8L8x)VueB^)er7E^%S|)t6m%t|{Q#w}LN$|5E?l%b$1uiRDeb2PrOkQ~%F$ z-v9a6C*$%*tJhxr)-QeZ*MqHlpB7sB)L%_e^5~LKSk^jo2AAN1e-VEBdRSyz*8WxF zlJT2!OsVJy=LG*r&P?p@?0lG-c;yc-PdoEWqQQQegK447K^e!;jz)upE9_P`=N@6p zIL^`Wl5xU&Lk&%hnP+5Fy1H(DIlNP}Tq9_Khk&7q&;*CX8M=82=AE;S1V^k6PcsOR zI$}Ad%Hr3gTQ^(0CUFOKMGImS;H5Q;>nQg(&iYzI_>U`R~=?*5)yCv zmsfXYDrsb?C1|y&Nq8kWbtrm7r8RMxG##^0ZdtFm@Di({qtE3fx&r)v&F0N$D@f)M zaY&fq@#O2|Eo~i>s{hx2`9CM+f46||jCYLzu}9<>1^2IOxF1lck>}HV!ni_GtX)0& z)I!543w=0>9L^kTw>VJcAfmQT;2J-RNVCktON=LcclH@_N=#CfIaqRlc}7Mi*Gets zs|*iag?F#Fn5p;VO3*s9Cogi0E4!>$D0CJ3scH&(FFFx>FvBoO_ORd)wN4`orKYCV zRXme}_*d?_)!rm9QVjtvKcIhH1MC`oxtYH5)aotVOU zZ_Z!OQvu)PA6^gc{P_6!56(x55s$CFIPasaW!JOY`f%4o9?hMxo4mN|j{J`homgAW zDs8YQf!<@L?oSPdC zuf1`(%1U~RPD4V9;Lra?F9Q#-U2t2FyCM4bZsP;D+g28byij#2xU%obT(MaC@wEPN zkt2r-PbEn(pN`sh**KoH;KSsCEb^OynwG+5BFwV8D^u z@hr>UfoIEttI{i2-rQ!1jd3-+Yw=iR=4OjocE8tUz2tf&mh>y3cEapLM-8j#cj}w} zekd zy?*`2>rFpiKKIFFeg99zJpbtRzOqH}UlZQ$S9y@=@Y9L=l5@hr>-C9;3v^FTUVnS` z?A#Um&CkAm_pyjQ#zXJY3MtjJls6`cbzR3Db6Oj*3$g$)A!BWf|-T-=Iqyhem8wFpDce;M&ehqe3$hzp6z*k%FdPD zo+s$&p5NOp@_c!B{aeA<>o%N3oy#!5#gONh_9bZ`Cf^|k-j`f@(~>h^uc z{rwYLpKMkP*m_yuW$^C(^1Bj*O*d?Cc(d7ew%wjMt{+J$`jHtPt_jO#UUJ^(w|e{i zbIo_(^h*1k%aZ1c*4Nx4@-F-0S)PR#4*PtcpL$QTe_h$jhF|h+4EL8^a?NS>D&Kk| zR>j-O};KleL+wv$QW+uxd+ zw8XXD)Ai#a74{vceNE*bO6^?{H*r}>`l|bNS8^tvs0?VAGtp5|a8oWg?i=nMwV|V| zH1XzY7L^dY8ylOKecN@amhbcHD-ktO`=0l!t?IvT7dP+qK8t;aHTJblPn>wne5J+P z;)(n#KRmqrJn`nzH(#bszAN;t`jMN-Ovf8j`OLUH*gL+g=+k5jAh$P<7Gm&mrD4~O$u8st)37am#DhN zreVWx^9dEt_}(!7N^0bCu@pW$n|qC8cw&=!(6S<)xVZrb^4GdADZJty>oet`_l|cy zDs9g)W-9)2H%?eNmGk;OEvJOeZL3cNuq?IQs`qTAl;$dKwuf?6npgbeed6VA-nPB5 z-TcRE{aJs1OQm+Lo3J&j)!|X4-TaK|#flOKS1Bx6!k<=q*D1B8 zu|6>T?zG-k^!tWt9*#Z%E>2$!{yB_KoZcqzE*2p7h0H0T;3ZxY-cb$b=%2tZGXH-uH)I6 zb5%NcHP3h|s0ka^s<|-#T3DFIxUyjtqs_a+YZU*@51Pfqamltb@MM88^6wAKcHf>yXudg#2JqxB@e>ytXW+m@=VS^i2q=?g$$F4IP3Y;}t5?w_+1)5*BmaDjG z&2n;FC8{ZML_wfQ^p5h92^R|6zAa-hIn}dLZD|hg3sITL5t_~ddUtYoRQPT-6%?QA zFgPgg^g?5GPKMJ;M-3;9wQ0!-`4zkzZVX{o_`))QN!4ouy@a7F7JqQ@kU`{G)9C#N(nT+9wwtX|Jri!`%O) z{QRd)_4Pl3L%Xk^D|%e}PVK$;+PH%se(+469e4PpDD!@s&OP6Y=eMvOGT+)zm-1ib zSIb5Fqnf7bU)AqSnW6q^iLCoCp~)&&)PD<`{GNPcmO7WWivQQ8msOt4KQYr|_SL^9 zrz})*S+eBT<*J-n8v_#f1X%bu1nL}`8ur*nSn*#FpuIkkzqDdAy4lptq=XHRoN z4x5B*8~Y)7i+TZrh1)oOUu0@yo5;+_uaN99-@wJRlj-0J4Os~mo@R$73pPkic;0Mp z>AZWgLp0y!Mu)qB>Rgnmyh#a zICm(tJV+L(f1%=`utJCNm4W*DpY_T2<}^HEIKVEjAb!Gvo!^))aQeT{Fn+Tn&hht_ zE&p^^@NZ*jTp(aSYhJnId;J4V0u#1>kLJ0~z;mPF-xFE6#~b$w7qKV%9Q9?$J|bJO zBVPZC+evoUJ|TywYa4&6=}Eo(TPVfjWAA#g?1*LVi`y%!_u9)uvNfA5?BD$D*@u#VW#`DbRn^EvBZy!gAg=lFXc zGxJ|=+kd~=?0)f&%zyjN1%GlUOKx0ock$ithP$`d#k@EEcGWq8ou&EHvHyXu?3IcQ zCQRbwI5nv?N^pJPn^0N3MmCneOC=H*&nw<}hQ{7iaztn~zk^O_*DxbW%aw zb%RzU+sc|+wKt7Q%P%=J-cWyMtjXNPROw~2%_V!jyQ7JK0;fol5-XQ$l!S+nfU;nU zcmr2p!s{#TI^4nmFSzzthkW+@bA{E(`PQ73mI1*_@>F)Yb2iM9z zvG}QMVBI1tE++R=e;^0lNYzj=?CnC!2M z1iFeeZoOn+vgC@Om&JDd;QUm;s$e08=-&=TzgZa$LhEEIZu6|eb5fyM02^3tu z(?laTmaTDzjNAgfkH)b{L5pHjy{^;H=#E6 zxXQ!dUi@E^7+-k0pRcPdUfd}3B-z6MCd03Vc4v;<4T--yT&Sa_<1E6w|M_DM>7dCgc?47< ztuhwyU4GXxDgWME4!*}zuiTHjvDw(B7PNBk{eJl;-m-nf1O%RxrtM24A`OTmFvfAJfb3w->XVH2t+XZ4%CbYcK zV^(euXi1V-@Pxfm!q3I|0Pma6T73)4Z>WZH{r*zKy6izP*M)2jCVqyl07DTjkG8W0 zHyDq#%PN#hD!k)O(7cs-wEpOiZ`Ow^H#8kI{%YiLVb-B8bD6|7iCo8C-fq~_6cZE7 za8!fKK~o{XCHF7WfzOM|=Ir>%7HHh-;&;(peNv<+??YA&4yWUBH`afeAFw4~+GG0b zbzahZ`|d72_Cn6LIdK7>Qqd=;giRSTCkizb4>Vqw$*WoOO(~PZnpdVJu_sLV2J_W_ za-SQ8Cu;JCP2Fh5P^5bJ{tK%Er}w-4Gi!LnxI@d)?}WJzbDMhF@0ksj^J27kLtC^1 zq%TzEm-Wl1Ji0we;3T67L!fx_q2+Icg@QS=XK09je;oKmi2v2!GnR@<8sB0Lb8Hu} zGvJ%YV#Dtsw_oaazc~9e<`eyDR_ldITrYP{oc(*bo$Le`H5M!5Sr$?px8y$bw-wyh zu&F-1M*Y=|9W3A1*QM3-az9SZ-!NP3vS&-<@14%`L=qGd94CY_TlW^s5brDha6)5d zgSy-D)+DW$#(c4f(~dt7eq~j-u%(>w=|#r_XT{|AE_IH666E@#^PWKaS`CpSPnN`N zXTCFmCs5Dx_KKfNcp7RWJZ{^ni8Iz2$6Nc)7V_yvxcIjnPbUucY2Aaf}B;t zeFc4n4GK@J8cO-s$F%IfP}I}e*5t(UO??KZ$|Nsah5Ym!dv?v&zIs&-ui58u`2CqP zS-JTl?@jJQa~tYPZ9cbt42xPMF*n!I@tWC;rP~}=bzGh#x?8&Jsz!8-Y*C-u?G2MO zj9n8~2m9Po=IA+aN_9&@YOum|DU~FbUAuXonTW;gT)SuTq)Mg#)7f}K{=4!i?q2aG zU~_zaMD2?d>uohZH55eN^X_7s@KE&6^6QHCHgM%7&2Kr^q9X8il_am$RNF#bdBuYw zpS7&&ZZSCT>Y$h z(VU%S?8nhIwU9$Pa46})Da%@6xH(XA*Ek*%#ML_taw!ynSLhaar_Z-KXPdsGj z{c+$}!R<8lXX%#Nsq^pl>r`Y~7w_o()*0@odhtmbH{)&}#tWte?60q6WjJa@&OGLm zZ*U^uRKU_^SD~ZPrzUMrH2ATs%tF%jnz^oK?zbt4%(JBVT@3?oehN7~#Wdt_AWsKN z_0GvJ&U9PV+OV6IJyK|MuAg-4_tJZ8v-n=fOl#1zS(_%+@g^aK?M73kQ?#4y`^s61 z_aC_w`yufx$ilCq8hYT-*Aw0@8}ipP{0QEuGRaeAvgac?ryoDGpS^c( zel=wZzeRzSpxHjwM}n6OG_|K6xiovKu7bvNQNEiK-fpm(qT~1?@D4je;DgnP%m!jE z*5?{jIjq@o4SFsu{M0yO|Dok;^`kOa%ucEIC@2X#s^xY`uhsjir0~{UT}koy45_6# zStiS;WFOx)@9e+JjUHK6j4Zs&8(JnWpLcfA35z#JgJZvI%<2jF(z8NKb7_hKqnFC< z`vJzca<#g%j($k*Q|)EHGykJk$f2W(p9Ly9e#Ke0sn#s{7QL6fM|e%Z799bngWU=m zfq7DiPwEbHPUbkBBJzgS!&a-`b4t|@R^90@K7FYSTqG1ZzenTxIo9J{OqX^k6i+>s z5n%1eb0sKYkz*i_xJldwy}PnP&1pwUyV_$JAAZauH(vSE2=h@sKaG=<+xY>U-bU&Fy`7rUZ5ZdVx|TqSVat)xfCSHi^NR922atCccyielESEO8HQDT_u{ z4i+{O0X8NsMG4uJCKFp_EEfFU@%p-;p8tg8`|tm3GqRI1WoEayTl{x!J9E||!ItH3 zrkt(RvddI*KA)J{u%=pn%~tJqcJV?kwQXDz_?MlMSQ_-*q2}kK;xix0r6!h^f7-V9 z*M=`kRkk-6o~>HMcDP7(w$C3Y&g2CP1%Db`VS4fYf zg-*@vQH^t$M6@S33mx&%GFYqQ6x3^x>g+1)S1#b6wa}^by}&)@%*nMs)XLWCpOe1C z!-!=hSh%TKwko^$Yflf>wuFzCK7*NlO&)TWYYP<4&UM z4C^x9M$wx6kxL)lX4YJylDJDsEJH2l)0guT{dY$*YdMy_vu0=9^3M4a@44eOZ48fv z6TC#%vbRU1a9+11%$YlsYDD=C%2&xu)p>VrK@CIQywt-EHYcBX zs=QHW6uy4Mf7cS`Ny3*Lm28W$oc0L(W~q)!RH{+;>L}63DQn2_u<<;ztly%7%ZRbK z-NGkpp+E}@LlZ+n=L(mbjUCIL6kW(DoWaJfRLOMFylqCpTQ|or=!#}}$LvS4_3F=m8qSElG=CF&Wxv5RE=pqo=E6j4NE!l92{hIEu4A~5WBRo^spXnrD{k7X>wx0cD=ZPvC85g*-9u?qQ z-@*Ca|In!^ihomhyuI2SQsxK#xf}ALzbnM^2haMD8Ix~#sPPC@AN}BBl`z5KkbGxJ zjocQ^kRpdRg^R~H%?o+t?F;5e1v3bkI`JF6&|9P^GV#Bhapsgehec;k)d;o9nVyhv zPZ zG-<8;hChrGo|YP3*0I+3vO`>t_s@OR^mqR4drwVs;frWat9jltL9v0gx~FUEg4`2X z4A=h6=3OA`A$4h5f}Ozui4WVJFs5x*pd#I} z(Dv$v2L~iL{Gy~h6yy}mmW#dn@`FRu@#>p9-fg}jTka}ecNaC2mh-#Iwn$8$!PsMh z@5|>4HWW11$v0~1ZJ9E~Wy6;5tV`8+SeG(pPN?MQ7Mwk)eckc&z#$7LGI3uB!Z zKC`*>IpS&%%e90DJD#>NDozcYIMLfMBrr`y-*pQ)Io#m;?U*9kK_xz*wm9Gn+a*_CNFba7fU)O5;sOgJI@ zx|vg`LDOkpwSAoWOBGXLtAswm>ueu6{MWx+^38dk)aF$y0)ooDBUT15=P-X@f8LvD z{DEn2`x<{E`8_`>&Nv!BZrU5m-_sjZ@@GobGe#kux8C9#W=!B>oBE(aI>tI+si3c2 z!M$&L6}XP-Iy4ur4c;JHeCM^fo=3q}&E?bXu5kIDpx5-;V$Gu2PFjkc5BpNgCRaW) zpQQFy&-OGh2sjZW&>Cpm+u72Ym1s0; zSun`nc@sl@mkS@2+i3WbVb+gbAu$JZ7SwpobnIdYK7K?@Pxg4%^ttaAPoExfP;tW& zt(87In8n!(_#90PmTy_6%wgKuIenkqyXY6mC!LNc$t-bEg6{Y;hk;ap*tB^S-aU7Rj+v2q>KVV?fb_s61F<)1in-PgEJxgwE~5K(%_S=;Mp z(1Ra2+)tVkJT_Q4+Nk>{3t6*raTydGD004(VY*a|!$Uz}vY3Du%Z?S1qHLUrF9J3f zK2UQA7u0uH=0=-K*uNUJ-*K^ za`aY3TBvxps;c;Z4qNcA=%iyybVQM`(i=h3w_bbCM&JN~X%ptZ5b_J=~W#dq7^)0z(5U%5F$N<~mh zbFIT~{|c>#ua2p4@FkpVvb0r5u#yaXsG< zaESNLMRk9pgyl{#R}Zk?QvG}H%Bowd4rD!iDDC;%=D4a&%R9cq+k08e6+VUVynSiM zw%;tG&GBtq(NxpVyZSaCiItx$>rg20RFSE?xajM0E0+%{ULI3K1oS=^>#y-pWVzt6 zaKB^ldgYAChYz=Jx8~0l?zyq+XhL(5@`VW;Dh8R_i7qXtgGD$dD=si(b5AbWwRU>o zn|{Yn>_=1luN^)h$i$+gT({FuVM5EH1K-;$D$h9niJV@rP;7Q){6(2QPX(2IM~pV< zIzJB96+d<-=pgTzY>n%)>grFf)cug7#mWEe#<}Afa)ECbnaQ{0Oxqx})m(G}|3qGe z^IfhzZo%PK=d@Vgc)PV(YLTW#YqMwfq)V39-~Z!fJKX7}b6Cpnq*mDJl)uvd-Iy7f z%~CcP$ZZv^V|QG&^za#}qe6`S2DK6D4Db3RI5=_+u=+7Q+Hg)##ObY55(E3yjeAP_ zHWYkq@aMhoxIwn#Yx?%!rk#C@wAhaPTJk|;YVg?`&Mmx7Y+VgXoav?Ty_UVI@nO`eCsV5w8l4U#Gds;cGF6~u zecY*qY2GeB8IB~dEDO?H;O(v_bi`6&nZWgo<`XRrpAxwQ|Foz%G=FPRe9(NehLwG?D+pYQe zcK3Hrf8djDt`>d0cjLd~oBlK3mU$QWy3+4{*FuVg+_vQf5HACo63Hx^k#Hjga zsc6EDy17n~f0M85E0NdtX@AVjK1FcJgc)AKlOn1Qz5dFp7tkcW_piVlo7_j-I%x&6 z2P0T{4R@{k^Zeiz#&^b#O!9(qg_B|o_?$&p=NlEXF#Ik4v_z6=iY|u`3nvpxBTL;4 zy=A`zyfp7yptBRg$CdIQTTDbM@3Vq-OUcAMXS_i_q3l|$zHMF^vlEpa>tHvu!`(Hq@u$d zV)ekIz2RJ+2V25dl_bZ;D{|cL?Mxm$($q`5Z}D!`T**!La? zZg6>f`}sS@ok4Xb3tuSD@ry|0naasvzpdrdgHu}fwC!|mG2dlu;nnzCRPWuFCi#2k z>~}{mIRzcvd5S5#{^PaO)X=u?J;zKuRUXXjR9q*pMgQ@iiH&QLlcgE{sN9RzNqhZ4 zQ})xM869>$McPkR*40L^{>rI4`yue>|1Eq{JB_0jWeOPfG2Crt>CBusG2(J^OYcMr z!3%6#CZzkyWQp#5@p91%$>y^2&*pF$y>Q#)FoExc3p2BcrE-GhyJJcTV(S{&vuC$l zu?*wgmSJ=};_}kts}v_BJ&=z7^7Os!GwbAl_0RN|tvt7S;$K@eWy63+$`cnFOq(X* zVB*fve@N-kMv28t46KJA@^3zrw2%9|fd9*THI7#pe}0n|;B}g!QNw+Nc?F-`uZF6l zPnZ|5@E24~co6up^{uIIi|z6Wlb6?-OT2Q}f4c4T`M<4AA2%JeW=UL?Y*kjV?l$ka z!a0S%?xlZnY~FwITl+$34r%K*{XKkBIiFh}a_MkA-;}<_xU-2x!v9ZzsKflNQqz^+ zJEi=)vXhtF)7v57PMbQ%ftAZnob*v}?(oVCYvc-03-I+@;{R){SKS}A6C5i{BDr^% z2y`9YaUb%r@P~c!yW}X0!j5g+?MVe+)pViNr=y*Tp<)p>KA_Qwk39hE3JcHo8Urk%lZ z5fk_v{ueG;9Jtu#!kngrtUufLU5=DU?75uUdy&cQb;$dfnoNSGOF56tc3JW}XmV6g zd9%UAwplwm`5ISf&1`8nxZLsg$9M*TTbvIb^z7$ve8{1%v#>zFuBbrSu9W+!ddc}z z=W704GUfd#T4D#?eryo9;{2?!H*>PWv}>)WEF=zyZD*VkBXzISXS1ZQn|o(9?}Wo1 z3XLr66`agXQ7b)KWM(Q{xbXUkrh`w%p;jXnWf?X>0Vh5cE?!=>i4$^~yf%h9G;&C> zFwb`G>|Ch7dXe+4CbfHDde}0=8FIK^K%klzqy1nJj^D7l*eezIMj|!>?n!Lt@$KrV8=_@O* zu&?jh-aq5)^QP^yRCo#n{634wSaI%aUb3z4vv{GHa^bBMag*tD8d41S4Fx}Rt}$nP z%p0}O;f!t5^7gCGudzuT<#DhRqMI5aNmN>6)4?3vgu?6cI+zq7~fujjHg8&2;jlF2e<^%SvGkjZFs6>{l& z+`oRW>!-U9Bksv+yqZ_(RNQ{Jvv1{>h}#klS+WlmHZ(7=Su|t*g^B?2#8YjKs~Kc| zAA2V?H`&)Z@xaqN>m5QB@>*3qx}Nkgt53|juuEA&XiBj0LEl#Mt&CnO3lvznIzkl+ zGv8!H)!RBUdirGeOgyfmvthGMvaHxMbj)>KFcyi zZ|`TW1b=dI2)}-}#%hV;-h~CxVrffaGh{{8CA}{_kW};t zn8M4-s;J2Ae9^+|pt)LSN#|2;b^(W@=0|QUG5=kW+>rZ`|3_Hy`8xlyKZO=Ob&M`E zj5|XA_M5oze*9#{DBjSPWtg#m&rpTW!zMdaB{bAcN@BsCRJlFISJFGznao&zrA#)) zW0&dPW1e>;+5EPcEw6lhsyTMaUQrim#yPTu-%=)(P4?8Be#l1oMvt@mf`~#6>FFu5 z4`f%rnj14<;b8XmdQK(L<%;|y2O!t%QlKSbUh?VNnB^i1R%a~H8%w90df3;zC8b|Ij%cn7aUTiQn2oezy7729W zIed$qOJh-|z>NtD4?42&Y&2#mZ_A!=Sg9-Yrpo0&7hi92U%3|c6OHi`+HW+qG*s&s z20q!>;Sntn?d>{6H!{(B-JXSy$^xcaO+6`aQ&w<8Vv}6z&n^23qdbL7OdLdRa^bxn5VIz zf{b8a<8)i5Ja=mbr>WNyHB8G>{3}!njz_SS=t=Z-{Wr3j@T%qQ^VW%VO7`iirL_(k zU2xg2_9hRd{$Uq#3iYDx5Q8?#D78q=Ubt@4N_N*I12BG<63?! zpmRYCzYpi`j^ic+iN=dH%GV!v zoFJaNsQUOZp5O(w8|ov~?_Ue?eAAM0j)`5N&8oB2tnSNWIfso|i<4H}T%RM%ByhvA zq(x2OnIrq=o?^GD+m|s18Ou06lM-9h?&0F+V8o%YTZ+q7@hsEhS%>2fXJ*UrMD~U8 z%01)%`1k&ejB7`?@f<(IdumO4C4bGCPU(|_h3d{i?h$i8+OW9_t{%5C$5DmCvl zzTNi7-?hcvRbbY%jvG1wZ7~<8*}k5eI`Ij^9pz;WNy}z*Uva3LVN~{PUFBbm`u1w& z9|m3xX&d8zCfIyhzmzFR;jfV-|D{bc*|mg@PN@BSHBOa%LVU`>1^@Nm2f47F{a!Y? zT)k$(*&0(nfn(n;7Q?=%;fd@_i5s5I4zhtM zjsbTWeZ0TQNhqF|b-d2{UoL)5{k}SmeCC^vda`==dE|507B1nKCuntX;V$D-k`B}wU{m-6lGj5(cve=n-absX` z2m7m*U2|BK{1-kFZM?vDg7;8D)7_;4H#B}s*uC=L#Mo%}N%HrF3@0!v)oZ*_Z(w+{ z{h{5_0*QY=|F878$6^y(v;5Br!2Jp3Pi|IPff zXZJFzborzAbnNfn^D(UZ@qbs;Q_RXB-QWLv|LMQaWd5+%g#TRNp*F)Z`i$y< zHdX!h-{<;2{CinG;p!**Wf$(UtDJlMcV33hZp)`U^FK1iyWdRE;X1bD{4bp-i3zJT z{>E?qWA%0G^FK0g4~aiHb~x8}_OHUND=(;d_&YXx*ol@+zstV^Q3Gq+8W77OPe)TeaS)I%%`eA|b_Fjp<+HCALN%JX9CDJpakM z-S^wCMhUa|`iuUmNhwOo{9O>pC1Mh*Z#3WN|8}VUQ>p*`54O?Wxt!nDF&wwx$vAq* z?x*?6`lVqG3!H`a=1&w{vit7gm+BQ0jM`(4mmE5H?rh$Kkjz2_wT7${yeC8c9cVuL zHT}JNgX7g+!_0H@99Ve_clTa(f64GElWq4pEzQH3%Vx}V<=f0)cqUm#bI-QQ$jdzK z>H+M&l?QnX+27BfEIjX+{K-3wFITNvsifd!lk~71AL1IaZkjoNBFV256%)6iWqcVEI+?kzfZqMWOKgmCRe?yjIn#dHv%9~f$*s;V+ zHaz_F-#!1w_Rhx6GnORJU$o#)pyAQ~Vm#YF|EmgJcKgMPyUmuxo$K!$%C|Q?fBO7S z^RrXjQrOFWUVLrueKh>d$(m?pZVjC;PGZtczis~K&fr*Vf4^k)ou54=3-22C1$Dho zh+c5}RK4m2qrQmE&uiK=>tyQUDkeVt8=&UZFea>-Lpfi!QtHZ|=2?e-|z+ys>`SrpJqN@2>w`@$>5rXN9X#5&5fK zHdpK|zN#;Oa@OyAA&=J>IxE~`ZODd%4;@vhk|(*ynXezPR|0gTL%}W_|O*u0rdSMd~?E=gl$*{j|VVT}J+M z)}AMOE7TvgB}hH~@shtuOlkYE%)fi0HpxGp-M_e>ePV2=dT;w5(T$Jx-oLa~+x5u= zJ1)JbWw-c`tZ~?QDU^Nt$u3pydol~fcs!;RRVm19>}y{a@N3PR&+gB^UiTG0llX+~ zrgNFFz`0wEo1Iy6BvuO~^{S=MdSsk#(Y@X8o`orIbb{p@pXE$Ebvu3($K^|2wUk-^ z`0qvEL+>Irem=d!KJ%V!ie3Jv@AID()QJ`Qe+m7}@mcLh9p5LWKZe0in%J8Z|Euk? zzbL8Vu0Pdc+Ehs)L%;uhOb@nx`!2a}u0{AY+r$NbS1$in>d-t-cb@9vyPxyjk5p)h z-~OWY<$jw;aOi*eyS`W4RycoJ(OV;`=(mVX{%w)^9M9XouO3R=^Rhj}ZYxvX-&qB} zD*m?|-updr%cQieFM1@UdP_?pAKqJI$mR8|Bt(3EtnQpdb~!$MyY&wfU0yk_IC-*) z-$|xityg4rCU5P(yHn&VoT{9Do{)DIfA^y+k8xS0A-~Tdm8tXiefcJ^?nHJbzYOo0lo)=A>SU2lqD3$y}-x)59d7n6gD^X}H$5UFB1M ztZAFtyE5{V_LEfCd|a`ssP6VA4{S38>XA|{w-Yc}zS ztx0g0n7muPTta61lD|`@l%`$yFU+?8PtE&zRprl5)K>(bTbpXJY}6Z~!7$}x4mlfwN;0Y83kTCby2DrGzW`thrm?yTWIz9f!u#V40n z(?WTJGn6g8_cCp|9i(vaRgZh)=M|2dw(kAa%ADi8Kbto^MgB*&mqU&KyOFTzI#ES~ zzW;46R>$3J^-yX)e&E!rO?rvz?Q`9KO-PE8dVh1p>E)Ay7PWayRqKvVS5 zE~m8W>f`Xq@>>#LSe%#~o8S3$!ngZx4G&DOb@a09Ul4cwm(ZIJ|IgpweNxQ&GSA!d z=c>bJYRJ8tZ=z|zSN!$U)t@(BO`jaL-~CT@|IC>S^Ta!N^I5j(#glbA58hOnidXmDSacj?53>+7$++bd^My~OP8-$iSd zW;P`=R>;4z;q9@moAmm}O-@cl?yeF}l?fB3t53PyR%|iLJl_B0 zr#ge9{bHwX{kmOkVR%Q){v*XgO@5sur>J61sC~Ut!jkStffY;+zqe>z zcQzfII|_7|$O`~A$oO5{l3hQgrOM;Ce~XGI?AYri*XuA_y5{ki%p%Rj$-Q4|`I za8FStLhQfXq+P9o4TqWe(wftEa#|cRb2holB)@2u+rd4XiXD!4&oNwhOhJATLyn-? z1c658JqZ^X{w5Xuyc|@WP;>Y2Q$?o>Td%OO+BV-&Py2L7rDgKLH{X9OJdl{#&%DS^ zMbFaLJ|k1sTcug%<@qfOY&P%syZ4pa$)>&h0-IM9v^~<-x!|%ws8y^thAV=B%_aB> zbBBY`0fRQphac6GI27969t`m8O%CBnlhJNw|9!iZIjB%TEa$xHuehG==jU&}rhNUm z;MRkR)^_#m>+91WFiTG}zdKtwago7wvuhsG#m0Nj@$x*JEs$*Vz2{`-vFK;Fym<^Z z9!N>y`1sa1Cxv_YpA_bd&THzy^Zw+XFV5UlzSqIOSRSjaiFinhh?AZPl6Sc5sGD z)6VJb*Q#13w5X)qW<48{FjFf>#Kv6smfRx2MlRWhThx*kEneRE?w9cuwZ+TIxK^xR3?Z#@UK%Z5J)Ve%GL`a<5_8zFq0y=5^N;3>DvcVo4OM@0R+c||d{F2N*K+mq zXA0(hG|4bs>&E;f=+~(QE4F=JknfdiXHsCu(;GXxBl+aHJnTi4VH>mTpe4bwteJjFXV{-ATePc$JgdPPt?toWLKW?Pk2(J zY+u(b#g@|BFHGjh#Y=wp68A1%GVzxXr~WKw4%s&A1l6=H}`s6b$qKyt?sSulu&_*YVP)|sd69helki@D7T@L#vMX{=JG7{9 zUi)+Wi(P;F3XP~(uuR5amI-1xqRkMX9a_w)AaoEu6z;zi7Nx+l+Q7vK$d zxU+_X-C@phhbZQzik0CP@|!xkAGv^sUw|70cKI>%BLhYVh zK1WZL0-KiVj$_9TSm&QPck#-E+l7xNEDH-d;hizzsb(cn>b)n#60idiVMA zw8T`?gE#n-k`?ba+&F#wfE6#RSkMW#sXO0vH?$W&T{ltWT904SX8vndu^YEM;SWlX zS)aFX5!X}atU#}h%@MjsQ| zyO#}lOZbCi7`VRAOPo~js-Q3;Pq^d7TrKi>=XcuHbrLll?qR@7MzmvCSH$ zYzr(8`+ei`it{;gztKg+EyAls%we{Bb(JE+wa^QSjtv%bgn83CC(MbOxAs)|{|%o{ z?@LlPontw@UbQ#q?#;=v$9_-WY`nMF{&$1f!!i(1Wp6g>$T&IPYB|J+@oqv>nisG#=QVaJovBXT#5_9pZ z{vABy@L@hHu`RLg>`oFtySq9TT;RIUkk-%e_hC=!$GeT@rk6Ed{UWL?INP$F;!4d&_nsb&x+`EALNC^rhQ*A zr+qQc?UwR2g0fZWYSRlRn7(ip7qn^Kf6c0vCGKy#szioyNVbpo@uSl7&e=}$d*dUe zvO|@nft&WgB*0?T9;-m{AaTc&|a_=XsuHJwaQg653*}X|ZqKbYZLPq<&!s z>m?D2NzKb0q&U~c_SfD^;hM-|t}Q;tVz-2oWm_00Fn*yH7e-$GUr_@8v4P z(grpzyM=|9vNTo%#(p~II!Vs|a6s&_34ENH{zawVX7HqC_#SZ(uJP~{64J=Aeq!$U zYM)=4Lz)-A@`B6^_wySIlFbY^@oqAl7r^yu($$QcDl!en90T<-%DuQZ>Cb-iB4N@x ziOmylFoR7R>eeUw7G+;P zSfsV2l1Db<;7t|t_TBQOZv<_*mhX1CCy|!yt2iyqVQ16Uw3N;B`Bs>&nqy$|NSnpF zN2%SCqxs>i8m+cNishcc2W)MxgjVd^v}lF&fvQ6bqc z*%l%=q%_k`a9g8C+#N^M^6A5pf&*7=Mw zTS8QmgdT{;G6V|TnpjY>z)ZERw07c*lJ3=Dk_E z?2?nG%3Ha@5+$XNEMFDh@;QE-+;i~w4O1a?Z8o6@iIj~&^B9{P8DFoKUEU|mp0GLa zjE!@lDaVbcG3Shx6BsA`tKYrH`>ONw#OU|6LGSOD$eXZTe*NUq(VJ6zBLd>oC(56k zzi;s>j&~N%A0;%LXG`<;y{qES`D)?Rikl_hguVa1+p_As=P~_NQ!--N`w!=BowbXn z=U>#LS-)TG>pAe@zvjX{vA;@=UDFrRe|4hdQP`Yz-c@G38|$*)CTDM)uYdZo^NlVlqm&&$?E<)1$uyYq_F!zg_#FDBMscWN)a zm=m?#D9z5`Bg@&%U(%+OHBVAG#LD9}n+l-i%os3l=%PUL(_zu~jR= zV_H{~+{^7pZR`B_#q@iAFWek=vh9YNQ2RGgjno}Sr!-A3n&HMeQPOY<rnM+-y#f8@SEqoeuOvGG2Z;p3N{tfo|UaL(dVjLH57CiRyB;Wh{ zrzEGJmkBggo_;W;W7fRO9zm7urb}$So@|foo80L5?MQfr@~&hr{ubX;NBAXVz1oi| zPGFog$DqP#c0;T{OI^DW!@=`0EV=D>Og2AiQh(BNf8yDH``&DL{j0~9d7d24y<~f} z*Z-yEBu>6O{7-zx#OCUooWBxs+e~{mT)%HL*Iq=SJZ`y6`y-o$0@7=~2fDn!R{Uhy z_q-Orx?F~>fw8@Aa(=J#Egt@RZuG>}QsUDGwap*x=Gy3IoDELwWs}>yYE8+p$zF-S zzb!n(+TrGUYR(%?5An07o%O6VpR7OBvFK%9dn#&U(nh zt|8<9h3ymb)ejN75_eb~@A%ZlxnFbgnx=h?u$b-oM|p;MamSkKVfmoigGbD?SvqxLisN6iWG*l(isiTg{CfUJGWtjoulQ z=jkS^7sea@IVoiE7EKM;=vuk0k}5OzX3kskc=zOwS*wB!9VTWdF&sH&(EI%M?-Dy> zM`8OtUOtx(Za8s%-ijqFY~J0ntz{KOp1GFs&E=uGum?QZ51 zZhf;KE7cKz`e-+!?(ayuHV zoY^R~O^rF>O~Y{=pEpE;jWExODKJur;yZ`ac*I6$(IdXT@+T#Fy1H z&?QhXMK72oG~mkoHI0V^I47jNX#R8QZ{MBNSSE#M6J(P-Iwn*K_xPhzQm+%>)7j-GzeC-F_k?24b*KQW%T;D(QRTCbE=>dDC# z{*$;JEINxX^~lVb@tM$kvj1|J2MBV1nlUORKJM&94iTAsTn zcV$n5e*a~@y6NdCWiu-_6O8Fyw4`6!tiTVW3AS7hu4BN zOljxuoLzB7P=&v#aOpIGUy9mc6EC>3sb>b9>X^kI(9-qKoWzn~U<-Z2~@cD#aKbOZu%F<)N^QxonAZ zr`eZ6n=LC_xC{zp4o?iqG;X+3M)2? zwy>-|#v@>&^RVZ`iim?L4^L#A6m~fgvU94C$rc@f7k6eDb}*+IeYmA!;y70!;CyLM zvZ~1;)fxHw3(lNfqiA&ck(sDY(4ueF5w}Y7Lf_ThI@O!+`|W+k{k1*E4xBHGcIUae zTtVHbV%DUp6?qR^q)u>Kc-&y+Yl>pd;0u`O8YXu(Z~e5-K7VdCUhmlC#Gc~2Mo8Q6 zz4{s{_BRI~x>$dH(R`q4BI|uFl@m>J3o~Bs(C8}gV9!f@Fezn<{4SpKt+!tVdAv(J zrNs3;HdkcUwdR;VKQbmPN-msyN3zA}q?E*gwyz}ziWb=ZDKD~COOsHsYH3*J==j1z z=GpNa5n0(E+0HNB;whxbxf2WXH^(7lX=O znAwA5-f!3y`oLz%=a4U-bf1OZt$ep)7EkYvhs(VL1I;w1eJ!Zu&JZ>_*>zbxkLS$J ztE(pUM5Ozly|}6I)i>w&{oj^<54_*#yNRco-^Spe{+Z&l2iIRd-FsX)w^g9iRb=tr z+wA2n-YfE%cWvstXMJh63;%aV4o43r&soO-)NvUh{e02ETs?-@N@0w)s(& z(?u30)_*e#G!m2)B|0YmPFXaiGe(J{^WuyN{*7%+Pn0JuNNG6I@Xo1`!Ct0u!h%eZ zM*;`Jgy$=-NS)jL%9sDR-QBM53^of=%#T_MDH%4N4|HiZKlr)-+SzOMQ-2pfp8tA> zbYyuk$Fh#_666}c4dOd3ExZSx_mEgP2kE=vAX&tHNZ?|uAKWNY2M=wRsU;3d4wG%^GNe=TI0H^ z*kdY()D6jgfA3`W#Vqc!YIe#zZc+;Jx8|(S$~zulU%dTSzuAVOLY6bB9t&M}o?~0z zp~B^2wTPu(%U&#b#t{`)Pf_=*qk^yOgjMX;2*fP*VpC<>SO9;y6Oc>GZOaygMJ_oC+R zS;wwunf7X}sq(3h!JpSI%J0tz-xj)S#hpCnnB%@50$oJ{eX9(tax9+IG1$iEEA=&( z7PuG8n{@Er#+UsY?yyBJ^ytaroAM>% z*=I!`zh{q%-(uMyVe>%$Jd;p@{*@EVtzWt~_*@V^`M$@uH$N$fvE?yeY;V@v$O4g* z9kR;0@0(K18+NEDdH?#%J8{b)r!BnO+9tEQ`p?-o#q8&@?OR=(M4oc62re-DCZ^_a ze$Zn?~8 z;&}S0yi9JF*V5mr3k@c8e>-#LP^Y5Ig2YOOpZ|2(D}GMt__=z?_g6Tz>uz~;Zg_D!h zE%dC4beOv2mhY|#^K-aZnXx1~lsQRr;p_(P)ia*9p6YaAQh)vZ<(E^(FDFdYg`;$jicA z{&q_jPrY%{FEampUlhOOvPkb6HioR16a!6Ja_!HC++5GG|48}%2FKbBOPfl%#lGYI_tt>Ri(L*|X_*R`C@9~bsFEHR3cGW~E*Nig=F;^Xg~H#PJct<1KsnYYb^ zg+We8k{qc^^XWy9ly7>neTdxG$$HU6DGhUrG zo#|)lawE(w&FGnH;jFE!Gi;)~1A78zB#3-Wo3UYIG1sOjyGX+}&C=OD7q07Vj=01U zvY7>nlk8=wPO-+6`M`L0l_mO*UMgb{~$FH-7-1XrvOI%vw@F02Bg0@`!b~h&{ z#}GcrJ$%19v-3YyTb#Y{!18~`&&ekiX?d=&>oHK1;F!R*pi^UtLyGP3#*R-F?nl4< zyS(6XfudyU+Eu4sOXt|dKjUb-oc{jsSA*`UO*y4k3^jfhJ0pnX@DyL~k}sKiU2f;BAG4Y){;K|0HaXOj`=mMhf%g`^xm>oMe-<3Cb$3^9okdwgcC)>d9Yoij{X3L*QCbSktN zZtFOqu%Pmc;2Hi;jte#R<%BNrspo0c_vK2I-c*?$yi)d2!nb=YnFl7cMR+MCRkWpM z27KvP&1>7$9QbqT0%k`)OQquv z5?E3sa>Cw+*Q9Bk+#QE2y$X|-tPtcdLy%*jbW)n20MA@fjjMhKc@8J|Z4_TGYX03g+40ze38in8RFv1eHty3% zE7899Zeg^$MPqo6yY#6A+hY{9XIG@1G7pyynlD)#ET^LR{r!Wq43q36%_?8fDlk1z5y-#Tl1>Q%n` zhwR1XeYywcPQ5Ggs5sh9X4j0fnO`on?-e&WtjLupwAypYEbqXDuW};#(p~2iC7u^d zFkQYV>zPyMv&BL)51#grS#5Uj9)GLXJ+qgoS0;MR@>#h~ugzlHTFZs2qS;*3QdAn8 zIeW?kUS1OXcy^7x=d!6u#cA8Jea`Q-W}a?l>XyQLuw7{H#9HRn2?C8KQ>0%Uo2axv zO8&XY-jFG_`H}m|FC>3@KE;xwLLiLGp+)nPRM9)Rv$N!CWH0&~ZV;4WSlZ;-!eA}u z`1s_b>_9pH-Io^Z@M!b!P*Gsy*z1y>%B~*IUu9GqEAm_5yL{}sou{K3e{dFlG3meF z8goiM|5mK?ia*O+?zwa`F;yh-+pOr!V7T~G)xONx#p8g0#|cI!|MjV zHql>1wQ^#)d2>^B$WPNl1L%e#8Fyf5x>P zUuJ2t<(lf4X&XH$_&^Ea>dTQ;et}}aur{S=YF^2DwE_? zndYLXq~PWh#ikHCr6taO_0`uC>}GU)d8V=Nkg$Rm7mMG78II2P{+PZx!t?&caYhHj z)0by|xWn+|Q;=0W`-_$+=8YVGCU3G0P?z_s)j7EC#ripiIqs+E-95onRkH5gGsjDE zS0aQDpKrUkLv}~oqOd(Zz=ef`_G<$p}$ zg-N~h=N5MHJF;)O8qRs;Pe&PtLi3M6i&xdQ)2ucdc%Dkux{)KrCR1==!3Bi{hq*gX zG}W!Jmz>N$QQBrNFN3v!N+iFfXdwgl-23V72ND{VX{?+R@?@6d77?=_T8Z7k4=j6T z2{p?;l8CiiKiTp3<@I}gBaSe1hldt7#%axM?a`Q>{mLu8>)Q`-csX?<^{f9z^IYVlaqpEoPW`ALzc zuJPS0?mO3a`tu0A;WuA>Jn`WL=L2_j4h1$RUyAoyd^lmDf~{LKd%dylnbdC^YjdkM zG4&Q5UU201##eL1r))XAz*jnL&$faTHkBEdv>mnu2`=5X-aq$CdeO8sDT+(Du1)*? zLN@yID#44YuRToEUQLmjCconNo7dmHfA88XmAFqv#$@xArXaS-y4OB@=zcqIM`*B8 z{=?ZeHw~2)_C4oukd_QF<7l(YG{5&&w@Jb}zvzXvvAOQ%od2Rs84I-6 z_}9-mVJ6t95_RczOPk6yu4Ew|fy5b$szkTQq`r(u^5c}%Hi@rDU2=T-*uvFFaJ>7BOaDu>Ap zn}%(Z+)9{d*z)~cZF&Ts@2|Xgx~@1=pe5?YdO^o28R}Ou4tAP}JzVfz z@OoNaQiU_S=B9!Zi<$b}m)m-tQGMCpcCYGuyz+jjuAMf;j-de|7lnmgLaz&nyfMru z$?U1^R0!VRY^r}d?XN`VoHN?z zobA5s&i60=Z>^5>uV_+ID7jj9Pj0~$ANSe6w!i98ttixQ)ARHXP%W}KMsI4#L;>CnlxqFNj)i6~5-TS z^z-MJ|47Fz5)`VEE8KUU`F-ADWxEp>r579AvEo}4xMOE(?+s~30g&7G#xrtJS$ z{(GXEjOwcHBkjDgz5=~ntV}EQnm=5wzV{>|R5~^7c)_V-bNqPLP0?A^yU5D*vfJkT zABp7$9tT-2>Zv~AV=OA8Ijwi&Hj5XJQl}l9*TR2Iidpt7yFi-vlBJ$k!xC9peJ%yE zYI3@5y=|QCXK?Y+L9f~g87?YS%1Vdi6?ay8vuzFxJtMYp!@c^OY9>7W$KTvd{(8(w zFvY{UaBs-xo0h*=R&g#$RQi2m?X-U@o>)Dc%kMQ!qVvjYgG0_HhkZjP9NDm^E#oPN zLyDWA!ruLipDXS4=e#ud{G{mYujX>)(-$TcGP$kw`*Nu(`Kt55@F@xB-xM!CxU;P1 zyi?(S>CD^rEw6XqYg7t)!&RH2&nfWg#g)n>jp?6_+K)f6YTDyD!9<+vfQH6`M($0V zr-S8Orsoz{R6IEGNWjk{B=%zP0_%p)?1v;4>9IC4y|H-x>p62}MBHLUS2*IYUJ}D4h)!*RpfUD~eEp4U27Ejie6?9j9ob2Bpc z_DOXmN^FTTR_a}rl5s6C`G_xbg2Pg61+x%0pUit!7bea&%_>~QS>DPSV{9E|&%1X< znwo*QntF{-K6_Nvc~)V;BaM@|SqxZwl-NBVi5xBx`{F5j8VX(DQ{D-_+-Jjz{90g;F5B4hY-s~k10W&bJ}OQss4TWQ{nr5%VYD4Lk;B=bsIZs zE^sdjc&YyCiE>qj!GlxAnOjUG5?c-gx*TiSQZ2^ID6&N8#9?C*k%=Z&aXnjF9Agt| zEhA*p3x$GL3Y_Gbtfp%4vf&l~MgECu4rzW_K?+YzY7O~UY%H%znO1x2rBr36Z@|RO zOw7zi8x-Cic>kgD@HFX*a~6DPdwirn;)h@yPej6l@OuUf7dai~8Awc$)N?ZQkyM?* zII~q>-m3JJcHb!p#)d_b;)gU>I0keyoawxY zlMGvC1RGi$G;>9 z+QxgrCmZ=j_Jm&y9UTGAPc$Yt{MlZ=?culSukvFQt0qWCTc~=ZEl$0btX<#S^LXw( z#v(4Jm|m8`MTQ%cI~J%*uY1k&<<+S(e*>p)dvN8Vpw|?K=D;LxMt|H{g~ zcpJOtU8&*dH$MDd9vb?lbGWl%CT~BI$RHNvALJ| zCiMM==Ag1!ij!SC*+laWg*)qsOl{&*SZ?%QMn$BwwQuW&l!CUfxcstB!oy_Y|h zJU%Qm+wx(v^p1%Jr@9j&q?2;~ZtR+Cs;PU*Dsttnx8`k8a_>r{-PhS_UXHVv;o!?5 zr`GE`VP24W@Wk3ZNYeH>-P}hRxOZ5~#E;l{M8(7gX zt>KH{#*4F(rhjt&SZDL8xv}?H$wrM%j!AR>-12o4Xx(wRM`p5q&I=#)u*SqgyBm^w zZu4wfvuNQu#iJrd4bLqjJ$sVU)cy9!gogTUc3HXLh%m!E@%$E}X~Aw@yIMNEJ|v|6 zJT|$i+WK)AW2n&TpsZ;VoKxQC)@%;wRA3Jcv`en-cIymMTPLAtoq1Vd^--9TFmNNVtD4dzUA-v@oP$ctxvI^wD@YN<6gsTg$I+4E$5sQ zdr7#n>Cf>pH*PQAjCcLon#;5c78qQ9y3d3=*xc<_S@zO}Z)_Q39Zt!wVmENfx>7cC zzd&VNzAnp_CGFSGd*6SurZ>@OXScplWU+SJ^7j6-b{4;r%0rd@G_ra6C)zLw?~fC& z+Z?v|t?f$}FJT5}Uz6Wf&-^!CGU^CF|G82^`AG6&vG2hzedPKVJl|oGB=cqMksV8q z)N`CzSih-dlQ_F7yN)6s$5ln8tZ1ggY#AF26G~?U=x|8ta!y_$F;OF2BG$1lsi9_p zQx3CRX?#|K+CkRW5@*_371x+9S5XUDaPr#bfCrN%c$7?QXPxVjY$V}OW0!FBBCkuo z%xhkTXGvUvDy}dc)6G?Ui|u( zZTKGkhRu;J6E3Mu((q39jo`kiC9yEkv$5sT60u(EcHt*S7c)FCE=cFRd5KMkakqL$ zKf{MflV&YkH|?SA(N~{qcAIiadlr8?w>cXz}Cyht%a9%)^2z9o!f=e&EC&o9Pbf3G=-b@;eS^o-=#w*lg3h$~daqS!3=*_n3`a zE;uCne!X)sP0~?Pa?d%Ya3)>9v(IiRh1qhr^_Fk$-Q}FacFba?Fq@2%jTCp}u@5Is z9BX4X64<0MM}=qimZW!EUM9>eD#*=dSZfyfIFY@#b>>XzEg~_`JYMmrXl;4sDzro^ zb8VJkpPH{>>HUNa6D~_jd&(-AGWcv*#=>)nEtV(BRNO4$%ch+k#?C=UdDzs7Y^9-`C~`i zIJZqWnzls4EL(}gG&`c* zXHG>ghYeT7%uIV9vK^bvWfdRW@npvB#R^X5N_Q20bRG*0`^a;1kLf0njRupvm`+z| z9`lZyAIs|~mFKOnaJJUNtsQrJ(!~U$=bD_|Ez})d@4**56`V?>i_Jv){$qSkJKb}!8&&38oT0j zpZvmetHr%8$+UV*DirHl-`}~gF@m2{(Z{Mig*1WrKhO*Y>Jh7y#L#E5N zD9q75qHwXBjXBWg>w~igrE>44b(f2V1{W*|6*1d&(?-FVdEpr+@>Vf>E?wAWeFk9{jE!&4sa7-yyB^Tm3eolQP_iQy5Kdk61pCH1Q_ zO^?htcA%%njaTN0Tb@AHN$D%C9BGf1E$L8LCLn#`+o3I6cx8TH-2HW9q0wGx&MULj zmd%oD$S+Nt_IN>arHkxBhc8#WS0x@4nz-|I){lji?kgp3HayXTfPMZh`KOW@*Jotc5ooal994 z=&fe>!FO21GImdY!{rnnKjR6X7tWiImbl~i?pbekOC8+l67*o23x5vd_2ZgnHnXy+ zNVEUh#n&a%c1`&DEk4GB42Mq&HM<^2kWPAcI;LT6gCNI-4+pnav9;V<*W0#Xi@JN( zh7WVpCNU?;ZFcU|H@Uc>VAj!sOBpIp6HJojG$%H42M0Txl{TRFkc@$ZXCs>*pAxBs$xzxBWMwsY+raoN6CHuOz<{ds?6 z#TzwdrA1pi&(GuDDd{Ell<9=z;f|H3V{bjM?=+C*yd!ar>F{^CU=|yVg?uk8IAk3{ z0za31&0jT7-7 zs7>WUB~;YQFolhOcesG#ae5mOLzENOk^X8W~QXNfPrnn>ag&Oq*RL%<1}0C8jUsSca2YtCDNv&N)++ zWb*6_{k?B4;JHa%aokjvL<|x+vWG zYVCcJaJFO&4ts>oMc>UzN|NMdzjR+=!gS7YelB5y0+rvhOMp{ z1|`#)RL*8jKeMY+)H*+I!BhUTEQ}_>fr2WgzAjEd-io}ujvlUx!iEAaCTqNWCJ3vr zToo}o(j(yP!#YDk)F@=qS0Oc~CCp5`>c?O3DJ)sA>}%1_qqg~lTO2mt(Of zb;T6_#TPGrzWYnT-+tW!yZtT=Zxl3?lq9DqIJ7O)QuGR`oiP8~?mVrpRUe$cI0al2 z%3e^oz}(11Kt?p!SxLymDc9MX$Ix*@f@Sr50y#! z6W@oOTHeQ}Q^hUC7@_G|m)Z5stHN%@D%M{Qni6h%K2e&)Sf)~uAaFxOCPCXbtM7Pg zp5hv|8~xig5-m@0xCs5*6sl{)=w~=*irgy2CS#vl(dta6CI2)$a$=dFqBMzV5(h`8 z+w@N-+DkWIQe&QzvC^emLGc(f$B`4$I9ZMzTrVc%XlDL&^4r4YuF4vLp>mVcJS8TD zvK$l%R*|bY#Fd_sE;y;+nWL~(@11#Wc~3ePc3<|9)+y=^-DAweH|Z`@TCTut^O=58 zd>tQ7s<*ulO6^E<^0B+&_$u*7k+QV#zN>bx`Qp1HpRQh9xUJ1MMdMhOBj1_QTTACR z2nKHb(c$k`lx{ts7PIcQN*9nE%4|_IU5M1OR(y?KZWkaz}_LHxSo0jaC>~3R8 zQ?pQgQ8Mwz=T`Q!R<-xEm21Oe%geX$9T0Z#-gC7hDn=z>!RDgf5+aqqZJ2K?YQ223 zy(Q#pscPw?NVWI5`{QJ+WX~wJZ8+$m?)h-9G>7D4o`)jN9HmFBm40-|GuOKZ#ys+P z-m@=a!oh1bK3jqnZm0U&B`y^$Kc&v$;iD2@$Pp5J zwwC3_m4?Yl$J(@#FMqlt>(IzHpg->i78X6`{cpzi*u)lr# z@&(^T^Zp*5UpYrtHRJP~>OO&G9RJpw(oNs`g3VC)x^;PZN>rMboz@X0xk_Jw_pR+7 zJ6=n?x}C|NrC8uO(|~Vr#>p*nXTDbM4HhrC!F7p;Ut-#Vb92|6b?9hi;aIvvk>9G} zoS4{@UqW9j&b(c)N#MhQ+gF_~T}k^F@j2Guv9W@ye56PBo9p|`*)mzS+BS9@NOQ0< zF(+F#tjELte&sFwEG$RB6X7%o_)OwE2}D2COzD^#uKk@3_r`vqIQj_WsU0p$}a>e`d~i zzWPI`Nh;xKT~&AfxvGx6!5p@{o8y8k-#%X4n?0X9c6!e4g7P7ev6BlVOmC|?C(oRr;L!A;V1p4yyTBufAQ`6s76F!~1rBctxtSCNI$U(P zZ`&5<8MMrkxNmhjKD;bY?qEXWip&g;)8=;__MNf4AmzAJ-(~Mk1D7U-CiNbkBRhDd z51gy{@44_m^^q60fwQ|OCQI{N)D$|+l~AQ|WuL_6wHpW!85-Eic%<;M23L z4o3r$LZI=}Y$%6uz8dDXYwEdGqRoTa|M@y9flXDX5R;n<26N z#*(}=uIaXWI|`gPYg#+J(B)fp;b4+zDBtltek%h3#$cAj9*-@7X;lp5xlt~jRF>NqFq znAGKrX0Hj!S5{72(HL*&uP30fRP8AH34gsyeoZTs+h-dre!DaA=8lKUCO&m`uUPg! zukc9l^MK}gx%_J*1!OBu?)>XtqvKO8_aHAZ%Od^o-fFSSxrddMZ`76Wb1wY#`@Y4S z*KJug*9!bXSD)`xOca={yid?mP3_U54^M7p3w#X{_;JwBqOHyBETKW$KvCANSs_$Q=xqE&sGq6~FkM+nJuBjSPM{h_re*Ebw@3HvU$2}gJ z^0Tu<_hj}9xrFIGY+fR&y}_Ivxm^$x#MqZ!h?L>_OxfU*NGj6p6DQyaQz5Lv+Z)`;Z&6|!+R{tc$ ze?}_)&QDvV+&zCyi|aU__ZisczrQcSlV878BR_ce-44TpOY@fVb3FIlb9wK5eYy2- zV;?vuT#@qfKXk5;%T~Uoc&|O{`^np7)!G!A=NR#xFP(fw^zg%`x7X)OFdx4bBGDG6 z*HhA|^ZZii+QUVHUsWtWKkB&8;Xe7HoVBo-fGNkF42K63R6LnG_U-5IzOjC$(|_x` z-r6rFoY>hSvtbF_o}16Cz0=pexGrF_I{BRG9O?uhK^d-Fok+0gHHp}G3{$Ti7xu7pQuoYP{>C})?QH+ROv zg;%wMi+$XrPS2|~Gn;+{{@nJQXJtFz2)c8x;#ruK2Ld_vqOPUsPxBUh>l5 zs?H^$P+o(#t7PThI>+ek?0IHvclX@+>+#Zp+tXupJ_uB}>!`h2cX+GF`*rJ z_Nv-k_2@_7>E0DL&R8)T8(duMImv5@f#4C15*=NJ7zM=@9j~+|JhHmQJ&jrKyb;TP8@+`S8Ei!nK)RVnTfX&S8h-6#EgLPM_l5@^&=HH%mr-rgU;FpM5Srm6q^7xWZcN^c`ejqzJZ=&(r z)df>u-&XDr@aDO(UE#0IvZcjsJGWVx#GR!{kyZEWK`Z~>ng-7I8r2Q># z`5VJ{zHh~%SmP31C9Y2;nMod2DkWPMd`Xy5v7^i^+e+zhp3PDAzIY+4TTDkT-T0<9 zSu7z-YWw1=hKZ+y8Co@0FFD%c73`{T$TzJuGAog;z1}mc zwWTL5*S@5y6dqpXziiuq_ipV16Z2*@idj0z&J%Lh%jUlOd!>bs?3X{AI89HrUEKRF zEOq(1e!op}R_E*XNSj~VaE`CBUT7oG$zd+=umUrkk2X^6RU zMcac{Kbma?<7M9KYAoYDQvUJmqlq1CCm-I_mHk!I@cZ^{#wFJ-uer3q{^0XzNk$z> z0)GxXliJzk$Z>bK>~ro#=Za(en>Rg<`Sfy1!NS$kc0ZHYYvIRwPr-AxSL~OL=PWw+ zmptRM-fvSbe|g7~g~>G&l^%XNt|zdh;murjVePuR6VLIy+>?0mm|=6*Ms~f57yiwg z4>W7+DifIU%aK1<>gDGZswXqgds!>?39Kov(c_EST~@0g=BFGrFD-G4)~6pjC;bnr zxhJdmh%`6+GQF3ZJh#)YSK(rMp3r-vdUZtqps%8vxgZEA4^I2&~|8*!{d(H6+S&*eOGP~c`tOk@88i} z^N70hCl=rRt(P74WTVD6u}7{h&Fl;M4TT@g3Krt#lE3=kz;5Bm^JT=2mo70jn{M!j zYr`Afw=ZiR-u&@=-r197e;p?-e6q6d;^d1ja;@F-4yUBfsOJ53l6SGqE3t?ze(gy| zj<HY+t}qM?{fZPetvUblp;@vZRJ#>EP=TqeTqx>CLYUtdH3f1ob7ft=A~P! zKmES8e!JA;BVh%n_r2VG)z0|w^drta=b|J#^`2GRBz7iRb_feE_fEN?ySSyQ>T&fc zp^7)nb3QG+I%`(yrR&pMs$O?F>sj?g2(kFACWbtNJj-TZU4=IJ9qYyJym~oCVVqCIPEy`tIbV$J%dXV-rc@4 zd%f+YX%>gqOjBFReKTX#j9JGFj91KEn0mwH>yfDB5A$MA_E>hQWM0->W4^g<(fUS<*Itm zaqQwv@8dIeTH>5^e?Duvu9Ii;+iUEy=5EG0a>pK-u2i{jtBl2Z^Rz9Ob`&PF3octE zrlA-#vE4^xm!h4?Q>8a`0ryV!EU-9yM?!H!OG9!%#o^P+OJ4Y1X!p4*t(A7NcVp}8 z5|tpK)Q5%V9&deNop2#j>UoNEyL)|3`te5ABNg|z{giP1e)_OngIs=);a&47Kg)e) z@`ox~K4flt=&83;u1R3BS?0mZ4jU>fH9u(!M$dgv_I9#oUd@^x59b=5XgtCh{H1Ui zOsNG3#bW(AME@Tqw>6gQ=Zm>QRDo?I+=;7LWDRr2z(#|wX-Ny+p% zELkpP*);j{B=gs8-7#(+iCeEdh~05y7vIZ{?DKxsasQ5=s+q^~$6=brg|HGd-J(-tS@7MLyv3>h)=b7ivo|M%oA7S|+zkRx;8&6sD!t{+- z#Fk0ai>^GCRoNSG_>b9*wy4)loY7Gij(>l^xARMb1|zH6^5!>3D$ZTFA$v}sY|EEN zd-p7y__3hs&5AV>w;3;pn=ZckQegk;p8VZ0hLyZB#?x;$=&@vSvj^N->~M9~(G5FS ztq~2H@zL#SvloN=xw)HWF6BM>Np{!v(%I>%temqmvREb?OlVP^9a8El@$A{Imq*X# zr}O9 zSI*U0Y`)kusQ5&>o8Hc|oGH#vUTpFad;D|bvt!=VZ)QIiKfP4HX3p2hi-$doq?28; zHe9I6Sa|i|_143QL2vpEx-*v?zNFA>xb)l|ry2oq9p<^ySDqKiS!1@N#d>De^`FIO zeRB6z)UW)zaP7I*GPjE)Zp^m5t3UT~)|uVqs}7l5+#|8tZ!`Zbc~zm~oM(TuviZvB zNEdG3D=2a5Ta5mk-4EWcdKTL|W9GG(d`0twKQpV7<~o&0?&LkE<+6M^chc0S-|xnS zr#Wv4j+7!uxFNs#}w~<=NdIyWwMvM%ap|Qt!Qvqqjya+ zNRY*CORA9gioIOQPNsYjOb3`ngt={EHu)ZyabU*A!r4bo^@mTnAnM{~7^Qi(4N1R`@>FRWz`H{6s3!k?~>HGv&(xJs1+ur8W{JNP9S1NHF;kK%Ac{!uctXx=Fy{u}p>E*3b&adu?DZffl7L5p5 zXb_s~oj&8w01zAbrKy^oC#n)~_AJQveGNzb_V@0ew+de^;apF#u7edR!c|KNq2`}07?(5lQSpR%KjeD~gcqdAe#=GGEF$&jVMx z4f{$$&ctmju)Oemiq)aOJ)s9@<=seCG6+Qy5e^;>lFVLQ!Ipd8ojhTz zlE^usT$5X9%EpJCR*%{(6dv1bW!>R$M}*s9ce_x*3iZ&`zKjh{r}z5kY2=+cy+-vw zS^IDM9d}|>I47>uu+)rQ@*sK7qtlVKcOq&QzA`Ygx~wje9H{dlL%+?J!(~I)`@RK| z_fjIZHMRs=`nVr<$aM;pGj}v{-=w9MrIoa*L#?Z81xJGl$HK{ON2hgI6ujlUs9?t7 z#jdsIvP;X>l1*A|GG|t-UUrF7;wi&phD+)*r)jn%E#xbA2|e(FM?Ph0YmoDegH>8D z96#^!dt$|=pph>s%*iFSsI56+>!Aa_AGl2uf{!Te>M&%r;s{ufdgJ2F6M^h3?wr$i zK22kBo_uERuSE@pEk#nX0`rl$vJ72#>`0%ty&MU-Q5`CB75)<+X45} zhjbsV%r*0My7KP1D#t^21!+Nn=OT@Qo~#LhOFG)ROgLIuwR*g?J+gTWJbVl{I46A< zSXGkX!)r2Wa@fJ?GgB(RoV03kb+XwY=yZPW!XqC43sTA@7gx-f94VouCAMHf3-2cB z3-O+><~EdXnppVnPKm>+fCHHa?w@*bQIWs*tM7c`{v*3{@X;Zhhopy-K*s=8JRiixC3l|uIdK!h;!%vEQ$lD?4 zS&(s5;^ST=iIWU-K33eHxBfq36bJ#ud+X}l!As+1paw>wF z!fV^Y{dP*IdvbkXKPhowtMJ7Y{~rA_sn+TQ=VW8m-SN1mD2ScLHV z6)$7D{_tB#_HxhC6{}aJFf8(zB$iXWm`lj((VG=jWi>f6#RpH<^37fT{+Xtxke{u! zYkQDbdYsAPvJ;K-`&@0#*x95QK7IH(?CCkS$^CkX*Uo&~_2|nav)R*+Sn1XK*Xo@v zeZI4bz3%Ah6WJcMEWZuQ=Y=X+cue&_U>S76O?Yvmaqr&UEXe{{rmVk;MPeUS-0v(n zaMmccccHQP@_qem7yKP%O8kr$o0i|7d0zOU#jQuC$4%DU@6h+XeS2nr<*wb5eJ8xP zsAZ@guTrV8(?2M6({gh3GxmpN%7^aF`(u6FZ{htTAACX%2R^Qvba}b<9{b!oPkk&t zZTO_Uh_`H8vYoNEi88zF?j!j<4`(j86BX|GSl>Zydd22B6BqGrS#eR|@>?t302_a9 zX0DG?HD6^nWE}4~^G>`W^T~bYx!*3#@jbKi!c_hTD{}JPt#TZ$Ei6v%<>#{#kyvg~ zW6c-X{$6j{nZAU`9ZQ~v`OgPakh0kwxv6L39b{#t+*@uC+9=rQ~R>w zg1?KmObqQ6Ze8BGvZ9*j)AM<24q5om+37E1SIoP0_v6UejQ75~C(q8yN`Bj;$M-OC z^{Pisj~819AC28|)Oh#fMQ(XEp-VD9N*5gx=U%TBb=_U_q_0+Q-*5TsZE+hes{KAu z(z@TN)Ja^(`94ou!e_m7j)i_Jd)zB}5Av8+zMrgZ>60vcyP|2^olw!fi?KG>UWv_H zI@hUVx#GcF*($xJo_}uN?`p49R#Q9KT=sP?>w5k3K6$bc>-D1^XP%UkHm=~l7i`tl zS+wfzYpEmOPaZlKJp0mtwby4{GoG?#E1Ph^&U{JsJ5N7tD>tv>o3?eX4eI&Q!th^Y)_&?kidYCThKLtzP0bQ&XWMNQ8qW%Eia| zdG}9Ajz<2wp6{B}e@;32p2;Ji?rYQD4%-F$Urq?VH%q1L27^75w!(g$LQN0GC3Tty zM1Hh1dfd~fUc%tz)U;@!cz%6_NsCj)^*@bG3olG~I>mpIz#&JgC%nEj@w#@&F7?aT zOBy@<ax>>|_Bss?R z{D|+*x zLrzXUxeXo@c1)Jo5|sQxT42NPEl)SUvTy(NPxO|)kF>0I%l5<|BR4;eOrFLLaR))IjO)7u?<|{ZY-MP=#&?q18QU9O2_hz2qlACl z|K9&DhtI;~l7gMmv7bj)c_=a_P2f1rac)J*i;br_i%vVwoV3N>{K&iyKdlP?&O3il z|Fqq0mtRgAlds;()@ZR~Qfp&*xPm27*m*+FB*O*kE-BjY(ON99*u^^aG3y~NCY6Y( zkqw*;GgK5-7~I|~W;*SnPvEkw_$v-c3_)vu|6{Kzwdwi993v~yHi7AR$>d-RzF z<`J4ZRx@<0nz@W^`N3In=F%}XF>x|p8>D*zdzW2Qk?adq^X%jmo2XuNtt)#L+lJeV ze-w50u3J!aanr=rir3rL&2-KcNKBq)+@{EM_pODgRkM&=aGQ|I{o`@?l9NAv76sca=4F2l}1m?^bejNPpx|b<@zu$h9Ht4$v&o$(-I%p(&A|UAMy!&fU z+?ao8=1m^i(iCYIxpNKsCt4_av3#8HtE7)5z$v4Vaa!0Cm6NCX1C*Dle<{79z3*_! zE!p>C6aQ=QcX*01IC6?QAA6MY@Jjnt);kK3AJbJ7|EWLI@40#Hm7n##@3t)E>;W42 z?<2S;L>axQlRGDCay|0mxsPGqUca-KDorXfbiAMMJmsLcdlYl9XzAg1*92Xkavzu_ z5!hT5D$?Hfgn#3yBw2%PHl0VS7OmaHzdUZox1(m?Zd{mmFJhL&lm6z(vnp299zI*F zoAkWKz$ITNTsh~deraHbDZ4W3A70O99qFbi0xD*?i~ht4e#+q79hDRv zu5y{@c)LoHWntdZESp~KXw33{$~R&BwdnI{XGoYM;Sov>>@f1TZXN1>*a zgWZ8vfu2ZC_P1QKHrm}~^*^(Kb#8ECiSM7elP@bPEBJbzCLiuIaV}=mZYz2er zCs*!Bh|E;yw3_Sf=osl{%H(idU_yl1%qi;{CS@qtK0c$Ad7)9js7`ZXrn9C(n~J@Q zE~i&xhtVQg4%ruzmMI=}krMKWWH`nYdZL3xh@o)vTqlJk?CDFGgY-BaAL^TGee$)2 zN7+OV{qozT1?lrHX0N%wpnr<%rcOtf85Kp&S&P-2 zF5UM=;d1Qdz1PKse{vhoK3DsFNsR0g=AIqreoIN7-%+^1;mNkhwn?nV18mCL%7mhW znl693vQ_n@!&G6BFFUtyEuUe0&Af|EK(+VAqV%;lW@f$#`F75_Y2pk|Ev`Mak@><^ zC-llco!n<7q!Bgc!%dxcFJ(&?rMzXUx+>JJ-0`Mku5OCT$kQ%yf<<>KhHw5SI>LnxUvpOP3m7gbLw5r<2_Lm4z4q0H{Q4L`ppm585eIW zD%!aF;1%@@1@r46SB%mg&oN{ZU3O1NX1k`}oF#g%Wj@@Eify?ZV7*l7EuTuugtmKq zZ>A*Y?h@Iu`$L&!;jXN%_xIJ8#|kGaFJE$U!W|{^dAGfHT+_I>J(xMt zk6qz$g;)7%r=!PCUvS|IIQoG@Lqhj+gu1J#L`mGw*Y4dSa}SvDxIF0ynygS$k$Lg< z=?b?+Q)N~*rRp42Q%aB!_#b$@uDQ11N`N4%hNG|}mnh2xL-lJuS1vIgpHRpaRq>vc z>(!&zg;i#qzxrzDH%__m{Qkzi3+LP;m5daGjMwbE{x7HJ%sHb~3#=wP@5@Lr+vhxa zrH7pD!lY?w+*h+^IWm~5_*=2xWtk`!CvDm_qx<$JfBtQgA1H4-W>!-$@mRu4$tj}p z(=00Q8y^#sUmS7ZeBvUF^M_}cxH9fru>6eNgFcJ@K6Q(Ja4e`*{kqHmwP%cvP0Xnx!P6Vj`2n4ViV-4f3xT4!bG^1+jAQIQ8n;E^}iR@Mlt4 z688I5QtD-p~dmo-I2StUHP@v z(ekln-imdfB^{z9S5CP0jyJ?Br*kQDo%mh5*V9Y4@9@2Jok{j`hhB=+9MN-@Y2VHX z9p2`rxM8KGsp$?!!!1uFCpT*BX@C0KWZMt+dtQCBR3=Y8owaq@g$-9<&Rg(lht|)z zX?jx4=bnqXr`vp9Q4;lT!Ay&?se4>+0F?l~rWP&!U^xm5Y06)KZ8>SgE8=l87mRCqDB&-l~@y}RK;mYb%VDju&5 zzLWClqwIZwXw}}_M>&%{hU*~OBRQNKR3Qj+* zh?CwYC#zX5zW7q}MHh~UC(m%Y%w`z-;PSJ&#itH{| z*e?XWmgtcYTVW}_R4?ZA6zNBN?beG@pZyN^TCgLndNSuiWv&S?_-4;ouzdM(zu+y$ z7nYi&i;qa1TULL8oB-m9Hi+-IS5_lF?2yKKyi^2dI&h1~r< z1#K_R=zV0p$L>pf`z_PRS6%*xURAiewlkd-SABH)N^!s)EengoJCm;)3f_G#@w(hh zRj=srXVty0r?2&Xb$^X<$=zRe=Xad?-TjvB)brBRV@52eS+Ki=#Sv!GA@rt(&W8@-N#1_ysDT$?O- zP9f3q_66a@EjteBFvYM>m?EOiaTyKj}S#@>b31R9RjhV@l?=xDnb@hdv4 z=WJnbh-l`iSu}?s)^}HslI3v`r=KczA$I4Ni-r^hg#Mkdk$v7Vt$yY=tvMNK*Y3aU zQoDJb*F~~b_|R2%&$`=zi=u2^d4&rxS!y}&5f#apAkx5YQp3BZfcwn4RgHgz=4jP@ zcyF?B!)cw(ZD-tWO;S}z;&bs7I1_kRl;K2^torI{^JNb8c;3A_X%(BIian$95%thA znPrQ(mY+?L@3OQgIqFlm@XLgw>_`C4Z>!mXEhXiO&3dA@ zMBh$&wPfKUv)Olg%z1pQZpa!uSXR%R#qsKhS=z$Y;yy}!TZ(TO%`h+H{7* zq~He`-Hp9wha2t&m{|tNbZ@wA9Gb_%rnxAX%WV>)n2HD6!>d$c-437 z8AnbmOMmOlcrf4sPnV}i>o$1q2~UCcz(O7!BfIXtZ|l^K{n9x_?M zD&(@kS#DiN2+SR^nXHeh&TzcZ+Izo*s3q*Tsni%lg`f&>K_ zJ-xJko)oli@8@6eYWf}o6ny_WE&4X;h6v|Us=`>x#Q<#ZPw zpMNP&;!pkSaSu}W>Q67@bebMwykq)ZshJlKIxJY?(dx89*N5Z8icsgUG;O&=`)omn z|MQLr&XTf~D3}owKj%r6+}g$-gY@s>aZ4Gl-8|rBa{H0~xr1uQEm*U^Yx6g~6am8FjYHjxKoT)6<9rlXn^LO@X ztUrF4t5kBP)$xhBGZy49_F2Da`uF1J*DhCQp8en6Ofb|~a;fXCquuK0i>&sWX1VAo zvV6|HNtt3Y zwNWQc<5`o@EXfx+XVZei(x=IpM_BAoc{$VJ$eUij?!eVvTYA{e@OW-EcJg{8u$QlG z?wi5|>gMhJv#b)=DO%q+ekMJ9rq(iM>Ek@f;gyPQJxJG0%EUea~BZCiPcxCj5mtQW=q9`BasuCmj`IC zKfu%TNIi{LMb$d_c;KlvyAx6tT$<*u|2*5xZp4tszRphatK6Z<-ly2B&#^49Xg7U& zf}kQ(*tJRZh8{>kGJkPxB3Y8{)OWzxvU%y$Odvo%@dyf<6@AhhLOiUM;@>izr+lLCp z6v-HYrp#uABZ?SyfR|@W?L)u`SK_1T6ULj!yC4#xC4Z5W8Y!56677 zP~*?P`|S&7T~U-tbTm13sAqwcMB=YM|JFZtV}AbR*;%niu8&%M3pkmTW@YIw(mh|I zQIl`H!A3!D1KShsbqXodJ!B;LWYPs27b~j>xt~i3oU_&CKHG|Im!1hcFI~7HZ+&p% zWnGgL{YNvt6bmjAx^cDLW5%fqO1}c`$2&8eIrCX}s*#coYn4)?yIUYP_x{i2vCZe> ztanV4SuM9OTkiXv{aP2kFY?*;Ys;!f=_z`WbrDM~-tFbvrSLek%Kp0MH%}wIp8xgF zva2U9_I}8@^f-d^)rA9@I%$S^qMq_R$4huq1GhJ1M+7hUa$)_$ zjT`qd<>=&Yd#rHm&KKPb3E6bNYG+dek7HbyH_njyzOajP?mQ_DUmfKqv#w-s_`vm7 zKvR4F9gC{v^;Uf0A&e3%2CM%VwNx2a{FdjGN^@?>(PJ~zX4VSZ=$Z9qdWT4|+ZjuwhnbnU|PNXRXUx`?Ac`AcMxlH9lbHf^=IZ;`+Vz!@TU*@-TXVgAhHQ%US zr$V!DyFOVw*fvLoqs{Bht9#9E9a}V<)db#4_1ycEZzhp?P$tlGwuxn%prEU&s-e_{ z2rI63$Hr-!RTr*y>$OrfH2Ct!{>6n9!Q;%UR;?B_)cw0VZ0{bA$eKq>uPzihd#}u! z@pRMMu1VVJj_;MaLYvQZX?j&D&U*L9s*1a@c=wAJzDsPaZpCc)d_`sV{mcKy!yRZ&!J z6|0xg1ltAgW_`KY>~NNI)`LU0C!evjpH?Q$=ejp2aOOI*jy&frYK|-Xlw;&?FT7*B zfKP!h)m(4M2?rx_%Z*$W{d*S5UF)Mh*iy^d&%~BJ zfzz?F&9~#0UhR(7&u0a1GI;PbBr;UANG_ahI!XUdD8rLA#V`%SoxHtG}JT_VdnF;37*o`%x>yEqnB^EY#I5DKV7A~CpUbk7Op{d^CQKK8-|&CG zierG&RFBFF7IG}-MMWM=yUrwFebLK|ahIxpdD@ps2Z{A_idcA_z5j6X_>+(K*UvXC zzH+-<{X=MufgQ&Ro0BXjjMfXK?z;V_?(KG4S*Fh}6a795^ldt>+qOdLwAShJ$q%1o zY%faWxHtW~I6;7zx%RT&Mp{VoY^NDTe# z=(ys_OqIiKLIp8FuL@R`DfTSoZuqD=`xs2|vvC7}p*RI@e9Kx2^%F5(w zH2<@kK-9)nL3}gTWiOMy(HCz&J=l4}EH0zs9Zf>~*Y@l$uH0mI-BICKST2w9&iRv^ z_}EfBgRQ%cJ>S+La@P0qrPzbKH!B6aI0YQcW}FRJ$IR9CL~=vJ`pwRZ+B@vy*{l_} zJF)w|y5;I7C?T*`r&LnHm_y^TKBruPTSHoz^oMzR72AG2UNU*>rX_2d*OW_Ln^?lO zk!@d;(vlM|moHHM_OLDU*_t z=ImT>CqHHce!1-*B7n#zq3Q%08~CR+?=wns6^<=Oy$R4q?ivcQTXJs@KB%c-@118x7-WPs4@hwt0f+(P&-~^#p2=k z^VK)g$Gcc&n}|3(zwEU9*c~H5Ll^Hgh7-TYe9L=buyolXE(X`2=5t~;OJju|znUk0 zDfNV3i1I_DC1+Zkts~A%va>wrcJdUf%N#+0ic;wxa&K1Oe6u&SLp{9u_T=9QvKGD) zN&*cYO#8lU3Oix_=HmCTJHhSdXnt?yG6lc(y)rFqrRyS$(mPTX z`18jvXR$1;uWjns{3)E-b%JNdJ8_RSoor10pQbX&CqCe)3Aj|#zO?E3>Z#cpN$g1x zw~N31v8fa{(5St1=hDs=t7~jc{w=o08&dY}bDFpB*737iuV%My6WDFR-t^Vceu5Iy zgD&Cz?SBd$>c9P^^ZMoYTP3$nc$#P}?|Rib|32fwhSGhvHgL_KCFmd4)Ai_(?Ti`j zr`a9{UDa`%z-YGjU}wqgM;f;^xA%3k-`RIxmc7P|Kf}QIt%;uV3MI`<5yMrA35FXv z{G3eIHgX7*xw$IY+3axK({r~q>SkBALfev_BPMPJD|=QvX0l{z+i*nV$`r*3l34+V zcs5L2v2c<~v4P;_fX>F5pG;+{m!DMvFxyMZ@WW ztkc3*Zv&b2YrH#>ntPnIpM)sw68;!_ME_~~^Q(0^CtHo{Co4xzoVZ2fkk3H_PSX{u z3cB60#U`gny0y3FY`R(7(<<4Z-rT6-oOwc6Ba2-{sb_kar-MZD+O`kHA;D`-lr&A_H0$wDv4#1tC|+{99Edpv?4-bYXQr~#ax|g*CgFG@I>_r zrg=%EB}xj1s+{EulZ<3+?VNFlRmW8-BX_3Irz^&>Ytsx2U)|a|GqEAE`H;)nnLQnj zlik`CUQ2~c*vhMR;4GW)a)YZLrn!b)JQ)&gr=BPr(|FtxD6z)SEj4APJ6ny!`^2q_ zeI$a*IFyCh&RyvGs9_=|;K|(Cw*C8RyIR*7`-TR(K+#eW#YqOKW@Xt`4^LbPv`_LGK>o7YkkN)YG|r zCU!EXEVr!MGG~R-MgM(5AAUGy-CV=7Akp!~Kf6=U&UnbO2v7a2wd$Ra?1H}^YiC$; zw7y%zP!y=4HOozDqLQYNf__I1-li9w z#y28oE_Wme(IQ{{J+zI*CM@z~n~>2NX2#3o6D$4B$^3waxl+vb+!oy_5)Lb`HIznXamr{$ zPn~3t+_Q;G`=eh>yhhBsoqerNn<_n6l`b$EiEsvZ<(jfwaGBuC@a;kMvsss9YHP!t zN*a~V-Yg9GRcf;Q{hD3}#lzv79T=7er0imN(qtR(i~aJJas`f@UC#trCDj}QoCJi0 zowjTiX1Q`HSSXmeTfJw+Nlz75L048^Uln6kW<^aEk%PXT4n7+_f-VHIc)FZqnat^O zWQwbbfr+umW@ZL&hfu+wfDmPowI-b|qN;+*|AZEB3C15QS4f>O<#ofQuGdz+zAS>0 zvpH^k=g{N*em9hD^~6h7*fjcJNH*QddskS$8ws%)_O%b1PrtI+x8CWIx6{ zkQa@9;l#orF6nsJF(tK0HR>C;cgxPKpBu^+E_f?i))Umq`+gW;i@ z?wU1oCY)cz{F=l0J%5(jHO7Do#z$)`ONu@IPUc?n(Ej^Qmf153SGl}AJZGVhRDWQ5 zaOR4OU*&@2*(}v>7hQbQZg=vNGqdaBPcj-_-2d3_-bh>}_O!RvR%|Y_$_byz#?1## z>3AtKK3gfJAr)ZPEWC8th3xm%=D&rF?}zd^wN1DxfAQsI_RXJvocr&%_t8n=gh`wN z&TA5`Wi!o9aE|sc4-#0M@k36Cd-epz*$FmsdoFbRHnBYCyl(e@Nv+NoWmh}1mI?eq1kSepol=R~t>ZkY5`5(l7sl>|Hy@BPfXvGO#mv>5C zlGZ-%^Jgnh-rv7+KL6Cv7qNXCe=YQ@dYJ~JJr)hr?@9w*q_rsj&Al97-$ z`Ec9yWJSwz!$UI;^NCrUVR-iFw84{Z$0N);Ub5Z163#ktw~p>4*@?oF*OY;la${aWUxWhr3+@6Zw0Eb9%aDTF$1HOzvBM_8-6U*#}ipiW+K_N=r19 zq~mx0+THx_!TDR$IZUhC11=moqO@k_!~2$p-zX@ggtH}y70EH4&Pe|5eB{8)*WXpO z@3HSWx8Y;v`-iRp57$}mYVj_;bfanE({Ey2{tRC2zJb@Z)b?qbX0Cc$wecoj$E4rJ zjGY&bPdJsKa#7-ddyqsI-y7>S8=BNZ$}>!^8$5rc<2OfNeY@ZFuE`16avN%M1&;U} zo!sf-7&+5>=9JFV7O_N$lN=^XntO@@4)Vkab;&xeyIU8ZBhvC;&CtZPCNIO{>i6Ex zZJjp9OE-EdHtiF*Qmf9veWKyX$z^Fww<^~+{fp24@SDMU1@k_ihEuO+CKyOf_>p*a zzV0V!wqNrtlJr-3w|Tui^Jn7ORkndA_8e@T*=s3iX!~t(DBI$wQ<=Lzsn1q0wN_SG zvQCR#a-r7rIK`Mt(z340a~Nt3G!q&*?Ec>`IDY=ex%iL9l`EW%nH)OKDYHsbc1_Bp zgEw8=Zn#F6D?E7ZaKosNC8ThfrLLFJNsrs9g{@M(Ru;!zSaUpG8}4nmXbbO@geMV4 z*{px8O}H7AlQ_ws>{Qo@H?1YpdPelvMcw9Pp z+tR3s z9G^_56(=%GOkB;f4G&z%;^aB3?%VC#(Rq^pL9KCAbHrR%*_Dti6)WXX!I7L#8!q&c@PZh9{PP^w`Ry!ZguJYR8+?>@$33mizeR9hfZF zUaYgE@3_j8tK9|%gZDLuxi#*|4n1_`Q=(eR8EKV><9vT4OY(g8OuMe}GG*GqTQM_I zTAQcrJZd!iw)q;hl`9R}7M3L3{}grCJaWU5BhuSmw(=x3`^Sa*T+S_dR3Nx;{}WNu zJHX56ebp=Dd*+cH{&#W%;Kddg1%PYx&KOanaQ3&gD%zu3||U< ze6nvhpFY#U=a4{CtVkV;U6|2~RL%^KevM$}M`mI?>d($wcyKuEEBMl3sbu%X`D@>- z%f}f{b6DM6&nubw>CfXIT5PGVPlP`(_@BM0|JkI$fO_981kdzG^yjhSjIZQMlWtoxw#Gi)24g9AT zcYkjBDRkkAx0B0iO@)9CW9D^Bd3_WeOgT;n8hI{|5=c;rnOeInK~Pg?imJ$AKBuSI zEL;w2I3gyiBqj?5D>W-BxwS6T4AcndYS0Yw@k(4SC8`l6G*P87(ygVDGu4SxDPWn( zLN`Va4zUMCGiGs3sLG6QC|fn-fWwppm)H$>xtM?Me`sT2b9I;CH?I50gFf>@pk{b}ZTV&}{L`R`I8evTiIhm^SdRtn*vqaAm_9hfc={ zX$g!I1ZP+{u&4~Prc(=>bU=L5f#`N|dh#ifH88zlTV)D&#ZV;3`&^4oI$ICCVD z_x`*oJ2u7GRWC2rP<|525%c1Hj6#m%nTdRRg_)Nmxj75uJ~DWzCiwfvx~RvyJ$HJ^ z{VtN4s=@N@#7wQP4L>;iqM|b{i_Ix=;XipKUU=V)Eo^eLXXUgf+WR$_D!x=TYs&cY z`G!g0%?*#sq;@vUn&{ZjJ1fy#wA;~?jLRzpsb({tq~(1YYeVGUet!FYCByqU zD>nF9Yvf!{__$BtXM%>3@t67jM^^pV#O3NK$;sr%ui#Zx!>W9%&R|VX1MjQ7k^eW# z&+JH;&KIzNUnu&%cl+7ZDutHQTCOwvHu$9zB{rAkb@da!UF&mq>zHYEKAEK9C~xST zk!;6MaU`^p`=gD~-xV`fa6Voe>+$>T+q#P%uCXY!Bz9HB>N)EM?UM1~xsn}ZIa8xD zXqCha#e@sIOIl~jNxCF7a~vr=%`~%NLg<>93G$oxR1dA3B~s%VS8=Ox=2_8vV~%IM zo*KJt&vsPLukW=kpZjmu*KgZX{t7CsEb%mCm~-RPC6?JWUv@vtG`k!h;bFf{M56G5 zbwY;PnR7FwX8E4KQR>k8?w_u{mO8)me~!4`$?7p#eK!5+USE=~Rk8>AAC)h<5zrIq z(iXT>HSz3u-IY@8eBx21oAS!)-F)H?$#rL)5eW?{lAiwSfkyk?pPdUgicGm|W9#y4 z%5G2DGx_1&#hd2LopWpJ604ARAs@xp9xGlw-FK$cggM)4mwjwsc=F?X>$>$*cH6Dx zbCIsjvG=&7xpjFGYsiCZXDt^MF5h&kru24WSXjbY?&ujJ+w?XIZs|D8GD+#o@!QYN zUJhKl%KC82^~8$D@0x9&_uk!hRW-((FhYIaA=3^?$jcOCf_qqTj{3FiGX4jS($NDYqYKC|q~g8~E2I7^1vj%eO-xyz{85{kr#R@g9q;7WynBe6J-)=B{m9dPeA&YME`2ak8|tq}%%Uhuhdv zL?q5}bLTGbWJ#E#<65gIw&0Nw^U^E#ln;vM*E?6Yt8eLZJUeZ{6-%!0NNXb*fxIH; zlrveuE!&c4VPwkOk2{G z#kR<)^R#3^la`j2<`SkUZC>2$Eah#dJ-r12J*Hd^*{IFJ;^P!BB`7e|DcF<6#Zjc! zWv#*yjjOyofvhaTuDnVYF7VVfUM-MFWDRi)iF>TrT*YtseL9oM^j-Y7H(X;AY27wO zTuDgh?9x9>*-qC4m&fw8^({S+P`^{xV%yW*OIdy^Eo@{zn$Ra6d|+bD>u)EN{?tmqt+~rDZwo25vwnJ`FXy0*31PR4M`!hSiao1`;cUnUH3U%!})6@== z6WA9C8YXHec`jV2A>q*^(zT$CMMKL?iDl)4#;m0cO_5EzZZz%)=ZaXMs5Xn?g!IRR z7n&NJ<#**y+GQB;chNCXZWXY&uyxjBFAKj-46ko_2ww{LeA?x!%L-FwzaMVS#w#^S zijJC_M?cnEa;QCj8}sF&z6<`GqLm$$j&#cmArN7q5PIOd(tGXh;nmp zb-Tu}XOhB<4MvjvFHFw01r=ZY=l|%+<3-FX7qd+4buhBMQ^~m3;79*-jpZsQG;YW~ zKfHL)ss*1EzP@HVVN(0HsZnRiL7_Vj^d~*z;;8ZYY^IR5`SOJvAJ>Vz>6=b*YhGxZ ze@0wj&SCGPhdFzlY)(wb<}U75d3XBT+lz~tXPY*!6A>}IvhaO}xOmxdnM58w-Ogxs z*6J@}Q}~(%UJ4rW`KtTy3M5%bFAA1fY#)2qFkr_G4Ifd3x$RS(p05+PcFnne;@nMZ zw)i(ogwF2J)0!b*%aavw!mTQv;rT~Jy?w?)jH$Itj!1tA3bcFZ{W)&J;ig?@54t+B zY}#!NO=dCyhrawluF z`!Mncvgk8vNT|9w^m(Lx47m`HAeI%(t5dJh(e&+pROtjwqaJ zzWl-eqGwZ$PE|Tg{LcAd-OP<5@_7<0^(*x|qz>F$-XC`1URTP4xff;zv^2#8pS-8E zXT_c8;j$JkJP#xddRaYIS>0_3bTW#L+NiepWQOA;rWs*T5si~-&x%f(eA_@{La8|a zv4)GA{{2`slgrdok@qR5lMT-sU*^*MY5B#R6X&jRxLv zzO9%pkhE3$U~#C~HVndr!*Y)@+LySvI!KJEEkx z*k&!5)=;r4*?ISY|K=+m@1J>K_bvxXZHZfpb>Ek6xG%XmdXE3IiOgQz3_7#UZklAl zGnMmNXh4J7^DluP^xQI}yx&+QuGw_81Yso2l&D|V# zdc>oQ6XOqi{(K-VI8`%{H_&09);x)t`uhI+di(n)2-XJrDs(zD1kKOXD&yZX|8cx> zf^_rt4}Y21FW)aOYMS}S)-KZh1N)j)S*upATG@E?{VvTXFBX0Pq$>IpfnhqM!QSUPpj z%#{k@n9GSY6x^L|X?tk( zioY>)>Nm&rXDQwf<>ioLyuq<(R+Pdbu_nb1&P9%^k`_t}{;O7IyC8XwXYQWpl)0N3 zV@w?vJZN!beqiM*^Il276~6wuwRJgb#v}gZ zS;BEH2D4X8k=(_3peI-_D4zBBHlKMsYbv|cZUsfjhd(Vj()p?Uk?q9`9lakrclzIZ zEL@PRm8X1L-fNve|ML%1Z%EZWWBY08Ij1v3;lhi99~Qg!B_6P~FB5F#{;{d8)xPkL z<*TA?xql-qw(R-!)bws>ibzLG5W|cUhEZYD7Y6%I@qTtbaD!qihnzc4$Mtz9eL0=f zW*lQM3}{=!^VMagn_}~^tP{Q=8Aq=18A~nb=$NH+dnw!Hic4GHDNXHlXXRsVO8)z8 zTASVK)_qUTnPs`;9Acd?Zy)DvX|a|7We=tPEg`EbU6ZiI&&)3^>6wLS$QEJCY`;Lys0|HGDi*U?PB`v9#FKg7CfawY zu8+WH332YI!*Z zMb|q2%r(7wy-$Z{4b5)!7rqHa0xMO7B7)+81@&osZaA%wJSKul@SP znY(-^d;O@2-G87(@xXk`V-bpv^$LYMi|(oQBr|j>bWC(VIYEqr{h3XH!~aQ-7Ig4y zG8cY*_~CZ$%STw$u5yx{V*y`;AH-uH#*$GVMSaC zj=L|Hzg%{bsmx%doZqz8L;Q*sGq(8$7%MI@%G&8SQPZ+(ezXU3-yCbsm{=DxRsQsA zuRDbtd6cD%*J$mVzUVEUm}I z0zXN({F>X9tD(7wu`RH-$f!ht+5HOhv-7-)iBp#Ht(pClvo)b5n8&!Fp?sdy3r3Nx znw%`v^_v*%>?Q^Vgb2B-U;dPRPN7~zYfV$b8#$)}U$+CZ&7^i*@9wL&-rrPfviE`i zg(T~$4u>RPcY&SE_j?N%XIQjv$zv8^EI8<{cwbQQ>ce`~&e$2Nj>af|>-^>Q=UdRi zi{^YcY(>u{WwNTBDiHk6{o|!oIQ|Iz+KJ9ziciZIHHEb$Ag3Lu3-?pXP zxil%uK{tYh{Y<7;ZwHIeU&TKT|JL6M&(pK>&0J*1yKr;QOySL9`_ zx-ssG0%Pm@RjQ%EDoY&yw4a=Iec^Sb&~1W?A13{Yx)?QK%@yU@hr{fdicfC|?(WPq zS9r3>Wt;Qi#o?bkw=v0c7Wow~zd5_LhEZtlieE1M>yN+7XI}Oo{6U6t{_-<&G_xUSw=}NEisayOr`L*6&cV|5;AX1p>6tGnAWSZxN_87swo#vWTYx;#tnZA|j18nmI~Or2njin|@#T#r$CNgw6g^-Lw0w)e0%;lLve>lhm$B99GSjbz7`+s9SAD`{xhp zjq~i?FEg!JT>qv&B>d)rv}lJ6x9(*p7*py^MINzADApZnx0mv(`4OP(-`jcYlj}r< zmI)K11n%Elap7i`F3aXm?$czaEMA`Ea{9$%xhoSNB&`?Rb>`5*ZvOjhB^i%V`H*CL zVS7>%-^H6I6IWZ*n*B0cH+#!cwhLb-J`W7nb~rchKpp$MRQ|B~{yrtAr0*xbH53Va zkCYd4<6&9Ma^$;%+>fjlDPH@f$L?RAz0z$;N}7|@gd+BnzCp~n20>G_3faZB@OgPo zbBK^kWNZ35@gfUP2aB0Xuy_9zS(}e)8NYcR?6BcmUbK7hi=Go7Ef<|hUDT0mI8!Fo zZ{`7+{MV-M+VrF~;Yr4H?`p0S8ecq@)YZu54jPrkKA=0}*r%`ER_DyEQ&CnBl{}Wpd%~4_QI0rt5k+?lGHl*L)x6`Dwi^ldO&! z39R&+cj@+vMY*px=eI2HyOPvia%Jvh>sR7ot|B4#1QWw7PWT=wT=_#acWc}#%ka|U z>hnW?)^}-qxNzY{O;LQwzR%aPOXa#AnXW!&%{!Te`=0ZwQZXGz2U&wNXB0Plx*&O3 zWr?@hw%1R6wrm&Ux1X}vO(gL=JEvpSpL6ppn7vOI9>{EQ369?)WbxqGx6|5rK8KAX zUtHNzZt`jF>)Vyz+p^N;Fmtmo6|7>>Vh}3TE}=V4obwt#sjcMyzT0P2ui{6a({JQZg|Q=Dhcjo8P{|x93dB+m^?N?bKt+mR{`s>!+mbc${a+ z$=ONL-aI~w4_utn`Jlj2X#N(5$4YY+6yE;5Mb1e1jINK1;_H^LEv!t%OtaSo2{t&o z>6Evpq(nXWnq9jqaNSM|`5sQkz1s~xo!ff;3>hDBNP4Od|u})Xy5j^?#!d~iWD|4 zi@=Cl zS-D~zVN&Kx+ft)`|UblXqGqOS?hMZe71)3ERJ_YYU*D0$9tFqAL)RT~g` zon=K}8`qyAHZIk~H#aX%pU$|z!ll-8eYW@dFEd%BzSv2>J~8+7OyOlQC+0~OD<#el zaPj#w-70SRHJj<@uLQoo{KwnGNo7x5BV)voj3ayoho8MWdhzVvs;UsHq^|FEq09Dd zS}b$s!1>7$QpIPh-xk%*kKY!byyv+6G-0LpM{81++85Q&vwQJ;*S`l=Ge6!JSI?`x zcjc+YipATrdCM&fMV(ptRyzf4J?ap%J(jW6VUO^6h01@@TA_9JZ}$hh?!K1E{IXqj zZbNy-qmmV#EJq^bmKpwReOva|R9M<0l4DoBrgr5T^VXYfaZjD)1ZPRhUrg>_d2@l} z#I#1+BU>-bCN8R~D{Gv#L}VJq&FqYAq=bR&u_$Gu*X)G5h;TY&-3qf0|`o-`;e#@Tb-S zug*WmpMHOG@uHqa<1^FwYjb|}1QvY0yUoO5v8;krlgC!U84e1L&2oHZ8dox$HJlDD z*v1mcDsZfB;qjGAP9<}+oq8;{=<>?NjEkmbEOGY9_A~EN_Umg_bC$lT=5b;kuUl6| zdqLQPJI4~6c&wD8j$D~kIBlLx%ax@oem=Ray2nXo!=nzyhpwg_Tp21pMrX9PcfE*O z)bRb$dq0MPNeoGfe^m6m60Q9nmYF&<9#DE^!q#}g_r{@D5k1XCZBF|CpCuI*>WeWl zHI?&tdTRJEE{|MsN~h6)iOZ!iVXkK9G4tHi1#7h%ca*cRODt(;{IhrEInhTk{Ie%~ z@ONLASIERN*-?<^$lXuLDr^-A?9*S`*V-S_(PD^U$vP#lqGcC9W8EJy{m(B}M!fxe z@v#DLhoWtVd?usm`nU}NeupLRvKkn0?_N~0(Vk~R)uE=QW|yD?IkTM({Jz#u=w5eW zAxCa$veU0KtR)^66SV{H6-ussPKcoGQ%Z9{YNK{e460t=_YXMUvE-pUGl=t%iGRenHaqP zp1s-WH#fsiv3(5baz4Pnh+Aosl62dz2|{9yo4yLnE4s;=W$NWU<59Q#}NVs9gBrZ9w>pF~0F2YQg7@u88(RgX*x0>^nDMRNqMy?PI*GvHoMm2ql zAKIF0*%x_vNhX-AJW>58srlii0FMSuDfx#A&eqLQu@34V0}RZbp0HlAGNkJ7<)6=t zBWF$R5_x+nruHV6(#L+kXos68*$%LFFs`rr8?Wctd0hVck;(%H-#LVIa8IwW`@ml% z$rUf)t5nr^Wa38=yZ8xzwoZ)jsAX+*dv5Y;@2`mLh{VGyw@)odzj1bULGS$D4*_iv zKm56t&aru^>*8zJT|etu>74$$IcbloV$EE`W(7pXIWsRY54vHpw(RX{hhwiE@|$=r zxg#aT@m+iI?lZ>b{B}#@wNH%G1sD&MzxSOH8VB0Gq$;us8pPa5xcX|##Ob=eN6#GC$ek$r ztKj{a+p_6v7g+_IvhH|L8~D-K^K}QS-$$8-H;bfiKE1t6*zKPt*HhW`KRK$j420~Y zY7}oyy7=$-)7F;26_sr;X2zkl5EzF1@7qE%H%>2J<9t~Sz)4%xC| zq4|X^t_mC8do;eepSY%~_)e_BEBTyP_8uZ!A`{u3?R&!Vm+8Ar?eSo{Kc`n~oGi<> z*Xz0D;wbh;Ydf3d%$f8?vheqaxhI`knmJyk+lnWY4QDs*;V;{?9N3h5u6+>O)Lr>Q$xBx*3OEb z-Ta;NoBGiYpXSbF>f%(o%j*2DWOx5Di-dT+YrB`%X-9YlUyGD{O|xNu|yoJuE&8rrO7F1|S&$pH=?DHp#t zFa(6z-{%pzFQId`h2iJpIpT{&*F@eHzs+6Hc+llWk;|`=oK=$_a;d$%Z!We|OW+)n zO0>cgxt=r*UQ9HS<`(lu}q(K)@tfBD9_MI6Z+XFM^vbtq9uOX1J|S%=>RG1r`l z`mQLup<;>?i$kK#@{T3dr`N4HtTnGuQY=kmw*tfAV|Tk1#qYj1Qb?`fT$J%AZA!>? z)>rMWlD=PmAOErQk5`?7R*M!#*1z2!?nS1HHeWmznm^^6`xGq&nUgnpv<)?6lrkoC zEYzH|a#q954tX8L9gln(*GxE}k)c$fa&C#(e3N(nGVc9rViMLd%9iqpx~wXXnl>kM z#~~qk?*6lDj`nSG_OYFP`1y}g|AjLh9q+OU*0&qI+tg$%Q#oBxiS6{8f5)#zRsD2W znxy?-G$8cw;~)d=*2TZ$uf6VFvDv9l_{NcH7Nfk6Q)<-rq-gBYOMGR&tm;_w!XFQL zPcE)VoYDBvm3heoKG&arp4I54AVckzgrqdLIuQyW)S63Z2~+e{Z-T$)lXo+b8#JoB?;;W!wb)}*YlqD>>y z<-t_unH4MjRC$!9C@^u!9a(0yG-%;YA;kqrqI?_zwl1B!tUVbj3hwb==1npe4zmhp z+kPp2jnA)k#glJepWNMf`^N7x^CoKt+A1omsC07(diW+hcp_}V>E-f(jm_%xq-|MG zS{e_EbY5VvXRuH|pONs#|E2a*^Y@$9O~_*D`t{(!Ceh%txA$24eVXl;YL+I?mlC!l z?ZBSp+HRIh3KVXoOzLG#(#hJht!jQi!)?v(4;ml!7Bbe6TVJ~c8gs!M{!Gupnqs{nTR8Y3v&|x7P|tc z$Exd;ODB}KPoCfRPtKvpTXxPS!3pzKLh_6!e-zL*JYRn`?8mCk zzTEz2XMB6vJ_mhGyu8w<-iA$7t$Xh`U4w{a-*Z;Iv)H~wa(Bel-K&~w)FevUmwlUH zvtbR-*7OCNDv!*wjj~9w@VlVCkZ-$6!R+n6&n`Xle8IK2^>DOlNx+SSgyx6eul~z- z4!;tUoLnn>VB@yq35g#hLu{utJv`aCQiG|Bse60wzWcl9?S6Mj?zHI-oqI)`#<3ig zDtl#~Sk0?q5HC1T;G^>Ks=;y#^{u8GK0cJQoiaB<0tM zjde#d6&v#X1pmx3GE#dj6chCQ=p;QAX2;Ob%K;}hERdUc>&OIw?=o_HGp;ErwcBEjx&iyC)%%mLO}Ovq zd4}C{!3Pc{83SW2Wo8b$`TaZXWe=*9FLV|X6ydoN=rkqq@`v+HM>-7M?r+Ul8p&~# z&9&teuQ|ulRf&c@90pr@5)S(^dDvZ;rjqtc_fyJ_1fFGnTbsX}>s^$?S#ji~z^(qr z=VkdA9Hlu9I&bw2?q*8 zih)yjg5|cbgum~q&sFLjKa_dmQDLfm9+x9e)0YptTk9@szOwD#ytzF5lF-A_wnI-E zgcMe-a=tku&*$?x$>)c4T{a}z=1iI#EO}tEB3q}X>|8_N1Mf69oJm;arKDWl_c`sA z#>{7%*;-~Cayph|xS8WLLwx0%10}v9>_GyC2M;6(O9r1mB9LI-xzo)g|7o{$-AM`a zH!3$TFHuXrIa!d0=de@H){l2ecdt0ek7tP*t zzrSZi>`HS<_wEey75oAW?>ZW*#S?#M>B|`Y?Ni(Rh9@gXwB%0S%jpZwx>_Ci&v!r1 zppZ$0X?<>zo>b#9l|nUVA+hHy<`yoVzEZr; zCb$P5^~ze55Py&_SRmVcvDUsfxl&tpiU#tzc?k7dcKWgj9TU?CoY^6A)KJtXBqA+! zX17?Hg(aKIPPYWV)T9Wr1gEX7*Vi#va?GyUA+_U7V-Wj6f!Q7hCw4_B$gIshsh57A zIo9%=ZH_P3`VwxBWkwS(o}T^djoOJ89$!`oSqY}Kj9zV5nCB%iHOx>}V%t4sb`Wpb zi^S-raCQ9j)$p3Zb625XpI8esEjj*`$a*hbm8%p`zNXM!!^2a}Q`60b zab^R1=US;Qty#-vy?AYG7`$rt`=iDV8LKKb|GDu=dCzCQiuYQ60or|63fq)f?v=3K z3075~y7Yv5jHW4H)cU(huYP^%aPL^tYsjM#6Jh21Jk>==w$@ue6fZjDkXei2@5J zDc2TCoRR5Jwu!s)l_@pun1;!&1094Wy1+HhGGuO*n5TxY)#3 zs<^FiQ2}F=L%V|R9LZVEvd4DuX*RjEv>a=g>r$2UlC8SnTR`*kPN$>WZsqPieA(OC z%^;*e@^p`4X|h(D$C0yq2FYulY)@AEa#Uc&uQR!l*Df}je9-&MZ0K_AQcp*FMNq^2 z)D`^feY4hTbYJJNGgRrllado~;K8o52CLjMr$*D6Od{Z|ra8;W7NphXpw0WBX{drj+2UQ~M6ufog|&zs{c z#Gmy%Sor;!Nl>_VKGTH*Gn_A$XV1NMbHnNx3o=>Ek2oDUD7cWJ(Ahi3BIRw<{qAP zmgQNpI3;D`v16jo_B&i%*}LR{i$>$pTO4cFe60EW`R1|h$6L4htSMD)FK4pwzSZ+83AH*8AEmP$-;QYv?|~i+8T^Mi%$ny@fI=oG*{f^5ff6 z7&`kko8qRL%Sn#C6PgovE{nwEWf;}TeOc4Y_VMJ)1(#1=xP0v8Tgz~s+ofw_I3+q& zf_>TKm$9u2l#*ne;M?{kXv=JcFJ}&`eEEF!1dG|hiUR_V7a2J7B&9RRoHO7x>-0Fl zli4H9#1Sw-!OVE2NGkI}A2|!&k}BadOoD7;j&pj}a2N(2>+8r^D-*%@S*UsD)ohl{ z;+)bh{yeFx@7=Rs{%8O0d#A&8Mr$or4A2T(v3Xk{-$z4>DJMJ?c{!5~%}>ZRkkQ}O zVX-D|-aQ79soYV%pT!O=X<@$7)RL(3IU)D1`6d@LMhPY6+=-U9sdM-XdV3z_y9KxN znXb5_T=XC^t^~VdTn`a)?UnlirOZhBujwQzoHI|qx zT|42-2@kbZspq`Coh4Qr+nATKnB#`@bDgk5DW+b|p-K)KN)m}11r*#aUGbLbcF;_6 zyd%2C$9JvWbFd?+t}vhg6xFO$~+N6ns`GIAFRS=4o4qw1=s ztiK-3?-1mE;lTJ^$;G>t!TYs3XRp@vR8J1~@2R=r5(%$bi;|3*3m)XjUR-nF>dfF) zA(M$5LC1|7y&SoD`A!~*xu)5m@nwRLg2S(A@$$qU`OD-vlNNZjyj`$Z;Z(~U|0@T!D0r#_iwXw0I61Ny zczSZb@(lLe%JO2uSqI0P4>m4jX$xpdD4fyO%*3h4x?yd$+oCOQbETX(G8Q&@Ef(D% zUbO546HAGva+^@b+~74jKF1}_Y}IU8H0#Z=riTJ)4qS^SwKTaOS;)!5;FrMoHCu{v z#j50UX+ps!AtyxwOpRPv9WJvf@*E5jabZoI>2qYVi_@Aw4VHr}Dk_XD0wNQ2gc)2y zSyYaOxL!BlSfbFV$iQEF;cw7=#@_|=R`)YmFLb`+=6!dMuiMqFDNEJ~%=*2&*ifHs z!-pw;43-5MPdcx*>h+ee)ZRDv8~Am?4*gS(26pzI*`mtNlY&29&WKv-{p)SfTJBkE z5?Zok*U0gG>+AD25{$FZx7P|>zyJHWgDVxIU8HPRF@HUw&v??M#oYl*!-6MK`~ zl*-p{e!MfdI`4DD!u{r68SNLXj~+F!J65O_&S7!ih@nNo{6MDsI(n}4sVw6`X<}6D*d?jhhu7r0KL2;zA#<(6|G6WQOFDzxQ zEd8Mqpvr#g^5y-y9`OndVqZAq8urMG@BZ;7pvo`a_oI1W?n#$jyW4*A7)N$Zw2+fN z95N+c%t-lws|kOFR-xPq;X4A2i)RRTPtWYP6tX?5GX3)P^KK?(f7brX*|~Y4#=Y#2 zdx2|nZ_Z>~@1ZU+_o1eds)h?wfH1d^$s%E;Mji%P<`(t|i7YqNPPD)Jk^Rns&(HIK zCG$F2ewT*$CH(7`Z~mknTCb}Ta?n**<8`l-;l$w6ccfo_e#14zUEnYye=w^)hSeQ<5c0G_9fQllYG2FE??rW6uN(L@-LawYd1t* z2&~OeUcvNh&6Cu5(+_hoPmEjoMqs)A%T|3 zER7x~#Uixr1za|l z@~*K?aWpvAIa@;6vAMf5NhK{MEpdXSLduqhS-wspGSV`dcYV#i`n*andgpukjKs+d zgVMb(PWmKg&JdXrJYj~{5tAnlE7ypeG-dc|VLPMjyK!30oW_ftRyQRcB&M+OEM-by zD&xO%yXl?lO9rWn;xA52R0@t${P}K?mE}VfGp3hjA&v|YA{-_kxuSh`|Joj>!f~V} zz;i-ECr5zdqDhRcaWA9-Cpoe%Jb1=&W&6q{2PUrh(d>V6;>M}mo8BEgWtqR>al)yt zplOTwM1@W%x}~XfXfUdlOGHna?2_4Z>P%N0F_ zT&=<7iTq2pLE;d>fVy9yp_KiVevO`b^zmmE|(h0_> zJ_Ch=TV*oj%!MZ0jk0^Fx#p&(Zs85nAC&&^ zivFAbXJc*+pPf-y@r=J`rF}UQxBEz&)V*GQWzxIy=Zkm^7<o*KTw$2=QOMRjsTbbqb*Wnu8Krm95i>**(l0@kl%U!!=YV8W+% zb@u>|Bj10R#$MiW6r}huCKvXu06MW83>`rb*4wJtZEl@(U*&;@tIE{&h{;w}Q0o&7v`u z35#li)=iS&;S^F%xN&RptVOcEr?1|*!^$SRTwz<*eH;Fd?SYA#=KZtpD|xSWkL8YD z(&Fo^mzb1Zc9|b~x*>Q1-v;-osZx_ahFM(;@k$YJ6%pc`@-V5LV@9Ld{r$>*4|yH$ zT;kh(>t3?zV~N`j7p~*g2)wuc>W##w2h2TJ$r$XqB2p{!Y=6FCL&wZT#@0sJB4)xN z_hr+PB$eY|=We}Z)Bn9ZLELtk@9wL-XB!zBW@SijkIrJ8AUAQLX{W>gZEEr?T~1F7 z&sW~QQC;!s%VBjJ zwYLFFOeY%pZR4|;AIBJzTBX^)L2lUsi`fYejgl^}Ee&FM5m&e?v0xSBBw?H0PQF&2 zGczpC9Mqk`Ym&QSukhrO8O>{anfQg%r)f={C}qK+=%;8>vRiP1*!;YiClWrfZ4MGw z^YYMiDD5}(O51R-ZAt(8C%%0}+q0LwJfXa!`&@G3+8@gn7rbh)zAdhsk(774!Ro~R zebPmyFN$UeX?gGz#BSz0CBoDuc)0KE0&BVO(~By;UGPrtJ!}8UtUlvHY46+p&pXUF z9A2z*Bh@|acG>G!&#jKuwQ11GkdGv#gmG!&ZaN2P2$|} z@{yjBiAb2s`qSq{3wu8O-2U#vQr<0dLr>|>^}TC2Rl_!=@tAtumjk=P+#(C*e1tWW zKRj92^*(7zhGX&!L0{h@?<_g14#!gM8);3(A_^0h3#~J1<5=u-NpeC%#Ls0_{VvPkcpGcKkCc#N<~hUqenS=Q?I87nRm5Sn^dWPouT>TYe8MqMIOdX zSKa~@mPkqVuFrSRWL~Lw^TOY$Ea}nxSLVALjVpfRa-em5*LcWmOEpdCk+Gfu$higAR{`%s+@bv?Jv(x82 zxFyle`eAFLNU~HWi=c{NkfDNa_PXuIwiMJGuXFdzX;xu=JCWxCBbx-9j%ByP;iiNm ziu~K3JiEEEL4U^q!$`J?8)X(6%BS(KURAY+*GzQh(LkkXk-A+#hr2O8k0rs~r(&G%>uG z!+47G#O~l34y9igq%+7b(zJX2ktIOB|6=3i%rD1Jg|rG71x*rlpAs37Fky<9k728z z@Kni}4L93Zy=SDz&oS*3Rb9jB)XI^}q{!vWm2GUSaI#xi^{5K#BA#YrgVU-f77H;e z%vhFkgr}9s#Ybfti$J50z)T*_Da`_me{Xrqw8$tYPv{V2{=^u>ciZpO&j|;uoJ=Np z{Jc8%dgUdizVP;=KOeB4(mAK<7sqL$g4#jm z6(UnF3wAJhgtf0eAv(n5Jwbz=9E zpV|Cpw4QtL^xNnrLyyfaif?`~zjz;dq^ZAU8mH7|uU)4vEP2rBdV=kN*8&$s;r*K# zt@;%j*nbt9#C5nEPq1V3&*5Y=ybzpU`0mO61I5ixukAB?bSXAebmM}rpT4O%*zI>y z^wz(0(_yYck%Y1evrwj&%c4b03Z^qJT$}DRpONv{q=uUIPt!IjGb$W zAB&ekuD@5xOR`mEpH*=@bhPX3`&IF~zdQ_EvzUFuzkq+0d+eTXUU2SW*{bNPuY961 zn=^Op>OT2k$)iB414nr;%$#|N`A=`!4C%5j4V8<&v@Nl%*JO~dXA$|Rc}MQ&PT3Ua zkOfmT96mb!Hk&iuQ+l0*!Ty8F9(pW>nt^$4^L-YtlJ1#vK<79!k3`H{e#VXL8xJJB z-@M*6;qrB(#8paMBH4k>DStP1Yae_dmwcmORpZNv3m&;1m>6gzIAMaYgcMtY7ncKP zgMd;{OH{zpB^*mMI5hUjZ!!P&H*)UrnC_2hnk)fF?&X~DFIg^Z@S-c!OF-fGGYLr* z_7y$B>kcb$rcMe|nmK)=Qj)VPv(WlwAtz_>dZ?Fh-w~L*4SQ-uqm<_*z}0!L?-ACvHFKdTYMYuCXuHB3AM#X zN?%kw_;&2X4VAgSIW8O&TErz}U;p_+M~Fb~p?-OOrY}EuUDs@^(TeC`d6L^`qPRY2 zi~jt>my`FF3vs2VTHpJTI?diOiRG|@%jq9+SIqckjj*Ev$3d{PO+c-zFFOdYwN%JHPAaWA%stW|u_PrO!4zVts#i$CLM0yl#iQ zi{bZE_321>x41<|y`(l}o4}>-ldL`()P7buao0fAe;V_D4({@J(;kjK`wfdPIsEbc zdRyzUS@Rji=Nt<;8buV=smG}N&g4u3WBC`1|AR+iN+dIBGiXOoT7m87xw^ftyd2TwkZc+qyxlE?q(ezV>aN3ZNr@D*~gU7*ZT zbl`@e_<{$98`qxD=l!ZH^?73dnV(5<6^kD?ZaO#P`kc>NsZD|EiR>pHi=S;cY%6qG zV5Q1c<1E{WRo_Ft{+;^lc*M)|64mO}_l};LK5gTJ4NY->I2744!V@i>oZJ2FkL*J?>$g&6 zW*<)0+oeme7Opc{Cz3C6!kC9E%=g?Rv)$^ZE3!`{H+MSi=yYG4zEo^o{CS4*?Rj=j z?&iI4?nvn{*IiR|`Jb$ay^G8pSzG(_)r_YmI$x=|w7zjhLuKRNO)Cyu5#f@ynzX|C zSk^yT$1cv*{ANL^-l_&~8iSl1HKk;qv0RO*SATKjw~Yed6qgNc5Bx5euz3G^>%2Or zuji=9UjvKo8QPv*%tC!7yV~6HE2~pwKTT~>RMJY&QeAUqL6U}&m*gat$xN0SIlER| z`FZ#4l&lb`{Dt!vzHX`cykwSseBD30y{8Kt4j5=L861ddbbWmD_?(9?FUT@HI(m1n zR@236(n_;^)P9?Fs+WY@wv|5rtM_qp+#I*s;(nuF*QP(dSKRXKij};@8)LbXO;e6V zDKApE@HVY0wo6gs5Ub+%+Spl^oh(Z=c)jm(RWgMx_4BLq^IgT~_CssF&ji8yf=or8 zUiCcO%zfulms&39%Gs~E^N0C!dCsd#${as#XE|B1Cx+v|43BO9)*mWrGCF?!)tijR ziVDHM%is7ivd6G6*V!xlw7kdO&(mtGU{UsrqsqzM*(6Elp@4&}w!v(-eng1H{S45 ze|TWQLJdKSiABPl3=8;utWRu=-Ev4$>4Vd<_Yd8fIj44*Je(mSzQX^QYowK3{|BT1}9`Ejg1dkI3{wyqd{H`mBx38@_SN4D_ z?*ReR81~Fh6C`r$`Ky_Qjf3{|Pl^9}LLfv%Vu?u80Z#t}CGpZM!=Wr8v(Y@=aOvBDy zeFXxItJmH4eHXRiUdWr~i=i7QuE9CrnPKII4+ld8?F8aGJKt^;*kJibJMVGl>vb=0Ht^U+9$b+l^{8gy{p-tYXGdma z&HS@+Q($IhmJy4(R|(su`!}a*mj{&z2N#}qPBz%*!{#I{naF!v>Q@=Fwbln?uN{`E zOy&#=!c@Zd$`vv^nDVs1!sPw-*|ksR{@AU0cY(HP{ev2{A7{3IKUpH9ddXC#Y~uXG zh1EUN*k>M#oi_dAveV60QvMnd&UJr9eXPE0-p#_isbW#ltwRYY>5)h0QwI_)Vmd*z?X+m0Xnc~8o`ahS4bUysV& z(4$?8=5FLzasSU`E$Z!6w#!mMDurn9SI$W(8U9Zt%k7jyQCpE{z)qa=GGGxIMe z-@C@!5{Z*M)vnF)X;EtYBEUX%?wNxZBbg3|Nd0C!tGRT~A+bAZzRs;5*mb5hH5F{Q zbfkIWbT@;&E=n_`Z!5Mt>0W(0DAMLVl&lTpdaCAB?bhuz( zb$xQfc5c=sTv1M(H<@ZfDs)}u2ApGh_QbGrn(CFD17^H@GKL|(%{Lf0j|kNSJH0eH z5qL}{J(8d0aR=jC-h>kUlS~eZtSTEmIXTu8)~tCJRCA&1hXAkZ%JQ}o^S*ws%=Ftb zOGCDG&Ej85d*dr-+Br_t?`xg&dgVg7hlj6uNK0JpGAmKOxNLRqo2oSZcXuT=yWDZ? z;Z0;nTy}ejBHIZkzFMDq!ff-L`ZjrZIKF#R6ybI#x{S z`?K*xSH_uwG$u3e?&W?l`4Q!5erwX~B+u_ZH_`O+WcJTjWYQw1etz7xeCdRv$7EhB zG%bBu6MMX_cY<@s%s@jjG)2LwzbmBK#HXOZXLnA2|qrI>i0qibKFf#_MegnjZYi8D1?o zcJFQFz3-h~8cG57=NLJ@m%m-)k=UWw*}|q`()eaBdz)PI4uy_wB3r_r-rLf+vLr;Q z>dAq34M~o6$`iYMl+4pICwX|~8+$RVNKwdqyN81UFKT`8T2K7mfr2BI869ryTV80|wzwQQ6B-)iE0FfZeEaR?QCFuv<=(YG z?z2i+-kkAXqv_QwW+Be&`9BsMG@kyZ1%c?m`h_y_>U}`6elB>fW<&Kyw z6F(WMtO`n9+jnBm$4l1xzMe3CYBa+&efhE-QL9(=dQN<}HOXD_e0DQup#P`UQtqF{ z|BSIofbE>@tiB`8$2arO zovLLN;(o}{bkY~U1$KFdn@U&SWa{re#FWLo;G^tJWeG7=6>ce?BCaP)qHabOCwwNg zuD#XG&6T>cY)Qrrg@=#dE-;wIIO7<%(hG~!yGauM)6YJL+!gus#m{&*=a9>3+m1}g z@BR|YnC8pdY&xA+F|YadB?A!Ime?tE4-}_}1yPRy6-W$DHCbbTA>~GKbOljy5-sq$F&FIxh&J|v>#Dtj+ zX(W|%MHR$4{40LB{AXE4*qMaN{yuL6Wp&XU+Guv z@IvG0oTKNw%Xen#E%E6!oiRT_`|Q&gNu`!ucPL%9nTuGKc$FzrH7L z!e1B^wANHo==d5=UH78pp=>QYXT8HMlqxseZrZcq=HY-(DboM$v|n28rBKnZd39@Q z)I`PLDQjbYEIXj|o{#_d=A3&Sw-ec>?|41wz|r+*mu|?+k2X6zJA)-v-J5?w*gyNL zw&_RqE){$9$mdLk{mE-7zxJyw_6+p?XP3j>xlF)x;=M4e`}U=V>O|KyiBE2b1f9@~U$CpE@sA{r zVB=Hv$il9Y=zX(!6gi5y+1^#>#z}vF_agJ;(zRMLB{$4j?_6zkJR`E}^p@_mF|iEK z%^kld>rt_zX&z_s=IPaHE6RB*LP>%3>&y{JNMLHmZ59wvcT{BM37PJ4R% zOvXuPS8nE>l^5R4ILhYyIOz(ff&Ndwv{x}tUVn1#>sYqx!qT7<|Me!YUtV>n**Vy6 zSN+7V9jR6;RDHP)q^${@|2W;^`0p*u{^CVl>9M(y#dmf}#M+w1&h}ex)yp>X!t4tZ zISwioL;kc%mrza?1gQE3b4EI$53=n)QT+vw7WNni_Nt0T(D zz-VNsDARPuaN}Hy$NLO!bs8*X5X-Z=tCnSG^E0ERJ?*#7yRN-F`GtNS3405Y?Ahi= zE-*iFK`by%)<%v|=Us*6=W{-y<|%w8!G&|x*FA6GZD=~k%pqWG#KOWh@7c#vzoezi z-W(5&{WQKA9A1^fI8FHSdA@^{hdsND1n>7dJN7$;7wwv|s6B8h+tSCU=Wm}UTXM$q z^qN@?Cw<+z0vlJPbZSSW95rFvaAG@Kn(ej81xc4ZHoHe&U9jju&ZIM@nH|fvoa}95 zobucvW5wEp9X*ch63@&;vJLr^l?$Y{+-8{|ldAXU_&PotA<0HIheAodrG*`+la_DdM4vzbS5YA!*AzAvPo9}-f-ak8Uvdpp=}~sgGFtd$gKKWXLuoeu)dqUr z3M-e*FqbgqH9V$xl5dq3N2g}TW1~2pbH?)NZ(qMY^Qzr>=Eh7Zu2~Zn7)kkbiF5F` zY&n(LyMeipch+1LN6SEqHL*4>^2_vR%$TUZYv!}_+%Ga5b=kfo?&!Wc(^bHEk^O!r zHE#W2*%nU)spSi51sA)_l)qG!a(4DTi{h!x4_P+MezaRkENSXt#iGg`k@Fr~8b~iN zzw$I%ctR$}3XQDiCmbc?jh6IoRCxL1Ctr#_V?g_}y=6B8n9^H#?oXTA=90{FVC5nS zGxon6c5xzh(K*%ZPp1mE2C6mRJ$c}@=b_t8pH}6jvI;CRkUzk!-my#SqR<}8-A-># zn*~gI$80_+FPYW&bVbefzWU1x*>{E5s_dKj-SH|@`oU1U8AGh zxRTd#MNHC4leD0q)Tt&Ljy!RhsVgEfJvW(igV~P!vP&NVJZGp|O0$`WN{BDW%CdAV z|E)5~Pwr=HI)`Ae!p*0`fWribMwUHncMM7C|*f}L>5)aQ2)mzF9>ht(mpBPq8X1tQNP@H?kLj}<$77d5% zp~2jVxfZTGvCSJ(OhgR&&RVQ|miph;_=wIOuck(?x*wVjjIAOyE3%~eDhs}EurJ%X zX1}wMORQ3i;4J^0*Bk_HDqON>c%;cuA27>gagfN7kck`<7<~TEb}jxa-@Lm2Wv89g z&uMnMFHL^NY#bywF~cW~WB>UVZRXN*%)d-%(dpmB_i)yZ35@Su8b!kU`!~e%9{t5v z%swTh{ywL}QvUSvEsj=)dQP$kDwG^%OYu1)%xx@sh|yCu{NXR=hkN`M3JQ7~u<|N8 z-q&m?6JmTeJB(+E&qiHCl_1r$gt=>tQkz^_CKzmCoY;PI)$ht4CG(=d`fCxlCMdls ze8IH$9pk$%pK4VPEb20y*vO?=TE@weXp&UYAYjvXX=RA8qQg>!3!7bD=qOy`XHux^ z6yet>b8b7llcCULDfbBxp3??G+$@(|%8v#H{_aGE4Tg1m~}$fW9dS*trumZuOtgpoLrUVo8SAw)O15UM@74P7SHzF$9&3s z>y4V~q$bLGDeho687k{hF0gp*i%#w7M!nP6UYnfQw9u<>d)L9GyROHrz1w!-r6OC? z%#2EbU;(XL9UEAKI9zmAl_#xSGKGC5Q*$$e;z`XXpYJEmTqy8FwOUaj!HeVjB(=-i zI67}--@oqoUN~iMFyjJt|J=22>ia&6v1}CNG?;5}cnL=67tfo^AO7jH;zq?GZcyKL5{i**x`4AD6ja)trM}h?nRXVK9 z8odNXbZV`3KfX94ZPM&a-Ypkwr~Fo3wnQjLxX5Vr#7isLk`|rH(|vr!?5WAwhdpb{ zFMFCS5PxLz;Y6Jav(ah!xU@A4KOSo~1__?p&~a%Ja`%9+O1T6BpI4E9(hm(!<{h2iCh#|{ul@eT@#I3g-OhVf7&gB# z>3f{1cSdLBVWZXaKS}T{xHB*LamO!(D=b&yOhjih<@Rm~_DQ>u=CYXg)s}?yyX2)N zx3+n7PHpik*zBxUx7TYjGyj>_8q0sYDD#odH2B=$|N7XhCX+&S{*(T!_tv{fU7z)2 z`Y&diTS^*}n3On~SFxT9jgyyuMZe6He1Rl*&%lV3ha^@Sa@e(KYpI5}m`g_##yXM3? zsi@rIuRUB^r!PiCtx-KNJ3(&04ySNy^WhHxvlnIbO}M`H*pHgH@Uw2O*S6MfVB5=o zvSxvgW`x5;pN$h%C@z`FGUI^HL8YkB+3t@5Ubn|Md-9tY-|Bp;!s0j~$RX_TeO+9Clr`!w$r-qx0Ez*tJr@&{a7tV2DX*Ab?hC>Gq zIM4by^QK{si%QQri}ywre+(~a8S$K7+ny%pW7}|9ip{aPIquO^LlI{|4uQpGmoB+` znT9OVQt}cMn|eZ|cVmm!T2^Q0`uYEI-#t928LaZ~Ft5;lo=Yi=E3{@s@Xk7NR`LD} z#qYbTo^r8GsVX_F;_#qa$LI?^NIV zjK%-rX}m>UnY*3|q@J72tZJIz=_XJXv+suwqgkDS z?;nMzF5T_ZR!X>UtIp|Pz54RX*(N5lbh-pO7Q9&e{=r4P1gCWYS-&4Sc5VnQfB#7R zv4zBuW66Tg0xqg5@HpUFan zye+NfjAn=Ar!*L9IV|Agw^uXt5t#ii*g;}e$D)^sLH_nZE1w^7f3q*Y#UOd+V>W3I zmWk)`V?Qsvy=(fyd&bKgltO!U?ETIn=E@RjcRA9ntu4cbr`6Yf=?bZPIY+K`u)W#4 zOvtf)!t!lVVlAygBLCh@e8srdaD#mBly<>n9;Ke{-VYPZCNS}Qx3Dd`*Sy2KteWR( zFt2&e3+D+JMHaRM9DOFV@zQh-gP7Dio494>TdAgAxFfM3rKwfIP1Qj-O(Drg$K%4K zUL_G1;fw=Na+@^lO>OicKOrwHqirtq*ji34E3v$|B{JlUbNRdq_P2$9(g^atZpNES5agl#i z?fIgtIPwmk;Y#Ljv(>{dIu!30uw3~d!Ao*)picrP!(+w!hP>^2I#-9LFNrw#Q^0N} z$DVY@*{dT3N_dF<-0YTsda!1%Fz z*teXCO#&TEE&qEG4)`vz=(2s#x+o#^$h9`7z`G%Wie8K=9MYV;a~{^LTvL7G_S!C| z3#x4G+zBE}d?RLhC3baP*%6p!s%ACkN>&HswqquS*E%jsPFNVy!R51)-C=F=WLH&* zi9)F>3}&oYkj9my)vzSQ;9IrzrX^p$SSl}fI;TuCjRf3utB>=C(Sk=SuSXkv2t@3_hnN zhg59l?EdW^-DvsPcj2Z`6A`B+jnOs+^4@pNGa0RpEj;o)mPgRQM|oRIY{p?8p6NUR zJ^n{r+yq>zYgIpR+j7*s>n~d%mFF~Lf>-c?SZvF9stQA$y-#@a+ zKRaWE2!o68-G`bo7o44@xIg^C>@w>x-+RAp>pmJ?ogR^N=7>>)3YU?rUq_Q>Z$!Yw zy&2bBGtP9FTyzcLwZ67O?etp?30vN@#W^`aTf!DAX8PzRDhIO49C{+)Ym@dls%yc5 z<(z!=bK1?>g@QXpRVGHb1-tUHvY1M;9!OrH8DJu-azn~)(~k$sgFmscC{Mp8``=Qe z@cNT=TPCjAJIj8N=cF?%ri-Nic+Tiu{pZM(ru$D;xmrw;wz=Q0@Gkq8|L@+4!U=Z{ z&Z>Mhx9<8q%a6Y`ZfsM@`ZYg4{oM1;l9Ea9WccnJJ}`TWWBkqQ78jqqJ}q=lnCCJbaSxU!uo@-CyO_#g`uC@6S@dKK=g^zzt2BWp>N!{sf|@Bx$X7glNGhjYf>KX?~tBU_%`-*g0@~1zbWrd`8_!sI{!xg zQSPZwG~2o&Ggy9l)M;ap;*B3aa{ioSqhNCGEzgVxpKt%2wfUGiSIxJ%J&$D*GC3uW ztlSp%`^GV&4Z(*wE*?IfbZh0+cY2E#x=NjW;kS=@?$%R3+6w2Gc=%4(x8mG!OCROf z-&I}5{0pyLU*IDY>X2p3uJt5VyXDX7;JEVpxAr=HNmy4k>9?9b`z)!#*Smhd-sXGg z&H0R=C4SF^Ear0F3SF+_^^POuA7imwHp2{8CCllWB1a3x*1iAvg>f_Y ztf{PvrmI~tWM=GU>s`ny^vy5WBCSw8@#r*GJ6*9Hwmqzi@14##r(|*a?<~#T+uE0#s`MZ2zs=j3df82S*HNo$7R%0grfGT42|2T> zqNBq(Z%35jG|l6QvIgJYE;;5KFr$q-DsAF{wwepSuH`vRjDA+TL;CZYpvzf`I~?cc zJ^Zj!a>-tvHm^pGwGP*o%}`z;x%_SVxtgjO+xITmVO(!lyG7}SUDdPHMca*c%OBtT z{ObF5lVrtrd`gcKFEejHBJ=I~z7NG~y~>(Wzo>bHM=4FYxtGoU2X9^%(;ekqlO{J^ z=<>QP|8bYLxbi{Mg8YpZslGbqOckw_5qI;lX82~$Y?SIXo9%1(N^MKjT#I(M7@rri zE5)P|j~iRIdQ82PCMn>0?*7x-NgL)oSebfF>AhR{vE7@GuuF6Oec#;iEPl=N@NK8l zlP0?!HcIY^ydT;5WKEq~$%7@A?&jD2j>^^Vogy`5y3@`jlRHzcSR_3@seLc?!c-4# zZ{ct4rHi|g&G)`JQNP!8-_89wj|wh2#fy{$)>(i1_~h87Q^iLdxdRz*axYpq+wb|+ zhlj7tF+H}xvVC8SnQNU_71zrj5AQB1(o4K5AD&|xkeev8>hk7gEVrzxzb;eStG*{V zS|LMZ(WhTL#f*pAYZn<<W*VGzl-qjHwcIQfQT5GHRo^n2M_Yi;SqBlT<72OdW~B^!F!)GH@4rhHv3%J`F6R7_nhOcha!(h$K_-_T_>ICdQ_*t z=5(>l-Lz{bXl9)SIr6qn1|Yd;e^S+v7Up{E72@-%FoPUGUt^%4LH{zU7TyL8#c zTH&7SUTzC7$|OyC&MCw_sq^76*^PORq@}c#0up5=nK-)fxqW*iu{zJ}V2h2@(r4Fs zbUv;*6}zcrsp5C`{cEP|v&m-5zRc1k!prc|@W9Ncr#xfUi_}IW@11w^H+!A2)sM&1 zB1Dd78m~=mT*>Jy;3AjiR$<4p|GHi2gj1et-Is_*?)p-FKD@Q@kYLKmNvAdyUzQED zez;GnCsCls!p2dlrr`d*N_M8bn;U=MTjO}|wEFVt2ZN+C>WgIFzy5mLJ1lE;+t?l!cMwF;VHdN?5Ktn_u?sGae_2U~nK6dW1eww%}F zQ>uCOs;jcKaAuR8e@Bk!;?+rSrysVy-gWS`rSju~IEH2E&mz7De&G#yAY{$|qCd^` z-i%U42Sr6=rMZV{W$y0mdiWsjb^6wI`eC0QGJkU4^Gsti=dwDX|GJN=-~E$*aqySY zL8dE@vX{NB)2OSgP`X}g5oqKp?8|~^IAYa3!PmD}yvpo&-TCBGK#Fh6guH_X zgkJhD*|+t2O{U=r=bxur!usx9;Vs#|JR?PU?~j*(`%IE8>%w!YO=bFbGk_c=A4_mqg;jK}dJpB`y(Z?Ri_(wluJ_jcnfhw- zyvOW$6>r+tb<|yQ4fqt|U!CpBzN}=z+Ybs#(Z1|6Hx$?g$li1D&=hDek(M!gxBKty zEqa~ZhyG-5GV|M-R&uOF$m)ysi`=EX8$aHfSW}wn%Bn717?e;iRo9u8JV`aC|D@3U z=QSciH)l49{3toIps8!sMB~0IS60uoPo2=e`Pskko6GiGWi4!cXuCqyD?pH={M2#T z*MfcTJA>;QCP9p^mx7NYr}g3QzR!gNh3;K* zTlJTp)ogur>)p7R3oXjbySWx9Dpu|I9w5-Y@L8np6wTJ%@{J6SSWfOpIPl@r*BQFZ z=O!P0q_}nax|~CEI7(VnIDA5OOg7wd=%>Yn_4Sr3=H0i*t1O;lk(ya^ZR6_q0W)S6 zpGtRKQ+~wos^t<_CXZkp_Ra%4RCYU?om6Tw-Mmrf#P9U^vo1e#Is07XiLJ|bopZBl z+@d*dDd#<&X{a%obEPEzI?YAV5(4j@P4S<#B&go(j`t;=V-YHsy)V3b>VEI}slCOM z*)rWMo~SxoS=;<;=9khdUb#!D?YlCsv53-_$E)|5NUZyikz7@+^M1iCPxH0Y^oqil zW-+TuD9mKMdGXNf_lN8%URyqMGYM(Gq51w=fWY0Q=dRsiS$KUNXB&5w)#OcfQKj>Y zW)-(jo%*Q9CP-yDtC~TNdW&fA<;hwanoA}`*-o=6KmNO1);jfLx2J)Evxnd_=PuXM zjJw>QXC61;JyyE;qx*HIt0pW7?Q7IO{w<8@@^78?hOuT}!agzeSGvj^l~X<+sp)@X z=-k`VC;j8N%dQf8qn6Y*hF|eJcmLp5TEBeFNp+DlQF-T;>JOe;<)mwimWe2qUU8Tj zUO&~Xv!ngiF*Wn=wwv>-?`=3PYho#{XS%F&h3=m6?z}~Px|cGaMR6UzB)0XpXVc2X zoM&|ol`ON@Vn4j;m|FV9+gok!OF8PC&i8jdyms|+zrRQ9+<$8eF6GemJG-*UQJ%Fx zbKk0YbCond^Iv{Cr(ki7?a7-nQht}L*mu8B?k}IA^~2ML=PEyr_$t2l^_pWV54>Gp z#&<~U&dK6)_bp9L`*Ni=eDkTkv*wOU;FC{Ze~Fy6H0KU?IbYTF)2H0;g~h`e`JDmA z2^U&=7e(_lGVlmE8aM_B`0(hkw3-MU6>)K75Hb)@QDikV+9VWuy?y_z7Zc`AEWf<; zvd;6SMJ1u4Ou0U9<&Vj|ch{Egy&-ph%CppyQe1p9=Dc*?p0#S0x6OA0{Y<`>GF{B; ztS&u~U*w#AB|%?Eww3QhWzZIZmU4-$)7RvQ2XtE|$*KjbxSZXh6Z`3(N5#*-_YW{~ ze|(TKVbM?iZ8GQb)f3~KYs+u!@_S+yVih0xG2?#Js#TNJlB$+XpRjw^L*;KJ|G4k2 zxmaq+d_|>AmT`~NwglY<+vXLKJ7zq|ST3=ov!FA{U%bI-9OqQ-sUfbJ#=){Mf)VRvpqO{E& zHl{10ebb76$6VbUBM}*um9i;)HP<;cJ#*XLmzR4As<8c%+!47_b+O)*D-|CKk6$@y zH>b9^XJ2636~{yRC4W3CCbwUWij?lV^~`C?z8&Xya~=LFKd5d>FPmZItFq&fz$_2j znKQ+B7GLR^pi*vN^I#&oQm+|1vlYJt+YOa1rz)p%ugDh-yZY>K)x>}Nn)kQ8xjQN7 zQT&Om7i!Nb_{(oU%5&nTbgode$W^PKr)SM^`E}M^*u>fVX~~Y+@{_OYRW3;6efF~< zKUYJrTS17IRfSK$S+MU4S3}|r|HvhV+h!EZPe0ad6){7g?a$3i3~EI}Qv|O!%s%ej zHJ3wD#F@>_qjF#T@n@Wh1)EQ=<$Jhpbx!zq=g!K9QeVFg?rtgp2_f7U&<_1+$ zEk%tRT9-C7hI{LI9b9!O;G$r}tc-0XB3zG5-c|IhF6`N*sIlRc!NqGP?<{vuGKym7 zlr(cwe)#?{`z8zDi;I{4ntma3o{DUt@qT;0KT~h)c^blXp#5jMG{5l_k71*pftiSvEOZNKXA|-%ufNLf&R^C+7r)+6$|l*c?O{ z9U3PIDx~zPxwlwqzm|CP`%T%;%_&-+o~yYA333=PJy_|$>9O$0%zS`#6K-gh1iIOS#Xbnq`{K95S9_#W$~N;t%Hoq+M#@=4l|yjG3q65q{{2c- z|MqQf-JgGcJyQqEg0*jc@bK5P7OY=$J84nnf;n>Xk24S2=&WYjVZ{IG0AJ%)rNHBc zr#LsiJNQ7=siAK|8+9c=9fR?on(i(XrzO1%iUT^ZybzbCgYel&&MeJ|SxRhDiO}bvkTe8>i z?pjI1l`GyTYSw$-bld!s+1qtIluG`R@f6;3W$*cp*?d%?&4Iabdq zrcZQ|nzwPq)?m*@JprZ`O`~{G4T}RY+ER@Csjr(F!u1>l)oniJ@b)I|Z(Le+KyCfg zFCI?67w=jN32jNsa}E=bh@8R8CzNs`(oj-RZIULhkYLy*qs<0t zMrWEuI?foJ>1uRowe9R%D$}@of{THOxTugKuPRF*qo|8UfY6m@t{`Kb1DoZV*%L2_ zZ`o6Jgxis_#EMs_N#fqIGEBfi)4X(*jp2P3$u|WOBDpu($tRiZ9=) z{w5c*>OvlkAH|<)rFl8U50<}Hs6JxTde+pHl_g}eiLcB}U7yp6!GQvv55GKB>qy?F z=6ol8bp-E5YsIF6Si_>$(JAu2@#SChj&vhogZok^Q?=Z9P&rVa>xtE0bX1286yc2ipE8D7niHGLw z`6Mejp=7?VnwR$?CG9YwkVwT|RmV3?b~n`Lh;L=uWgGkM?M+Q{_xrA`twNJJH{SgFO!ac67*m^nGqV z_v3*@>+kGKnyVwTGby)PA#*kBBmuPu^<=Kqn>^e8W;Lff7dn-f7aa0Bc=eLJ0>)cLuJEe!<4JNIt2+2pmYxXtC-K>F|McfC z_sFX=XwinL>@GQHrFspbJxmfhzIgt>%nk$Zo|W z^Sd%1Zu+iN8kqIf&m-1>fwKdFG*4QD%l_9lC zEn-53Du=+2=-yN8hqHKvZzZnnY5sQNx9LL0hn2Ci4FSCyUsz?WvSvtCUMMh4+u*{& zB|M=V8YavMiF}+%T4GG@3;`Fq^c+k@8g2wNZV*|Xox-r=h{%TJTA$RlHnm-Okl11& za`0BcBQX{ZHU6i3?E2})e%0+WOK6Y_{MCK4tU=`vgW_^6jR22y-t8*&#}zO1=}9)S zUt&0{^Qy~4ME2=Nbyfl9vXn%YEqcxG-SnE%_9_Opo@i#Czy7;b(c5pI@^2nA6bv}} z;M-%3x-XJ)bL3YsXNJop#k($eC_d$G+mFmFrhB26ba!{KFW*{PYG3Cnmu7R`V&R%? z``pw!;_en~UAALt;pc;UWsZ8!aO;zDF5t|r%eZA?+1aI`V&t;vg$(l#_5}(Kr?03~ zscbl+AM^gb9e2w6(t>$w{z&Yb;H&56vNk~O&d~|B2GUzJg``_fZn(IMyVEUe!(!nL zEhX!N~=cC$87baAcOi1l9!Z zZpF_AS0ND%cNu%%D*o1lefr(o85X<_5y@UI{rB_!yRM-jp)P?e7foG#Lw!Z~U*3K8 zz5VK!IW=|XXPj}$Ir}fa=5nscxx-5L+$KfNQBU#I_wW#LzLvzV!sWh5zqd|KZ^v7| z|6a<844f-(o$9DjU7$v=MWpRv$F*PC zYuKNZY-8*cI#A@kj4R+*Ys-t4ww4pk7Zg)%1x)Ohvj=kcZsd(w8Q6Y*mKaC7)vsWk zjEyS%?5=OZxeU+i8KsD{34fDglRKK;=FuW4esoTc$8ui#OyH1No9rHbmsS~4{*26{P$PVT29{1< zhM$x4&;0hYUdOBS6rxCknAYo=3ySXyCOk~x9ma&2geeQ1}?_to60MEPh8MX z68>KIVdjUE*JTuoGWZ_MTf(AttMQ(Yq51nQJ3k&`m)Q5=@VekmEBU);gsThghGfO} z@&vqVFjoopR8~AKyzRUGB$qR<7a!?)TL**R{Tw zr1xS*$0Vg}joDHfn~ohfT0gnx>i0eW*&qM(UuRH%oZFds!^7h3BFBm~Z-2_?=shJ{ z#abP`IX&T1c2|t-@%?vKh#bJ18D8NiJn|!1cgdaH)7IZCdW)3I+l8gNA4UH5c++HgJk!kaOyR7f zZjU4GcwE%hJT0oo$u3+n{rP`EXrrC-(a z>9Nn!x!a$(_^IV{W%F6QkumWRaphU!B&zpe{SLL4+gP}suQMoE%bBt8=DsNqe5(oWj-NmyU6^tu?%@yWvL3Y=OrPmsq-tn5V>shabDSypnCtMA?YjI#*QO4|PiGmYdW(RUG^|emt{h`CX(8csvg?>zr`GG}RlF9oH znHv?GCL8UZ$&Fcj$b-SCz5-08Mo?{Ye z?I>{XxJlWkl$i2myZgA4nIh6wwq1N}UeIxHx%JaoK@to3FZVs!n^G*UG40*yrW+=S za_7tsvd6Cbyl!Xa*?HIeR=hMxt9G!9J#kOwkj#yLsy8J)Q*FK36ragBM(aOx-Ia1~ z^4`PuxExzoOnfJELhZ0ON8SEsd9$|}E&aOK&ef)D-xG8oKL=(l~B6C zM;3*084th43vJ%Ik5{aFwd~9KO;%gabFSOU?3jP2FLFg`>Mo0QJ~I;xT5V={&7BiG zm-i|Eaq)>w8Ao^X7)~r|N_?=##YQe$d%oi4g63q=7k{`XDl#6A<~X%l_{p<&O_#va zbA;x8?ps#IS5_RepCjbWoPcUZhP`aKG2Cd{PynJ zhUQ52(v??}lvhf&G~zI>1@N)?rNVS{G1Ku6NUE_FF4>@+_}izRCwBy*3K-+ zOc9Rdw~lA&KY<3#82l)*)W&)@Q#*Kb1!g2DBND=V4Hd1 z;f%xQzU-C>XW5eWJuf)(o{Qbxg2Tra%{Y2BPF>BgXJ6a%$ituRBuV#1oYI!?h&rkE z;l{zKJ6RkapFSq_E#YIF<*`-FZC7T=9ZP#Rb0+7EZQKG)%aXV3)4h1yRJO0jz$?vU zZsse=%VJCVQr=JM3J>ae6yM`G=bq7R6TWbPh(#3__lgDI^(kn)Fhy<4jrlS==65u_ zxfaFQcEPf_B<6W>QgF_Pvej2w9DM9#JTFhZr@lSrqu|E=*pvzHPcG<|6wZy9Xmvi) z;_5Onnbvhblq&;go@W1kndjSU*IVlE zeIF+fyy@Y_vrN;<)ReSqE}m@IYn>crGOH!qCbskHvvYgy@znly`nblvn%Z0p_bCcHg4(j-d8S%KZM*~Tl8#VX%fvgSm~ znWM_vB5RVOEjuoy6^fmBYIe!2%Be$VNAB#1 z=FYo;bKZxpwfl5ZV3Kl4;pVmjab_2uRm>8}Xw90oXKv&prpCFsv9IF_#lF40uW+&a z>9O19Yxf0l&0b+;a-KQj1PD;Y%Y=J~T5v_9aPTx)F2RhBI$wYcVHfdCjrj z$DHyqb;bgzI6)z&iz*AfqOW|jj(c)jP3f}LHKsHnx6@XycchyYdQN#giKFw~ z*JjR=l0UCGO^>&@m7X`A*Wg@yc+UH2j4RV;27Oq1TXy^P^@00CuEp%$?5rBd-6(yE zqpxa5inO1C&X(Q#-u~b^UTayiciAf?^+iT^cW-PfmvNR|@wELdTUL)8F?%?vYbQGT<_~DSB?p%4`v=XIAf>5iS)plvQsyToF%tgzYo^rZN2yF z>f*J@LT|$EJw4#E(WogX^~0~liqFm#wt6j&KKHjI(~!OEu%}KSrx1saiS@VZb50bz zoj6<4!n*gsj2rI!8;g$woYr@Vw*Bx~Kgp=wce{+>O-05n(!z?FhD+Y@o-b~Zn(=s= zW4lbx%Eb6*Zx7mbXWTvEP?#$0Ap@ z_8KK_n%kmrVsqR-TNBAi9}3PZx1Dq|NjDV9UG-3XGN0Ji$)b7L=Y-`gq^eHuHjZYT zVtD1pggWUtNiTipI6PnW^u@HcyDKc0pOBGQZD~Gj$J4F{J5nW8d`vu#ZQqo1cUkWL z)yr7=n{@l0$@ZD4D=*KAar-gh6j#ClbC&Cjx3caW-1*>l;=@&^c^r)%S@q@lhktZW zba|Ej_~VzAr}lJZ@$-J%d}Vf%6gd?w@1`*yy1{udsIZCU&Qc+tIl4aX zopU5NJylCulGr%?{6)LQt!qm*HrINHt#L5B73MUj@ZetEbyd#OxlNAu1aw!OzP6p! z`&NEstzS-3DLYTcB*Vz;V$J(&Hh)O^v#xbU`JuA%dmGu$i+Nby_htEZS{Bar8`-&!iw*QZ26Ps3w>owmT~iXdy*xL7ak2XnpiPCuXKz+;&;Bc=P`B8M5=f9QU;{Y1a?gGxwCi z8IvY9j^bmE-_xG(NCbJFk+Zt@;i!4w=J4G&7Y7`>_P|hZ``a7)v^HBTdc9D}s$}Pf zTQfuF%ndpv8mHM<^t-*G+CVVI&HTXCx!=-!YHF`9UZq~%;%FFH!f?Is>`_<2D~EWJ zlV7Tcwd61xyEWZh`t)X5tdQUno?8pcVhuiQ+hNTnBIOZrL66mmKl+_3Dy)Nm{YfKBNoZDLHUGqQs|ccCD>a`|e=PN9-&+0`sHx_(-fuy_?RL zuF~~RUhJ#+idntq*3Z~F!C!Ajk9yD6yM8*)@;f#hm*R_9BRW0mxq#-PB%?I3O?}gs z2p(_Ud`*JQ_l3l6Q<)92JEoTyINnTK^(Mlkw6|odf_?dy?By#oR4tTMsB4F+TI%CaO%SVMbcp zoWCpfc&wb{o@aeVU0dM%-E#-F=C8g|oX_Fa5F*)|ym_6A2b?v9)q*4XC7 znn}$UE>3LbW7)A_;eshmHcy2Godp8;>^@)ae8loVMp2+Zsary}qeOAt?Zd{_8gCsB zb#^RikrX+((DBlo7PIimJ5QWB&L+=lck7axs8X~-T6v*Y=hPyuDTxYA0?oyzB03lH zPP)+Cts{`DIHCQFOn=cV4hbfW8C@QeT0RIWJak!{-1_YEwXD)LZfDp%%8fjA=9IZR zE@O66x={6i=UTwchF(^NdF7v&9~4yoFMhpr?aufo9`B@|KKbgMG<}69eqL&9sR}?t>4e*o{VJLk5FV2tn*`QhPeB`a0*GZf@ z_%!0P=G2VF9wslwZABKx#AiJbpXR%_PsZf@BbCjvMX3?9wBEB#_q`Tz>%wf4RM$+y zb-$ZF-eb+l$gwP3R{Yxd`;LoyGACGVJ;r?{ZteV4+^nzU*x1F}4%8eHOFHUp#8>u# z<7`2iw8DwEijSB32b)gXlFTG^=#|EXqVP-+MD>oqw1{gq&0c(A_HYZ9e4}`zZ|p)6tJA6cBJv> z`qjrTcs-Chw4sJMYLDi5#sfKT65p; zXbR*|uzTTr|53$@;ICgUM(SStm;1J+ETJ%4!x z!%Xnlg(a(mlxN5?s1;^-aE2B3+!VV~$Y-U*ReZqZFiZ9a!D}+x z87^}LERg4S(Ri?H-lYpWmn)y=WUdR#U)6nZ`@5Dzp9nUM2@Ab4Co3Kkm=@BuSXq*d zMK=C|*}lM&ALPXx=9{jVaLIrxIGTB#{qLQrckaArJG+?4rBkHqee;y9%F91_n*QYJ zw_<+vbl)@%|H!*ZG8kX`MZ$Bd3aXD7vn24pt-G!M<9uv9w zZS`V~P4AiG#N&PWY2&4%jk%X|!%8yyLqA@c5%_k=mkzdf+ndY`H{8q8x*%(~PRh7f z&v?DkeP&COyQ?l~=_%a4x+HV!jExFmiv_;AMyK=gc5PmE|`zq>q=4Z@EmEb)0J zTzF)8yyd)}u9BYq@Z(bk`pO6% z=4&!vn>aIVdmh&U4ULI4RYwI+CE0heKba_h$U{DMhjUP))6BF46ShwGpc)~m#!|Ki zk65lKPihg!d$@u(wZY`+3gO2;4Xa*Hc0Fd6u>auVxf<`}b|g&*e<*l})5_E1Q_G4V z#UrX5AHy>jP0>kmWYe#35@?(wq3k1VxMX8g)Dhh+Wod>I#}_oY9e&dIAf1PI;$snM zh0g*~tDp3=yyLjmv~oj>fx!87=9N)t!F?Q)7I8G~N^DJe$SRVk<|?9QIZ?$?C{$4K zN3cPM#-fgiFp)!WGb4*7x=))8d^`f@0g# zmouAoruS{h)85!7c&~(yy=8(DQ^52~%R5_CJUAWx@y_DcKlG>n_?E>yk^e)M^(Lyh zGA`6vduKL7;{(2>eop2gulI(ApIpPU_lDFKW*;9979rKu?>sLDOqrNv?C3DD>6aVN z-6k2YDQtV+DSmyOwy45mMN`^1v=?-r}MfMMelZ^orOYzw$TWhFS3zAAx zGy-f+o?&2HAk!$UxiTF%peZ^BmrabNX$iQ`kQ1m_u_ z8VVFS<_H8a)dY24u~~n4=FFK=fsb~}mh`USn&csy@Gtk+_ct@0+m`OxZklGL?Rj5d z-h~22u6>J-cYM2-o9HN%v*7R7Bi{VyTu!t7Q5L>dDeLsnVo{;rjNtRjgl|f_?`Db@ z`IeG2qd4NZbJwndz}ZK7Kdj^`c(-kJ%qFgf9GBLxUoh@#zG`Lo=Ip{(3!-K;&R1f) z+{2;T#&Axo@SgA9r}r(hg3cV4xcB3#RvyE0PbP`OUMre(Qd6(JnynjsO)Fo`wAp<2 zE>p=JZo15lOKxA_6>_`MWsq?tO1UGimnW}habJYX<;of1(|hyoaqcnLc%)-ZlXCD* z!zCt-+@{W+Qx6HM8EvuU)tK3$!LQYIb9>XhcQ7K{&eMu=N{}{*xn|?u5r|$EB(;1<$O0+Y&w>-D8*#KC&AYD2^Gf1=2M&9 z-1zd%)|V$QSCQO!)=9W=g-6;Hj_rR1H|efl#r~eRAR@5Uv)xuEchbwCTdi%mUCw`& zs@({z^kj95(`CPP_?t{;>FR|X-Iuofn!kEO*@N2w$ugV1oxRhM&N|m}S?#XSbw=Dp z1t+iNF3jAzqqoccIKR4J(!-X7v@nU9|2vm;C^eby;gvpDAN={x@k@V>s5lFmiV7-J zyp}!Sr}3g)^-bJ_1-;7NE{jh)?`-Hsd2xaC0?kQWMPJ4GcX6FCxv-*YiO&jmPG-dnr3EuIG?-d! zUNcmu3QZ6fay93Y-x{!ZlDfcKPk9cP6CziFMAVIDgdXYh3grk6={BAu;UVC}Xt&bt zuI;lX=OoXU_nct-6( zCF8TEc2yD16fVc+JBn+a4z)e>Qgdp5=PUJ|w?!gfd&TTi+HTSYEmrEWZ%4BDQNuDmJbq%hx3W@5p^fIbA95`Wb-6!Oz8@OoRRh_OI4GbR2 zKUybNb6CCQZtVGua8?fG!A4WD{SY!KCj_r{fu4nj=U;gyoD>1BgoPD>D10m znVZbycU@fdQEU40FaOp1?M_Me*(YAm%`xp2KH|Xm+3oE*eT^dLx#s;BH~(M!fBM7! zA&}Xu3xmX=>Pief3ots|JBx?|1UrLzyJ9^^MCw*^Sl1T|Fi$y z|F5_IXWad-|4-=G`k(dx{-3}4_y5m-@qguimDWG{`+xPn^?&34{qz5`|I5?=@%F#} zf2zOy`D6P3pP%dR{6GDF_P_NT_*;J3uh^oPA)n&m{xer>!NUipY>Uj<7G%xS6)4E> z^0@4BtC>l=v*3TTrLN}zo0$T63;*Thgj0|0a}M+VGd$zkb_ovu)WzC60+n9@E%)tl!W3TQEQFHQVIg z#{#d*V}n}+7o6khd=YbU(*Emwoo32r+c^^q8E&D%qx@XSC@V0 zVyViI7U!Jv@UoN97miQ$sabum!=~J^(3F0V$Tst&h$8b}NzH$^dYZM0yo}eSrA3;q z&@?#1#l=rPgm(BKmJ^M2jvmOEv15ah$_1%|7uh}>c_yRq zs6toZh@td`j*gCwSyxhzOI-;2I!m#SCrL)Je(MTmt2V~A3kMc1wVCmxuXBmiXY+7( zxtGk&mMvF;HrVzsOBC~a)CTU@aae85VKw&k!i&Rp%{~6DKC0VWqTjfKePQTgnY^kO zZu?!Dmj7@)#lFF-KDv$DRYq9-n@mQ4(t-{_&c-B(7XK=?H!eT^Z>-{6>T_(us}uiq z*nc%0({ofG%|D)xi2Imd>FaOCu{`bPC;^a{oRTeLPwfwJ% ziyr@*o3MsM&86EX?d5XArh6+zW`Dd?7#1&K{(iQ+jm8A z>l*v{GgaOAwfs=_iZrFqF8O>0ZMrj;bF@u)ylm%AwuN1W!qVp!Y+;=+;e@GiWZ|ng z%hlczwnovj?_P|)7b9nzaX)Hfn4;1aju+eKs2(UPk~}SLKId6rTGx_JiyhpKhN6cG zub8y0-Tz2UgX5i(TK24KTWlGWN>&T1HYBKWCN)NgBs2tk{dMTd3BO05&#t5}`Ir)_eFBY3D zaHsNxKS#0C_K9XaiOduJw+G&T`ad%(8{9gPZ7iN+AR;lSzY!|}IH#(Qkl$~$TEl3kZ}2><)_am(Y98A9{K=l^GsHgS(| zT$taZr?!Z()5L7y)YV=*VOk*%T$m$Vy_rh1JskP1Rz2ClW&0?@jY0o}|G%x8iVnLJ zY_r&xoe$(HFa5J)mg{SgPA47*hD#zBz5b}z9h5$7eJe7q^X>cM{~eL+nHT1LILmnb zy~igWWyM8Y-=|nE;0!L$KN)Y$Wb#Vfz;74hm5oZT9C+*RUi@FZ`|^`b3Qh;So!$J5 z9hIGe4SX3+UFP`4V4(CXp~}|am-2KEk0-x=Oc&}7T*O_d$J@A4S;<9d1^e{#vlreG zO<5hec$5p3`8Sv+~cP^GHG(#hE|V}(Y@dxr1&^Omv+G)=vbeL!JF<-AV{Kkn_S ze|J(?DQTyaNq_y4k4J-}7S`W8a`1$aXsOzQ&boI6QbNh{hf`Z581DtBmbu)Bp2B?T z!8gU9FTdC2wO&Z{aQo`hCw3@g{^!y=2A_pIYwJb3`6qZVe1HBwnpN(COS&z?{D7vP z&W3L^lrAk^&%Su}zhj(d1T3B(w)4t-?=Vqg@#~9UDjQ$2zj=Mx_E=(Vsl3Pr*VaZs z7iojwr7J#s=`L=VySYBW!NHB^|E^lj+3HKzou9qh9A`TM??LrchUDc}CO7YkK8 zmx)@;OO+5kr)1O}b*fu1z)Xy@i0dNPgI5Qqn2OBNPYnICvOV^Q>(d716-xZu6eQUG zcIf|oq^+RUHX({%)=gH@#mbiP%01==OU|E5M17#& zt#M163Fm@|o*ZI4&nm(%Rl$p?V zD^mHuk%o=IN*+tTJe#;mNpaFvG5uR1J3Lpj9h!AC;nI=0~AjHn}L zTC!SZu(X(_2#cyRvI+%ged4TQ&pE$h7WWsE+h4i7FNo^8L~yojG&$Ls!eo=MVZn<< zE=$wT#BQAxcu1F>H~xF_!O}VHj5}@Lnsql8DM^Rtok{+v!trEYpw>$1z}{w#B!S)Y z58W_g5?wM&ZK}o#?Uz#)GEEIU(3bXd|DBX|5^q2HAJa@+s($|j|F6Tp=CQvxzkm9_ z6+Z;IghOhM?Fb4Ik~NLFd&TtVDV4LX5)A+K7%!D@Z|_^8HedYYf*5O_1zY!DpLxAV z(Kkq7(KW{}}PH^D(wctv7GnHs5Qck(9FV*~Akb{SSMc*3l7 zw>wp43vrw{`{fGjBkPLN#)T7}Caza53(QrL`nmJ$q*-_DC2e1rls#HGgW-M~>qMUi ziod?q2cEt4e1chFLb>)lPDjC@iw0ho9NC}#+PnM1)}Q^n^1q%oc+}-M3mDi>7W}o) z)Ww;p?&B+)%?WvFHW3a@9vX^GlG7$M^Zn+NakS6nxu9g5A>|SuF{@|e|6U`@=o@@f zCqLz1vRY)KivFI>Msrk77AdP7C_HkKOW4Tv*(P7d|BKZmtVdA^n?-?!=+R19F{otSScajxZQkBuT9d$h8MH$vFWOHDl8Ll zyV!AI!Y;>!>>hnSPfk2o?YCvhhjY`+*lf58)vl_uoII42*t8(iyz%~Xw!P*Z>aRA) z{&8Xtv<|-8=P7VDVB#&gw-PO%jT0^Uof78U$~*UH+LDG)=AVHKrm-i57x_-~=w)^( z`gv|$Z^Y@%ztpdl-LR4rURI?#Yqna8Pjvf&9Jl{39_+E*XLix{(}wV;j^&e#R71~N z@UJVMwY;Q%TbEbcJgzSjp0_%1GMsVQ%Q&s6rRb%po}iF}{hFme>$xn?xEXot6oxA- zWbSO+J9F=$oelTheh2XUdcD4J4`apg*Okuo;k-$?am#cR#jiK^2C|$C{36J3NL0k@ ziT_gm>nX2JnXQv=;H*pIjAQg}TfKHm#kJec%K3%$O@2`c7lb%dK1xb0fA)R))f7|H zr9I!wj<32l^}45no&nR6Nj^WyZ;YtBXQZRjD#k>oJCqnNnQ$#e;4sI&9?V{ zc_mMI|Hrp--1!PG8vkFts(0)~8dJOXXOCLJ+lA*nmBkzsbMI9IFTUq{$0~7~Fzf%F z?T0eOnF3N<9U3OwNsn9niYxSY^y6>O)9!cQcTvCWWVdpi>P;pdrQNL8IzBodG4xj! zb9COOApI!wH&;+7Z)mwT$L43>KU%~n>{ajG=-Rt<=4;`C8^;v>T)B9uZEiyJWrLGO zIv)OYtAr#yLjn%F&RM>soGbU(Bc2AfcZ*d8EsxBdd?c^LDA1b6R_1t+%#4SbmjyQE zHEn2mBrmg0!%D&S{LxVHoOS z)`H9))1*ext;;$6CG4$Se);gLot)6ppzpKr)7K+{m%1v?ud=7f^PnMv%G4UQov z*?RxEp0K%U$>%D^w)@O^^I7NrNZ*?!z<9$(^uAl(sUKRFznvPN(&oj=#Qyp862(J{Pad}nd$o+e^QH8Yomooq7ewbK9&cw?bPf6+ki3-f zo2glEckoX@XX#cnCmx~$_$&U^dr-dVlPuX)TSpD9$l_A_+-<)lgF55*jk zOLs>9IFUN#NUzG@{O41qGC$6K(0HR%sMAHu=ls8a z_UHd=vL9%VU-65>Cu_msUWq%~{?;#@@b_8otAOvnHm^SVQIXdmNKpI@|1Bfqv_HL1 z3NLY5w}{GY)Q`>I=azS1o6qolly8qcH zOl9&#iR32}oa%q&Us>_|r_I+B-+uq||6?WI|LO79&+K*K8n;-KZv{BF1{@Rn=ii|B zwfnaAL94 z1SQVBPVdW4FWcj1IyuC* zy?WWsiFeb*N5QR%o0xnr_p=;sF=)<8HHuvy-J@r9KIXyojFn4zLLE0Y%u0XumgW1p zIZZB`k00t5Q*tAx~Dm@AAYImqj7GrLSb z`|0;j`pX5y4oX{!ygIT`gn7**PgWO21r4^(_Osuv`?0tB?Jf;T_RcKD%%Ujvf+%6* z%hkazS|-TFoZuIzx?=piY36Uf$_K{g3wGYq+b4Iwww9^!rAmfZT72>O{>?RBa!n3K z3q(6v%w?pHNcFnUHa_hTv+-i=!<8zh{P^D4wK90`@O{l6>37l6R!hntR8iE`QnplK zW_j!;r74OmrYu3ctn-tYX0d*K`;ODAtn+|>)XeX`@@e|*MK??xe%tv>Xpt*hC;x-x zr^Ejbg4TDBs7z?A+hT25$rovv`~36wU%pb$Pj7#}0)w(O5t?CibpR@kyBZ}oFSzQ{&6pVrNM7xlnH^R#vHtdfkX zM_e1`G0m=IJ!I--x9Z{ht_Hc9W7(=EiwqoDLmV0<0%mw5OKZq7uDJa!E3yB^_kgmj zPr9#^_N_~Z*t(u6wbb<2IuMEy6-+j9GMphNqcO|vE>O}JyZmFL3rKoLH{ zYeB}bPEvCY=LYs!2z7}rJG9BkEesJ%8YOEjE@CvA06E<&eWM^?WAwXwm8?JrPuPZfARIlF&}gu zKKQdmlZn4)mZWUL?dU>FuG6=V<(phMUAE!irI%|xS1Cz9k1Z~H@Z3mI=hDk(87rD* zFOzf$3Y9wJbehTN+E(j|k1Kfm(h{537y0@exxMj{&?S>I$1cvje^JHZXu96~mv;B> z%(B@1!}|N(`xB485nFw3uV>5M?o{K(v)7V;hdD4l4nKP=bH1Ghn`g-`hbw!TmQIb5 z-oW&P#bQU@q+|SY8+k%xg}d*wm^8HTUT|trn6iAy+npaCh}pBgVMu1>Esz!ezHy>^ zdxgcUJ2$qA#_+#3c@k(PR}f;K$lhP}Gf|jTqIRwl>!cH`Gq+gmeTw(`EfliUB-dL&5& zbEHWL{C@lP_>4{2HS>JFwDHe2{B!?QvS31<&-aShfDDB#H!Pq0{yp=&+M2Y0J!g2N zTpeTkezeb07vVS?AbT_4`1ro8Gw1o_jB}28P5oK7IB}Vc{|2WIq9&|$6>9|4AK$81 zO#JksWLDuRpOST5{&(g!Kzk+E!|n$l7wAqBOFrYTApN}REC zGVg^-huA!{6iGJqf4N1UmGk%i1sU=8LpsC4lG#rzdK|y2?u6O>73`0bUottYn8BaR z^xtWzj-md<_F458(q2mOw9P3v{C@AW-7gFFbAI`!dg|grpEEgUp3jbWQ@p;{q(aNV za3QCD8i(D75~dtQ?jwb!T=Uv1*cQa-H1erfy`Q~pgY~|=&;9KB(@xLd+9b4+LyaZH zvU&f{m;VplTJitM{^0h&#;XR#zN{VYdTSUoSa@|5R~*R@UdYCCXdz3_$w|Bc7hQRo zy)L^d1Um(6Q59r#^tg0k3oEn#I+=+VTqdpLY37@0;Cy}t+vXj;dMs;$U6}%o1YJ(- zR5Y}3NNN=jS~w$#TT(>(k`c#5jVLcB)k}w5wj}CmI<_Sl9B~m86cm~$2m&lVjx0Od zM7C^Xp72n+ku_1v%|hTNLr_P+tO+qnt(v86%%X~3$CM;e*c?1lQd~Alcuz|3zpFVh zaEX2Y&8zV#CwTQYSRSf-u)fjY{x|2%_y1Jd^WW6JT^(`f&#mATo0oBkE|*Tu(Es*# z*4`uDwfV27rMge}tsKg-;a;+b%ljo|7m6xOs}}{|=db=z!rFYJ;^5!BvnH$V@E`ia zoU?pkT)5;)N4LPQc2Olvc1}&-IyhpsoJ&64I=gw5e*f!T^})jb{omHSTC@1s-x#B~^lmNFE8pp1EU18oJzMNTszwd96-V*M<6y@hVMw?eyH!J$I8u`yRNSOTn_o2UM zOZg^z=A3jPaDv*UUXAFJm$k2mEjeW2-P0C$$m8Qtk$DC^vHV>t{)g}0pMB_vd}$89 z?D=(U?%mUH8^l`p?bX^{vZPB4>C=hnn0MJGYC;a{rg8`Nv|)eeKiM zADq}JyhtfkNJ#zt>>7!Mj2m9Oa6k95sw1!c=b;y?>>q?{S(P3yQe+H%{!?}*Q{`nf zp1!MR|L zH>cl@^~`VE^F#JeK5X&Hwl2rU=HQ0-S`Fov-e#xwI=<6lYridgtjGBL$%W%mKSIol z0yl4)l*Tpft^?#Q9UHfkW=E4Ea|Mve) zW&gKHe)9kH$^X?~|DSQh;s1X_$4Ir{$a0n`%1oK2R8p#X~=5*KYl|?CLkUeJiqe?>X=J`tJAb`x?zynJ-v*e9zv!S9{+* z-IMK$&*zHnZELV%zn^?}ef5Of*XHee^YX>Q1*~hYZ#%Q6de>YAo*WT*->N%DOz+Nj z3$UBFa-l=@z266F85kYbe!4gBd~N@_x96(oS0B82diVPsj4$lo*Zh9EIj$kP*p%_} zcI6O>uW99b*YCWaVO#NTm)^X_mvA~_HtWJ@aElb*Kgll_3MSr{P>vJ z?;dX7IY0gK?&zJb&ffjFYo{jbq1z<^qF+BXEZzI<`t|z(9W2}T9%_8Q=jx@^&wM{y zm$7^c+kHCkchW67871usu|O;inW zTzG=raT~|$ySsQi7~hodVc@siyKUDOt6w|~8Vj^v6#FkcUcq1@!uR$h|L!?1wi$xo zZdTp7$alk|>({pXb`SS3e!m}n;3uR10=>f%UNC;ixW0bz)c}SX1_s7keRmJMH~8Lk zhJWq5M_dcIxWpHF-gxaZ{HlY z@ALKU#P@smedBw(u7H8T?!BM+_Sh$Hw{Pyu%ly7~!@K-Fks@E$Zxe}6T*?*rM0eZE zqjrjmZ&gQHFIXUA^o5n7#44ZZ>TRXcokgMIQL3S?-#)+J_xXO=s}Em4c?bpB&1(4l zzQ}ps&#%?)cUOLWS8Mw|fA-t=Yo=e_p6u`QdhgrnOQ-LZFZlNDeeU~>pZ8v@l6!Ua z{N|-^*XPuxzD>XG_l>>mC(~_Rsk!gtEMM;^S+8~O@NVv0u2@2aejDyTZv7&f7#wI-}{$eKB|1L=*gCO;b*Sf)jOZU#HhrqyrE@1BkO{ovl$-1gkh_ltKwi`|=V{CM$3f6HUPUvB&G`M%|+ z+c){vR?c0w_}RDjem6_EeV_GMFP>-LySLFwnPR`MKHs}9zjn*}Jzw_iEz44CkUhh& z^i$e}>eF|Z-}}Aqe(fH+V>P#a-F~`5)nt3^1NQ2o_3KtxP1|b{ns)p0bk@B^yR>6= z$;Or*-d()+-Py8l?aM3gZhm%e@6P)+CJBs8UUH$Fy<-I8@ zEzPfey2fAZ_pGw+%&+Q6SKqTvpMB-og#*cXCiXj6E59c>|1>! z>d-fa7m_xc_zT;M9&?!&5#Xp?+n%XOyZyB2sZF5b5HyUF4+Z;x+}t(=wn{qpX; z*Y1W#-1}W6x4u?v*3CDc7Tu1!b@hR~pX1xFujPH;wnc0^;a|Apch=l*F*&WbZkINe zU*Grb*V=h2FHg^%W7P2M+}$%$(bm%*uAcGY)@-%VeQ#y+i}ya;^KI5tw;6Kh_kF*8 zhcSm|7emDD`QaBY@B0yO@9nu`elNt%e*5sH@ z&ocYH_YK2ZBSvd;rO5KqH{bGJm#p1+F28u^ld?$)Oh0a}&$}DPyK!grO+GKir&n3m z@B3bLQ#T=O+m@B>nUCEujsV4XBUZdsLR>d|h_hs6- zmH9&6wL7!#m*0C;y1Ob`{OqK+%X633+^}W%l~G%A_wKvzC7GXZ-+O!K*UQW0^X2pc z$yxe!!%YD1ouC+UT?`z-Z+ZOOIc=2-Cx3!<=$*s;> z_~LiT>$7s_9zT9p_2r$iGSB@yme89k7^k@}y}q+LHu-X{(~8^gcYX7Z;??bnJHOVp zTI=}ko16J=rj_@F-KuS0@b*Ih1LOSCR{v9uzZSldo0Vm|N-ltbLBjDB0|Sq$35Oz!fWxdz!%|s#w0_ErrLH&%?|t(_-onBt^UDR7#D!_ur(wxD=4`*GBKL? zFfz^a5nB24NlQh@m%k#%Lgkj-vRPF%%kbBful6Ay9iN&=Nir}nFusE5Wd7YA^nCHf zx4-8F-?lw(`R2d+)>m?>$-mvd$$$Jm{a^0(uoU~1Gu{8CJpQ%WKmNw!Uq6q(`@YBc z$3y#tKbI#K95XY2$K?J<{ftslhlhu!NVRR;zQs4+F8HPR)qlFYUflcHDqrWDR`jP& zc)eKGs_%UD>2>p6FZb=|-E^V+FRN)~#;5(;)Bdl!uRhy;ecQAi{V!Fo(*C<&dbMt^ z!OPmn>Kk(By28?eQVKuXee?MLJf&t$bLT`e-Y8k;t8vE^VZ9X8}DpBG=;qMjpMj|T;}5T@Uu2;#s#`0duvjV%wHdD z;=7Z-C@REZPj}p%Ph7v3zHfY6Txu+6^Z3BLM8Ok$ceiEeMzy=&PEPIdMEJW-#nzIN-4ugm}BYFVCh zp0jVAR9x&_@v2L`PnjA#_~&SKI9^e>)L|LKl&CSoW2Q!*!=f1n)I5S#r7&5FDD31& z(f&83&xw^wl`DvA|JfO84-T|yhRvK9(i_b}(|;B^Em$PO!L=vIRcTT0 z0m1ObgvIuU|IEMtKYRQ4|2O_W{%Zfae*M4WxBqSbUjLz<{lmZW|NDJ}Y)$0W#I3ST zYnkF{#31ymKmXz%`}mjt?f=SusjvU>`QQ03_gW-6CmA|3O!EFFd;InLe-9^I=+HgL zcp}iD%ZRDl{cBx!^V}se->euXEqYu3bqy<9gPVOy*vI>Y_fa>dMaCvj4DsPS!U2Um`Y^ zmgy7LdltQ`yRbzfafbc0?e>=p1d}`&?Y@1Q>U|)7!gT(ZN-6z+^=FFOe{?ULFjK)K zr}%Gmb8jQ#4TXQpFFxy)`Cupf;7*%C#ymmyO_~=>mliYEPx9^lAM=uhEB=X#V%3GV zV_S;MdC%WYGwZT6_Gn9K@o>@JUpuEhYbnEX7K>Tmzxc&I+@teafIa7h`TS!A8Lwym zs=s}$!T#B-!Wr)x-l_b}5MJFoW9L7e_`GzUqpGa}7gCZ}EDUlCI&tUYnJm?>ZCh@9 zth+D8|83HPyORx4*&mm`SmgF1kd-y!#q^5mF5^(2z85b|{-#=UF&Ou#WvFLO{@U&; zcZhiopR8J@k33IZ{D&XhKN6m*R8M(vr`h9S*>b_HKJTYzvsTNj7wdYPu-Fgx?7c5#St>_~B>hw01l`ZTRWq~JeXRVtX zm0PiJtH0sQ^Y81ot*&~OJ?B5m{CoeWUa$IT#`x3oLyz3E&Y1am>z!u{HZ`m6ES~+! z{MF-eghmeb1C@>DLodW$fPl znYE0!;$rLEsr!ET=R`H`%{;$j_qhwF?>}1bqN06UxXTi`j6G8V&1P&iWj9|{@F6mB zVg0J#_XMr$zjvI!X!_dyN9KJ0Pwu65Gb*g-N-7+(*DH^G`DOc`i(!VX_dnhK7WKcp z{CEB3U45RBnM>c_I-axO*h=erX^ju^G+)l${_x(<&Bxv9Rp)<-e0Sj7f)s{di85y& ze)KAykX0yKXV%vfvS#IzHVgh64TVQ`^Gtac>YdK+-hTA9Pt@y&lMl(Z9-nhgPDvz~ zv!}~o?TaM66Ki*0yxSR{k^c45aVf`DZs+`bOaj!?IyC;Yr=Q<9e`d1hl30bm7B|Eg z7fQxTelC;K_kDY##8Y-=#*W`|3pQCqRX;ax+NUqX7)KY1}>P) zcYVs5ZwVdZ;!XeOJv_hbR@dw8Lh722I~7iDec5{G#M0FXmy6rt)OpU%`z>`eBALm2 zw|YzdEUDBUvx!+pZus0iYV>y5_KUTAUc8^yzq$D%@$>Dzl%n6C7cNV%PKdA#{T=ODpOWn*R{?f;N-6vFS~y}^*GV??dkmAQ8Kz`S9DIx%iHwo zbH;kDw--xA?K)rTw3}?)+_7iDM6>@nz7^)%=h@6y^f@f&3D4*M^6OSkky?3j>a{mjG|N5ye7t57Hb1`Bga}#XhRGj3{H03SY^M8kejc9O zn6~+jO1^>rwhJ5gS@1bAUfVzaM}2hV_DxgSpH|$H2+*u}+;jUrU+AZ~36HLZmfexw z8XDFsCHyCT_Pffzhu_t&|L?a@M`-! zn|o{3x<$XH87{kBU;9{--Rk0#-g(MwLndr;=ZSkE563Po!wsB!o1|} zyr+uWEkb z-nA=g$!b&1IbIE66y(xZMFIi^3 zIdNc3@gEfx5Nv1mAf<#a4;M&0}^)Kmn+Sa~(I&P`$_ho;p8^3(&@cjFB zjgJvOV};t>w#z8>#=Jjg-?Vs5e%;C3kiu`4>n@8Wf8&tXE3+_ib$+PbYSi|$<;jND zqlSl)A1h^VUb=pHAO{z7`Si;hR=pN*G=I*cmhd}5nE94D4^!CFvw?1%UXx#1Ic3XV zyb~05#$={JX3{PhM{(&ZZYsQY{r4Yc^C*`NVEo5s>%-q1@5g?@+4D+57>|)f{@Rba zGg*z24eRgKElTOLh1ox=kH^lmHV!LZ@Y9h{77F<$(i6Szn*%!`Y3rk$_Tq6 z!2CX3NOR^*vt2@)zPHBg`tdqyO46-@0~;>1L_D(ImhKu{+x}4c;hTiqkN2Nj|KSg~ zwov}_)#t}*qZ7GK9XYknJd#Jq_lDiGtZJ`gd=Z&{*!3<4IhD@6p6l{)zGc3mv5=~W z%L>go5;sIxIxam3oN(75R9wbFWulLm>eHiXpEm5-lXS{jBQDP=#4zb-`*CGyY3l<= zALsa(ipVkjIdk=`hGA+jpV(8SX_rL*D7mvykj^wveCRi`CcgW%M8ARqyL#J}G~!GjGeG^YIPlm!~{r zdQp0_^WX>VE&Kaq`r9nKM6K=Sd@&0NpTyVmc&g7G<1{5rjm<&VS`PkIIc{TdZMD&t zi|Y=hyt-O8#k@)_O+o0x&R6E*Vq%lHBA#4%Im;-qJ*8@LPOnhnee7|3SJz2viCl@oz0T7o>Zt5It|B>mB5!2Xy{@1GQ&v1# z7%p7#Y|)R)hP)avX00|yG}3PQdfW@&D#*oc${YJl!<*@_mATAz)1Ep0s(+(dTB&`Kx|%mgIs@hDUnUv>M(o+P_*d zF8$p0SEtu>`c2$lq}>qWa;k3LXNEHSi^iAUSe*}5f7KZHBPqs{zmNUHk#p)-neXyh zd+m7Nf8Mz9{dDG#@`JZ!FBmr}KT7ANiWy_>!OcF1~~%&oYd-_+A+K%$dAJ_EO2@ zH6@cZm$EK6#O26gG-HWSyMz9kI)NZ5>*qV|-gmB-{JhKY8ds*~`^o!i#d}0VWDZ`- z(6mu_&Ay2Dpy$rFY)`)Udm7m(@w{$6bNPdOT2;#Xc^4`iCsg?F`Z#%?Is2xQA1BQZ zlua)vYhEHb(|?b_w@pu9FXK2k#p=E_%M8O5YuV$>exHmI4o>^TC$gb1$YYAry>^q0 zHx8TT>^&oS;@tCEqA~@%*uA#*+!x_kK)#t-to*)jQ2! zO8DAp0!~}4{*+K~iL7r-@8a;u?+-MTi~7FV^yuPR&E+fG zUax#1^~l-UezwHiLX$*ao9Fu~ZDgB1KL5~A(VO?oFwj~~+2Huz#h(xL$-lXj&ht)i z%8gGZN2`AAJb$ISaR#3wVw`0a(y zFC?QCP3n2J#~wGxIeg<~@SDkA`dm>$uYYh%)L)_|b=fVD^^WD1iPN9XnsL=qH0{IB zfQPn$UL7@`i_bp%`PCvdB!tJ{v$TnCu*t(~t0MmJ&GXt@qQ&XAC!--KR!Y9$K>wl3%L=lj=ddo+}r<>bta zl(bO6(7<;Z@9*7Dzu?U5r=pO>{v*%oSekJjzqQU;m$R)AmyMp6M)PdjxT4rcY++y8 zMvqm~8Whe%Yn&~e&DFE*-0`Z&*ZcXex``ZnHJjP!qozjthsFD1)D|V2(%66W_^I`E zvKIs1o!s%F_qO7pX>$B~T1>ZOnlh*6n5cS{D>?bxcyYtwd~V0e)_wfi0$&oDCkHr5 zE%2PhlMpOFy%d@Y%4d2SdeJ-PI=e~4}+uLgXhzJ~*)qdd7ixw?e zxxMc;tUO^i|DfB_XL_##Z`Lj3Xev(fXz#M0r%D&~DYLD5e(tKI2M+4*d=e%C4vahd~MKt~7<|&(}YKQH!dHrRd zY{(tm*`|+zJc}G`mmK;Uem~P=WlvItK*MQmkFeZNS29e*C%=#mJo`;#y4=SHGAlLj zB$>~@X1y)v!=p3pX)k%37pvA~xfECZIk~j$%;9NTjR&vBTsyUC^>R;9^@gK)u@8z? zzT-RC%OiVnUWk!Qw&aaXXRNi({x{X-i`GXtv98oSJaN5Z!) znExj3?hjbpx@ttu|&Zl=9iXSeV$t-y0;&$!IGd>ni=g1gz zbabrh=;-*HkW=eCL1;RY*9?PaEsrOJXUMOY61}47Y+0w#<;UQD;nNm@P9~`rb2w+u z=Iuy{cHbU6+3vWxc<_t|4hPIc1$hDkM3$KvN6ljOSzYwzMX8wRb)BEPKK#%ruT;@6 zNepbC+V{e}s&uW)E|X7{ZAQtK9R4-SKIqTjP!c%4e)@)t~#gUEl0i`ONAW?GaCQrc5qh zd9o+pRjl6GdB2MlUsQo$yJO#hgEtnQZf`#FbhDyQ)NH@6A4{)uN^8lSh;U@>7IbvX z_1UhWbLiq>Hfgt6R=5 zSsp7JxyrR-+kGwJn{gg%OoU8zUA!e0d`#1LXEy1&V8vSRvQ15Iir0$H5ISS*5gJwg zT5g;Erk=p0nHQ`My4I0a?T%@A2`ez(#q^?lqNjk%A99+D*E?a z%=BMxDLntIXSyZREIvNNr6rnnRZS%)j~o7J7&napJ??ymjxP1okW z`l8Qg6Hg^7GVHqHpr(KJ_ul&cq98+FJC&VUOBbA&tq}4m;itagZ{^oo%UG3vcRhHt zdg9^WLX*fDvp2rTP$@_h%s*VmDQ>@@?>0~3-CwePU%j1|AD-DbYv#P5=F6AT$^v>tKM;e+RJqwZZjV&$gsB+nP;(X*RtsJ_9_3`-?HyN z@ za|KOVs_7LpWvPP0^Uju z962%RQY-s9Z6TlfaLFGJKK^;kGLxNk$(z)cnN=1<9GDc}wVLBcq_$MegY8ML4L@(3zv1fQ z;1lm<-7;p&EoWBjm@4=1lJ!*9HWt6HO3Pk(9XcDkE&81Lol0K+vj&Z?94eDGF)GQe zNHo~Hn|tr}=SQzR5m#Omw&o>sfa}Z+p1VU9onCPGS14o&=Zbg&N*Ws+>#nIt5=d9axaOsPVe!lyDd6p3dqb zj*!cq&rjc5H#P@ceVm`hZGKopKG85N5eyF@7Ti1B6+Kos?K`)kb6W^&E zo|L8|r@X`BxAHcR6L)O#mMmy1dX!!pu`1+)UZ>|V%U&@Z^<_$j(invUjvsmy%9my= zqA=l52#=VUtZK)$g)8`KdcNh9N1yj_+A3mq{bSYEawaK;4Jv{&_U*db!q8fCyxU7a zM9xOj;l`@9*I#lv{N!tX_U?9wiR3G-^n*L~`0eK%K6+^J7DvZ3E+vOmq}&8|Y$tM_FzF zSjZF>{Knwgp6Mc6QX^8Yb~*~@^zu$znzrDUho?tk!lID8;Qcp+maJd-CZ$`C>*Ae2 zv&geHJ5o84%Vl5RJlqi~64JixW5w;DH9_A4Yy*z%(6E}fuX>5s3yY~S8Z7F@icL%3 zUJ_sYz&$`TcG+5;^lJyiudm&!>$tnF;Cjl>Tg}Q&PRzTeYos2VAX393I8SN9oRu3| zUd_%~Jg>j-ru#d`&;Bxg&tKPnX+Qq5K)T@Hbv`M1Z)bnaFRzaKuV3}ua%RN5hK(LN zakskOUhuo#rf_3NjnE?QW5@R{*DsF$QoR58{l`5T=R-}->OEH2k@KQGy^bkv@{9}4 z<$u;`9aAy<*7Gm=gdVeR|NR?(yZG~!)zU=uzv*#-cFA0v=IdejX zb5e8VpH_DL$g_EqJ+|_Fic#bcXm>HcpL+50Oq-rLE7ey&JsSV)1;mCv2PQz{K6AirgpoYhzMRgzRIh>GFVksGwDyH zMVi)T=hbWXIZa)YHYd5}xX)Ih#mO(GEPHKHJa^X*<|n3e#A_4(Uw*Y*{PsIbgIud$ zp0A_ie>_YrW{O1I2QIxmy{6?pQ!Y2EX*w28+~dpk^OW&F#3?tk*% z^+#^!?yvlFZgz-sTlm-eY!g%(i%zV6plE!%?(vs8{>?9^Ke_ihMg7JicH#A_`a?P{ zb%po|1*NhDK3bQgm9o5yOD^@vyQEhJiEDm+6L@kl%vJD9punQX=dF_7e(qd;(WIb{ zLx0Kc^(AgP3PwKh^R=&V@L#K6^@Gps-V0eD_x|%%^Zt2Cew`MW|MN=bpHSC`d(-;& zviNS;>-;$;O?-_Ox9II}a`NZT6-xEB?@v5DRU@EG+CVT(6#ZtWo=u@v*oqvth=+;mHnGk z*7dRcYf05hdt1Jx$x}AmS?F!}exu0oV&Tm13!ik=Pu&0bzWX1;```ZVR^xtjHnYPd z@Ve0XKlgt;?SE3ga@w&kH|$^ktavx+N%7g=Z5aX1wv zaT)U%EHX%wEPT**&8FgFv%z65#%6;VpM{hoK0fw1w(;>XW#!J!j%6GP2b+$ZFp@w1 zUE;tY&V4&R{g?a9cIV`mz;8#oWqry#{>y3F*WB2^BCw!$-Ret42io5|RTs>&-|79l z-`m@ZTzg7CJNkuqer7hP<8Wqt*!BEmRc$)=_j_x1eR{kh zMs2yTq^sNR=5K{Q|D{^K?(JG1AGUgZ*XrD`pIQ6)ca?o+`?meftO+?<9LHXXO2#km zYd)MlYiX$Q-;IIo9BNa2g8s_gT$QJ0{OkGGS--lpKJuQ}rzD`>F?)ZwwDtCrDwE33 z?C(0YKl;jZJLU%_bzK^(<=*d~6aDvdZ1wVOGaELaa#WjKooT&5==$MxTBcUjG6{cN zrZKB@o!6MW+4Z=%wR_0hQ|~8#wy#|Jb8gW_HjT16e;37b|JJuPbvVsf-#2~ZySiOl!pV;FJq2x?CYAR&rV@>lX>4zW*0tjPO1Nc z*Vj2tB(0ylkLz%EL-h4|lh4Q9duJl2=D1>gFpu%AW<$qokuysiS-0ov?2P#nzH*E4 z4l9+XAfcscL7RBzYqvOeR}T-1D{IX8bKC9u zOz$=2$2D=vGriSwFf1$(js56jgxwW9a8>`mQg zZ#NoDvYmeLt+bla{ue(LByL2kIHFfjw&PLj^O~zs%XvLEPPn!s=73KVTaV>ke!e?1 z&*^@BdG)QI*i%&}FV3|*9xYQY%$K`$cjc93O8(1k{8O_w$hX&(&OLR$Fyv#6p`51W z%z0in9Gpwt%%qB63kCXYJ@IOH{F3$E7p7&uQ3*b?bLER$cl^3`FEYEX9aQOiKTB0{ z$zwr<30t;?%_$D$@L3^Ke&M-n(qh)uGPx%zQze*}D7>uLz-VK>=U!Ya;5{{Ud`xR<<39f5UDGK&{GO=~R$7JJ3p%ZV~ z7F|;iE1Ig!Ccncnyd=2dcf!ZmkE|LTa?Mvum>`~WUz1Uj0l!f0giQ%Kv ztD^`1++KL@_&;NJdmX-niw!?JgZ@t8k-WF~5p(HL>vr)tI|Y%f5~)1t$nH^J}KdN0ff?TQKVs>n)qe=7Po!F1HEgop3*{ z^1?1$aqhCjJWsceGyj;*VEOP-=!4;ziJfIjTGc14F8(NyqZca?+bdKi|9Ugq+kNW~ zL-k-%AzFE8gqz{hBd* zn^xOJsYE4TW_EdR(dn0+rv{kZ3VB*nrVygBy=&#yZ7H%d1C9tK`T1V22rkb&YIE|G zDSPL(g-@-0(-m7*EJ%BjE5nnoE}5UmE7Ih=XE5-ObMLrUcln8cubc~UeGwt@;xBJ`0>i!fyJbj-%XXoo@waeS~S`{nj zIk9(V7%w=t^4q%yAwCn1h<$z0c(htQ%XY(U){}f{b7JLvLlO)odk^1H@f-_3=Wx#5o6`dREY787Jk^kzLN$otRZ#b#T?UFEn=@ovA>^F^k= zW|r@|^M2F1+cq18Z>`;StH$E{nb}ag zTiT9n&gKTSI$0)}SC8f&+0Hpho!j!5gqBoCRzRr0!bOdyYg?3(<;(LHP6#u8t9kSG zqJJy??oI5r_L109ek*O&B4=TViXEHhT9vKc`ub9Ni$ZH#nTN5#85ZWWZk;f1t}U`( z?>*(Na+mLYZ*5?ak-VH~#mryDt8^B=crP;Tcss{bk>bl$j1xqry>O7qQ0`REow|0$ zP19my-ieLJD|5wGi_ZBF5HNdr^@4?Go*fH#|LpCT=ndVx^K0~9^|NK}dTz1M*s$Zt zUuPkS`}ZWCo6hIla-ws=l^pFPO9!>G?{jC_%v{{hmzQ;F&H3{u)+Ho`+)lAHxtMq$ zjZbEJxWa_|(%peIroGh}iKo3Eo}BsP{+#3Hnv-m%to>X5_MW%vRZi*0*H6VBxwQDw z-%sobX9JfXTp@Pv)LMaBo?VgL(Hf#VL^pW0^woGeDl76g%bYbSTwEm7G%01~KKYH; zy>pW1J?d|Mw&2YiMT^`E1}^s$u5vo>Jo7LwVUxkD5dO?37cQ^9a{Td)`bAgb7nIue zA8oMYllW9vx7qpUh5wKLKihv!_Q6Vry7SZj>CWWoSQY;3$NbsnaVBDhE{=5F=dm)x2 z`@3&lcBg-l{JO6`|IR=E)7$jF@F@IgIPOr^+|jM?QT3nD zPXEi;IH$3zzl5(T{FhTmiQI$#$xqiL^ZZ{X#lxVW=$-ycg;mNWq3%HC^a=8B+8O^a z{!z8ybI)1B%ex^rpi(WN+UbJA(W^@`AM}S9n1qBiZzz)DNHUN(WPgf{q3-a%`46`U zAE*`l-*=Sj)8YT$|1JM}{#X6v$N$%V%9t$@VJ{od$tcP%5+HHVH6;F5?3J$luY^HfsY4zq`pd)-QrPiIP{fpe@Qu|#-Jqc&!EgrNA zp13gcB$K=$^9~II>#K|c{9Y|kSBwHFZZk+4pG(q89vxP{Yqt&Ya zn;ieTXtg-}?`=4`@6aJRPg$odrxb?{kH&v@?4R_1{eSzFbo`=OtP(DZ6m}l5zgeQ3 zEK+xMve%rd4Z%ExfhXnPH2x9ax=U0Jm1V~RnX#b{B0(~m4?%dAsn9`JxWN^ zVAfO;+|FX4uvzeg)0CH%jDiBnJjQGuyHmI1uA9wprIUptAjHFE#g79iU2Zq##H3B^ zNlHqp^R>Fh$06*?GT{)b(f1P%-Db>~F=LKF3%6mxsa2~E%H>KW6>>~+W6oSQ;WR_9 z;!TzR{c8;CU;e+l*+|IA?f(-IciTly{1+40{j2-sE6Pr4n7M78u+HXSDPsrQjQ)%- zq5-cih4OEbP$-jsyTIE*~cC!_kz9eh2Sz@G^;LI_U4TmJ?sHGw|P+MLWL>7%+1ChsTr& ziZh(TG8DBuI)#PTR6M`W?fp0V-dUzAyx1A{b7ML#CLzRlb9uR?R$xhXfS8azK93Fcg4y>^ql+L=c( zN~(%1o{Z1!k{ZgtS}QVL-qQT&#p0=6UJC9XwI_XE zdW`d(rMs^!((iuUQS*M`{D7*D?lO}ERN7KzWw<#r)_&-yn32IWu`@H1%j;{c+|{IOKvLHHr|W4cLF2Yq-o zc{EOTFnA@d)tk%8wpn7@gheI|`*V(%t7eMSJ!C#))sSG8aZuq7lb9MO-)Xxm${`}Y zVO)g@Y7@+6cnXPJm?0@7)wr;iG0o3}MZi#mT_`bAKukT$MPRBiM{LHQYL*y=zmM1? z7EBYgeWxBP;nJymW$4+6632NL*8y$;8><>DoFfl~^WmnL#*=fw=&lGUu!~MgTNry5WeJ`XnvgPCUCHMZPdkV08Y{&T$DWzGn}s=@`R8WX-pEwBU@KGIUnf-`#wA^gvKA#wTBX>vXvK__ zdwK!xmsC<+PSm}~jh%JZ<&dYIK$3%}u*>owAJ4BRW;&`&uvR$5&3TH$QzD3kStY2^ zz(Oze-~R=l@2WIRC^_f*;zyccXN|GX{G&}@e=b+d*wZN8$;rs9*m-jA!pa4lJ-zGx zta;+0>0cP{^Y?_-!&qmh&IbyNZc+EU(WU8BUCsRY#B5{Q?%q|b^-)MJHYfcng>}Tha=qdf9 zN8}YF+rvBZ1ryBJuCpm=q#pjgOeujyoyByMPJ%EW$MwHFJQFh68xuQ>9B*cDzk2$> zv`x9q>!(WQw%`X!%n3mf&kR|!cN+A>D+zQs`?mEMACFMCHoQ35LXhhcvxB0Ff^8>H zm&URduV5ETQ)ht(rjBh2|C~e*>@PY#r()8pT$wF99G)noF!)8NvYbfaWn~alVtL@^ zBCTq0wck6+Aj#klV?)wqEw!GbLc#{&92_cvhDyRRb96dF3)C7;GIt)i@VLb}h`FUZ zT4v(~gDt@xQkPzvbWYmIVA{!@@L-)lr-z`c_->J-SF|}b1QmL@t}!Kd=*n;WGxzz+ zTXUugIL1tv{&vQSSsIF*i_}US#he};oa8f6Cn@29M1m!!fQ5(sDrXL_fQy`_CWkG& zS_GbOcItWQt&Etg^nQnpQVOf2-NjH3SD6fj3F|^%wivmzbqHT_%2~8%u3$))3gb7u(0>_kXg_wm^J^Xv&U%>~(%$6(dOrKxGKe!Pg>7z9D_=ZRszY7hE-S=s2S3mz*rY9?181 z#eud{2b`Ug_bj;bDCh6;#2YvIr36A^qgnhsCiC+Azt2wZtm;Em0UL$hQubXu7E*i#PVxU{CO z?9k_YwM6M{*@3l=5vv2F`8!wX&=@0_I)f-g(fURUl)5g4)t00vA1QcDd>_ zgkTp&b;PkYf`KHm^5i($Mo47Ui(jJ;#X>KiCWgv9Cxy9Ld5(D876Vw8K*X` zZ0dG;aI{xsi>c#7R1%+Z>40FsD}#Fsiqp^4Z}|1_Qjd?%;kk!pKX&^)ntdtfNkmSNlXSa69`o!> zdGSJ5r#l~{wrB??96XfkB6{A~Hs;HvsBe`Y_HBIpQ(tBWtM`r~Z5<861B(-VOXc$% zy1E=6IB?}nYD)Ypm6PgjP&L7qH(h-tv+seK=X7>D#F`m6IjZnZQL?f-@NMQdjoJ-Y zT>QzGQ)`qP5d(kGrKBf22oOp{V%`;>bqj_A+YZ4VKHFx-%bnGvAd*M>M#~-5_ zm&SiLvb!YTEU}ruuB7>YO8xYo`x*}(wg2$7J}>>B*?gz0ISCzptNK2Ez18D#$UG_k zg=TzM#{vJjH7cH;dxQ4M@vZ+FKlNwKPL7|h|sb?mm(n|!uKzpu>O-#SZ0geQ&P;0S-q ziakpgCGhy1Uv4$OOLd_OyG+lQ9cPN}RjJEuGl+aVEi=mZ;WEV!^To21ozrim@3Yd7 z>DqYJ+0ub?#*Gd&)kblh=V#NNX{iM$i`xo@^9WC!5GT|rzs`+IS@qHX~mX8~a^joEU`yO)s6qxH$WIZMP7K0jVfT^DL zly61T!cNYceCFe#rfh?RJSOiy-*A6Zhw?1^NPVLh^O7{U?r1GHRHWmE^pX^>^_Gw&UmYFaK+Yl z*45P-K?|17`+PYuUyiG$dPb3wgjWnNd!a&==8v#TtX@m|3ZCkHoomQnWBYu)(4sRv ztxI;?3t{!)%{Vnh?-Ac5CRMhYBWI5uWY2h`kP+H6ZNodob;_GUvg#wB+kZ6upWk_f ztwy2zn6V7=l9@06Z@iY0U~pLV2G4{u{Lk%}xr`4Vd8aHHU-Uz&E@$C~OpdQUl^RWL zIwcM#qD?2x;5O|#W&63I=|Gw!Gw&(a03{g#?+wokH2R86iiC{i6p~WnG;CUpOjfLG zoOs4%%Zl%(vbj3;i>;balj3mAYgf8+ai7JUgvNuDOR{xiUAMowkm07RlC8c}HCp0F ze|pP7r3YtDwWr0DS4l-G7p0u#O{=VF{MOp^wX!n$(*5ds=RB32qA#OX^Kb?VME?7J zeCezS_)&b~Jb}n{ebdA>W{D-V&i3Cp^_H_{y{JOk3ii^aU(P2uJo$6n;cAVM zXq2(T$s6wvzO{T~$t*d?>t^B)lXWcoocD^&mZv+e`mv3{Nr>xEn2UI2?#j5P37&CA zv+DV`Jm+?7d}C67%JA^g>3hp}{5oGV@9>$R+}Y5^vb8jjSR*W6uq>Xbm{ME}Nb z8TnF8Wl?93R{ywnliPU#--B&oo$SK8+RM^=QYS7wlVQxgReP;+)eQY0=LwQ(k0ei< zE6LlKx!g9FxSX%}=cZ8Gvv*C0Bqr;h;m~H7wn3=rt!6?pTja}gMXZcZPnMr{NSqj- zJKJpbvDgfUOjq`|m0Q_VIs~3x`~G#??o+x4!q^VUt=4*Xczx}48-C6g%lFB6%y?`h z&}pO0WOPb_LqS0$N!LwLqveSQPXen0--5i%&5Ob5TefRXj>6662sIs4Yv6yvP z)7n~NFRj^|&-;Df*;64CBa`@iZNXA$Nt={cf!!?ffzLMXxNrDcBm9PeNb8AZFXwYw zxCFTy{*ot@#nfl=eQU5~Y5VncS{A<0z*kV|$((&X4<5hGFtt@bCur|bV7cH{N|3ahMBb@Bk)7`Ex0sbq zbts(NHN9}g*$dX&9Sn|&pAFg2cx{Pqwg2NiO9Ui29FE!vy=C;WduILL|Ja@92balO zMD*`SeSZGrk$l$KIn}3X9v&*&)Vt@8i%4tb3ufIc?Q23?MT3o>+bmU`_|f0oVOi;x z=|{>PLv~J{S|YnQOYt3l=CrH3H>{66>RBkB&T)U)slcOKe(Xvu6#AX~{l~}ab^V8r zbS|Db_0(~GhBX^^icMAhzP|JDA)c+~A-~R7KaSe|>OKFJ$L$8SFFy32%lhy6vFzw| zC-#4uf;ayr?zy)Xf!5v6=jxU)Z5e z=;e!sCk`G4OwCS0cN!06{MhET@Pn3|#(`#L2@$1J|m_i!u+}I6uf<;FWMclz69lf2O>Ql3tUE{*^pAt~Fu8BKh_@|Ah_wwb1*CHll7(4!(!8fB$IPyl>G(MqomsHs$jO+Ukl&O8K z;_9zd+jnOsbK()ff6Rv}e@|Fw>UdXW1!qPc%OlP|t&eRi*#y4Mj5$!Q7vIeecA^e`c@cW1H9;a}AG7 zXI}DfYcAuoR)!G4gY3tj9ZVLgXkwILPMG89v|vv9N1qL9Jm1O}xCXQInB~|A@N#g+ zs|sx4Rk$S5Z+x5O;5lOx#eXxGRJ7zOUcTi513sF`hvw#J#O~@-{Bv-Mk>VlEpiQ}d zvp5xfwGSQI8nW+UR^PUe)>$hIR_$D{h>Ll-f2deN#_7jh7S5F%vNnFlZ&V1#zNlyW ze9fxRe9^n$16h`5gLqynSCNlABRO-I$t1z&rgtLl*fB~TyH%p(wy9_>v(iVIPL3wt zyq#ZiR?On7^ZQ=5PK#?^dt0@O8|gH z4_K>jmvT74;dF-yOZVVz$Rb&sAT9*sOOwn-srlQtt|m&V!wfAM!UI(3=zQ|GxYc z&)>bPR;*m(CwpI_S-fkNR<>|^`Qe92AA`M?ZM0a?5pnpjMA!0FN0LPiE!+%yLPaBv zd|mwHn7d8(?Zz$vrZZz4vC<1vCHW9aR>4 z?$2G8p&sU4P&4Vs7N(jd&u>a-M5ap|V>>Hhxpp@10qHpflX?_Ri#5d`u&|Wz$eCa# z<|6zdhP$whiOnJ*QRU%XhN*K8u4CtNIouv_Y|ZUM7c0AON~hnbxOi|<$(bArY$mMFEmyx z**B@4+bONUO6QBl zyit6D#c_+6%}f*c!cy|OL{pgDySLm9^hg(dTx9e_WasIp3nE2W3g1moGED5{(=}t# z(6QCfT7OF+SAm~Fz&K>7roXkSwUERP1HluA*k<=FN#mTZA^yQH`|*8&jvL&YUnsbI zUp&`5)5*%&%Y)~+);XO`D#@!i?$NEi@!4dR+Qx_7d!o!Z1?Nh&MPvXSFO^P zye{>2iY5P?$~$vfe{q=fIEb7)SM~3{f=|lp75vx2njNLvi}|{HkG5}kW>KA`A8q5_ zef+iJn%OntvRggdOlDm&F;r&$S{p9AEP2Z#v#R)g3AeZxukGCCrEIidQCgNw!J}2H zG&i0QJ@(i`!RE@>LV3@hz3E$KUMX0S$YIaLe=`3{f8q=mj%D8atWWUnZ|#0{`V0RO z%e_ZmiYY|MO#0K7@UbFWLj3HCo8M4-Ue+jI{^qC0pZ~u6R{tM2EQ$K(^XO=izWiMI{C6+s z%C7zTM_+g!+dn3&T-WDX61wVJk{9wC`8b??D(k_*E9Bw)In+vzpE2=k-$pI3_6Fyb|7LZl_AmLv!F=aY{W|gUek_7o4A;z* zFEd2<3i28o3My2!-&%QES!IDpy;g<$y(dK#9Qz$b9#!mi)U;TCLHnlXk!zVsiwsWR zDRf!4rRG>n`_8|q>;ktgyw4~pkzcya>RQR`)?*n`%YHueaZhMDDKce_Lvd|8W064{ z{|_gV&*u%VJEq7ut_blFc+wD5QdG|N^!fjD0*AjE{W+|YcQa6U{VP)eracQvpBGK{ z`{S|yz?m02l3Z#g5`#%uB8WQta;_q|Q$&mVU@ma4VW#<7>B zG3$`(_NtZ=$+ECbrAHi+UANv_?{VS#N7`dl2 za>*69#cF!m;vGv)9a3I-qCs4Ub7%7MD@RqAA3T+&r7wQg9k;E}zrR;gTZe&(JVUs-q@9?CV$e&&@tZDGYv^=kTG3e{t8d#U8>_b#O+EE6ciPsN#UYDU+voEqpZ*=$=3Nvy*(i-) z_1M$XDhDSfoh@fd-}!{!e3O9B@tJKLTb!z2^i969SnFj|m4E3rmLiUTCXtG{*Avet zY(Ju-Yw!P3)1Sdu!}3xl%OB&{_y1WOYA^D?YZ9f*BGa50)!LCG_nzI;X3L%@u0AYo zClm`sRd#((m+$&@`j(D^MiTp5dnV4EUWwriD_&`*N&KGVu!Y-FMdZ_Q0~rbC6`k>y zjtT`Q-dOSXZFQz@Y485p=mp*~<$7H1`5&@dwn?xRzm$1lzoY+vL-8TQe}$b>ng2Xx zTRdY);z`Rto8NvA5nU7R=yBBfwNZeRNT9oMxO2apjo*gTi={XO|E-qmk3Rm5|I^MY z>s`B8c<H$0%e#bDaQKE`hb%*OYFO;+{N2w4^& z82I*;(an1d7dBg8u4L&ke*AFmfB!nMB#YAf($Nom0}U5(Heab#byWDw%6#Fk>GP)( z)Dv!<&{}pvXyp+mHL({3{n0i#GbZG`TTtcku`Bh#JZ+tHxp-W?ENVbxRc({@wnJPk)vm(V+H8*V;zKFC+8;3)UUbwh)^=J!2L z6N;2oKKTWdHO5N2CC?S5UkAeh z{4Az4g*hGC7pL0yH2V6^;QaGR|K7u+l7IXQPbx^%dvb6tKJw^GU$)Gb4~)HrQ*TMF znznG#uZX*InFH&i<$^RF(|t^uL?cqn-rekez1E%UnZqU*i@IG}Iz696_qF}om(IEP zgCpCoiB3{CI}RF{v6dLrvHUR+JU_AJB>U%yNmml0&OXSyY3dUs@w|D3`{GNw@hNxa z=T9;#s{7%4V*Rqc=@YILI&=$bYA*1V78ncBp9)+K` z=X{pg+{buAwRio&nUymhINC{scy7NnjVUHUo>!i&m9an1^}X=6Hu)L-mRa&5<)Mme zTZBbqq`lLWrV5{D>gkzvUgUeI{rse5S7PD>_!=)BF*&g|V*Z@_r~O4V4#j4_;%GnfS_{tvNsX?c{5>)g~#)xmhUb8M#Ls?#r^W75s5=#>Zu? z9zVXc3pSoB$`E|?Al_Zx^!z?{4I6Ri5F5m?_avM`B$IvMJ7YDteNK)hkjn? z(qYjq!6tiL-lcX&!YYpUu4_L})toWqlBw&&dunTv4L|aCGo|IKtlsD4*yqes7GD;c zqpfYC`<%J3iqA#SNWdspOg*i@?IAa|>)f0KynDV?A#4(l$jxp~RUvf)*_O7YqSnY(Tr z6Dv#>G0|yiN^Eu@J)!@=f2|6z`ri%Gaa65JnQ}OK|jc% zT~%Xs#fEi)S`rp4JWu>ZY<6wll~-Gt9AoddT;S91y*m@G^XYz@`22Hx^6KzcFAe9) zPI&dG;CJwg87jukC2g*|(jMe#KL#sWu+jBiQ z7Vc8JQ)Tg#e=`isKTV(Sn|fTa%+B!3q{G{|Y%G+5^=#XU--k|}R+-h>dveXWaM|ve zL5?|>Po=MTdu*OcDAT8gE3%06?Kc2%T`7+w`sk3 za>0^OD#7B+9*b^KzGoIq^$=!r}R;K}lyhl)`gw%nADUuksd`h2F)LTsF_$ zs{gv#HK()h`S9+D<$0ZlQ~U3&+0c__-)XVIb4H@(<_&K=9vhcEYiGWceRaczx|>Qe z-kZCP#W_59c-R+JoxkbT!`pq}O^wVHuc_~Oo>aZ&`I(iyoyWVsy{+VFLXo)o>`upz zJR27rT6ELpZ-PSXhK|+NX>QSP-3=2%-b{!xpeec?u zSszmscfQNIoOjvvSf8?xk8I8vQrzKfEREw3g&IAoA>NlJ=sM`}{(gh|{%6L(5?KkMv1bRt_}#);-{iH0|u{z<(t z>pUhYy`r_1OHurgxU^cR0e!=HfB4&0)^6yuzNd@s2MG&)Ai0+r7Np?{Vkx zl6NmZs_HsrPEtrXP}zJgq2_7brA&YG)n~1KbDZK;dfvvT5h_p-ueQPekmOvR%32A5 zLu(J7|F$UJFyc?b@mDO_GTh&HKCx4Ow14KzCXO|B!k>-aCn4^6w5b|5TDCDtPT8W%rs>7GT*fWmT=yF9_q3}#t2}o0 zg^4aWbI4LjC;VF4!tXZwonOE0J*4xasQ)0(p^0%DU2a}Y2vL5Qad~y4(@klu6Cp{D z)UN$7u2yWZUr@K`iROa8seHY=c36d+?tS8MSlzuOZNtyxzwe(*^s6UvPy8aWGd*ZU z!g=P3db72wLr$r^Y+L?p<-7c?Hy`d@-|g~p)sh*ZD`roQW0}0=lfZ0+vvXd3`DL^()9YNVyNjAXv6#h7Ip_RpUBW*Zhk27!{!X}cpFzog%AbGbGG8uesFe4Y z?VU5RQX#r6q$*)g?_G&i7FFKc-(N55D4RO>&B}RkuP>{l7#&!@{=;?EMZdR6r_R6X zzTVO-ZS9s+en#aU+QR8bbV#bh$Y=9Jvp z04=jtfmrX0KF1PNlPfl8$;?{VBjm8!JJNBTd*-!B1s&VeW0yU06vFB@H90=Ddwq(# zO;bs1{+TYBq{9=;KlZ)2wB(7{?LW^poKfV_zBc)Q=-eaaN#Svm8H*S5CG{&E}%y&CRoCo-*3(6RM_I zuYU8x?1sM^JXDmK)l2GDuH!!{Zg+FT$rbwMv-x{oM@skV&FN4-_fJhGF^enHy!FaWZu&g-l9(0Kp>|b~ zg1T0 ze($~J>2T39i*LHy$AD6U2lvlN>U^7$F^yrlNZab(qvib*s{11NBj$bH_vv+w7h({3E>(ri_9eGs(e z{Unc@BHQt5u_VKtMTQ$4Rs|-p*mcBa3U_wg&SYY>vi-GG`M{ww zCl=`+{kwkG#JinSq708Y^E*H3RaFRe>*nu}JMnS7T;i(mS3Ce%4PEbxi4>zCuV zc~-$`R?Z@CwOsMoTc3);f5FX_N%x<2Cr{@03cm7ZIJ)-z+*+Z`z*jX?2ll%UWed8$k)t+@9ZyuXo^gXWd!_oas*2xFkLC6h&5&Mo;nB?L@6LXke3vyhW{86k<8xhC5BFpkFS_G`)&JtL&?xtsAO^A}& z!KS6FiaNJ^n_8ePvvGyli-+4y6^odZw~Aga3f?G^m>FecBzIs||E=B&QU{7%4%=i- zm{c$EkSTDAh=tIeeMxaf)0a!=L~-z#&hQG-`Pt>{GqplbVCe>#sRFF5g}g^*h`xU1 z!BJ=YiAmar`Nn6%p1NzZr85_LOtMov#M!pAAtgvmYMeCd(PR%2OCKVKn}%&CjrWN|talr=f}ER*=9wu|A)jhAi(Mg~ndx=4M>=9#t*_KK>h$LiDT%ddYjkXLz~ zc|~PgQ<_@3QFle!=EAhlytNZULwBvNzV|HZslLnc2MztZPrEi{9&hsMDq_Fy1YKtwi|>Z9hUS6=o>qoXxCep#6GhksH@Y!IC8XT>84Ef5;^89zygoVcn zvTs$+-@H&X+RB@^^#teVu)vdg)$?|4V=gn@XZwijbT9ALQu`ydJ^ItHCHy!n{>9_w zD=U%Du4epBm-27@VV}d^dhoz6Z~cokF~JU}Y|1Cte7O-6btQ5>_l!oxuJ>mjSROex zao@Fo851=V`D!_=e{ITI#jgDNyY<)C%cqszV-cUSu3>@kg)|M#Yc=-_{dRZfHHclU z&I;6<$a{8fquO51-SgWX#NFMiviBo%->%c%-;|hsC2n3U{#b6bI+eX%l@o5O{L|X-@#mY@X`K_6mt6j#bJwVr<^GNnpJf~~n}67Q z&uX{ZUzRgLFX9fH+O|*994Aj-biTIl&~E3nhn6iIDOt@QE_(0j2;?hzp~u*GHP-U| z{e1r-xf2al3C)>|Cu4&DXs_MX!Om?dp?UYtYbE)u3U>m2d1xxkEnu;hm=m{6@Xlk) z$B(ss7geNWK3&8XJn>Xbj*ZTry|exlYa3}CyLC@{ZQ|alk_~gOJ$6{eyVGv&j+%$p z1X?)c71I@yuiq&8bZ<#`tKEIxn;>vVR zkGFy)Muy+vp&_H-iH7io06}dHhYUSg4kNaeDL&^JS)Eo|J+=K+uDIE7&Gb39S1wDp zT|C>vp)G0N?PG7#Rc10My?oQ>S~baH$B$_p{hxzVd!Aixn6uw0#notu(%U_ky|*$; zYw;~TWU}J$>t~NY-1IpbnVKFFpZK6^(~4GK$4V8mhc6;~Sxmidl#1qWd#Q7-=rE6p zjN^wi-)|9rmiF~k*nW?YK6GizU4_4!ZXE7x6o~wjYB=qDUTk0WOQz!+9^5Y6vvQhD zNlV?-d1ZQY9_6izmSjF`r?rvmoUfxq?gX!W8cIxhr*6EPJ=s^x-0|YhH(SdczpVBl@O<*LT{T+S!LY0o-1eMoxU8A*Oc$A(^EL!eW`zyh<)+<2M7Jq z_PL7mKbm(WwDzO+>uk-r?+&{btSPDpxgHq0F+D}3>hXQu;!^MT*OzTMweeNk@@qBf z9tDc0mj#)u-pc!Gul~7*-)1Q3_|A_z_G#Lwpr$1m&qSoAi)?9Rn7F8sTj|J`g;!Fn zU7XEZY%^wUDt7(b61v1Vf%*6EiRFBYPfq{(Wp2^~oufxxo!cv(*nYNrB+>awqd%QP zYRlohf(mAf*n&?m$#E%WwptyGGDy(hz2Tz0QvF5W6?YX@$do3|eP`KaZ%Obz` ztE9$(!=ftF+0J^rTl1+`gjw?7ZjZJDl@&R2PVM&mcx{ab^M=pmpJiUG6Oa|^j&eA~ zb$YeSiK8034>p~VVQF46`$6|**;AtaFZk~ya)0X)eEnwm@n*%_+kF&1zPYF(@uB6i z!o4#eoD~i}anQ6k(O_abR5|&X_r&cEoR=nQSAO{EyeRG;MPnCCg#oUT^lIW z^J;T)^X5KjH|13>Ngphh=lZzv|1yfTVo5C*;p*~l3m1q=pV6jkA$pjTQ}mL3e7C*o zmde%MVjiY*)}@(ob9qb-lsK8>%G|bb)2!JBMjOvebVk3h`zz9ge6zC2K3PTvM<_c*bIfTV(;C4jfkEw!iT7Nn?+u zhAZRNutlC1KBV6}=hGo{r{3**jKI+uK8}8GS=8Nnyi}$&2(#svPh~8*7_~Hd@|uTB z8Xf#on;aY&MOfDtD%qw_QtG|Sc4*$k)oV|=9WwhPb!W4w$iY*Ks;`EHt~gX0Zk(9; zaN7O*&lCHrt)48-T({>{&4Oi@%U(=NTR7v>-Am1t6E>yItNg04PFC^al;fZNuiStB z#;=(i=cOfQ>4n9_^Xxpy^|46EI#De%{o}+BX$QCG{Bv0rciYY_y!1)&twS^U3g&$M zZE2}^uIyU=2g?hyB6au9VXwQW`?t=AE$y9;%^WH7JO4JBr7rJ3_juODo0}Lt%dTDS zJO3@%RI7LE#3r*@lKqjS@Hpt6c&&%V(@S z-zFJZx_G(koxtulx4d`G+RpiW{nytUTM_~lUmhx*`6Q@Q{KE^ay>BkLt)AsML7=KW zrKLlYbBo_2l@04P7GKQS(EWMmHr1%4WIh$s&g%31T(T3nV@iu{0@s{9{Bh-<3+lVv zpU5>HUGBW{=z1ny4-Y-9>a)z{oM(=$s`AN7N^uA?az1O^Je;Nzollt36)cG%Gq1Ep=h_ zV&w@FJ!ZE|@_sAxBj)1qU0>b`d8VYl)#*~RQ*8+D&) zvg4$LeT&quRa|@^@?HL%=cBp@3BOcXRxw|-)H!=AcAx{{G#!kdrAv{qTZwW>>2MZufI3fiMMy%Vx0c= zC;L^#HwzUmirqNSz2Th#m)EKD67w!C6XrK~do!Y#XHi(R?=0=V0hXI{B{po>kgzxK zS=h>Bue_A*s$W>O?w78ncw{VNWT*1Jnk35z7o{_XLdgw93W7UZd3t0{E<7k6mE$vK z-jUB9E+P|N-Kh_j=!uFj7X9_w^i%E?mo3T5zUcjbTUKJcaF0f;yTv-MK;GDcf>R1N zq#M5Yv0YwqdFhumud3K(&hJvMyChh^#^ig&NUMheE!86TXx=V%5@dZbEY~5!b zeC^k{AT9Y7lWzqo|J)@X#g`_&_72M#o)e6d7HLH$JBn#aTI`(R-yhvqWosK^X!(1; zp4G-B627@fXHM^Yd~UCC#rDmPh4ZY=BpkoAx8j`6TEY2e{q9bkt`j^%YkMB!?{lv& zH|MUhnRwXqlGl>*iN{jq1J&E(X75aAyKu^iTPjdX^^$XFh;n_`-c`F^`7g{lW>t3P z>}F-V8&1Vbbjy9Sh6t^E)Xu#dC)ocI*rmoG7s7U-OTA{+p6g zUF_yBWfQEM=Tx^Jn=rw#Nj0!8LxN{^X2uiVRk9cE818ody7bkDgA*G0p8n%lP}sKY zITsgio|8u9)D1hcRClxIS?(6Qy>K~KO;qMHrNGdsmadO%j(TjEieB1MYnGZU$A; z!skd`y?^FiK6By$nah0zMjX>3(suvZ->_fz)7f>epKQ}Hm{Yt{d}3u>C+dvBo5n3xJ{NbJj>Gk@uJT?-xJlR z?(ex@mBG0ENREUPjY@h3v{c#qBcus-4Zpp&7aOLrL{v*H{aos}fe6?`G_S9Csz`s}k5X-(xgv#RwV^S(@tl50ZA))T7#Zk_dO zBP;uH-qSPRzf$|;Ez|Vfz{>Z6$CDQAh|e3g9JEqpSgymb`t?@O+~ylu#xh%TXFQEo ze{e0uP_%$njb6st9pSfZ^uVj8!=kEVs-6jOyRu5arc`(T%)SmMQtA@w%Z>*6M z&A!~2x&P(|R+}qA#S^Xv#T<9A*t)1C#M<%fti7Tht{l8_>r7_ZD&LZL+aEDwx%+jC zd$ai8=`P?>{Zt#FV4ADwUpm+2hHGAvGf%af@p1O$K0^AbosXIlgNh0C;$qfH&W-a?IuPchl`h$ux(Y(PeT#madUR^x_ct9X^2sV}ZJvsr zQAfM>Y$%mEaGhtt(bKE`+z$F9I8`jP{&1IGZ&rhB_gVEh9Tqp$Hq0@OmiUm}IMI3% z^Tk@D4#&n>zR{k|OHQVF-#@i^-`%Oc8$W%V{NYb-+cZ~Eff+?PWpcNw{#O2belbdM zTmK&Q=)(!KrPJ0ZaJ$XxYPo+pMNB!PX2XOz5#Q$1k{C2>e)Mm9TG5V8XH1;AsZSj%HlSmJ7T( zk>`Y_-DXDz5fOe3mEcFKwH=Q2*(K?4TI3!4{pRzlnMzS{9tPo^WiPlaJ{P%3WJqak z6R~2E)wiit^O>O6XTx#vhlbYC8&TS|dzX4G%nn5$E^XqE-taAEr@)Ti4<282Iq~RPZ|aX;-XIQ#((JS6O4pprnbp-Cni&*kxma6Y ze`A|N`prd>CYz$7er%N%F?K1OCMGV&aqzCgTjz*Cruz*+JDM(9b7ac@ShzamPJk|# zq|p3>=V!Km43BsH_k4NnHnzn*3vMZXTYvof-?%fs4==2`oaNUp-6mTpP$n$C+whC| zQoD|%Y^b`HYrCH>2JKPJV}#NS>oPlczxepI8E_Xio=uC z1)IX7g6Cc5W-zKFx`SGujV+aJN4qvCx9wNz?Z96T@fmx_AF8^Q^xA z^l{Q-E&es1ZYFw9`z2=iGyAXnDU-?{l8y$4wd0l^<$9>5v;U)^#>Ku**VvsI!jJDQ zW}I2Cw?z7pv;GV1l?T_#F8$P&%XGQ=-JPEQO~y+dYtE&dVs%uX*v0hUOFfF=%LKO{ ztCswhbboGhP5)HJsvhe#@1JQ%Tw=9(>QV6_u_xf`i|a;OZCUMJB94p=-d<`ik|N?~ zYV_4bt^X>`wAJ;*w}Z}l3t#T~5-GZ1=}l&_$oF%CF69+XdmkFfoBHfxRMg!!S|>Xm zMk#b!{O9CRSajwr56_p3&lWwBzmGoreXP|zd+&4)E-9Y4y4t9J)qC!C$t=9Nk2Q}) zclM?iOV3aEH0QVWtvqh8?)Q67dra^9c%x4sa9Yp2nIcENZ#l83D{SHAIlMof?=Dq6 zWpDj7z5K)(J&V6t{k?+gjDH_fSoq9C-g$D8>kL_8_VU(09`6oFY<@RM@-Rnk_NA16 z!N4}cydFLaA%TE=%p3|5YV`CQ)es$Na%+-orl1?oriY6UnJKAx> ze24OuGd{5*vwhV&dKxy}4Rw0+XPr;if-RpGCRrS2NmrWn_^*)GVdg%y@BdCNGE$R& zaZ+Y^dDexDgCAtlB|fhGB9}C2QewrSchXy)=}H{waNrgYj&b=`;q)(SN>xJHAF(&D zFRQQ1zskFSpDlU=mkYBZ3sZyL>F%b(2c9_}^!2^$+5c+Zi;}RV_3NCL^0Y3UP|4h( zY%ue_#EJt;{o|*&eU|iV4pvT*P8w zR5g$4F9kQPy0|opj#)lEYNc57TQHOBvAIk9u8+?)Try(KJHG7s=c+)4X|CVGZ@DBF z-q&!6P<4soo>mjlRqf!uEh1>U$OPjz^Vrq~TnN<4U-4s7&89qe&r^aIYV2a$Raej7 ztafBcl$gjiN$LC})s?|B7*caqtXylzaaQ8A>Gm07DzBV9o%Nkp&EN54+x(kHpYK;O z{ZMgo@s5aJ3}1cNJf0M9ye$2%SnBP|4)KK-{@&?+vafRuA3Ixro^S63%L8}%-t`~- zoY}lC#;IF)dh&jmJ6^wKubjWFeT8G@EpwK{>S+hAUD-5Ky-Mn_)~pE2hc3%|9(uRx z`X#Lvjm%ef75Oe_#Bn6sNLx>)&~528gJXM{do6avG<1j@w)pws`^%-Kem0v|U(psy zQ-0X;wp>GIVyCEM?&=L`%ll2)O}kS=d`u>3q&_lEsq_1gu5CU$&%AkIW=iWV#rCFj zza<`42G%zczaACueB}ILhJeYrwK6=6$E2-xhX&7*m8fZFxVv<>qvCc4@x!Ex3Dib5@&stjwX8b2N$c|68iMV_DYVX^TNv-3nvI^%ju-8 zIOD+i?e5|gy0+X#aerh}f+LKXomQP}iBM|)D$sX$aSGeD%rh6=C+r9f+_K~B!)Yo3 zI-ax6NqO;eR;r~E3_c}A)GRU!z*1bM&$F1-8OVZ`mMyzmM=cHS6 z<#yf4m<3Y~&7AS#kumGvx&{|UO@;`DcZYKMti*B_A)WHe}7YU(CLhENSBgbo;kCNT`i^O&CcaVJXB<)8%cN&vU$zV*0#PuKfPn+IcF{MBusaHL)`dNBmAlY~OA6%llM< z+M>==lS&%|4&*LYW$f<#GI=S3>qNV{TLO{~XNq2yYg%mH-&4aD<7S!=A=Z7!<;+^? z?Oc*AZL5M}C%Uqny4O*rz!kjm$^*~ocMQeEIu<@(H`P_>N)Nk^l95bkU+3y^K06xFq=-yM2Oq8pD0%X=)6A zmQ?C5k#M>f$1?L+rBC-KiS>e~+|FLTT6kj94%YcnR+lI4yBD-3iIrpK$t&S&dyZ{< z5XIbo;b+L<_j#H!0hi}T^UluP<+|stM)+o~y&jbrf|tcxHuw3i_9{zP3Nc}8IH8`I zuvM&~{f?cGi_7GymtAJpf;*BS z`1YoWas1}?t(T+<*E%j2u`5YZ@a(wi5Z!ZBOo(GUzeZV5a*6N!DeeoOOl~PDuspqI z_bh=sEj71m#=AzH+NfJ+8UN5|H zr@imsS*5wNW?Y!i^e0_&$9L&shuN3rcD^!xcKlfO*-HgiwZvCl>-(tmit%dS>lr4I zwM%EVO3%vMlAWef{k*NQ-sF#a-S3Z`iq}J!b9p>nJJ-p1ywGV0ium%!d1|<}NXC;I z@e6-+te;%GmA{c?XW^pY-St*yu6h4nG51VJ&rg-qWto*h2SOw#Karb}v{py(^f%`# z$Ic2iEfU^w)Q>^2L%8Ofz>SG(E>2qUOhM_Z+}WV?-Ow|QYEkdioWlHAAJ5cK2-2zx@#hFB zoc4KY)Rm<*Eghz++75wdqGtHEmX_^E)l0g>*Bi8%>td~1cc8Os$lNgNk3t7MzRX(8 z^z8HH?ZFST3x)db+*cOp4)5M~P3iU`JHDVRC$8?`xm2g+8+lQG^`w@R?k~wd{uQ)j z7+;=Udc<^r(!-)JYsjr&f9)5gd ztLT)hdtDRfpNp(wPMZ|+xNMcF!=g`9wlO`{Kkq0yQFy}ypEp_^D-$bDb!D&nYiM;v zui<#?!kJUcrF2ZTp2`V3t?xcbRk3r0^{XGMvFDyLcYKc1UIQR6VDIcV6-xI7pB<*u^t*=a! zTjYkelBpctFKeQ=RG&-Bxg2?VOB>&|iSwtvakic5aA3hxj>|Jutwk$~6?asgHM^`d z!%a(V!!~C%hBX0vZnpRg54~S*>1*&^#nZ@ z{xUaM((#zRgV|vZm+Pw?nQQ_VU2-)LoUDDzEhD{4en!T-7mFNy#W~r&yLCq#6D!r= z-KHelVs6m0AV7JBtAmxb-WC3I(i*{*f>SRSK+}ozL%S~f09l+;PP}u=opWNvddsPSRX1m@ z4+vc>slcgq?*@~@@4y}Vn^VuG?n`atQ!P}oi03+9$#=uzNnZQmf)$~ULb+=AK3^^p z5mwMEaGH;U8QxeXI{QTlD=Q&%#oaJ08PtBV)O)2`6e4kC^ z+07LeTdZ_lLl>K>xJlZxy!Q#aT;7>Hnf35t#uk%@lm4b~xWsWL&6!-noU@FDV_KvC ziM&Q(PW_92&u+UQc>I^&zJ8ygtiz_t$~#TYl-@Quu3Wn9-t632(@opFiy~*o^3VOL zcqeMDlLkAGu-pH2CVG*X3P<{jMK>TjesAg;x>m*27Hr? z=R5JM9}%#5?xZXr$jG&5VT0VwJF;y_a-kg0G{3iVUAnYc$56Xndgm42GuultK3}tz zIomt+z~|Q|-8aQart?nrdG`6Ik>qW+zh8b>-m)&9DE&|RxU1PBC*>Tb(>EsWo%m>< zkz8xwEg_EYca*PRo%-TiX66au3yXMdio)*A&9}N&-SB~9fm~xtEl-d_a?HNym$Qy% z=_oEp<1KG|!oBuW>CID4-`a0y{nuo5`j9n^|EcC8_P`TG`9{whPq|yo44ORQhUffa zCMB;H8cUvi_OrTRMef$CC88hYnM^Ftaz$w7H8D?krD<_$@-o$Qhrf>$LvI!C+j+O+ z+Gb@-hZmBEu8D{!MV_eS6*Oa=&eK(SS2fV^Ek};A)9%hgtqL-Adv@h5s#&ojMVQlC zZ$f-ysL>RQ#}nSoykmSdc(Ti+TU%!uSIpXKDLyA{sft(FTs6a@SGpSE24*4Ezcybu zwBfi~QsWI(0|kcVyME2J{N(51CQ)H@zGueo718tf)>mumKMR-P-BsXtPVxS+Y$I3q z*LPeFi|!~XzxaE~DrNKQjB$uK8qgBs=M~#*}~_)+ZC$S zPh2)qJBESwo4`&rK6>z!O1)n(?zi-n`U%xRgHGc&YsOX*fO$FQ|r zJe-0OdI^pN$3N#x&Xc%Q^zhp!mq|&BnwUNveQ-9o>z}&ij-AF#HWSaU_$usrSh?Wc zN>`6{pYwQCB7H;LOEzWfy6ba1Ypvzmt){6i<|Z%ow>1eeoaH#b)o)EVpPho2p@zjV zndHF99J5v@Tz5GpkrK8b9Q)|^wJp=Xs`;pS)}EXc`qo6RX7A18_ofMHnehfL zUC#J5Yij(wxc8G8bFzG+H~0PMaparpF{k3p^+hoj5*rRlpSdj`d6@AP>vnOE9}&Nj zoTM_Ur+vMztDq1StP=aCf8hejlj74C#>Q)3QlGNI_`quu0Ykro>KpH9NHYBFH=VLp zt-EmH>kyM`#^3of&mXhRx@T~FJy(b7-kBS(Bt1`Ey3~D1Lha2elR1ZXADedDN@$my ztdRcQt)HIFwY>ExWrd1*qjO=|U{c{=Jf) z_Sa(`w1v$%Vwdf@D5GzCxkSOo14@xW>u!Y{*9;IzG45J;)}tp_?Xrn|<}2IRYwn#l zk7$Tpro3e40)Xy}L#biP1^(i^uwjTfN=9}Hnee7C?@wT8- z9lZRf-6RwaB(a||d_SW-;TWgfhPYhWGf&$VTRpjy9)A4wblzCmlC*cAK}fU40@qPfFVs&i$A;%W=mlvkP|2&zJNYOD_DycX`Xi+URp}^QIJ5 z9(O;|!mMF1BT+ldVyKz-wUfAXq(ougl9rsOKJtD>@*X{9SfZdx)|L!n9~*< zv*~1!2ri(yLPESaaQQr z?qn7_&a!|lPU`atvWuSZ*DPKnctwOWc5wjb%6BdT>L~`A^bV#{>d)9ZAphZ_(W_HefmVo1&kdn{!S2F z_I243(RP_-ibeOC*s}9m-%m(9s#EaLScmiA-nV}59`pXZ;dp{E$0~3`vggF_f=X=8 zQw==6Jh%~ZDJN8lX-?=T@oQ3=lFi)gY$+Vh?lan+X>UB4`s4lk&v_gl4%FPOG~z6I z_UlabG{au$iz`pJh*|YCZ%)i+J@`3Ej=|D&>qAk`NIo-3FDDCu1Fi=(h1K84el}8! zJ+0|E-QHrV-MoDdA2Qr~)BNsMWYuq`jTQx(@Bu$yK^;V4KikerRH(41jr@d?t z77Zv0v`IK-{Yszp5p)NyHrp+W=uk``&h zFPmmbRGezL+9l)qtE+uC(h~i(VH!8S3O+n*IE5lTdNjrU#k3Rhr`{eNm6e= zx$;+jeSNT`HliqfPZsOPGTvK~rY}B!kbUy}$wnJv8F%hK_~V~^#l z>kFR*UyAWkHHl$Anlkg$dqayHjYrG6nCv?bHY7IAuuAj$#bLE_s;)Nk%I89dvi@9h z+iGEW>Bw7i<7*myD|w}~R&u}6d9OR^_VmE>EBpAX9@V_%RqaMzOQh>MYg3CwN8d%xU(^%P`E>Cci%Hi{%~2^cd9$njsc5Wjk@1&FCcIMj zqb06uCCyyh{b$dHi!*kKo2GVTvvhGiIPs)5Ov3TBud)bB>^EuS_=0$+_ex(*wE9$S zW#-J6p0&Ak`Ei~li&t&3l8t)85%6=1^Td0>HAYi-4SU!x)-bWHVYnb@qcT^^f0mj? z%9F}UxBmDKXG1|CIOJ;J@xH9ZKkizk^J~--?D;kL2a=Pu`%DMb=)ttHa=h{X7J=2--?4Gy4=DCq4 z+Mh`{K5~+N@a^)(>u)Y^@;$t#^Yqb;zbgWHmYP`Fty}W0{AA)0h3q5gX@AtVv-LZl zROb%hKpTA1z ztz?h-fluX*AMZSv+~41JTio0Cqwo{`%kM3oAK&z2yXRMpHLv_z% zF_wM0kxh@bCAF1H%|0FMdQr`Y;$luqr5 z2(Y}iPfjjTcFw}3CtIK26!p0v<tiV&i?_`(%ps&W6Rm7!um-l&z+p-w)Mzo7c-e(M_ue6@m;*~Wreke(wvPmre)M*S%jT5w`bzWTe*|7{^L`D zq!?}6niCgNa+dwrC2={aZ)fyrn`^$mvRAFRx}n|oX^GohCRd|RFOGM%nDHyituec4 zbi2zUlsC^w#PgJM%9&NCR(Zu$CT2W~IB&Ge(sqWEx;5L0$GdC8GTtUL_88u~#jX2K zFJs!tTpfoOnQsC%ro5c&`sO*uGd*p?!51CJwn0zKn`q}a4bw4F`3rY0Va_mde zJ=C#DW3uZjHE+)u`oUZ9U(^=Oopz*X&OkVnF2VK$Y>-CphXnZyGjrU9e z1|>mHcAg@ajtvgmBN=v=2KTftII!;E)d2mOb9Fra_V4^=zs&rF(kJ!VJ6~)+zVi5W zyRw@7Yh31}^698d3gP>ChWq2RnM>MF+pL+^^v&7f)~OW#%DDy%tAZr=ZhCvgX~sfx zrhpK3n=OBj)^*;Oe$2a5ETa2{PNKGG>^~!g8L2BaWZJNA;QE}g>)SL@&j#0X&E@V4 zudaEVtGKeqD^U6u&jF)JZB1v7MVg02IU6?K$)9Y>aslSWlPK!mBp{XLC z_YDFn{SHl7{OkO&zaEWp7vA_g6-{UfuCrMdA>Z=kic7$oGM`}2{=*tF?3k+0u8 zw*I+w!j!AEM_YJ1te@^*s5rytumMvV>-XhPe;Y~8Y~kT)^T-qtufCt}f4BdRk_cPE z`5ldq6@DJ$b@1_1n5-hCR1?P#WbaV>FrxC1V$z583Kl+=&L?)A*0=cM$7ji+sQhu_ zk9EIa?(^F8J$m(n-SM{f>+UbNE8bQZT%KMVw^BQ1udB-5`kC+9Q?oAlZJO)kxou_k zgD)#fR{ZIky!-jqpFfR{${hQl;<5FUXU)zlnFU)WO??=&@!r)Xdqq|TO)7b*cY0~l zy{k(WI<-va-c;J!bnjBw-fN*+p5^K1idW=TzLqn-b?(o%*eRxxJh9r%su!d41EvqDhs{TiHA; zvJ>^fy%#S(b;;ZN?zcKVJ3n>a9d+85-@mWj(Y^Eg>#t4+zp8v=T<~W@t+M*HjkRTr z@|NB+Ur*v+U|dij^K;5MhV~~9)t?xZNlUxcI`3#pT*>@WW9gS|5=NS48(zLWv3Wz& zgDbySrif&_m~_lO-u&xSz`kD1*SiAl79R4L*=gpJ(6GzL@#y{3ovRYo_TOiZYV&T2 zv@zbz`l|J4r$QXVthY^DwS>;EinZlyfMrGOjC&_13o@xswBDAa^x7tncWDtn zt31ow6a_WIKfdhMN`mPnk{5DrURWgdpig;8f2PW#G?P_trB?;H@$6pOs2&)h#xq@9 z&0>*<*_5sul2W2Pvt*t7_ar{bP?)xj|FCvwOKD2Lf=)RhMh-Qlh{x>y>4MuYyteF{ zEnr_8k|fljsL{{eEMDf#^sT}UVQ&=tMm3Q_dk!V*T>-97u-);xGs`Yb3bzAWx=8n z6U*iwCch6aaM-hE|C-lcT0FDrmn8m~S3mjKo_RLEdQ4v2$$0imtGl{(Uez_T0?o}! zezM0iSM#s#tF?JuDztu&Nq_j9f0GOu=FLqN=Dbp9HusiqSx9Zmf)IP>!!qA8o`nB< z9d|pf!p6?#^&iV~n|JI#EuB&Cd5#om;p1oSqifF{}MS+mAOtyz9|%bk3wlc8^&vFHiK0oBOQn zd40tDizi*vuSy&n^eW{OSAjxu)_idMO`4pqylT{bXemhZA=A1TD zEbT|)o$X~^?)riUH}hB--aYL6#ZogaaA|-Qr<#}h?es~D`#$#z^_&m9ey;GP<@xUQ zT6!8!uWouNCAjAAhgVlOoZ&0(u`FUdFS1MOmqpBt=nD}pC-N1}?C9u>JHgW!AFjCe zgvX1dU8#>0*L5?0xP7L&=h!8-ZXd(Pmb{G$=O$#PFsD6L6XP`%p5FMzv2$d_ysS!=9g;3Jl%&VO`a>|tGR5s|WeakhVt-|02luj#zR@fSN=+ak%|zij2r z6JK8V@a^vR2$g-MlQ>nFtJaIN?y28id*@P$6yrG=rxKZ*y_b(!DLj)~D`WQE((*;; z!}3}_zgU4o9S)6Zzv`k>mDPlm*RT0tq_=s4$$_>vzh^u8XBp28`4)Ql!Oa@!eVgj* z3y<}My}0u*oA-0d5$;wE*{cpeul=ei`Mde%F5xV-_cDQdFV-&m^!I5`(U}Dw^4D|d zw+IHM$Q{sKwl*qFrFH$wSax~kI#!Qc$J)Kmok%>+`s$zkY4c6)1;>iJ>%3n4>9y^# z4stvte!#rrQbg~s=I55#$-AB@d|0kmo^mXC+C{PQQ=R92^=pJ)F*y2KrgQ3faZH6gjoa_1(`qb=x-n zne+DW{0A|+D>w46OlMwVo@>^2IrICx!<9~IK8Yu$NuS`Ww2+lO^mN0s434{VZZbIT zNEV)T@6uhJoRq!oNx`qCty7+|WJkJfCv#WcD+#@cQW2TdB7qzne`O{*_v1VFm zF!xmzk)39X;DDIIbpMaXki|<_=Tz3jWcqAe!_zukVHqv%KW_|AU z^(`$Xv5HJAYO`F}@A>_CeBl;jSLx(ASGVmnHV~V6)FFY}YDT`W0N>@p_)6s~A59h3 zyP4jO*>O!gK^`dR!)Jmsqq+RXuiIXS>+Ex_)O-y+hFzr}HjkF1cgsmaA;o zP~dtnn)$OfN43lu>4=OEXV-;9ZgXgfI=85{UD&cCs)l{ebET-5Eh4il@31Sy#V?b{tn*6S`8&h!ns{K9>se3O#IFYdZZs$Yn{1 zzWkb*XQiGU-tVfZSgp`+8oE1>J>PPf$y2|S=f0hjas-1koq7$8pNcxobo2SX#zjGe-sVyEI~WxwD1^l7%5wdSu&yU*3Pf7^8PTGh-25GBtMEfb<352$ug%z3JS&)>bM*CIX`wV{HL0xA9XcGL zkKXQEcv|&RjY@C0esjfYg+J{rYem-R#u)D7F%XWq=COtMtI(P$6B;h1-{yK|@+ir5 z(ew@J%~_>8O+vTrd?J}pow49)36oC9PsKLV?24#1_*TYq?}PnHz1qCn-BE>fdxw zh0oxyB#)wsL}D8RDR4||pN8Ei3Tl~xxM|Ch)pUOFvujjfyPvrP|L zojD>JIh53dbt+j73#AIA2KN1QILTr@Gc+_X)MbL3`;-LDfY>0HPrv;4$^Oe1DDCF2 zU;gOJ{K*gX-V1(AQ@-eUZk1jA%dd0a9L)SNbDzC=yNnBm--)L&bs7Ah9^8KS>)hM= zjlcWXw%xjP>3++{Sr6>ZvUVz^WeGUXPLQof2rwR zJ!Q0Fo87y^?@#>dB&|0g4>x|8or9ppR?p*q4Al%hb;+-tp^_5JzpIBR5tMG>Zj{IE3KA0 zHUD<0_ETlg*)hxSU%GkPc}j=;@~hvIHif>AY&msoKeM@u#q>2ddGEYlkl1pUYvYXx zM@n@k);BbUFslT=cfaN_o4ss>6YKm8%f?3=)-}eSXJTv83Q2M+HrP=q7SGDsJF{Ee zXy%6ONgYLep`3y1?0eISbee$G z*Mf^Wk3N=_TPQr%>0r4&?H%LSd7IUbPHPYDHSyhGS!r_2{OBVyE1oRtjaM%o&hyf2 z&gJV}=*%l&c_v+Wvc#G2iSe(Rj!0$*7I(!@5388?x#&dKC!@IO@(->i{+PGR^2VJ1 zx{Qu4FOs^{eC8}Wc6o8W)7cwoOAe>3GOfF*A3k|r)^}l_NZ3^SxX$+T7pI&lgtNiI1f}1=gJVFiopCv{&)h_H( ze509R5Rm(Gh3RTj1(D|RI>YxlGLKUnZod7Il4Y%Z>)h2lJ}0BO*GgX0TPHuze0}a?!~1fa2kJL2USc9QQ%1+mXR(6M@+SrX{>$8- zDR8K#u=U8OEHpT*F)@gbnW0(Sep{N{^K}^(g(oCb5)K(DEc~AxQF3>Nh(lrMnu5tW zt$P{^Ta8jVFHA^qjhY;2mXzR|Xpwu5#al?!qcF#(6-FBw88QUjcv@qdBVOES z@mP4mxnq)(L#+#!^9lwl4(*FKw#;)*F24Ul`N28 z-6#>t>7B!}mizbqV`h%*%*F;et@b{NuWq#LZ%CA=_hc8FlvFL)uaYQGE+XJ6%+sSH z^|(^XyrE$7g2y~bSpvqg=VSmVj zjqDME1sPKp)XtRVQ%EeiqfroNT4a!OS=#BfT<{an0Ho2Kj-h0KM%+S~1#r246muQ9V^1>Y(I#l}n_@vz~`LtOs3R@THw?;u> z_sZVh($yMgg?M(gHU3$)EYn5CpkLsMqMVUHa-iE=o}*J*d@>6TFWi%OaduS6(QTWJ zyPGX8vc|Y57`9!wBB^+3@ob^R-hLBrg{fVYyR=ke%L(4S9(L^PEqX314*RAyR!fKQ z3GTgc+l_C-rJD>97dBi;>o~Y@qe!M(iN%gjJeNugj~tWwEY^1Ga+tx5V}X5|_Z``!))QO<^t}{NbICbsUlo$z#i&53e z-Al#0k8Lz%XXjX~^d``E=FYwfsiU(SxBBR$CJ9SCYMp7(J! z<>TmEw&9HCHs2Q$T1>9VeA9a~dqTIX^u=)1?rFWkX$ki<`XYTMHcOZtd~k?o=ad~z z0`Dc=UL5G=(BzC#gJ%z4ZUg~_GWsjYB<=Aa=Q(V1p@lU@u{7ZZn zC_H0|=)bpn(^6M+F(%$=?M5OT%PJdA%sZ>~31_o~l%0c*CzOG-I1hK!@v5) z)U6kP^)Wy5mUHNzy{KiMMVs=YzY7oXTAVRGC)3u$X>dX)L1Ctqa{dpC5*e#A9Mjs| zST~7?1n?~7aK7tueVU9)^-HssE#0$yo(lc`BYpZrr{K&j^BzCGp8IO*ktcS=eOB3_ zjtix2Ja(VnoX-DQs@VVJmwK10hgBxD2HyFbe&*4FO7rYvo^ypKuQ~Yj5S!ZB4AbRu zN^=zY3r{YznbMXvX_dl#sS>wSo!9m}USjsqh_93LtccT#eVl9)ZtOET#52Ld;($WF ze$uzA7j{S=I>*P)J4GbQ;I-m4>*qPA+)lLZyS`_$^Ib28hOC2E`BD|Hx%`oN^j6_r zQ~S596 z1+p7udG=1@`*?b#uiL{V27(V+vSOI^ZG8*A8n?tP?fD+txqSNOHby}~K>QUG4%~3co$$&jp==3j6KD&R5{FfX|Ag}CZA~syVs{;8vrEV>I8&^9 zF5^sTDHr$OWnCIVD?*v1E2h0TQ@wRbv*?WL+$%R%{PLYSHC~}8TgW%yfgOjYY2tdf zdCS?Slyxb|?qn0SxFzAf$u=N+c8AMFkDLHWYlh=OYzA?RB0>peO)HlawuRmgWc#di ztXX~H4mYRHh~!8&*F9#R&Dc8>G&Nbzs{GGT#q^L?StZAXh5 zC%pS2<}}CRBp0umq3xTE3!FJFJoN7Wyx~m9w-0mIP7q4i-+o@a^yER6r!TxDvIThh z2j+)=;wocj*q`qYbySmdd5m9_xh5;Lo?H~nCy%mKk;37hU>qQ)PjhI zfG&>sE%*@QJzv(6)RSV4#l}=7xqj1b(QI`^@-#qD;#WT`A809~H zxwhoEQd{DTG%3a(hJ5P(ii-oz+$#U^-|^$qAOC{v-_^x8?_Ct1zbk&uRiTQ657WPF zzxX@-_cDod_Ui(t&pM?&W#RAoRb9p+0*AksdkW`2I>r;5edo;4;@S%rem?)<{$oR^ za*NXGX60zvWR^3l^&@|`PqBM^?vG|x&MNsi4VPc^Olnxryr@OunB#^^jcUOYU>{IgUTv z=oLMiZNZ;_PnVe&70y&VUntUMAjray5g}^7L1N|-zm!hT&&%$-xgGpGW{v7py<5AK zINbR6y*}RfPy6WBrJuMO3tK`AJL-g|HF&I4ohtX|LuXq2*`0x#S*%WE)aM%%3v+sx zZ=Bh4lsAQ6aYKJf*{$VEgPV1yIw}fZxj5&T_}i0R9VcHk-sbz;vmkb5Qs7eI?^lI2 z%Cyu(g|#{_p4IbXf8-s!qrN?t(@eM}l2s)_$Hv1sZLjE(@Lx``Mcr3;7j5i_sB3s0 z6e$t)dlioXOJ`??^^wEtnvZDhXZ#hWf3Z5XxoYwuWupy;l=wZ{7_RQF`}^yPg~Jhp z%!N%0(?k{}^eh%^FTAsxcfOHCRr=8riR+d5y4TuG zlAfW_tHLNA>e8gt8tRhq^UNE!j=yfQeNO~#xHa&fSj|$yxkn@ZoHnyUzYB{s)A7|Y z6Uzl=@htBwIdI@(LH;~P2b;GDqNyl%)($+-FD_ zwwIShuf6X1dBNQTJ9#a$Ng`e;%QOVScoJ9}W(d7cKYs8BlMq^-@3@>N(ByY}0@tJV=*`7J8UQIdU`Jnpvq)HoW_RS4x2^&AzH6{4X z4A9QoZ1mkGciTnYo;!Y*^yK*>4JwU!9zQISI(XqHlj71HLJU_F+ta4-Ni-h5op}GX z45!B$#+rTYrGJwv3LH-y{%*TdaA8U_r$WoJZoN06ZJcvl%6ildowf^ZIMP>}uef&J z7L~H;Vk|BT_BMWCJEt1ATk&A~B?G&Qhm%+`Wtf?j%o@X(E1G#b=o>DPR2LzCO=6 z88L&vlu_d zY(?p+7@4FAiIS|GO*`~u&n7j0!(LH4;=5d?KT}F#6lP6{SuEPuB}He0`_V`!3n% z&UE)1C9*vH7BbK0F@#KzWBRkC_Wz25PZj=6;y(C>W8Q`h8aXf3+Smou4ozIQtLXo0 z#Ybl~j32UzFwXL{s5yQ~YvCitpC`0F$S}t@oJ@Pn#?LeNn0VMBwuHs+q_dfqUTS4g zWIn<%m0?3os&rdmW^aH>PG9Tn2Dv57icI=<_jxv1n6JIF>sGnEMfSmqCm97-s?6>& zaAXd%(BtOjzId>Jx$)q^Hi;CLmh7i2s`?N3UoPY4Wi@}W!Nhapia1j)C$$yHw=2D# zt}A&wi=();eZD(OOG}qN$A*)Ox;Wn3OP-LfW|2KOf5o|u*d;TnbxPzWoRDozaxj#h zmc-Lm&b#D-h=jG%S-XetZ%8u-F$grXaySMlG<4La2XP!c?D*rz&CM%p6>W~YnFY#L zF*an1@b7Z}a7w$y=!l?zi=)s{q5pgGx8CM=nq_GhV13}hEkll!?*cwcc_ui7hPX^P zG3mgBg929$%zfUy=-|Ph@^hZ1M^FB4at1f1Tj}-O~P3D?}|i^yPs+{1rg zHw?5>V~JF7wQrpK-Hr9{ikSUJgu31-sq4i)Uw0-v=)n1>f4mw~1XV&+93AEF`_K4u zzy95kpMSr;VYuPB!$aiy?aP`ftp8J_dH)+;uz1h+^J1-QE35nS#+NS&F8k~$Y+tlr z+r_s1nOv*;@~`LJr|j+W5@wG0_D;@VBUkBTK7cJ$F{AEjoRIYx8@(Qq4I=~K>fe{biTX4`G*Jo@G9-g<$1 zlUq^@ANHwBHfldSkgV|CpP}iEqyDpr*KV}BF8}r~Kq+j^mhGLVmxLAe7#wV`oxOVd zA(;Ce@qm^xU*N*r% zQJOZQ#c8%npSE8pjQ#uTkF#8H<@{}|5hnx+pB>qu$+Yf)Uya1XU8cuWIYo>Ozm~PA z|9%VER_@A~+0V_{3yV}T&eiz8)q1LR)8)am zUBBOYran?o?(gt9Y;c&_;7s8CXV>?KJwEo_GNT~apl`i8IDaqN8vUGiGb~3^Uu#7RbKsk2eESU#9RHNIb*5xXb`Ig_|4|(%H;@|qm%dgob z6_ix`)4y*b=X-#M#b=_)QD*~TPWk;QRr);q>y(xX7JBWy#HRO;5y#>T8fI7 ze@_3@yMb*-GQ;c7rJ;9)Pd|`97nJ$o{K;3L--EBa)~WBDemHimwN2`4uWMEg7AIB8 zgICQr=JkucJL~L?%u{Bo?RK3l_p8b>O%i=*^Wt;s&)khC-+1K&Oga&$QPmMEcYEs} z7N17G-+8ucR?hhA`ghv2cOH`HcTw|XGJV+bsH;~+!R);x*9pl^Ij7pAj3!65iw`Vpp8eXA>9UI5 zB*_CG1e5|d$24*oDE^-KWnRzPvbqL^7MU9NB9EWP?;5eIhedPANG){d*f`JmAJ^CB zT$BD@fmzL0ES3dMU-4=Auj)@*ZssLrE@VID`z-%`hP1%#Wxp>Tn5{cq!)p7kh!p97 z1GURlTk0+@&6t1xZ}P{;hDMh{B?S$R7m1DcoZBOhem?p?_WD`Qfa~jTu5Z8pZvA_M zKkA!Z!wi1MZ~WGO=Gr%fo;i_~K8M+aPH+bQef{)GjcTv|j>yl8{d>=7Z>9Q9^&31N6zo47uw%d6bfM;;i~o&W-4&gGg4;LEpX9;* z;QtDn*7ZulXEs0j*IVIOKl#R6r+Zl(T6zwyrE|8ZNGB+qx#HWYH|4kLg!EUZe|<1- znsPzIO1&_TP1eF>!LN?k!)}icpLl-gmVux^vHau;Yfgrfh7<4gO>||i3(P8RjWS%$ ze|yS76SvJ*>|2cAeE-Nl{q<7k_(Q=bUzt?ZiOsjQaW7#HeJe5V$=eMYnje-d>`a@q z$fN!7jx%TOZM8mAI&r~T4xgDSlU|yeht~DntyBB-t9co zwD8G|g!n~T`Im&;1nvsuuCadpd*R=@_Y79yrahAcuiTG3Vw5H)8WgyE&g)Yz=Gj#L z?>d`yQ?Jk5_wn(L^{7oat z+zWR3qwYHY;=Gt=De&vKonVnm-=d=E@?ye~@97JxmG?1c*)LIg+0?{o=X@!sSh>;X zQUD`w6ZgLT_Iqxe$Wl*#Ze5pI_vAvXOIMbT)#cD>@9Y*$pC2wQa7LM9{hf?1%aX&# zR89XGe|L7g`ln=G{&o8gyEljL+x5THI6YOq@#?k*^7zg}14-gWia=3TAD(;u<7&RgHM-!FaMA8DKPn3K1Sg4EQ-R!*<` zxvT2ahoq$WTZK1AeF$JbxU`1N@w59qHIB42;oQW=J}u$*sr%~>g%!7}9C(>hsZ+4x zT-x>b9sf4kYx(oGI=ovY-~3xccJrk_0{dO>sP*q#C-vz{B(vy0U#Z4p$=jM=Dcn0R zclGk(ZDKjI(-i(|?&92Z?)c}q6Krbyg#L@Jz1jom5EIg)!}w#*&$<=F5;cW@LO_Kk^I5+sXq*M^lw+cH@`ldDdDcb z6Me^B4$t#>*$+$dN$%rXVz{I5SXSgQsqeNw_;_~lvK1M!o^WWLR?a@{TlN*ne{Gzn zbrb^sK0m0&ujT*p=L+q#<8s=MA5<=xk@|h=fjbr19hcKnPApycs8CLJzWNO@Y00T)g@S|ErB`)(@6-YBkM>3NUBfnfQQz#@5fr1KiIUh483Jc=4E5zb!r3 z{;ja`yyLe2dS)9RSg!rL=~32JE3bWqZ@=#?*s`SiaPRc{XP&OY_UUHqsO-+}(UI)mnXT33vKfvx1_iqVZpSpA{uDh{s|A@|e)u+ll zOFb;nJ;~^wvwp(|+2?W(^uzWq(Mjg;Q$Nmc9`IF}-NwMbXm2K8`<;ZMcn$GqnO~e# zf-f1E{yo3jm*>9cv0VPitJYUb-d*A&w;)BBo#lmtd6i4A=cMEhGOde`@ElEC^8AK8 z>j95%77d|l3jHlV!WO79S29d}mUM{!Okw}Myx9#ZvTluL6&l=6wpOcnIbK|uXE;$I zjd7!_=>~TDDZvv;=PbGz@~8Rqd-=Hs$};ApI^V0aGCp{-;z7`gIcGdHT|Y=T3tF8h zj_N)!$wGW&7{9A=*Z(gff-m>|2 zo#3|KrT>--Uhmy3Em$9QrKjrC4ytMDv$$jK~A)J8V1leNtn6#hw>1`SOqIPG;G5qZ-Egz^a=Y-1j#Z zOMIUkQ5F+%!YJI|qFK9ocOUyXzn-&gbL}24mA&>;`?#|3mUp}U*BqXb)O&iyyUwS! zcF8=Z&sRP&e04=8%=Jm+so*BQvvG=&%qk_jN(^Q&bXZS)7RYF;!j=J(DHn3S6xB=d@$L?inRUAHW;$cQ(Zp?+ zlv<0V3(V|$4)*W&nemhBoc;bUIh$YoxB7Yhv+N$`>fc?Rw^qz$+MD7e$S?L&Wnt)+ zuG9OszyIGZvyE{JzkiWgUYuFu3ng_UE8i2BEE1o+ZFHy-sJP;M-8u7jt6?oeNU>BN z6Spn1QioLS5zC1g>&_%Zq&u9rTHx96ey$tq;T`V2s;=zn-_sNyu>a@sUcV=-$uHGT z#Kv#l%npGGheU$^B^zwIKS68R7NuJq*^hqhoBM3>wsqUIz9fgnUym@{aP+|~$+M$x0n6om>LKPY*b zRZpsj_*-~9;ozNSmsTa)Qv&_Hb3WBr?W>+Y$?*PtJLc^%6J+HxEE>gM&(JRVd;W=$ zg!}!&W#%36-R~aHKR>7R^V(UbmhN~Y_iX9y&@Co;N8g3Ky0YqVbfx02Ia`>`JL0Y0 z*UvSaareLzE#nQhyw6H%75`?wtXA+$IcnFW$Ay`NAthoT9 z-1_{mS2gssT5@MMXUlOti3Kw|g6i&C-}rBM{Debc|0~7QElcE7%W58ew!inpuKnr# z^I@lL+CKFy>QdxgI`gGZ_3J-v{qKG))>-qob;74#-b*G4&Q(z=5ipr~Vxm&WY{&Q} zM(KLR99~DqTo&)xbC=X3f4;dKY97mvB`iFek_1}-1wqHr%QT#0NM#cEXgzxj` z{5W68)TClopJv~Y^5&a?;?EMzz@K**&TlyKSCiR+>sRDAzT7W*$CI8+`LlM4*j@HB z*|QY?F+Vb5Tr+>mGkd05g#g)oY>PiV%RN2kMkJe=+lP2t zV9UqcQ13TIzG3R4%iolF1WY{AH{JWg(*Hm~*g}_Yv+}d1?I)VoJ>@*osU*%^q}D95 z)j1pk(FZLY)cAqx*B`s1YQt@Zk&?|Gl z&*V1gJk#?30nYMsvW2AePgHD>oPLGNG3xx^b8$1;?@d|oLPF*#o6i&eYm#TT)jmjb zo8epgeE+ZdbbZPDUqAfZ&wQ)yS>vNxf#sjRTo1JIsjq*V^w{%fguPu<@v~Evi4xMK z|NR<%pMN@Q{hgyG7Xti(lg@N^msT4^_WIS?sO4^MxSU&d{qfYfMmn}4^>LdTRo#Vt zpF7wl!shy8ekH>_*ZJG##qIh$|K{q)=j*&3tvSA(e!V{O+G*2?u1DXkPt@@^#&G|% zt}lw;*L}LY$Xm>An%fKJB@s7gIwb5n?Aa6279~CD;)RuG?=Lfy*tq#zMSx7| zQm$o@c^6`AC-;;Wg&(!vsGF9SmL@rKW@}(x_xD*nvu3IOnD@u@M?PZ((d?gPVahLS0^*?PtgJ1XA`TWH9jy0b}xP6C?ff+Sv#OI zz>2R$PVsj@)rG2n$_eEPAD*=zX#cu0qe9??^AYupoWDc9DE{>*dC?_4^~^KtGbPH7 zp8DpG?M44z?w7og@jd)*yoBlVkMCt4pOU{P$oAvtTmFQ-%MWR4{BV83&2(gqbA*<1 zLXf;^>#fR#kGVg~hR7zl*(qn{$Lv&+TXpJzkgKir@|W)wG@d-ORG)O)b&{3;#Yn%& zwt{?qcdlHjnI}B`^2wu>kK5}+#Qx|=kMnJsbbHv2)8w|(3K09Bc=&;4kHW9S z4-E2UHtp5#n>Q{qZ~L?5iOiX)uCqRWSoHKb+l<;h{|wsle#&-k&{#HA@Di6#d|;n> ztpB1_57>9@jyCk%CsPv4l;dYHFV=1V2jb zTfJb<^kd6Eo63E5xw?PNhL*hd`$ar?oqFwN9=>fq`%v*a^UO_m^Uvn1)%l8ikSdwQ zZsKfu@s>-u|GZs+VqH`HkF!t9S`Zcb_2V?t;*Y^^9&HXYpVB7Q^W#9pR^>Mhxi;b< zL8-ggZv<&blvqhlN^H=W-@@>WL2=nk>GxCY#jM|+zE$|e-Qrrd+1uMn+FmoZDJjno zvNh_w|9qWEWwK4tZqZb$uh;e;?KyIFKYLjCmwheetMvuzw01;~#LoTW z(AEAG*BW#*KZs1LI^)GM?QR)QQe>%6c8Mv+cIzEC?_@mW5a_mix4%AcRoyi6Dff~N z-aFHrqSU3NmX!{nMhcCpPeuO^!?fPN! z%=GWG^rR0IO=u6iuw37u{CHeRhL}@Bs-Wc@iG-O8&TimO6jC|KeNTjAlK3r=d5#q= zPn`}#%wjBS%W1Z*Aq#64pQQv)O-au%B_V zU~}>V;|k97f`Cu!YfJy9&%gW4zG@+x`P}0H51(%On|Q>*YSWZyi5H?@gc-Fx4zDZd z628)NjPw4D$A_8U#E7!;)LYuEY;(TjYT0|Qm?c}4?_~2`jtV(!`N|>VXq=!EWL~bgT%nFcc{Jr2rfkWSf2|_K--xL<;MPxACmK1VO z5w+lD-)q-&UTaE2slz$t4k3G`?{c5ac^Agp7uwG$q_Z{-?Z@VoEUjHBF|{?r>*jWwypi%(=W8KyS02cw`b{zCf6@B6mGe{ zkDuqRWb1KKmHCgUbddNhtxNJO{9Uz2_U~fIF@Gy&B+;;-)`@#Yf?v5fe;@DeH&4Af zXGhg3bS?>SYvI`++I8~7k3%~CckL4sT{M23Z9n%UGQH!(_X&%Yt<97du32#L=IOka zn>UY|x2N@POFPG9p5{9@_Uzreb7P}>%$+^%N6k6fQgg+2ldtH3>T;18&LQgM7Slso zJ?+-7{H_}0Bq+!euCHFfc=_r3e{zqXOH_3I*%!rO$IKXiJ%KqWUFwn~i|rMURJXXK zFX{J~GdEsQ`gU>sEq0G5Gkn^nKhR}Z^6tQYuUrFz7Nuh*V(ocHxUBtL1B$|#Yd-~; zh?s7<>mV8dF_kdLS1^2O`e4T%{6c!6)}^bJ6DmzqtX9Wg zi0Z0KV^Dq;_>)g_t$HwDnVQ=XCUvFS6_Ka17FQLqN-h_8GVQ3+bd_Zff;XH$laiz= z7rgC2$PrPNt6~mcD^K0(J9l*YfynZWGagU)HD64L!({pMtA|!?<69QYyhmkATkxdF z)(PwMmBM&XXbhr)3+SO>V?7#QY)BNi?1rmTVy4` zc=TiKXMgqE=IslMZ#|2eon@7JnTt0qj`snS>d@A{jvlVo}7I|g6>|uj{4#R!lcXggcj0Il7;d4IU zovMBI*xdUcukWh-9XNf>y|BU=YxZ7^-hM@yAxHX6qJcrtn|+nj8&`BFADWP1A~?Y# zu%MbrZAo0m1HqRG3ue4us4jM8r+VhR?9Bmhs@NA5_+70yaoI~+%H-Hbp2NFO z2^`(SmUMVzNEXd+cx!!T zLHmj(_KZUepX{9T7MV#-VDY@G=I~)(natiOfrd5-LxWU>NCCbMhehI-76?h`KWaF_ zwS;TmPQLYeNk29x+HTTJ$y>pB+b(AIPQ3WX zqwts3zOES4mtEn2&PY>Vp(LKFq~p$hC2od~hyHWZ-X~}4l$HK% z$O>kd$_B~CDC&y0-NuiPTOz%Al)K0w`k%S zbJ?F7U$4*ecpP8;!BRfx=gfYV$v>P68?`ULs*L$vsq}n}cW(A|iFxzZENkMkc^7fI zK40qf-FeS_jQO2;k66yRWT|Z<^1wx+IA%@LwBo4E+ZWBVKRaX9&y(ew;dx!TM zi!OSy9J%#yijnqI;r;_RW<2)i%1M}Z{r4t?xVRgd3*={=U(atUc+pp8;uGy@_B9G; zAJ_dZ+FsKtaJHZKv&y=~lkV#B>Wp6^raQc@gCrS};#@ zQ;lBc{iwZvI1IO%>{B-2Rr8PE@qT{Z{QfI8J|Aw`$2Zi6PC6@TVyQgAqg|oN;h4&g zKeHZi_MG3j^WwS_l)Un(o9_PknJnP4cG@rV2ItLrPQ+RsI2>uC4|oJ=TM zB*`gw_e@lv&Xcd#HBPZ6&kzWdnEGrp z%N@5sl~-m2m-T$zShSOl=jFVZU^2 z8h^vr0|uYw@Nh^J?0P#}k=y(2QytUaRSWuky{2`CB<6PJJ-TeOaq*`MKTk#kJw3ZF z?B&c?i<Y+(Uwro2*?dtG zjkQ-p7G;@kO6ifEWFftC(UpVB6Vl=nISM@EXFUA7z~D`~YoPq=7R_(&N9{fdD6|Gg z)c2pbr7Om~_FManeCxA32ai;-*S}{=t^WNl!{d5-x^O&KmhyxDj6d1`x_mU!s9iqc z(MG}hzXM)B`==4Z`QJBOD{kZY7ngr)yGwrHGvoVESbqLgOnJui2OIvnpIT|G@I*WQ zF3)+#Yt_A{zbst6=ZdwpP?FhPuaj$(c4gj*IHcHfN^!;4`)}{N*+=}9*N=Ssx$pDq zh8T~GbOymGG7QaZ4yO+t|FY;)(}(9fiWdB;5qkZ(wx;eC=Tm?AeZOX(IX8W+h+yJk z@!8)`t6SV~nC-|H+0lm5rZjkF^N;Y_R;X z-}A`1C(d70zji6O2elQvG;+*)c}QyVfelmMa?f`vDt=gB?rwN;=G=dd`-Og&-tj`QprYXIA;xU>1^$f|s2ldW#7Mnl3_wy8oj zf=Y754`p~6Ki*IiTw4*vFeO59{muo>0iA3H!FJy(f1UdF`aS;=z6U0}`4i-KRJGiE zH+j>9^It^xcJI$>da&b=?EH?}9EWFYEECw@8uw*xkUg%b(9yruDDb}EeO`%upRc># z(@%JD;0U9fZTt)88sn#*H>pXxp4hH?RnUUr=IZo_c>YkiUJ-SbmWIOPyaFu}CC8Sx z8r^;N>C~j0xL{4@u9f!1Q%VD`vV9SB^15_n-}brBdy3}w$IY6zXWinkx#APFGX%;` zY-nUw)_TA4qCxuP9A!PGjaeIOADm=n-K>_!Sz6%qOzU%iY5&!~-Y0#$Wj0An4h{14 zadGBxaS>#3VR3O}F%aZiXu#OnxsaF9Zh_U6vv+5%EVvL9qJOk>ogeRnmpw)bH#L7* zEj%}eRc@2Xl%OLff;`?TF0Qiw^$&h&KfN^DQsVmC&1(LE%i9>YeR#80!rVe^nZdH~ z+X=1rFD$>g^z+W!orm*6@)J*rhzKej3=CA7wD7EyLBc`b)khyqE8)A_{DJ%OyZjJE z8HGKF>V$K9lPuA%5!kjVE;qw?4dWHAp{tKWOzjiTED2(;EEJiI#7;b$;xa zJG)|!Qmtik$8+%j%V$=?&!%@BdH7T!%bl~Qb#8$11NI8-H_m51cX6paz3{>1=RC&m zEILYZNA|AxVaLSshH283cO3k4{<;SLJg1`Y=@Nqz=gWVunBUkjO%7q0y&}+DP(;tz z|4hjK?Z3`={xAK%_e0~o5{J9eEB)W_Uz4zFVxLgU-2UOF=c$UlSy#FE*w3XnO!WM) zqHS61Vm7zKAMW_Sb6a|L%OB^?e3=6$TUlz9*&BS6jo!&R8dY6v*mpsed-KiGU-COI zo-$_G9c7(3v*p((xhE&sl6X3lAN>0e(kxN)e&*py{`;Oz@)p5cwlMrzsKpo{$yeMi z&D?n7Bk!%`=BEeKH-7g&^5^Y$vxl$Jcbw`-J^sA(zZ{(aQH%LzD=F7@pG$^_(KyWdU)t?Oh`EX>+x%Y3xPsQxdc4Fe|w~n zz4vD?!|}kMZ3D%JMVyvCqUSVb=m|xzEQonny}S3zSIzecar50$w=;Krn{lxH5aS7jn&USo z6!Jfpb$rHuWT}|0m78Pd!7^cXd+)nUxxd<#tk;%pd9(7hb54bU zp~s!&#S?vn}eXE7I#vA`3D zUtW?z4pwZ>6DRNZ`?>6m|E)jzFYZUa7v}q*py~Lfk|}s4+nt)bKjxd(1u+&~EbmL( zEBEbFXVqg(kE*5oOA3#*UiV$H>mN(+`;=LW*1cEpkXq=)f66k|@aoLNN#%;)GuZ=F zauqZ?mX){kA6@R5S=uJNe5d>s#zvM$3CZ8&m>8Mw33dy9n0sdrZ`Jdc4DUPIcP>(u zh~S(gups_NGMA8$0`t@64^ljBDNP-1T`V0bAxA|_u5w@hVcL27eo1ioBCuO6H6;!+-(#2usVS!i@HF&eHV4MCC<1O z=>BGTt8(k>XEAOIY?VAYHfa9|;xl3onD+TbAM>m;3*Y~4vq?OaV|L7$S9pDu@!G#h zH&zQ6P268uajZyzOS}Jpt$NQZW`D;s2FLGN9PTsR-jH%Y__eaKhv8&lk6B^*QdjTm zo%Xu4vyDTt;cAAqnZ}Pg)l&g^2}`fB=2YZ688`msIbQgmKS@3_scLus;lA$=-wI2d z(b+xej*IE~8JEiV4F1i0$km#OhbAC13z3*$@ zSTUTfOYL&85M3t0Ki9?Tk6#UYV}WFx{)PHYT|JNgZ(Jo=Hh<$TJ_8}UE05BzzMj&; zDf#m7^W@sMJ7y{!@js>cF*Db(t*P$JW!s{p!^szgGtd6Hrqh4@Znxh=O{!l{(zdEE2*^%t*X7%!j7TGi2_(b2Wa z^Yfg=ePV`J5;q;JsQP{U!Y-M@IW7{9X6soce4JkXR%B(^>Koa2)TZpNe#~QVSow`@ za^o9?ibD(&>IJ?|on$ZAF0rJ;;$X+|V^!xl8NT*Jxx^Wz9BP;u@Qi(VkYU4NUIt&6 zM6Xccb5ZR_HrjXoJN{~elTymN@+lhpn{L@GY*OiTt#WFGA}&;PWBu2Ima4j9a)xoM~OXY<)j>mlClj7HSJSo8NOHF zm2@_DLtDB@&x&`uS=jeiPk5jhKjn(}HRDD4F|Rn<9d|FdSfKQI5<`{~^Ov;q|66CR z_VS-(_pqZUo9*wWTJ^}FxKGw{Yf}82A2iI=cB$E^;d3~}=ZM|e`IWq%Q|>67`je>| z#3clob5MmgHt z)HDqLy2p?0QsDaKfeA$c%k3RAKfX2-3!Gvg`q{wvLaO31hu<6p9#Kwb-o4#f9egoN zP(E{E;@>&fXB>1rA;jdfUZJcfU&4sFV~?TxuL$$D@aW=dZZ5@XR;S}u+CRUxr9^wi z!e2Zh&WZa~KPp5_W4GgfmHA3jj`xI z8aZyr+%}73N-&c-#(FASKTqq1tgGlu&sV+&C%h4S?35z8;>P`Z@7HYcONnw6?{i2} zD{MDr{U)|~;c?-s6`W#^f;?_mCLC=qI6U=6AO88+AZ0+XlT`M7aQZ`W5A@oh(hZ&)yjoVt|!Y*lldx&A5V&?`owM?EYL=yNPt z8kwrG=wD*E>B>1*HAFUv%-}v%W1gB56xkjbV&NR*qRg@ToaYnX6c&-aFGYWHsLNj6 za!svvfArmgyT7uV%H}<4Z{)L@`1$%u-8UKwPP7Pq-jcoT{OxBaLro->#osyM{X>N3 zE0^!TKAAJ24$E!i?v(6y#esrs=K`<53P zzT3+Vi*l6Y`Wv2pplN#F@@pS|;Ev=yhFcPNnY1(wlw1;pEKc41c={6;M<6QNu!DWKo#2B}xniS79U0xi@o^u5P)fRCpHeYcmFtXtj=TSJ4^l~b*sIXd) z%L^F=A?`iRZ|s~Sn=C}-+T^z1aW^?B=wA3qMD*&4Pi=}j&uqB!UAiDytSW2C&vQ++ znf$zmy@hV{HN-!jb*59$m63&o;i&BQ>qn2>l59VsG$TK0VQ6yN_5JO)d?vJh<2xx( za3v#8V`j08;rHGh#+xJZ7d-Ab<+FLa?EZ~9(Q+!Ew0{_Sg#KeJp1RxO%*?dMD$G}< z{Thqe4t+eQ+^KcSC*W{#PxtCZFIewb_7cTO>E z?(&_&Dei&a#MsX<3F$1qZ?-A9UZTpw<#X>jBfCq=8&%p=_;mc2glJwm@hSbn#;7ii z_G3|6K@VaKroQ5Mz2MXHI_8esRUL^dpWd3YU{;k%&jO#cl$M{|{t}OCl(bWLifYK;ZKDbsy$??IszDvENU=Qkl1OI<1^!l&k=_+at=HG zwY{*PD<^WME${P6?kkf%9=dnmWM-SSw?hA%vmrspcjz9xqdfhgz#l(%{WU^W?f+)zxao8+b9^pSxSN-$@y*<$dGQx{ zQl3q#Q5LXGNX&eG{EEng^BvD;_;5V2Az429H7+>*<-^wu0fu6tgEY=Y3>XnJ9XxuZZQ37E5xdZrh54KH=A! z91Q>J9NjWACFMf9kwIXge{rkGx;fm|-@7+A#Ct95T3!_p1TP&K^ z%=A0N%{BGd0wIlOTLV@koQ=HWv1P`V?fU;Pa*6PfeOP|slH$=QdRP1(6tuHc(1 zC#2fUHgopUH@8|Hx#I=qXD&Qo{kcMI7Qb*oRldT^0yD|vB}H8Mea1XFGL!X`f@c*< zvMw{c@uGGyd(*jRKFuYuU1x<-PEO)VR&ObB3yWj9vXEHGU%cgC!JH+^&X6@Kkv zIcX>%AzQ1q;LuXU z#_(`U;_7z^E=P9<8GW41^-i#2wauc4wbPW&WnHg2Jf(4e!QMNIpPcSUN>)1bGG=Q% zN0DlmCa2GroTQCnn(c1q18zQ;)OVbrT}u8S_cx?9e=P^m6;!F!Dhc5|fF zf><~TIc(-{Zd`XK^u&W4?SOqdJ3a-o7#-cPGDvH=&ll?>F4qf=_*N`f>dVp?cV_QQ zuZsCI7M*{Ux~}eLQ*gwgLnoX*iY#VM33LbxnIgz=V#}H%YYrD2J=V*f)Zfv)Tc@Mi z+tNF6v)lOv7S-0}kJw5cPCEXQGwSI>fhkF!&R_PfJQD55QasJ{X~AAEwW$rw4=xwT zAIPyjzO6viLDfvs!t`K3cL%#iu922tK~g}~YQYZWOwVsWEDtRxJTAf5+cqg#;?BN@ zyPYo?NOiWdB`=kq+Q)In#z@WKd-DsEDLi2z)|&$?j(GH?$TTWU>`D7o9&Z9Q+r>f6}eV;be~W#|IY`v-`hi1gu+L zc){R&utb)bW7(gN?`+T6{*(7!UU*7SfH^t zyLHg6nJQtXs-=BpQ!n}(%ksV2&?3L%z#_LB9F7Mr)Uy;eDHO^+R$`lXEW>!aLi^1( zbw$fK?NUxMD!MmyE$VNy(74FU!eh|re1*rDM>0p_RAtS{UkjWTwP|p;{JZ=A;B2S2 zXMg=)lzq5NIO2oF6dv9Vo=6SD14+%E_sXu`XmT`63*73nDa1ESe_~_SgWrAg3tzaO z>r|AjwQO3S3aHPZ*v?^=G=_%jm9dEVXb9~(q_H*^#TW%TLjt_LcwA`VD%fU>} zIB>-?%aa|6y$?Mzx^*TB8*VaC3UI&1#Jav-yyg+_V*c8ttqYDWb8%wo5Mbvy`e=p5 zHx(&Q6+!o=S)E)wE%O$7Ouq3+ruWs1{M!P_Y<$Oh$`}qd9y)e2<=~CQ1_u^PoC@_) zljX>`^m$(T3kQzX=Zqe(EfGG=sWS1~7g>%6cIpe+&IP&a>|gxx$ItZnKmO;x_!%Gk zdR5n|Rf|@2E$CW*-{91$6`*@Ax;nb}FQ$eBx`ep82D;bp`1ad>!o`1e_s+DlecsrnD4l*&e-~Mymqfh^?-^{Cierx6=|FyZ3JQbCT+@8(d zcI%GHBu^tRk2@;w`S<8g`N*$7=j+P{l{?+!?^wwib{zWD{?z?joYFl9f!+O@cgnNV zl22JO*=Ot!e-q+nU(U_8#X51-o$`*0%dcj0vu%#@a_Z>{TFlDC;>j}0Agfj7NkCwV zQ)=Up%(*&zLUZqah_q;Vd97#~ue8CNQZsSUcJ<_m^3&hfUN@FGQ>?XW)xO2X%touW zJPWg&+Lsy%1z|^cPOVzCYSmhP)~z1*xZG|pSkg3c7pvHXOR;P#*9LmrWm+AbyX|)F zwwIx6kE#S~%bYrR=HMBSj#Xbvp0KU-qAVU;VGmZ#nTvuGRm`suH%dH;Y5Q zv^X-Kzx&%(^@X1?-`N^4?f%S`uAbS z;K&sF>n0YlVo9)d3+#^}?I8p44}^8!Ps|{xHGL%(|xg>UqASeC7Ur+?J7l z?}W5pnEodJ(czz5&TEt^``I|`9NzIXJJcNfF~_x@%a;AuvYYjNc0$a1dc7`u*1z5O zbRzqciSLu_<9gXAF^Ej{;x=CLbzYOm{5j7rF*%(`>ULZfEhxNW4u7zM#g#iBCirpK z74EB=6T$wqPqfic*;Z;Pjx}l;cX`ZPvo6})jJo#ygGW=bXx6`_d!Bmyyz~7gMx@~ONlD7VI>pFKa^=Ew5 z>e-isrq#u3$!UsAlDszieXFnIkBBs8p36tlgLayoj+I!=qgwFGEmW|*-{o@q?8gbH(ouU@Osv$3(U@#ps&u9WAfh1G03-oHKNVdm{NIW3-} zKI`>W&TV_QGh(Ye-{O@AKZyl$o|ezM_~-ev!!8afmjo?ueL2>qRMInH)sjc^8IH`6 zb4^#8G=JuVhhHsAnF{VKNDW?^^q~B~#*VC$uFczztO#k{$MAk}c=h^|%o=kx_?=_n zaGem^Cg-1#XQe&iyz!KL2GhvNC(ZAlb+uh#Gxdwzxv$5xvcK`fh81~FK9hBO!z-oc z!Z$iIg^%#e{x-*b!GV)$=Dn*AM(%Ju5iZl+yXWakjlXJ}6LMlcG)5m^Zz;;}%5vP~ zq}_}&ow-`s*V{Liq?mebDcpZ$x%8`}SF)#V@bwgEPX4n!cztoonN=UFMi^M!=I@~NAh^iMC|m z-uFp|=9bn@;+h;%V&S2Gs3Gft!@u;e(X08+t?!wjC@_KdAz#LHMt?C8!H{05=}Pna z4sqx|RIF^?oX;!8bB!Zt^!O`W~r*R3M`(?WBSroM){V%us{;%q3evx3))8wrGTX0PhnAnjv=c1rN);wM3y|a>kmsdE>Uv;)8yUWc!{#U%@=JN~M zbz*YfeK#;*Tv(sjYQJtR|LbM!f7Y|`*mHiE%^!cL>Ta^h;o|0Q@uwjkwlmAFwhJ$t z$oHQ8Vh`U5mmcTSvY*Z`jtNP8YtXp(hF$K%1ux%eoEPufcJu8-jydv)9$$QlMS@vR zOci;hl(Tthpzbm`i~SEO5>;Gh&R{k;ayEs@^7Qh|wO*|P%b%q#HWakce&V07%0l_`uqR&yBD&11S$>w{8zXy z|G;FwY8uOl&stME+q2m)qVf{=6#Q!@%DV=VX;44lJRREpESqzB`t@i)iTHF z*zC>Sc4BF>i@?vjwTnL6A6&4`YxbGSM*>=2nq9%pYget#yBf;(=3?W=oK<35Z*>)O zJ@fu$79e7H|J7N~R=#IRO(B!jauy#}KOcVfm&0e?{|5vd65bRV!!14{i+>%|V`brGbro=N6bzcEAt2E8;E=?m)?j94L8C1kM+JDb z9R%ezzxl!Z@QnV)d7Iz3yEokAo%(MbPg)U2;`C(W00H|zm--otLayId{V4nP&+^|N zpZZmptUe=us^;j*4O5N>%I9wnxZ&9N&!r)dr%CDZb!pCqZ#6SB3SX{mWBC=Cwf^A7 zhM5Wrw?#fyh_Q9w*P!-NF7~{LbmpZD-QC8L*JqtzS#&-$G{h^^aK+y?sVi@?Q-!=I z%RCV+IKv?oz$X#3bd2);LMW>$0yu2^_;*rNyT!m%oZvCRnK$2i0~+MglRE`$8a(jM70?3 zDQPW>eHD})((QH1XJgt5t__;3uWuipA&|`UAci}&x3~Y*r&lko_}Sk57g5wUXG*cd zyC&Nm5&|xQERHRVHGKL}E)KD&f7fGF`fje#QpE+A?>bSDSSbR2LrPy`1)upVz{U$pEglTo3y^rr?}EO3J|xg8JY#95acxG6-}3nC?@)DK*=Il9a|?%14b3J*Rfc5%Iae?#=d_JAeST>;H$#i5oz?54fBF0CHI8#>i2%E(ZzV#;CT)P33{^ zxg!2v;Dg2#=#9C2!mC;O8>i_|pFwd7LO z(N*U7zvkHF4Rs1l&hKRH_`dR3srBUqxVk(so^!E()#0OTzxDV1G|r#-;QZ4?D~}n^ zXa9TTRV#Be(`?h*sXNb0-F#Q=B3&-7dFK4Hj>mWRmXz*&(r@H5=ZM3^xo1widsd@0 zQ~m6j*&Q?PJX*VRMpK%Z&l$1Dlh;*#d79m4r0$oNZYwBadCySw-1qXd>94cXOz(#t z+<)yp*NQLMpZ6wjfBNa~`^z$OekIj zmQ8&{j;fs8ar+Y2CbPvAEIz_~@wt(W`kY0(Yn!$_U-hiv_ey2?_LHmg87wX+pLb)cgi;+78gvD_NX{7UByz+lJNe_nNHb0w=?p+ zd%l>@@trr}+OzUTzvK-}Zx1NzIV1-DVmZvYokPL9e%nvuFwMDgE)zPXZKHd-WmcSh z%<3l?*0YU$%A#O}gn)pKUHa#2N|-ccqE8&T%QUgy;g!?d1+UC^tqDs!o)udC^j-g@ z=*VT0=Pf?bZR;$N&M|?1Ay4jxH5(5*uX%63;^G-234TxK1)-1F*t3>xKNJ^KsK%eT z;pD4X2aZ%7aSd6c8op!0^lw_LC9eOg6uRzy(BU~_QirIpik5Fmi>V58a$3sLvT0cz zQ|4_veAdC@&?_`{R{uhd|x&rpv)g*Uvnc9Z;^jb9yP~ zr9|@&G6yHl{NLhJcw>pYof@b18*6(Ji!Wy^exGQbc&`0TO}~?eLDdrO3m;c7yQ`~P z{nGm>fA&t{$IZsmPWJS-y}hlMU^3~ngPe{qucpIA3LtYujIm`uOnuY&RaKP48c|#AtoZ>E8#B zv;DZQsT;H5#4nvUM|b&7-ky71T=1}r;AWI#PDD@bL3z3l%0A z-~P+o8qMU!{3qbUFB^l&x&p~Z0;&$B-?21)Z_%z&#b(>AIhF7Dp@7=fr>f@y?@eSV za@G2L%Ok0==1Du7MB#BA%T+6u$R=FQDZA}c`zH6%U+1qD|1-+?^9H8ce`V$dBXOL`;uB7KSkMlyov{!W#{pV-1;GMKKNr>?S|1-XIxeW;?c5FKD88R{d(%N6n?-T?%mA9PtbhNZg~Tn%MuSaRm6Sm(dz-|G+Q zOYGsl;OKTK?CD`2+rwARBu-h^FQc9Q`qaVgYc%)1nj@MV6lHk9FCtKC&c)TTD%+&e zxr`;2oDo+xIJr7yRRrZZ3)H`{d|gysd%OQ|DvO4<(<*j{=JZ!a3wH|6(9qIhV)@up z`?g5`z-9#tw`Fb%*`NA1GP8-id#{$&e2(kAbMX<0IcMU6j!w;Gzq5MTE%ym`>jhJ9 zzT9-^RonrVO1G+ge(l`t=Z()fvs7-*3fQ+sWE3u&q=b(n$j0hi)oO+!KPToj3cDHJ^Gs}NaJgY3oKPuuX9DAe>l@13 zL#0=}s){*l(rV%$S<<$t=gevroz*gp1^q4y_a>Jd<~eh*!sU#Ez{4fxE0|8OA1N&8 zT(VN%qW@`GW$f{d0*w-U2YnKpEac{W5%joKE#jVb&>m9t{iGBxMms5f4@ASeTITY){&A}>3riO3pa0^#~HLn`(ka%%SuN63n>W( zw&~7}dz9KI8i~wLl`B%$VSQYGPBHOJv_pt!al@;lav#1+>c^IEOvl?_y02{Hy*W#{;)Kyt+bKI(&V(d5G8l>O zP&g9psO!Aeo9}`TcNJ`F+F3V1nHm=Ghlz`9AW< zsc?xtd2sZR0SlK%n`ngPQ{!iiy!W@Bn6XUe*WTM_1pWnUA3L;Y-Xr@ou@jk7h0i)a z;J;&{d*#4X&Hn{2ZzOz=FH5VrnavB?3wNixJFa=Myqm?qal&E!T*m(oH@c2{H zA2x=TQa7U8J2r)FkMm51~XIrB0eiEE!O)u(*xlgND= z(G{YWC)6!w8<>XAO!?)@zv7YkZ9lV>nhT7hF5ecsdvddSOyTz84NZquEHR3G(N)=F zR-@+C#a32fVPf;(V}}s~f8?Fw8~eV<>HVC#TVRvO$q=K{EuSO|VmaId5+=^v(xh7A z-fX|%;?~bs|6SI%;M+3J0mUAjB zRzlLjugu#TBMc90IDT0}xpBj#(|QgV27FR^pr+WyqMi6~>BS|d`nmt=R4vHc6}(S8RrTu+ zVg8-swRf;%Bl~yo?~aI zV0^OTq=K7D%QeL#d@Ck&vCFe<&SI8+psx|Y$!)rDQeSXG1{Z0t zv2C3=fumZvtM69njNn}5Dfgw%)^~*6=hdI{JBDeNRFaa$H->p1b(b$x^p|F1{ONvw zZc?$9)}mE?yAFrg2*pO;3Vfx*9vuvldj&cw0aHS7Uc?DbaVM&nfO|`sWWj&{^5Pu(iXByS$cKe1<6dF z#K&jf-jgwJ11tOIc54A!o~LD|eWY!PiTw>ZRP7Cy+nmc3?%(n^&{o*I0-mbHqj zsvV_dTAXggEze&ht8!waUDl4YN8_%%MqRz?#dT!4769?*ONMV_~D5*mFdSmZd^D`_0`kzk|Ja8%fhnRX?~mIB-}dY zKbk09r0!AB6Kun{&LUCJs%g^$nWk$NS%njG3>Ga~W!79RclaZN`W=PuyW~`EbZ>oE z$K?9v_i@W6x#9=hJW~S{n^_}Pv81+6yQtT6W<~Sa7Yx>NtOpY0@19!lUSUFK@e+Q; zd4?B_tnIcCdV+-%ake5KKYb;TB?s-_D}N0%GytE)U`Qhe7% zXMU_#VHf9xpp=g{a-CYA@Gg};q@wuC`Bre+gLzCH`J$g1{t2B|XMJ7l9-k{MH`#e& z{l)Xs=0{(C>b{dzG1U_?yUR7yo zW%1H%R1}hMU~Ky`e_yn-yVN^ZUJ*Ct6XHe6C)_St{Q0jCIYGiDG*skbD65O37w2)S z-^PzOv)??Kohz_{MeoGb1D4MDQQxH9eZ6)q;5<+*{;W#IXJVp=;ssYTiEHbp3WkOr zQM}pT7VxunVdFL7l+Wxs+&A-$5p%%hG7rW({-TJTmr%NZ>aO(!NLempm2(V4@_ z#uGStvM%_!R4?$^`tWdvZ0)Hhi$#ooEilTn3H=zRjiuBPW&78eDBmP;fgu6}=cV?u`0Q;(7rT0CxMMe~K*okdwQ zUR+#Lx8ejhIg|_%Y+Geshyh+My)V;DKVwTDT}e^@*F?C2`e_P zUK_f0g2~Zs%f5%TDo!ZWHuy`4=48u$k#hI*-64P9E``bG=eZ$&&n1PLpMMC7KkrOsQ9rQ%{`O#uDNpC?VL- zHb-r%M?vwaPtD$KocT3nDtXH#?uE)P7ER9Qd6r}yoRrw<+$?am!S#|4kHMz1w>Z{L zxzBQr)p7-&jllDh))j5XH&0Ga^qtStQOy3-@Q5Z`L-0y1&VcreOR)_**$>Q9YnUSw zaYC;_-uz%_E7u<(^-oJ`H<%c9?bHaE*~+rNoLS)dOs;wkA(jaXcPzB~{$3+lP=Dca zey?9@uO>2neyYDl>ynStuSEHr{D%8-^8^_#7aUjlCe815QAp{;k`_6E4Vy1|$ZmXN zX6Lf|$qWsR4kfjP9bB4CYC_#tpDr<(dzXjl=Og`o(L+3EgjoX=&sx5#o$pX`^$LfI z@qrioie4PeOdiHel^Q)YtE%Tpv8uN_TzphzLxPrt78G5JU=U}5HPJtf1JT20{W%yLy9M~zN)6QPMxxv9&rlTf# zQRbo?8Q!h4Lo)8lTd8&=9cSGl$v$(z?YS;XN*tB82WfjuXlvv(Q0v&X(?wQb!-W`i zR^~%FU9y+2J!hV_LUh@J-ViM=xtUI7T@nxVj9A>hB(V8EKF+^v>9e?iQ&TSLmoA!l z_&|<%`ZuwxTh{C@8VqN7mRrcJwAos?C}yYn+=fCm-b+(>u9gLJhR8LUH8wVHU?}TS z^tzzG`(aSi`EG3;<_h+(xO$75x0m}0Gp<3P%UUQjVVw4mC1X^}$H zuY_9%D)j3$ZG(928;>!}9+ez!g4!_#% zT=0Y8#}q;RPOk==CId&mT~DM00>0@NZk!zXq>5ca$dpk_dBT*-z6{rDf*!6A&b+s% z%KzP`GON0#6Z&O&4e$AUPfN?CC$dNIPIP$J(Z(Ujp~__+k*8yQc#V(4q@Re{`EtQ|H;ro+_1&3ozc|e3(q#Cm z_<3%7BKvjLZ%XO?Mh(J@nyXnON~{(9TKU5QqCTiQsU10@!Xj<)jBQkUH zrCE{|GG^1NV%TIPloKnZ4nDAFv&d+la{K+ihbO-LUZkS5q{-u$O2>)S^WHV?m$Q5k z`^SRodhM5EhZAyQWu$qlB(Lpe*>_*u^H%VgARz@eE|*4b4G$J!gTsOse>gZlYWz2) z^>^`=1`{LpR0q2WVUy29*}6ENeykyQ%x!_jE2TdL^Mp@WH%W1RJ~a2z&LBZ;mLR*y z*E+JDs{S&6qJav9IU2fUS}IX?6n>d!sJBq=dO;wrmOg z(Di-Zflh`ljSQAW6Kc*a@n^rVyg)3?IjQl6XMvlF#6dpUn*MV+WtQi2R_>BreB;lQ z(5knJ`)vFxC%q5R*p(Rg-YDfvUROs1vuB;t!SZHL=d@GX0w>l6O*q(atmNXf2eH$? zmn3D*XTGSp>B%D-zj7CwHHVsYbEnAc%+=kwIBM0ZRfjFM?|mL3EEU_&(l$#?yu^{OoM_Y%kiAF&xliQaNrHk9y4TYTC9wa|p+8kjb zaB)Gd!O1kA9XhS7lOHn%elE9fO*nFg`5DK&C5QGgSi2isbJ@J&0#8Qvh+t zLmEuYg6bTLatK?@)Kco1w z`7#b2NBb^(>8R=tuw-~7mozcJ#$n@?jhqXDM41GX1tywFa^8Qo(8BFspjmHMfZhEJ zwS7g6=6m03Z*zLNO8Lr#Ys(g}-Jd+?5YL$dN?gAyPnIyP>gZ0+m+tJa7yrxN7JqL2 z$J&24{{QlcWfr^qK0#G5J!htmMB&<#&QcRT``R|#&h1IQaQ*W?&F44y_EmrMNPB(b z+j`4y-@eVymiE5bpLlNj{R?Rmmw2i<`5apBnV53S!nfz~L$OD8^KZ0D9qeRz^6dAN zux?SILo-6et_S;?964s#+i+Q8&19waCFQg2CcgNccwownG~OxC)Gjd#YlzJ8)5=mv z@Xq0v%YL9Wkrl0=?FvEh0+oXAHUb zTnlMC`b3GLoIms9Y$kaDcGaMj60XVexvI|bYFiicFi9Qy$ow zIqoZFSaEBXHyOrp)IRy)yyn*Wz=r`P(M<5!!{LU5 zO#(-jU$V$ln5)*laErs`t(Vk}J1&}dF_+o@qj8s`Le64ArY!feTMumd<=0FSnEcG? zfKC4G4E5*C6MJ4vV*eo2_B5}6e~t3rMeHX!?{NGU6o_Q3{h`6;;mr21eDjI8W$8{+ zpHwBNG}tVfVE0O%k>5n8q5P8l8znI;9=Vj}>4Q4Z&ol)dDx5+nR`vlb;a$Q`zPX{rxa8LF7Uy-fCap1Y=hgR9j z6;BuC{8KpC(fG9_;$WL^|D?%rwXutDR#&^;`XHb(sYH?UN2+pf@Aejn2sfX?Eg7*xhO2>njT`PF?ZD*tKbw{sIQGW)bcHbA>rCtab*xe`UgOMuA_G zMNZkWNv-=-flx=c=x-O1XNf*SfuTmuPBlhPd7_P5a@f!C@G-a;z0hhDK5}DTw}DHJ zo~oh1BBr-y(-JBgmi*hPeuU}End2)LGgT@vaCtO)u#53C-w`~WZrr#=nPa^RPeA)Z z?)8`d+&nh>lg6S6*Jc>rh-p-=4_;`tuh#g+y|nFte{G9f-M7aqmPsh!>pxZQ7q`Sz zDcz%nT~4jNPi#qqvMv`}uwVE2S4Y2cZY-#{ZZu^A@99VC6Wb?xP7nz;_{r3NT8D$J z#gV-^E11>d%qEU0E-WluI}76)siGsEgUCokuNFII62Gq zvRiN3Vji9otF%^_))?m7y?**2`wXkdN4AF{b*yy?`WBUUn9 zWv_Kr4jDP=92980q444lpS-0^n#{Rf64s7i_E}VDZc4Gb{(&oxIR5veV)j8-A92zXp z;>vO&*x-oCgJp+Ast+y@5}ep5_t2WZpoU4(S;IPRfq8cii;|)O<3Sf=fm@8{{kqhX z-!fF3xU|OW_Y>iy%FdH|i@$`42tEpWk=7ZZ*`bgo(!7V^v&>b81S;x}a`7xYCv{et?eU>F&6|N49Oo;z(!b81DK{~8tD$hF z{(*$=GiN*9*YR?B@hF4$!clYA7miC#A4%A;;jQOOrXyYzbKZ9ZA9%|zQSob!Wxod7 z0p}w#n<9EyXPlB!>WIqQ$l}bwD(Cvyc0;XvXlSXd)zz^2+m5k;zZ2>@>?SGCoSl-x zJbU@N9ThJYPkVFutg!ytmgF5~wGE+3Qd|OwJ&&20bRzZ~bMw_TasJv}aPOhyv|S!% z0xd=@+ImrDiIFp#Q%%^?czb7U>z&1X-DkRe$DJzEH5oU)EHG{Q#m2TxnC&E|_tuMw zl~;VOZQay6!E(!#ux6={KA~0>yn>1)hw|Qvt)=;dS&}?;yR(a<5k~} z+=!k2hxMc((>pyUS(&w;+9Yz_j=t-8G2v0d!O)P)x0bDZ=66ECM4F?%=wmUqwopqZL&-)#++w)O4Yyoe7JD;1E2SQ1OH1%yLFWLtntZP zdU0)>{8Z;-4ih6B&+n-5U8Ex~oUpB8%13+6{j2xPp4}w+X=AIRLgNK_HEzeNw+{7I zYvyt2th{@-?y%A;zBy!n!dJd5>ahe!T9gyi>H3-O<{UGlsnEsa5PYD9#_%gn5{l0JTYmxWFYHV1Om z1TLIi%l9Wha_X9I?fq&N9FmM8{~A{8Shl)5M3HOJ1bt>ViL+`86B(9Y)+}t{u-w&g z;g-_6@Fh|m2aaXlA_A)N8sWYrQ5Ry>BcHk~U zS5HW5_!5zucKwIq&X+t&e%?9jl-8=1D}F5O+$S9BZ6(k6lCOomsN=JR>*sfN@fyo5 zvZO!$*p*Q7U=mM5w&<<$_6qIR)iD>Jn^na8+$AZyc86=Z_LOV67P1}-Cm9L}I&3_} z5b^T5jg9`xSkWSf2cO=!)Ofo47dBb5i5_zNT9Mn5Ae7?l!76j`ZGt5SEMa))`@=U5d=6QxnzJ+&o1D)z%uG>f+O&|3VMB;e&a`c1 zQnK?ZHU8c(i{`k*Uo$N_A<|c^Ciu#Yyu$R|#bt>sf6{yL1d*-g62V3M@ zeoV=lk#O}H&#{2Kx;}eZF%|Roh3wv`naiJE{kCyaQuO|J%=vQKN@%Dnz2q^UA3o{hUCz1nY};4Fs!Gl6mpZrnGU#d1LGJ#nykVAMH-;k2$0;b48O(a=OC#mpgj>6e7e$?2c=1WVblw>SlQxM@xhcSua!F#(yPU^diWMqloYew? zTWjyLZ&-b*z-i*KPcygAY%>dFmh((I(&=ivV?tbyf|GP=d> z*CASEGF2|v(%fjidX>yqp`3!MzI~66-WDnSV5sar-Ml^E?J{AnX^G4DC66uLaz%t$ zM9DF6wh-G^#Vk)2_Ao1lN0N8G9r<-pgF|CRiONY8-Th5VSADYK-Mmor_MVQX8!}3G zwk>k(_Ip)#2j&}h^IYydPa~%!nOmBC!RA;ZhP6CBqXVDnQM}Db?*VY7#`(qUzXNCbtm#ev1egWX`y1i3H1 zweuAuiW*-r*G}FtkCCJD_~I1@ukieLIVH23OR#xG@N#JlW5-KtVcVXsJ& z+BZYN)#buP0l`RN*)=;qpMBzGy+BX7OQ0`xiO-&s4?LgqNVl_XI{QQz-3l>FY!fBNDwPeOI6jogmolkT~9_{0Rv6h6fj za&DJP)QJ_ER`NMB=C8M%^hR2~vPILaVAU($a=oJa3Yy|U;loXZHhZoO@1Cew2JMAXy~r2R(U6L z)n)_VCtIh=<$Y~*;1IRA+*!1Z=iR$EZ{Bf~D||@nd#@rUqOh%PnNPHVOdIc%4!cVq z=36@ctgYKFJL?zo*~uZ_-0qpTdD#m{u-s95D0+wEaL0_V@0Q4VE?jZaW!t|gZ(I#O zzWiL1`q0Jtkdf5kt8$x69`a4x@Zguv;mtFyDCcwVd~I0Rq+Ho9B2Z(K?#CHBwcxB^ zMcaiJOcPeLw=!RTaO$9=(4=Ko!ms!;9o1=&v$ZsnuX)I$&^krTQ{GT|(K&vv$B$$J z#fmlvdPxh1&PnHX_v7r~NMvrgVIC64B)RpY!m^1j6If3vr2hKCcl}sldfQ)*U$4L3 z&~GSKRNeVIq@8d*DWq;+n@>eEFxJDqi%2eII*Ei_+GI3)?Fa-W{mebw=Vq z!hvts#9~?nTv)hfHFZtctum8CbZe`qqKhCStB6P_tAGm&$3m4!(;K_B)x}jN<*_(V zpTWMOYwg!LPs@b2vs$R^?1)XccAhoFh-;U_f}n#}eCxdxHWYU~WWO+TiRt7=JN-`F zvRrQ4>G_`H7w?rIpHLM?p_4MJ_ON~7&Qao=%E!3gf9C~f_e)uNhi(+JU3q>?qGGq6 zd*88u1qY`qo|rK2g7q=E#n+}Ey#D^#^d*hwy^gRQTGcEdpQEe1GQ@Oh=Zv$VqJfO_ zZS)pCG1lM;YtdwVxi(|*rkvZI3sR=u-kdk#&FpKh)>Zl|A9Rry<&O!JyV3Es>q>Bi z$))>C_zpCzKFDItQoz2_KkAHPpvD=#mY+xCy%v_L}jm_(q5O4-6RJDxBCP zwTi`g+5x>I>`$x@-1&8^;m=B|hbD0jHp^u0EkAf8qE4uyUhp~3J$;S08bQpxJ07gE zkYzmJa*1imrE_;?AK5%Tb@s#3g@R61o)zuJOSOE&eqXj@IMXF~j@=-kXo0hW&uqUI|>wdni{6eOAJ3~ ztA0RKsz+^mg~I!b3#E?;pImh|M(Nn(OTnRycVlxzHuJQxwAS!^Q{JWNr|@Ipj0IJS zF9jP#B?Or>*bUFHrOTe>mt%gY|1@}&-T&IUiG1=E6WG3ohKBZY%v0JkZ$W$HZG#^? zk=$jmor@X-8%3V1YU#XE99iZOkT%DQ-pzu=R1jftngDWEHc&=DpQeZt8{9NJY zg@<96ym;A9zKGl3#rIi_$8}Faey@nc*&nkcy381!G_y{bQkAs$VYj!Jn#EyGFC$-B zKT$qci3XR8O0yYGZp*3eeQ}ca^x3KP-akKCJ}MB`xVi9HzA!IOx0+%1ZOJ8y7Zw=F z8)eu$I(YR;`r#9TRx2hLT$#?V6nf;?fdgfa1*Fe-sB{MSHC~=3tmCA^dFYXlz_cT$ z-zqgoJbdcYasBDiKV6CM-*9R0P39XshXuK zCi2RkNBpUt1Q}dW$1Lz{f}H@cjPYm9iE4l6=bz zZ<}5Z^s)PTUFnLL?502S zDZ;2KXQ>O@?1aOwnbWiOR~}&cA$xk_qrFO(o?na%D|uf$y>6PlWU;}CqlYfMn13hl zMN^lFY{joTC2||?zy9xJEY{&YZ&N4#xuB@+KlUkKtKH$ByyE)b1%kdiTqZTRDyM(V zIN<*-`+YJ0*^SFDr047XlHv84dp-U0wf;AAnvV;#1lulU;omts;@P1^ABulz@k#D@ z!BX8OyZ*!!`P=huc)nf4e=+@)=*$m& z{oGNRjlF2i@(&3`SDjA?iSxMpY^zOoPWhV>D1Wd}`^%i1U;Mwmv9>s69yD}Qo2H|A z&?=2BP5Sb5jpD|=eacJEb@}?v+E8@hR|c)KR)*H z%l0q*^-*j8n*ZCC>}w9l#68{DDN}p*?)87sH3!vio!i77b8WYysiK>Ejr8iJC7Tvm zELwHw|KdvqOaAXsJYk|EyKLoRNnz(ZOa>(nkF2=S@i>3Y%+E_6eO!@ew6SZdhyA6M zOKZ-Fzk2s!tN+n`y;{x_-c9w>dvsUDQqOw#l4Wv2ks&L&K3ksudB*3%Z%?Z!$$sv7 zHoJoP^j(jrux%CA?`YYuQkYXoxU@9bRrho0WRB3akLTnYPucRbd+pUIo7E3j9GceA zv!U2_R>!RU{`TKDRy?yW=hqI(Hdwei($zfV+qLXH_ueyIPxO_lv{ zTD{QAI=aPp^M)x>b3*;TxxXqlIlTD7kGlE2>pYciyz5Y@S|_mUXR!3)NDiZx&nLCm z3-8qBU(-kqedZiwxXnx`YqDZQc3q{^+}ArhvS!?8-0ysU>f+-E&whJ%XyY{>U(q|o zZ;o>D75&Wcf5d4S)xIhtT=t($Ud%Sxek1jJcTC%@wcSJ}y;~%!w4qOyGuqsnbCUCJ zSH-C*iHQ-R(^6X^o9DEv_p9}_Il3iIO_Pk=TryQua2EHr@UjIH%#R9$Hhq2e+PKVU z-W*XapI*@wNkM+gPAUniw1!IU7V>0qo~+h!XOHU5wf~#HAAY}gsb7^@x$&kqNdik4 zzfL)OO-kl^PSxC>ifJ?FG)5@x*nG3sO?Kw|iY8&NmbFs7o9|d1RB>`OT=T|%mdEl- zWj@QFJqhkRae3m-mP-;&)vHo-mzgU{&Pi=#PkUo@RnO!}S!B;z^O#eOdn~tKop(0y zoyJN2;yz>3`>ZsH}k91`hdS{5-dCNee`6eSv9qq{5tUc{5j$9_iqC6)QBlRWq0aaUznUB?|zkm0oe#7^BpZ!mGDl^=wju35VRCZgLe=9xMP2s{3 zx8^;vnOnawPWT-owD?nArS-#$eQ!m1mzwPOXgbZ!eEpv4CB}Bsy)PYgTIOlwoD$X( zvufh?UkA_}37ltVe3oixMevnkyyE*-5GV_OKgvv&k>hxU!h- z%rV8d82xLqnh(mJPvZFW2UTRUBR!%^xKB_a`F z!^IU<^?mn=E%93xoGg|P6MFaN|;r&E?gv7w1sh^`vEn3$F$?88-)X0w*}TL@7({B;s1o?PV$NqQl#V# zd`@pZV*JJbk`2QP+5H>jgA$G?cYc2PLt=)}kGvUo{VqHx|8|I7CD7+Ad)$_Pm;V*I zUGDriB|^7Z!(fWL!5X#r+v&~BdS8_U=iJ!7R@Lox%O6p_OXn>Po!dL9NbHHhQ~t#h z1=k99+N(G@{ty-7ygB7$f@FJ*bEEq?&Z|Gw&&Zvzh%-1W@Iz(SgoB)CtL}Vqzcowb zY)KJE|94m0gbNL;ml<}I1ung6(((EC>vg-P@BEb&H}!Avc2Ny(fp5XfFaA4ld$NuG zuloIh`#Vbja6oXfiLzm>r1H4Y1|#&h!q zzZGv_v2{$I{FJNehEdG(_-BbG{5x$VCpn(eOYTd3+rIMg-=F7{>vYbgZhU-swMpjp z7q>(0T}}%AS13;Z^Zpr+eC4?&nf~H< z&F)L=KOVXN+s;w&zjDQ`+g|ne6z?T1t4`&g#L=w5)1F>#@a)I#%~k*1ZC;&io6BAr zZa!IRpVf# zpr$l(gS;gPOd-yNI@kuH(+nf#a_bdMR5#{i2=i<+qop-Mu`Q2w@r&c4a zTzV+Ud;048yB}Wt*}vn(^k#nkZCrxQ$3MT`x!Bdct;kkxmcQ{%NB92Yku8ehnZfah%k4Vm-2Bn` z=fel@?zxK}-1d7J{q^Zo{rg&v8>iUwYev40c65_Uzh2oZcH>!$V)>mChr3&zJb!MU z@gekG`|h)|A1IYCdCRx<9@p{rp}P;>Q`n;RHOS@XqaEAAik|n{oL#Vti+lG&rHZ@i z52qwg)F|Wr`Nn(i=UFv>Z?qf!Pe^n#44?JNRIB}J3VBY@Ksd%sa*^i~%Yo3TL z5KlX?_+V%;^XF#O>Cb=Nj<481;q&|V*R>??_bv#wjEQ`Zm9gx=p$R{}GbHVLWXy9s zs`JNzzRnwKkJs&+aIJ2OL&pu4mU0K3)`niWYEs9{Ef**4U!t^S+JUxI#+OZLr4v8YOz?m5YsLQ_{ZHE# zeydx2KYKRI-}J`%2m0b(OW)7WSasy3^;GW@OKLPH{kpW|_Kp4*&I`7t1a&*VWV|pn z>FbgrcFAW!NAAhbw2M2?fuj%h}|6D9B?(uK(4|kTjaJ*T>b9p3_iESMENIU36PTwE8L z)U`RU32Bn|=&E~vDAfE#!iDwHJ0$-7x4U2S+x6p<7e!YsDjnaKzfxZ#s^Fw9T+n5k zFFPT)VnGdd8$>EqSV9-`wBL>9b`6-&xwGKSO&PC6B?6#{!wa=KQN)0Lr&qRda10Zen?2!>=?+AxHTIV~vYk^&NUN`rBm{4RKC=sx}L#v^KUuK`&r7r8N#g=V6hjS0Kl%|;;Q&kRH zxopK-zd7y!(jM{k_1Sl_A9isGc`EnK*B7`UXz_-%%;2op@rrLj-?&Q41pGHIZ96@| zTEyMqNrFjNzrfc$H`9+_S7Z8-5w!5`>mi;Iip3y1f0$-L?_ zINOfB5SwD4bU}7k-PV$Wrx{xs5_n^yCbhB5J$+bFU6@yWwTQZ{!;3GUo0iO+l-fB{ zEy`0x&B;?mEn<=RndoiI?oL^W@Y6x=~%hIWfB|C+_7dq zU|F)<&2yT*U{b!^mg4~>>h+gumW0>6Uu&u1@5!aeJY)JJAKlK&TQ>*P2c>Yn`S#Ol zgIo}c5{v2brxh|s7TGXo%sk4$J(sW0VUvRMS5}PxS3Op3(QnKQy7f$3xD)0pC_jt0 z&}7hXR(%#e+xeHng*^i9rxI)#AI)s(Z0pikmat^mq9&$ojelFrD(area#$ZfP*-UB zV5x7y?+f?MoWH+%Gri@E#laSSg}IGitfp*;ao+Q9=4abTUgrzOj+sv^W^Zltkeun3 zaddKlsw(f5qS}W%oUCto6t688_^0R7x$1lOD&w@+GzLS7Ji$1N{?v)#*efRk8k{^?qR43%>ie&Dcwe{{Bivt%fcr22Z zW;5Ysvtj$Xjca(S#EW5zIK@!E~wzW$Zui^bHl+ydi)9=1s<~&txb;RotGMCIh?HWG*UO8RNC92c=RX31KZ^D z5$tvzZN4X0%xK;q$9PZT$2SdrzsW65Gq{?+oDSOz!79ie+jyS2%KeP2LiudrO`Y#gEn0U-t4K(T$6z*#fyzCt zl}if}=Q2OjKUF@5`M|`ZVv-F(q7GLkiU^6esrjgc?3@|Klh~Fd`GE5(d-Ofu-|jqz zQqO90@H>j>NSdyg>15L)E4S=RWwB-O#cL9$m-M}mI|s0)+j$y4`_0*c>M5lZCj$FlXQEPdg24yqK>s9K@+-4{2ouz zl8$8KbZC6fJjIYVVTw{jgL7NQ@)>gOjqZ&ftXn_3ued63gjrKtB#6O6NwUDkaptVn$;v9PpYWx`{!B^H z_b-2?cqPrQqWEWua-+^s&W6iUT+iM=dMCD%-Q~3bi$Z@ydBcmD%7PpMoE|Q>4JWZ! z@+#!mUEeOyJ!P-6z%7OH4^iSOrL!(}PB^W;($=NMfq~d08wY)A0)~D?|cMaUJ7N$mms4+N;E?^@2SjAy;N<_e;ei)AHGl9mz3jT<0M# zDs$*ai%kDQfifvyXOC^Fog1ulId4dc{%rip?AF4=IiptJ=vrGMtIg7h9XcL6c{^9K zYBH{vn&IDLt#}|KJ+PJkj;str2J4^3bAoMbKeZCVRF#A#b$MxZwl{v|yFZWNo06Su z6HCj43l_B!`Jpd_4PIGm&FIwfNLty^v}7u?NB7GYJc}mOTRA=#f9U(1Q*c7*meQLq z_gE{;nc>hPR8{V9lAEC*?QO@aQ1gVZ_uIO}X7MR5Q8aF8DqL(8nJn5jN}OxuxY>6c=DcWgs0T&KqVJR<@ZJwCVXB| z><3=Wey@ z$Q8adGk7)=6!!FW!Yu)pl9s>`7#Uie)gmfdxL}&5 zv+IqB?nH-xR>Qut`Qr1u9?0EN6Pl$lgRfZN=V4x%=+&FKn+|#leEzEDzT$@So?w%< z2`M59%vlGV8lAH;6yD^^9kAw5xFo=Rf6Yq~8H zECt>x=O3Na&DbWP@@~J~hoc$=_hK9a3%Byw7*8_NU2ChcTq->@ zdDuZjgy+S#X3ga?iTnq-l=rb$CA?gs5&HYAxB?$%o$a{_GnulR4eXuDFVm%Z}kvp%Mo zZ+@IxYP5>0#>4i9Y+r#{f}i+A{{=lBYH_>8eL1gHZt-V#iqTxe@Z7Uu)&v!k2WL8` zGW_4jAm6Ndco${julR>s<>?j#l$BgbF{ zhr}?WM~su$g#EdmMYi6&Z&oUB$3t}@GxN0wmHBLn2M(1gpV(yQ^jVefh4k50SJx#I zdly@M<>{Mw($TjmS*J}??FpOD9uDVsI*%%3PKy=^TDmNf>AdH9r-@x|Er;!FDJkvA zFEs-lDsGL9w~2_v59%2h?1LuBO}8h0XBE`msN{Q zt@tyJ9OJ&#tt_+Vy!g$?zT(7(5nPRzyB?&SFEP`RpVabQUezQyV|2v++=GN*e%o~{-61`_~}n3!3f3t?GNt8oyhw*x1`2D@8oKiNs(1guQm$@WwZ7e z$RsF<@fh%%G~ZHx<;Tl@TuS4~YPWRl^8z<7mFt@Q8C3_g8_|3A`68Z2Pw;`ebM>YntWM?DS`^gJ>rsm(3eR zpMMt~pHTj_Q{zWNv$d$J@b}{p7X<&-gkD?D%&}RRGsOP-VdHe^{ZlGrd1iTZgvc;= zNT?lau5`OPq1pc7iMZS~G7WyRsd=Z*OiJ1$D{;)sNm|y)ka?4*LE-iu-{@@Nu!|R4 zgqoJxh$Rb0PTOdjy9O+H>&VqDi&>6(1r{o~O!S)>7$Y^)>-LX*y<9W0w7*Q#c^n#@ zwe3*^TbhiGm{axPH+LrPWNkYu8lAQ6YVNArPA8VAU;PyS=(*!&o1Ud@0m~A-XPq%N zHaK(UFf%9r?XI-Y+-L(D1xCaFyslA)^hry|xQT0ERFF_dqifmw1x z3quQwR+|hPL(}u$*B*bk|9tBqL4AkTgAEdj=Vi(@awkN13iv%aa=_EV(>!y*X0b_^ zrzQ8iY>xaM$Gf6^QH7J&Dm}gr-*z2N+#R|*Kd;rW^WRRjMGg}l3YfKBXy%=;Mzl}W zaAM^{r;rVjy&K*6s@EpnZTr5cFXnh}8iUXW_A;$thkzGVp9TB%4o})^v2fACppgEQ zw2!By*N8QRW@}5_*HCni`c<`+|G>Y*B~NlEDH(8llz5sZC)wyJwuIY6Bhy!tap7Tc zwi|~Q$aJ-Rll`<}cA&3UlF$@^K>oyKoO}(>mM|(t-bw1e;AHQA#K4x-UUz!3i{45_ zfmONFs>Lq~`jw;z>C-SN@wsy1%}>;QVnpLsLE<0;KOsur_-bUPEvxAhYMRrqlW;$=k$f^-e_b6 zG#vSmTf=>6{c%RQzP|cnlO8lGR3ve!Wxe6_On<%B(`ey+=FYn1C+4^;`64iHgJEWd zsEW@Fzl%+-Gh|%3UMPQ&ZScQs(-X$zp{QV+W&dg3`ycWZMeJN{Y>fZfcmMchxXDAH z?c&09#T#BIo<23fosBDSQD}*ig50J{83rCJWHqFm7tXxkE39}mS7G0k8?)rrPrfkU zi;Y)Sc!!CzQ@@S3r;3Y$kI5wlks~f!8l6;?^fYSR{qO&)I^$s|$I@%uvn$PtS?Z8W z?a`G{!c`k(QX=}8+`g|~ zZYjw0yF6XN)&8WC`jH8HB;wwi1YBHt|Cz*bc}FSWPkF@Xl$ptwS?;79ossO5 zWMN{s;IW0D^h{I3sNHO5-y}`AacrAI!<3wWtt_4#hwpMReb=_mf3Z${^#;dA20mV` zx4fs8da!CQ;bLIcW+>`*zEM8!!jt*?CxmwtatUyG?1|sP$)fn}^K%o%37%YGOBv2E zUw4<#7d1V2Lt@pob!IWkU2IElc6cl>%CNin@8K*(yB@=R=QlsT{!#G7-nr}|Nson@ zcPMl6YfI#}A2@vcO9ba37Z+!vYDs|%h7+319OtGsWmlUf(Q!-F;*!+>_Q*g+ZZT~!^maXrx zd-YgslajNT&%?HEbFqXNj-%l}%bK9sRdl{ckxP`1_4j zP|;~hH;0LL67my#3f2Qtu_8G@%52qb~*MeNKBj~mecR4l%r(hiWwQtve&*WIvuOl z&ZG5Isl%kV*(|3;At%u*sOQ>chq4KeE!~|S*r|BFGTG}~5VZc;%5Ux}O}`=o9+i0Q zOKB@^;8mE_U^eSm%K=Z9_h*EA4q7PkG#{8C9JpZm8a{8wHHHj_lsKAs9WIE*)jOWh z*>a@uNQq@zSgY|LLq*m^*%$h^x0t7-9rAGHT~K&yhJu1^+>wh4vUdB9e~`BBYp4%o zRAE(+VE-IB_0W}-Zmf(Ia?OvJK4$!AG2oD7aqMLHsy18h%7Le|__-FJJ%7q2_DFb3 zJd@QCes{*h9>PL`Pc7sdPKVA}Wx*pL;mA_FIOm;eWKaxe&*E6;mZn6Nke(OJ`9fz` zK04K)GO;CIs>RA9bYh15(ltV_y#rsU2)Z)dFmCOrIr6!GM#A4^U)UXwu;+b#wlQ<# zQxoCq^KR%J;gKs+ukqRttR=X;$AT>}&vfUT1tl30H$pm&iuRqEmZU71{8pP~!X0M2 z56=>X4l!o&SI%N-@_6vxs-bwBhk0kLvg_^Z@&`YCD0d1lT$>-Ld~$}P${Y!8@4gic z$8S!!l-hAw;zrws8@fJoyUTA~JF3vPL~5PT1vf_CZ)-j?bSx2Cp}tW5obv;Lg->S~ zGOEeX>{`;ji>s0O;6*2g$6S6>KFdX|-o2{*`ZuNDj!XXKFJ|sDex93Y9#wkELdZ?+ z*y|m^4XaCa&+WdHERxODn!jo}yYiWumlyW3$ItO*6+09gPz^oytHtOE8mKSg$E8F;GAfD z=1oGQjJssKkh9t{UK^$t6FlrE1;!t+-yPQwB(zJB*Ne{-CTnbY%*Wm-;VPZ4l;Ue!^0 zovB#yo5K946MribJ{q`wFEDZO@tDZsxxk4bh|zBIo=YzjpWHmS#Ei}0jIrYJ-sWYp z(?8$X;LY;Ipy0q1!PtolrnD*Z*ju+kxIFlbWk%?EL#mPeGq>{iA0p5Pk1Meyq ze^Ln)={1>uUqre&*Go}j#Z+~sh#q4mhMdYHR&p#Z(hSZ|&E~B0`4idLsmgPbNoWGY z=Y85I{AC;cSxyyL@6|k};=fTOw_)=O`3^6U3)fb;@NtDy<^1uSuOH=J<}hbt=J&vW z&iDfFgY2w4TKo@uL~cB~prN#1#Cr0zvRnim^bWyG;^_iCPl<}x(z`0MGU+PWK zy|e0tLxAvv1o4#*MNGO^o(NjR#kxdO%tP(s>5Fl%&J=8@x~u!n(yUxyrIxctQq4Vu z9aUUulca90S$^4kd)NwJLuH1DbT(&ItqbA&e$O^7Jz~+L)0-?}&6s@ote(PY)0x?) zjJ3{fwc4{e#V}=A_nCccDW-Rg9W^@xkKQ?9^zzo1!a4je%&#aWKXTqvW!-g8Vv8qt z%hH~XVwoqpro4hWm4VjlU-J}mymJsSEjak3hDqxK!<}`tN6tF#SS`%rx}g18neFrE zQ|x^Nw8D2k{AIw{QCq~r{4ed$0dKw{iFOGGpT3>QU-O=$#)$vrgM*o+QrGx8 zn9V#iW*AIx$$iBnGTWtIQ)EwbbNXC`B7u*mKb92t&0{&ZCrKrNJ@}hotJ2=xc5@rQ zv}gFFpA9xybJ?IsHZT2>S@(q3EM^umyxM!_Em^q0lX*_J`?2to!W$C;S53HJwQTG6H@>idiz`v0!{t#qC=lS_&JM1lPK zT>%Bn;_r4C>ffK}e_x_~P3y&nI%;=Qcb&*-RkwU$YayGiktT7d@q%JkYo^Gvj32f) z{wHsf>c1i&`=RaJvdoseZzWZ{OC=PUTezf-)^N;8{P8JZmZQp3=h%}X<%-8Fm>3s0 z>KilM=Uh--letA9(&3QH3&oWVpV~9>4HPGN_y+~rsvk%^Q@`zR`=4i1eb!Hy2c#%ZUm4?el~ zYV`&2{@h?@T~~3we^EP|jHfR9yP@suaVD-kE4MuH3)yI&_fp`hK<1Mig>zq6|1)tb zF{w{~us)+g=!er|u9V=30=)uGEyvs(yF8sFT^0(ZHnOEL3Up3dBBaK`*6#^7S0WALUs+;xR$&TYLN&!;I!fK zhF^#8R5M?guw;>Z%Z4sz6|tiY9*GKaa(eHcv#jsP<)8X&{)Ube;guc@QY$z;qd&Yc zzVT1s7r*hD8&WDSCI-phIAX{YzT$7g!Q;<kK%-?q=Pkp=RhFg|=!n+zSt1@2Zc=PbarKc6`DmwSK zoV@ynG3kTsgv43WSC*NaEjK7=eUN(Bu`w#0MPOs@1!wc5xw8*EQxMpECFx1ILCjK} z6VJ^h7z?GXRu&bXx0R9U$dP(z{7@%cSo3M_f_D+o&V0=iZ^pFkN$)hcztGMblRVJ|# zr3aOjCZ&8n`|G`DL3zpA^OHQbFdyi0W=Lcbm@q+rK}O3%`HdGBM}T6Zqr8Hui#5A) zmx86jN+G2UiYzQGS_clXtnBbwd5BSK&YA_80u8JaIoYRJ@`z8I%09tKWrAjxrs9p0 zCnoJ!$hGo`!2%fuMZN}A77Gp*E3SjhN)|?6nHS7xK6I#Iwv)pp!6^xgnpdzcvSj6H z6J$JPH8*j^K9(${6MY(%m0l-gWD>V6GJCj#@u2PTRUFl}m#-|^J!c=w^8gi&70X## z*+eX#=QccGxR=N%yT*LKp!o#d5PM1Cny4c!DLtn&lEO4>bp zxbR2B%MVZP9AYY6*rj{gRUoEEWtxfeY7u9y%b8pIH4eG6C3-l8e$Mt5Qe4E=EXotv z#^S6b!DB7I<6n655)s2Ab9pWamfY`|>0|F-T9dgragj~Whc=xD+dK|UanV$q7OawrotLJlFy~VSi>$NAbAEw~{u*YNHa;`IRcRUdNU?n5 z9yjkbM-Xa4qkQPm#V27#-@T_sl4p9z27SZHVX=UUa* zyLT?fO8?#ThPT)=)qENMQ^Q!NQnsM-Z407vG6nyo-RF0jZ?HdECGcRTl#0P;XFIkD zuWaR~Kic=>;isgBl5eY4yVnV_SZJK`6!Ep=V{EoOui`B~DCf^bDLSXw1pj^l+l(3=3-$*S4lza{X40txN$~ z$*+93hn{#~TF1_KAk~q%J6A zxwDD|FENs9;ydJh(O&u3-S%yqONPVFgWsK=g~5mnfrvfIJ6h>J$1d*xJ*oy z$)S~_NvTOmv16&gdoBNiOj6TVzV@_nd@AyxLHK%2!>{uT3VBW5*svIM&f6})RwZLS z^Ps`wsZ$=5zFzS1OlY4%w${eLr&TJGLPJAC&hYSbE1gsg4Gnb-4HOL&4Gjh1P&gF| z0fG<;M%EPkkU91t^rm%ncfb`EAD3oVuA{6~D`nN0sQbsvA~+_Ejxly@`7J%wb2!x63$3p1ul+=}#Q zP!th9DO8!Lk$n#82dgLDuI2F_y+SF{$FgKJH^3LJNk~(HxyfwG zEQ63EpHfvjxQ=K{&|h@LBl@I@0OJyc+fAX<7@TC6)TYmpX!tNM>-RZZ#U)O90-qX^ z|4wFT66RqzD1RZbai4?Hi|hpRxf}_-S{oSc(wG*ew@eW+v^&r8qvc}r`)6+w7ZvO` zUF7vE*)4uWWFXLRgxQ%0*nTb<1*R?6?%oFypyF7L^)oht6xW%Zo%i*&MtIM~; zFB;4reQ+sXcH~%x#2ca8C0jNsv2nD_4RV@?b7} z+PEk22GjBlNet=*tsU$h0l#uJWiIVf{9q8|;k?sk-j_>DR@Xk5K8e|%QNX&}E9}q| zz6#EB4s$*)z9n;XNBUBWWe3^w{+UFq6VkG6PwaX0VC6kGx5J!9A`2JGdP+HbpC}L{ zXw%WYCO$@Gfy1Vx1jeR`pJuyBXRGKoxv}-~|9PR_rK2qr-O<-{?OO8@i;cg(UYK*@ z&%xW50xFC&6-kxhSV>nVTXfNUtnyT8cWp#G-s$i;pOj1VKkm{Ala2AC332}Ve9F|yHtLrC$8gBUlXsa z*?4`+8Yzic#}?l{vB!C#)Mt!z&XJ)o^p6XQmx@58DCiktj=k2_XK6@3! z%EQrRaOwW~wG1s49zxO#27V&FhHW0nTCcnA8LwvcNYLY6Br#_~)r`bRtuj`pSR&`! z4v`Ng7ots-qgjF_JDs|?tUFG0y!t2Y*1X5&tOSSAtgMbnx>ueA980_$kmi_H7Pq%~ z?s6kl(d5oaFC~v$IDOf9LR7Q$ngpxc9_bKJmHs1Ob!Wz?DiG6Zj`{9$a#A(ZSw*e;r@(ZoN4n;G&SBp+&-) zDVZDguFX2K(UEtl>ZM;EyXPF3I$behO5Bpw6FLj-ofTqT(>f(}(Uc7n?wINnJFlwPQp!j;_vMU()Q5#UmU|oDC9i92H+w7Kl5mDGty85^g4~=quh>}46q>={B$eB1cw@0Mi}4(;St?%4 z(#a31c57OA++sN)ZE$u`QQ?lcW+$1H^^8S?jrnGLF~3sz)Jo)&#oil7+Ds-E_8vs2_2 z%LF~hXI#d%yz7NR#^I1og`C%4pA@rsX*=_DCT`9=!RF$iyyjkd-jqOIi_Quko?cx&WnJQTZhhVTzD~N$`lq>Yo-GWd6sSvY$)(hWhn6!NR*uB6X+PS&|%p`g%b8I z?T%&KMz)~`_?ai%-_t1D&e^%4#jitU*-<6u4G-9u_Da4=7IDb3kmhCjWV1G~WR9a! z*IxD&7i`ieF6*dHbd+m2|JmwJMdVC7o0eM{50e#^I;I?qoqM=F#(m9u)f%PEsxM_k zv=TNke3_f>v*)(a*&C9@dRISpJ`q;Z+@$$HVtIz&4O^wq@dmng9=5*F~1A8?R~lXbAN*H1RInbw@MM##ms(f)q77 z`@Ksq1{Eu}Ok`C!$PwVY`RUu-z#EgegqdV=ep}0Pax0$at|_#M(@9zGCDoG2JmK^A z*1!V_m7ArQ4^(9a6v$6#xH849P1JOU&5ai;Tb-||Wb9jeW1Gu?+n!9zetzC!wO{>2 zLo(;YDc+t=BC%@|o_MJ)G@W*4?sF@pkk9OSf?+546InDq&iiE8qOwE8Q|4FSWR*Id zdy^P5*M8UhmtLge$td1%{!ZcFhkvK%GaXTMs7@DhN~_y(*iG=+&x*v?7971Swdp@T zCmsCtVQ!YoVz-2aJ*iD84Xv-1UOVIinKguy72my+|u6`uW{rS z(PdJw5a^K8PyEk2P0qq3l*h8qQ9(IE%Hc@!hZ~<5f4W}t@T&RyQ{63q(ZTiEaoyfG zDF;Hw5(2{bRNaolFit4ei-_LcU2G z=P>T*;pFjYX>y$)bVGNeOHPu~H5T*rjvJ>$hyG}|735Kr-0Gv)(XSvEFo%8eI~Dz= z2UEI=8BdAG8u~2^@hzDiB^Bg!E{AbifuzLZP}i0s?emM*t$MNeq=v}J|LiwS<(~S> z#7ph7SYhnHPi=9N^Toc?-y=>-HaH4&DSuNf6J*ys8+5tg>6P;qiVVE3w^)1^SZIFn z-G^1)2d2cGcDUSdYim~{SL?(R+>SYhX^b;lOql}$GQ5BJJj{A-(!Y%7sPLkW=$fk= zrp>%5y6VK%|Bhyk6>rMqi_Wq1ygB}cNnjV3>Aa7}>vn$(NG*FW-s4=y8pi8?xb%)> zvh1uCUb26KzMmmcrFM~tVliWwz>*iU$+$J~I&}ysPBacU~ zYb)M$B=x_Ude0+rrQqc@rWcA^LuG{eCM2B}9pV8(<#%BHmW*&w+>MlJK z4yTlubRKX#a>yggFd_DI+byqdzR&wUcS-fA?YMJ(spOrA3`T_`Ocqs#*k=e#Xl!=m za{(#Y>@$O#ha)KLL$sNsmx1i$L(VDudm9%UFth$jp2o&} zYPQ6yzV-F#GL_aA6-8%f#`E{MoLBB}61X>CI6c2?SydsUtKQG1udO;!n$ z$jz<-l7fp<1U%IX&$U_k7+5GDk+owFZTa*0cGsJ~oBnP&s8Cc;k}Xl`CAay)tH1Bw zr@yUgexRdiedCyIuB~W^W?#wxrY)Qf?RfLP2?0xTw*sV{*;75$mQ#gXM+MFkQpZzd|sEWD%F%QCGaMYrYm9}VRL&orOL91lz1 ze}DJ+keblHm+razQqot5{C+<3n&scBmbbEd^S9aWU8&P-*XbG>8ZRaB;lJ?gc^o{6 zGuEs*ZfKBv=V^<9XM7~W|bYAzP;_t54GYY0GJf*xw%(qRloj2RK{d{=Z2|4Bi z4nG)@ri!=)@viamJ$@wch1K&LH(%MP_cWAA9lW)mut0~IjjfZTTyTf2@*~A>6Q2AC z;*fd6oO#A~#~;1J=MQ@D9bWiT|24Z>|CZmoQ*JHuua6Mt4bc*iFk(H;I3ej_qY>w8 zPKF;3qQc_*KC~u?uSu{|&$MfKD$ug;^3TH)MKt^wCMswqOtqJ6UV1|%HiFS3QeNla0)AfCthEuy%%{}k`;u`<+B4l|*P)9B+E_S z-8}Q|I_Z(KChwBnQFw7jhp<)mc`=i>@2$Iow;y{P>JyZfe%T_e=ws>$zruSv zQmtdJ%FUXlDxLXtwsft*;o3XzKYZv@z9zz#HjCwuL&+sh9~GC7#Xjwq=5DyK_^kMg z=3M;=`z9~w&wtr}VWr*wsOn8ZkIvVw4XQrgv-+L<5+mW3;G-HRWC0zKJ)WZcoMucI8}PaEF=Dq%x&t-J`>sxo-!Q1)ygX})+Cim-95y{ZpC%NgGzUdrXnpuesxHa7rG+DXr%eby!>{{2{2H%Z zzUJlkaN0%iG+usi{oI_*%(s@`_O%_|SBn0N*a9N2dHK>m~=cZ`P1(NR#^! zB;~YbRoa6SlcnoRkL>$w!6{n3pWl40W9w(92$o3ZTniIsWu?hI1v!=7#hTiJx=At~ zoQCBdzk1FYhL~J1ToPfV&osT%C$i7t@ue@nGbG&oUT#<^a6;gA;Uvi$Q@R5;Id{B! zV8GGF#J5J`yu>3lKLMX}36BNNCHENfFuI5(S!N}fJT@1B+v2^G{hlx{+`;>6Ygmf$7;j zR#i4}n+^;7y}{~WW_dWVAwZ>YS;rgoYda>1^-Jb3v#>iK*jUSZ;j*7a({bx%4dD*f zAI>d!t2aUQtnrqc&TLstf!bpJd5%%9;7HOT? zGug^Dq@2BQpBYoN+Y60TEx{ktTaC=8uVzhD(+x0q`}lagxMuK*J9iJqJhwh6a%t10 zw4@XT8Ku60Lgqv^&qn?hwin7X6%>>L)*j-#VZ?EyKwV*uul z=-L@C&o5_v#P@Z9H_I}uya}NfHhZ)Cyk(ql_=3IS#0PJsp3U4+9C*>l;TV^qTZ@Fl zh1n0?uH3G=!?SGhdaJbw@>@Lkj$3Bwn_a8%4R>HQI3}E|^UQ^rZ|mcP@Q9dxk!x%V z-!xipSZLnepSIRdMJ*>m%6L=FzNn~6YKez7C@XH9w8_Qv#2zMz4uxljWVAdiSLIA_ zIrz>%oYm;S?%5}KFEke%w%nYPdDXD)NyjU@wpYT!EalyYdAUkARyKEuEb3(1v$XAa zxIxbC5}roRyQ~Klnfzjd8s|Lj&0HK}B)R2qqH*Zevz5_vi>5p`@+uOabLmZoOVNd| zv(y#Z*p9iMi#wFCt$}BGBD=h>Ou={Y_%L@Vwr^!IO4_!i^l-*KOUui= zr$x@3NX{v|#yzv|a^T#LlVp!O7hZVEy{2!5;nE2nx(>ny3m*yGZm={D-kvu{KVl0L zTUyCE(S6c(>?YAx?7`kGW)U|YUSH|M`_)0~mSVcD+f|*Hu`4G$$=sM;B5k(YWW@z# z4xd}E5_|0>pJ|jY4lvJbYrdGUZc2OFF21U4@5C1t4`!5Io>Bh6$l#FmckOxMDzowo zjAa+i=aKfDTxP-ZadpmC!`sqUBEnMw+BnO;D$eW^W_Rb_nbOc>I4`l|9OG%}#am+o zPd<0N^?Q1wLo0K8GHU|&w#^$Rr9YkA$H7-2np~22Y@uJfPSYckZ+>6@s#_s)APe-ZdNhd;u0z}<5OTddt1YU=MA5Q%B+ln4w^XSDQquO zm7ZQU`NEOYnMY&zew}J`kTdT2+##={uH<>Bx6H!gz}a@)?K3obkN5t(TzYZp$(N3s zl5I4NUL7=Pk6C(_kMYvh>+5Zv%+lICQ|09CV|NZVzKY-1x1l&~^32%_AM`0-YTQuJ z$8UAyX@Bt*L*-9O{Xw-wH*#l|*YNr>FmIg7y68vJaUMrDmx5W#H}YOH2Gf|r+cq?|)KGt3fiZFZbm=*W90<>Ve&@#mAna-sxy{l4vVs}wh1^|t*mXM+l( z!HmM=4y6;98{U^b>vXVCW*yVUJGIYvWYw~d9QR1Ga9(_TLQl_8rF=n4VH@0=RxUE~nW|NoAS#viVpPw%y^y20`UZLaMU27$8{NC2~`K$w5 zq-g#_>D5mT3p>dkxn`$%^QLlongUOvWtZ!OvkPx6oRpsHSXR010MmlL(+@Z7Q(P`+ zoZY$cW^1&$*JzCQEO*eI$jLs;zk^H%P6w!*Z_DT0ZtiR5 z^K4^myLe_;s@&$LVDqF-frHY~>WjFXeA+x`vzK4JEU@&v`M$p|+woF0FX`V9^HO zlx2;(?WX2&X*;$>F<<1JVJ3J=MQOIjvJ`Wn2PK-1Z>b+V`z~?A;wHgM(U}4rdKFB2 zbH45mSo4jcZj0GR0Ry?!*SfY@Xl`&QS$OW6^TvfeTi>+LG;kBXW#SenVXCZD;L3Nv z#(0y9U()uZy&AV<#SSdLGBGQf>HO@D#zX1NVP6|>Bpmh9aIYx|7cdXFmh2*YyKB2^ z@!ZzMhHLz!nGOj(j!@v8sWs#Db3-|;Q<7aD4y!$Gyeg$SOH4{Dduv#sMBbUc#p*1* zIU63oHHltvVa?_(`P#;tH*zKm%2>-u{JUva#bx4W$6nREw1E4N8(SOmD(9aw7E~>n zSNpf;(}y#&^V{lFrfl8z!6Q%UGW#;CgBomoEpmr^*RWk_>}x5SIme-@vp=F%%TMw0 zja`eje9LEiGy4dClslJ=?0K6l4{zQy5;!R~Cttnh$gC#MTiS&aUQBat>pNfmTs7?K zPpbruH=(~yubufy;(GIzqTOn2a(zhwZ_FChbHaToWuZ}SQsell#g_6<0swUD)QF`u)dsJhDm z9{uv-f@0o`p4TGDcb*`OuE*}T{IHpiuA_vNeyo!@SG#l9v+cABv1N6o&SzJ7Oa`gAwc z&8R5$G_P=VyjLm2)%Rs0WBQbnPt?0xwtV^JdZ0w-y-i`@=Ism9`Y%{q^*hYz&A;rn zcYeFI$m58n+k8cbH|*73zDD`TeNEF~&Q~^aXQU_!m5v-}6MJiUvE^t+Aj_$&#F%NbRCg~=+<35)SE#pR zj>0E*rh>}8pB1jpnO$ymdEE4D&WYM+sWzouh;2fHOsV1>g zFEig^C&NenQ`g3bE!;JKe$SyaXV%^w#sb!A?@sLbaaQ5x73)W#5;+|qshWr8T3otu z?CgyRjdSPn@iI4?em|F&!S^KLnVWXazK{cV-J-tuY`3zqd{r&dB)NE}{g!nsTkbke zY<_mrm&ZxkXP0#E>$KUgPGoSt%zbA2O}G)|hpG=0XyaIaZPN(u@l ze45L|U1YdqxKk%6rDXVVPdPM8O3}fBoAHs>i&!4lB0eF$Dz`@)osCv>t=Oix(U$WZ z!;20D4i3gQCP!3X7vDW{hVO8ai-wbe@8!Top8W^jRooXynxSC-C}1j^!vanQ-j^Pd zd@AljtjvcryjXq~9DL0#^T$A3;GcR;8r@3^4*V9ria*$UiQ8`=fh7G&dEE=LgKh{-=`@O9~GHSt!lX)>*LsMaQt{dLhq7UwQk#N7rUKO zo^#F7TBSf%=8E)|Pmj(B1sqzvfYBf(CCGPf=8G36Os!k^rk!3oz%+s3H~Z6O20;s!vd&N2ugRx~a8+I6XnNTB zdCld^si#GnE=skoViXkoXeg18{O)3#+Jx9^C#OB~Xclr>5oCELoTJk7=9vz8FNMc@6C)4K4}IuAr+=dE$Mt17Ay&*NQoVPTx!ES{&gCi6UF{NdMhqf650u1H2AYe_;Q$0}zD zi<^^Vy>?tQUF2r!@=!$a$(P4p+_qj9sJm$>eyEVC$l!A3lIbM|<-6AfIoEFbZrml> z+qH`G_DA`7k~iA5c&efq-msiq@K;meMd}GdLqWzCkBb*xS8d+K!`j{^r#4^ueqs0l z8;LD9+^3)H`xbMSr$uOEF!QbC&Z2k$7uohcTb47yl{Qmt_VL*iUrEm4{BX8KU#-^g zZr~aZOLgYXHlZ|@nH-u-t{fj`SQz*(`0}ifO~T0MLBVv+RFS-;nID}m%;0>u>88(N z<^@MOICGURMCiEZwHHdf_{}}-m|NMF+vO$4O~P4@W(mv8Y2|5MXnc@yhZyt3@|Mfj zW-i+DI`A>aeX*&ACq+2QZD(IhYPb2Yb>H9Se_a}{_fIR>dGlafhvegy2hVlQO&nDO zd1h5Jak{uP-egqT^is)VX4Sq!OP-ooadIx@TerNb>&d0e+L&!O6mONk?^&|_c#O!| zIdfz(ax$Oq$ZStM)U$G1+&i%Zt&i<_iL#I8ESPum1)J+O-i`XkZ3j-S-EKGI@xe1s z_C?ecpDL^>4c3`nGg&Apc0#0cSdhuHsh7obT}?y{dCtzd+nb@N(WR-AQ?l&atd@t9 zt`*KnvEw|&VKJrUD6`O2hDvp%PwX7}jvWWCJy2b+YZ=SQjTL?zf&yE#L4;75N}q6q3Z@#-+ZCOHs*gw@9_s?@Uw8##<{t zIEido>D9x+HgAmrtC7(~R}qg>3YRoDy2f#{UwL8}bg5P4-eJZ|O6{{4C(NDEsG#3; zdEx_k@yrH)3r3bZ-MvC~WnAc4^ zzO*e{cta$eJuxluQKXCFHQAQ9&L>a0&pd8xY7qF$U^D6WIb+6yFU;?`7qI($pKs6k zW54F1J%TJ#uF9U|R}VQmX-Y!Q&&D2(f@BBjE~ch#_J>@J4zKp>zc4eq{nKFkTM3EU zgvDMK4+7F{Tmx)6H`z>hZR7IpaYG@E7-*dPBy|cQ47!J)-5m!8M;*f-l>tTkE9ETV3OWv!lsr|b> zEyU@3+nmF5Ke5|nKfHhMsR3^wr&nO0(z%RFFD4{!Nn0~zCXa%_M8C(LpZA{JndV-c za?G@Uu8YHX&Jw{v1YQw zf=-JAH4kt9wQn}I+0nK1kM+W&siKyTn#^}ikyjCAT@f6zLc2g`&5gHf6WE&Gd|x5S zUkU)|YF-0>{TPN5y9?eqbiC)gj{P@goO$ zIntahGCq0n2qif_s5B{RE#Bb!)1x@anCHYvhDb)!wol@^y(}x)dd{}BrCoku;&3Z( ziln)vEYIR)meVXMik03u>{O^z;<21(x2oy*DHXm&xpvFkT{L;WnDDdo1$g+VD1Z2+ zeam%bgzJWy9WUg-{U*mCvnr#?FL}0+ zT*2pt8MZ%oj%=Q4{`I7~b)3pKttWyX4L{6oTc5mFNWkVhN0FyH<6R>GzcW(XkG$Qx zK~<8)bM;1Zj;u412R*AcWZI+F%y^HFOHsasOU-k^q=1;fuifvv9PPH;sBCvI z6nNnnUE^}&NlAA5#G~_^B0e1B(yPAny8HX0Y0uc9`G2@hD;J~Z92EHB(hAhw5N(pTodHh~kKlbj4v?bvPPIrmC(PrsEUDcid9 zoh!%52}a%w3wvg8vNW<6T%EZpWufK5a&wat+j(x6G)T;oh+Nnn(;^vo-;za+jXPn- zl%QQNqEfm{PX`C*ZecsSb;IGMGaVYPZfB5^liI!^A@>kZr`giZ)VT_!%NqQanfI;t zyKp3JZmi$qkSCWGY25kf7*LXSY7L95H}h7`8Aa{qQrmXk=2>xF?T3VRQ?tu~D2=s3 zA2iN#-8;Efl;fa|&@X}LCqX<~n*uJe1-T@PoXKiCq@A;oS=R8cT}Q$Twr%(L=Jmx- zR9@Ux#X3u&{ob6sPR)j1zB9-AdT%BQhlS`)O}Nq0EYkM)RVZ7RqL)a7TEgln9nup_ z&DkV!Hm03$d16@D+Ueqz5l-JfCqRh#crp@v5GHg{1+98t9TEHzO%itc*@Ui`8Dvz4)i$xrcEgX!6jJI1w zpG^t9_i~Fw;}kRfoq`u-<=7NoH!u41XXOJ`Cb0&W>-z$iHDeGz+?tAo~OpPZ) z$-;A7HdpKpOeo`NY<&Ck7~k;|>K=QOo-H@eYS^8$z=Lu6F^5l`(=Ba$r@F7zcCcjM zXlbVYv|;xAX)PKd4caeQIUJvI)Jr~o@Z)>s;Tg_;u5soMMXfh?q)a}Px~0+8L?M3K zDdPsSQgO#MzBd=nPGfqc(Xb|2@%_=*M?NgqJr1 z>>PQ1kJB#L3bbcDJG}6lySm8SGT#FpZEdBlH%oe4++Czx9;dw7{WVH}srVRQYU;F5=E?@rc z)3F-{pP9pSTm(+-*3f$2A@VThgG>6#1CpXs7H?eM-1*>m9-oUu${{BiE6J8gCl}{L zq_Mp?XJZ>W!`&oJ;)|RlgM-40SC+Xh93@tk(y@jMQ^mr*uI;xyHD_1Hj*kMzH?Zr- za;@Xx;%Qu?&*iQN* z^OLJBUP&fi=y_PH0uPTtgogy@K~a^tKN9S>|EaMK@jc4oz|+S%LseyyDocIKX{Ez+ z{ic3&^cSjZdB^A*{Qh9I@Ubx7WPuV}w+;RdYECb9wn`rSBz*kI$LYpAysV8Dla9r( zop3zDr}*?(no^Wm6W@V6N5dT^g>_AqTHBVb>8iPO*g#;7YwU}HCMCWU7uLj84a_fO z)*aAOW-6$kao}UaZH1M$0<9KuHBI5_3SnjM+;Q}sc|j@X(u4PsIs!h=n=N2!;Cdk= zG~S|EQrJslmGTz5=Ps8DCKV)kJe1|&H@rMQb%KS8deGa`$GUGz*qll_#n#Q|uWZU9 zUNCe1*+-dG@6Nnec8yw)B*o(}PmuTFN|k$-%USn?r%gL^M1kq!aVZ6-i~@b`g({N+ z%@?aYm)X5^+ODqTX%8Maa`U(>bLe4qS@M^;>`tR0hrfzSLP8;b;oAe&U#j+;GI{s2 zFSU$$!!7|E@vL?8#@=Q(Dgaer}7U&+$&q+i?=MNh>Cb{IYoaMSiJBr^u0CCuZ)?*V)gx=2lAWqXT@Q zLhdeInRS1r3jUpVQNHKI&BkrgiYZcytuyQjS~xNo7csgmzxVp)-iv?Ezb^aIc4%(i z#!Uwwv2E~Eap>I}ux~*PtM(d}5*05Xrgx@QnHlS+pi~gK{O(OQ3dtZpWs#(A0%t4usHpjm?4^@9~8vN+e zIC4iWr<>7hyTJQnf1XV5kkIg{d{LCBII%|K=oamOf>0lJ(EzpmHC%T7`(rX1vjmw~ zPBn^Hg-Wiu`Kw8OfdyBJ+Yt%<6sHN{6^sE6*F@Phzo<5psXug>bC{*-pce0amajav z3-TH6^Plr(&yvb7_8;;!op5BLa-`ZQ=s0V@*Hel+ybJRT84fD8IdOTVteBL*%&x$7L6Iq;$;q7Qu()-O;Vk~-HpA0Q z7y5iJsy6p6St2l3x7Lv z8`l}Puhs6o8QLZ-xG6U?V&2j04vq#5-hOV`hNAC5qEe+zBDa>ev?M%yTf1(7uu>`? zk0M9Z#XH%0ztm3H1lby#C~}_K)a9?SqEbQT-a^wO{0q&m&+4&T(!Yj>=fi^sHxD={ zIIZS!a#3PD9LiY4=(uF%3dLs0FLuVSY?7}C`Fu(&oRzjqKx`|Ez$X{S6OSCHe|hGc z!D-Vs(RANZQL$HQlkJ?}@-6k~3NY7_ZZTO>;byJEBQe!t9+SI{z?*0l6UV}v7hb0+ zN=Ws}%4}ca#HrB!)%%TNXs2%3rwN8NmaA_B3O8r;yyFpMz4x$HYN5Z=X~nc~iTn)D zMUg`DGF*Y0;Qug`h$JSaw|!?j_{Y{wl6_ly)f z)+X<=d%1^4s((_`*0M~u?7FpjGx-i#PEDGp;H$;Tpw7usQDCx>p+WxfS%+;ac|Kq8 z)10n#cB=xbipNBw*4w@=*V22Jr3+Xbe4{wskJ0nU|2>fi&1FT1`LTAAkYZChkEbAnexBS*l6BU2sMoMKAU zk}*7XrckJ7wlG(+>XKs|IyzoYo;xq%omQOmqP0tLWpmQ()9D+g#~6l+@-#CUt!ia> z*R*ZctmO>%>x8onw}(64Ik=$PrjdzPmzD3B7o(3c^Cm{UN*s)j&@BxnJvN z_1u#;W@@P_XvC~fo$4bh=o;#B{d%(PsS4T0Dv}5K1*|#py#;QqPG?bRystHhVG5&6 z&C3Is{5P`n7rt4t>6VVZszjqwHlspSPTS$keGCSV4MUSXJRAOQHCyiTBU7!v{88)4 zCi(N#Dg1LT=x)%MZK`zVg5mb*W`YZEXddg*P-&UkB>0TsgjCRsi5aCGvzr`5m+&n7 zd6-q|@JS^HudKh#&J*~ZSNO1mZ0`7KvUh6xj}P`10!D9xd+ME}^e?RW-^~2$fHC`5 zZOI>3`_kWQ=dz`_EuL5zruC*>#WSFTvtSCR8;@auitsrDhu$O$k0UNR%_6GleOtLC zlzN)h$4;x-{q^TS=U$y+&T-*{*_Btzl-6JT&fCex z>LOLQAdvTz_RaU#E8PC{O|tBa=`xzwD3pFtp?arP?~?4PxmRyxWGaZxSs`|th_SCEkKV4e+R`{qJz$$F}lF|9a)r5nsn|&hp#D%o0lnApM1k8A1B2xT;Tm6w@%aa)bm8)l{ z-Ds*v*O3>P=hc4)e_OO{Zgt|)S_gruh36UKh-5xGI2LeJ^ zoO!&C6sid*oe^1+k~kqHpuus@=TAj*mMb~&pT1}=s3X90$jN_4#vDb5KPfH?8@wm< zcpDh1HY6S4Fz}kb;o^c4PS+OIRZ?+;Q1`McKw7uqa|n0Tdr7N?i;uSCr#P4e9+ff@YE#6CGJ6NU&E=y_v!*r1nVtL1}$p=F+Ki z%&NTvG=9nddVk^a!ikMXmw%YR+qa^S+u^jy`LoxXTtBv_cb1vxi>supbUefGt+K$J zHOr~=tvO*e-ln=u&LY`M}EI{Dui$t z%Fi-HZ~PFDFXVJdEhuAZtZPu|Oby3PfkyI$ja#alm}D(Wwp%_BQ#>!-I-y}^qjN+b z3#-R#|BXy@?-?qeIVf@E6Z|2g~6pX z*6+d9TZbKz9i-pQHrrU*)U6}&aOHF3dF_ms{J(LgNSMhQ#H(2<@?EODwdSQydB=?N z2BI9?R~-x$I`?t3POy2R$Z$$h*RsieVUS!Llnn;CvO z;dUlp3tw-WV6b!EQkIO#;Ta5%7;F<6u5laK!SpU^i#{z(Y^FO@(L3UF%}V~ zgO7N78x9(Cxih42Sa2~Y2$p}HBAdp(x`1hND4*rl3q|v;T(NwU*>b+v)5T+_`!@AQ zpFPh+J?_n#U9O(NZz_^pCF7_6bk4+jp^WJ#B=~O&ooML^;&2d}%dx<)C*kChn2Cpk z7Iigydahx*_s1i|>0GBYz$cdTHGphZWPXM}Wl ztSnf$a7`i;>yI3}tvnCyi;XSkO)22=pW~DA&ZlPatPe%!mN&ZI?_i%_RKmQ%#b4pq zm5QGtT1N}PD;G+GU2j
EFD_+-HfhDl2n>O4KEVecVP?J)O zu;8`w%4V0YLsoaAZ%BBuxhYIBbaA_Kz@W)Q+mb~ffi0P5cFtuUfrN#*tZK}2O?-Jo zCN#`b4C$Oy#@!PVxUkKV@#q)k&iPNfx46oD>Y44}Gkrs0MN2Hl8l|7%@yp+7GtRF} z?OVuolvkuK>HMhzMXy3rO*xO(kK`QqS>AiBulpq#s(78>^ZAoo5=O#@y5_#%oh|Bk z@16hJQ?DAT5Agi@*|_^!LakC3&)oJ)RVQrzG?z#mGG4V<*Wj2=Niv5aS5N7(H>)L% zZBlh=>e+N4p|QcBLsnHSG3x~P*K*D!M-R{Ax%J8Z)|D-aCK?Bv&Wc8Du+bIK;hD+& z`pMx;l?e|MVlsM6ZWK0TrTI*`lO@nKD`gJnz1D+F$_6@W#uAbWmnO+f)R?iMjW6KB zRZgbFrc8&Z%lRQO6{xb4@3U>miP<6HRU>q#14MciNI+aAl3ek*y4o z4vW1Hs$G(hn4}yrBT&N4aQ3x^7GZYA(;7E!0>(X0rgMf`IP_9kqc;iO@>on2;uiIYfAz{3_JT{dA~){F@E zHEEONRF_!}##0G_fWZ$?qG?j!a$iDno2yrqM$dZnm3?f(^5n{|2WiS$Od2NO&c%-7H`&U`=6A zVw4fG{vyR!>+AaK-N*PY3oBb8@lU7bY4SUsbKj)y%%O1mFDJ(ZnXe9J^FEr%oYHYH zXj(ac4-V&MU~mqIa- zLYJRB);#*8Cga!4?qzP5dbF=|$nB^)lNmU3v9l|0aNo==3n%6U`DQMCcY3D|UG!47HxQfDvGOk`BbRGtumbDSFf+#I9PC}`U5XbU)&9Sx%)jT~&0qF& zCiH*mzw+0uPlo?v|0n*4IdLs7Yg?HwDapB2yjjTnOToiqs;EL8!v>8GX8xK$2dzZL zCYRi%piN#n0>YXOF2ahU+C3?{K_aYNLApGrc^aO~RJfq2bSluvg*RxSN1M@%6DN5zkaEcFt2;T&|o`g##KVFdW&;<SaYA&fV)oLmpKElJEtyH+eXTzjfK5`CK|IZsZia(z!Dz9^}!+(2cqXUm;>dcfW z7hFu!A{L3X`Y0~!l9(}bn$~5BLzY=fMP+1_J}oxpQ&7>}AoRbZ{!D9CDT`3v?9`@^LK{ zsfo-~Y2ch6@cl!(fKCvjxBu63D>qLRu(c>NQ|_NNhvVP*kdAns7gBB>PC_be5glrR zmT_}$X)Kgj*`&58Rjp~3s-jm*Lu2R4C5zH#&C*zwBAF7Y*5xrRRY}T2V``yEuC4pc z@85Dl{96qEHZS7X>nGr?@ZbVd*AI_N0TY#u1o2N=3~RgsfxjxK1zp-&V>3O>XoQHw%`{3@}JYa6%2VB zES9iw@VN;#oD8wEW@g;@=#R=-c7Kuij!#&+pEG>QU_C7S+0a$7N$1FG<{Qy=i`Q>? zK4sSwS%KAR%Q)w8JIW?CGFm4{G~QbzDxh9?t89u`W#`A-j7cvR^h};qkRZIxV$*I* zt$W8O{BcWfxMz7OUD(KX4#O`#k2u!*EWdqILaS$b=)7zr4)Z<{)8{= zi7|hj&fMu_+Hi)azvZ=tn>~|((EAuI*Mb1s;7vv0&%y^<(gxjB{hr!Gw>>1_d3_SG zDn`a>QuCB!9T@Hhlurp(W!Cg$aou7tlU-a?@tD>VrwKm7jteJlSk<*|PR1+M4NG1L zE?iy~wQhk;|9LsPP1)|o&5H$Ut@erVz7z=WyS2dO`P(TOMSL5ctk0@m#(pI@pgGr3 zVDjqKALg%#1^|4^NNNi6~&Vu+A1<$(`WBcst-JSW~IQ*M1hMh znGWBsK0hH;p)TjiC6*qcnj35^Q)<%KmtVPj;9oxyV|m(Om7zza27_{4*`L zE*Fz^U&P$daAIyknMt>te!}x(?#cnn+E<)Ap4TWO$-Tp(nIn6qS$0*-Rz6{tbtkxV zj;xZ3;%L!Wqr#lj+VH!BKk~$a5`&4Xe@^-zsWj`X%j!K-+28PMA^#M8BP;$z61pp1 zFZP}CqTbu>a1+Png^OA{SA;U`aM^fhrGemLr}hc6rY!MYaj)Q3&qSui>}e~6wC$AE z9hSHrP}O3h&1S}{yllbrVg`eoOguL(=$d-f?yhYqcDTsOvHt0&qRj=os}F@_iJC>Z z8TP*a^ZAp;ex>U+Ma2^`Ei9thegywo8s#3_E6~|$a{90zo3f^_u4KV`4K3qbf!Q~m z86*t1O>VVWop#1d)HowL!%LB4laiWZhorr?&R$E4{}DyU&HKMuvb}wq`LFEq51+V2 zGd@;aaJeVRYiTXJd*&bI?8!STHcy7U(Zc0=`2xI4 zS3Q|`NW=JtUGUEGq%OsycR&7V;t*+I*e#NNm(`^0_l!HtjDo>Ro&x$Ve-}1?`K*4Q zi7Th0UERpVUP(Zszq{e9On~q_ruFyvm)s~}pTl?P+$R2eI<2x<3EWmwEBo(sv8Y{s zCU)AMbEe#b&b{g;6J4bQrTCLiRm4afU$s==@b#podoLo`uS}8^ka1=(Xw}T9a25W1 zLi^NmmhP7g-@IN&w0JXW&MIAc#a@uH=T)G>#Au;26VELh5Tyf!cklvWg|B0c*f~VQh^y68^Wr9sE9Q-1t@(EKGpUX&5 z_M8yP#i(F=yusRk&2te`QA-uZcO2Xk@B9lmkg`;gb*A?NCLRsvpL}{h7#Ds$y3Uo; zo0+rV#`l(r_T=<$&Qp_kbcFA-F->9EvWnI2lHH70mP4C1Ey`jwkc_WxY<+ovhyCu` z6|*nR`fFe_N%Mq@0mqI70>i!8cD(!3;O4^%ueVsL@=WWq*~lv($n;uwrRgF! z2dS1bwZ~Si zew$m9|6cY?>l0;OFTOmoQVs~vs8GoYR#|#RkHdWLlJ#qDO4#+Ud$d95-GLU5*z;=| zeOWBNWv&oX-0+q0h*PkG=_mPI^4a5sbhtX2T@ScxJ=atUxg>JOJ@WjS4!%hOk&{%EERLRQ zNj})7)?|<-xnQQT43~~Emrs_s@?qg1sgQe2Y(_86FLKayT4^LIE2ZGZV0dDZ$IL{2 z^$HEn84^A_4t@TUnCZIWt;@voFYY>ZRP4-J>Z6rc@crm&G&6+o!E$O=ab{W!XC^!Tf}WX|u>XrOY0VB%h7W z8`FI`BztmPU(V2GaqDAqeY;ujSL(yw-xD5fH|4!ip=`fWEU(W%)c0F@*2W~+8&A%d zB(ZIAI3B;u>C?NDD^)5E2i)`XICyIlv!|Hmw1-~$?aLl1vWrO;Ds|k=xU!H#Bc;ue zd3I9DiPXc#8=i;6yzvSyiH}SB7c5}nIWsBR&QmFMiR6re9}MDdxwkbeC!a6X+xm@VS0P72;UZB+ zPo3Aw%kJiTn=3AIJT=+Ub(daOtM%(?Z0-&PYzNrFXRfGZN)hR6+!d4&8))7e@z5b4 zHu1=8p1H4DdCd}A7tXuFEG;K@he5>Ujl%DV22Rx{n6H1ipJ3bDcyIBGg&rZ!pC%Y; zT{buWWKBSxt(a}KPMP8iN(3((InUS5>%=T|(5IQ{YkPu7%tT zm&N?_R?8fUNlR8*b=i?v4+Wb7x)f{ybN`&Em1k6~|-pF&8IP2)&b?qW?&f<>L(3 zq~hgO1*U2Y${dCkUk=+S8y;rcDN`RVen?B;LFhygM-J{%CkBzjyG%V+A2+ZoR-C+v9!Z0)HCGQ(h!4=$c!X6k03=Q39f04N&!o{loS`v z5>f4J`@2!)9n)z&9y^mMe@dRsaXRzpz(JRks>cd9(iEi+B+Qtsy6n5w+Y`=RDS}th z8tN?_a~x~!o2DH;AiT!?ol{MKB>#~K4VD~7*g8awGB~un*d{QBUw^vZr>@|ONZW9(PRFlYvIpZX-glSQbYNAkR zqnb*Gq#IY`qQ;bKY8nOxQ(ZlRIh?#i4mh~1cA3eL#6O9VaWap_l?wsK))@NEyr|$i z?M$7?g&%WI)h=X=Yt}dK>-%!z#BU*S{#Gu9iAnB@>l-(Joz2g<@KNgJkU4rPJC&A7 z@+N&NQZt)W$TDHIbxM$^nf8H-0Ckg&4ctdE*?u^D)4rqd<-TrRz;VqJ{F}7qxA8i< zvYqg07BDa}I1;SG{?b}*@tGTGDO{ff1xhS?m@0HijOXrcW_CSWw8UbbnYVy>#LQs9 z4w1$)-}lbzm?XPABa6N5nVVy$md)nBXzr-W&$EuDez_XPO@!^r%n}api41D)4wS!{iCo8ZY!1Zz!o) zKD=|xy?{AlQDj=A%)3^VG81!~cIPeGN51S{6mK!nBh$4isrS$Y>)@=NHaQzbZ!rrP zot$*;!18yKG=v-)U2{{5 z7V}9*pUiMp>jM`R)j6en9^P^=nL63=_ZedjhQ=AG8hkum`=loqy!JVADnoJMop1e& zF)F+f^|#gabLTa_UHUEOh2Tny!#rxrybr^+uy{Ipa1@^tRtOYjvUpK_uJuChu}Lkl z2M^3V$?u@T<73s#ytY@uq2|{S&V4J51cR$hgb(DDsyMu4W-t_#Vy;{{*>PrrlL1G& zDd+e8TMl0sozg5=E2}?ia=87Pr4`1b-pyms)FI+6ZL>s4OE}H-sKJ2;@mr5P@PA#a z`Zm_}iG9Jh{woGn5)R+*9e!#(HCVo7&fE7sEQiGoIW-+gU~y`jDa>|!$rA|{_Zfk^ z=CCw-XgbLq`JTcwheLOnagwP!kndhm?tmXByhg^#H41AiYM%90@jk=M=~B~hNKv_b-SoFba90T?@hXrd%JC} zo1{(Q=6h*2n{!VT3+XNSl)Z52(iR_aXJhmA7Dw2mOd~EFSj>^xljXP3;Xuc>*yI4k z%pImjWdDDVpYYjTYNoTlV$%kWLq@UeXB(en@GohS`qX9dP9(-`!xZPmxeJyA6ikpm zko9R{YiD*#nxfbt5G;@tendHE`NZeD_pF>CEhO-o-;v>Ue2cD*>`{is zg>g2Mei%G(_2PGOcp#Ihusl(qykTL3s5C+y~Z9ke;Ms`03OQvssDJvePDMI4N!@<1!5FDCnKKB8WvrIiny&Ay6VC zU!gXwk@-?U;HBax2G8w&roPB!d@zIO;TdV3?&qp4B9Eq-RX9gXsbW{2vc*>VjLpGy zf-9d*yRv(2@wBMC%Q>B389aKM0Fd3liApPKPn#S`%z%Trh2XCp2X@0o)c!PK4PBX zoT%)SdrxYLs)V3YQ{aIopYE40W~h9&n#E9=;S9rlmBVamHm}=CFM0JX;}c+LuqX}c zoGty`)J@&ppxrQPQsmGoxdcmr(VQ zz^yBrU+rqK4mbKrqW!7mOTb6C!Fmb_J(-bwS0};(~GeQonoxpp^#7VGd zmc^7_fjpK2Wgjn}pI!FD@ugy~fM;H4Qqbg-jx`+b)T{#z9p3D`Jh6w*TI?ymO0&&d zE7O(*TwOf8I$-!r;lNB<{+n zxJPA-tWs;0LuZ#s6mri0%JYPYx4ZG;#wjMwlarzt9%p+uGX;4{?)dRLmiycsk*+0< z50o6doE1Lv9!ZcE^>H;bSlrOYqflb^qmjGyge7;_6(zQ-T1{GFIkTFUGECaVyXYiO zN763Q4=Qmjb+*x`rQ<#-9AcCBvUK4MnWpv##_#IqR@EB%SF*V{#HlT;7l9>O*TmG)Jr4rAy_9yHw`Lz~b+^MPA^_jhg zqpxAF$EWX8RA+ZAFH(E4?D-7w61&YV!3pyc&&^A0a7=7`ze7BYNB-S`-?3G0QOyTZ z4zEd#6$us93S=;0=QZMf>(8~vY@bqvmod|cniTIz5( zt?mfe%CNz7nZw?9&6_2sFFx`o=h0)fEs`k~dpi%`wORIV-BHm!6)f^Ag}kd8CERQ} zdv-_ko#x|xbjjz?aw(U|$!o)00so`wj6e-#Zvdr~syn3K{jf=qJE*&Se zw%w;rJaE%GsM^P_AbV^k%Y};)3mqoJEEVbPbN)~-{L4xHb?mN{SK5LZC$bAJe8XNB z)VQR8?~%fy_=b?f7ZeY;EMs4Juo~q- z=C;j7#|^|ePcO_+Op~%*Vlyk)>ha}t_hmm-6}mdD4la7YB$$+U>Q zy4}w3Ox|%r@Op1vZqk#BEi;@$dGZt6{q4E^&rv5nGNaD!W=vW4r3ec#-p)fO5*oW1teqS#C1{^o*1AMtgTewAC6)&=j_>>hH0Iy6 zXrB?eF-S>q)|!C(XVxDjE!K)tolN9><#Y7AZwB_ocJQ^?_D`}Zs(;b9}G?fC$_Oh>q=YH zoRL2Nv~Jp*W2M2NKXNR(kH{}}Uglh+e3N0(m(wc2!8~4airmx13-@ezDqjEM#DULA z%-QbJ0_?%+YrZcHR(X`N!oVylX8l3_gnr%r>A`;eLA5jH@;=^{mX*aI5b#~CRsYB* z`{mYIYtMQmRA)zLRmL)0i|Ptw@iN%ssgQceV$-HeYcD?av*thG(sJgq%sv~gcYde7 za+Fy4Fmou_&(JYD_~89hnTNbroW46UICLH|t$vVukgNKj$hp0n4O~{K%#K`nSt0yL zkXXkNg+;}}%!Mqc7*hmn7#^KWs9DVL&4Kr$+lfb|3Q_`l#VZaUWjrV**QR_WQCLE5 zv4@1Sz>6M(2XzrYPZSE+I$BAnPq^`Gy+>ioxpU6KlVneyX`It0kg~BU(6Z@b6L0gC zSEb4>?rS_gm&rXU=u}Oc>AdIYG5;+|kN)noZYiB`u_^p$<15QsHqt9%8_#@QA-8*HPvdTGBFno}X<=8xL!?T(c_2Z0-M8cDE9dlYk z70T7xo|sy>z2#C05tz~?_hU+ebx%|xe@k<}`(}TuEFYJx^*s%p&ie!|^K`_DS{<`p z=#i*we|dXpTh7EyEi2#qORm1eEqPGaHurR~n}tt4I(nN}N#n z#3xeXIN!240!wry%>;aTa;^&|m>iq`oqgfG2a>_&N>7^Frg+?&tFxFdbXMUpo(`=- zkC>E#(nSYkTsT;o+c=e*dWA(LIfO2($XTuA$1Aa+T#|8POQ~5e1ACYQpNkqpTgSyYo^5IB zDdran8bY`{Ih4%47}b4nei5u5@!Nm$nz;vmaMbpDrZ)03Ny!L2VV=_LD#)!QJ=MbQ zI_Kob#Z5}N8ty3*K6*Ldzcc@s1M_Vjc9HOR2RQ^C?k@c@U!v^Qi{F{z&sR5os$7tE z>V|yBn^r5U4?K5|n01lkK~6(Nbo<>@+w*&qgv=Ay zuuBxToaKD~>vQ|Lv^B~*4yNn)NFIpt_}yVYE&YKDTYzKxmiC5=j8D8f3+@Cxj}CKl$RnC)Be=FobW27V*YF2cK>yE zIy@{K<~QmKzmwrhtMZv-pkr7TnWuDh_VF1v-ky?a;topGvN(2~I{L>J#)5>{48`zfDg5zlU3&OlnL1<3a@i~ z*PhR~NU*<6?_%JtXM9=<)=M7LZa8dtSVrT(VUCMZj2#VmTDPQ1!dBh(J2B%s?~P-p z8`r+>l-KF!0C#_HKR7e1?AndHdw zBACS?DJhxFcs;|M^*qKr=NN4q%BAI%CtO>d-4e**u42NWJ8{>#0}Tf)^1fWRI*}dF z;d5eV-3^6umPtZZHKECZodVYmd)f4J1X`T0fBUm+eaH3lep?PCJukP}-fPUqq0#cqbd}NR$Kt%Aj~~Tx*{Adv zEN7j($+lIqd#mP&+9{qw98R8XC037E!I3!#y<6bdCA$zmQsf8bx7uCuAt#J=F~lBY(qm#R0p9nssW)1Tn5;EAA_QFP1OMGT5O6P&g*^ER_M6|CS+3Kr|J zZkzVwKJN!>kFRWQ6XvT53tZ&7Ig4SJRR8CBhZ~jB*_dVb%B*?2xFA2lKi%-cF#%r2 z>&6?~9UrT4NC+&EsB=IC*cY-Rns8urm9>^6V$uh1CBE5(U!1 zBIepE-GVNM1e)f~T_Q7~ujj6OE$_sS$u%?h1KiIlDZ03aRxP})Bl0s?DE{P|D8si` zVy6bVXrJ34pxt&%%^)`=Wl6S@MS8EuB~4|E3^rB{g;&`drnI|+ShBYM5a47mn<26C zrm(lf?x4W;Y%c%VHZX8hs?KZLe*UnwapKjKPwZZeDIBgT>X#iiTDos!y75QhfbfYq z%NVPi4^268&-Rd*Yforz8Cwh2qC;&5Ch|nc_f@2vDQJp6!r`bTuTXd4#cvC>c_-wv zPb_!$*km%($Z7V}RB;xSnTMaBc&=8zoa<8a?@D>m4GX?5e$q3ayZ-Wq!zuPvawqrf zyFOJweOHyVPqkU~39pU0ea@%nANQSnrsiw@6Iq9{*oHHA8lQ2jUvDyrdGhHG+jcgn znDKB(o!cg+HLpnK(!LiWPxnX6Vg51st(32;q9TLK#E#ihY&ef}<%cXhxJ$M|>b>Hc zMFM3`;+)PiL=N0gTgd)kU&Vv`;JcbmQ;d0Q&$GMVV-=p~wSK?l9Omv-D;7u0DOmZ_ zFGxgwgFQoK_d?bR#@kB`+a8NG9a+lol*P}5ImyRxlfb=Z@qOY|htBCrc}&CbqAH=Z1x#wPHjF~V`7=}g9swk5G^xJ*nWJXIZnCrCtc8BB1w zsKokhqll4+Kmtbt%iW7EZAx+xO5fG9#289AvYmQoUi5j_P$QL4V(DYLeCKzS+%3_q zKfEVZK5&)`=R7>yOjv5Int_j$DJ$bELBUhTl5Vp*c3(d7!S8ePrGme=R^7g{H-LAR zlJG)yYum)*JRz6LI*)VAIpbWGaq1-7v_uA#=~MV?G(wdZe&AE{(m435k2R%=u+LrL2b13C)6mH03nC}&Jsoc;#Ams>~dXmF0v%Y0~g?_$Q;_gJQ z;N`dUJT3oPvEiU$0{el<9+rpahRHL25@-l^71XXgF}L%`A?c+3EVfI^7`HI>3JHFH zv!wCE6s={;>pU~wDM~y(A;G`pk892I1z)#?@Ci>U+Q@CknPX72Sth||k?fanPgUbf zfiqR~0*>-X_O?$5{ko6SBQX7t@YU8*&I!Sfj2rZ1eASfxiK^Hx{5Zkqq@ut@_SX$E zli!KI&scJ%n*mWJpEL7ZZTS4+_u;eqb}*D`GuR|qAJE^)#rRgC zDk-%yH&dYHp#sy{x-~Nl1fXS%XQ8^6<{yP$?Ixjs9-Bl zrNK9;oQ+SDdC%oU29BaeO-U!G>PMy-DJSe!3-Yv^X78))*DTGS#Ok!Xy-(;|^g!_Zi1f`g#Ige4QSjen|03EWxs?FM(tt3&KA7S3KKL2Qx}g*whErZdDLr3Grm$ILtDWhvUjBwk8Jajxx862RRf|yOiA6L=#`9vu!xoQZ&bB5#tQ5 zB$e(-YbN~uur|5P?UG@2yL0umwhgV^%u?QyIsYkcV)|ez)E?$!^0!l{{mj1P<#EO9 zy$+mM(!eaRn5QZKFwYZb^L+&usOC4R7MU#6& z=P?*FCVYTyl^wHi9p+ zxMsF6%cE&ej0AXmgpN%v-PUzfdWYIkZOKqkg*EF0WF@1$cdF@xa`CzxOZbwqXh#3C z+0JeX9%mGl4l_*?@^SW@Z9TEEO*cuh;g%-X!v~qgeH=#;7A$N#Ve&Am;jv<_L=cOX zzGy4c#VvlXgl?L2G_x~qe4J4&Jwup};|Rw+sS6SlD+OepWjbytky;y;cw|-Qf`bcc z3p72LoK zQf8PNQ&!^kwB(&CbDK_RI0rlxP^xXoSSGXN1e?LSK0aNMHm!wHr+W@^TV*|CJm|y2 z-ufxVhNGY@$I{nNs)fV1Su?B2Rf27bs_}k?)Ww1wcl=$AB;v(Z%v#PLYZ;}njYlP* zv&(tcVqsTx^=xL2Qo$v&3*AaD?)Gu#cXP{(@|qraAuUJ4$ls7z%=AdN!x^cR*6^;D zq#P3?!@Xq+WoZU^1_lZfg#skPmJ8(FU`bMDGR`qe4l*6B!&X22=GmDr{)b zY+>9Qaje3bIYKJsG53#CA#4-HL$rJi+SI))(sT~9wh6p5Xyz;G$%rm6+Y;v^)gpUW zafkDsOBw-{BFDR0)~N=6UN^gmSE9i2!o?d~{292OOR$}Ym}Fqa_bB{9WX7ymH^)W} zFWwI?Lsx7mNH8=tYmf=aSQ5aOXZV^UH0$P`>K^|6y!kxY59Y)e%sR7}=a8C!qS&Pu ziXrQIcq|qjR?hsuD|c7;pm^V&xf@!!5;iuJzZ4V^$VheNITOp-*)Xf&q^v895kc zPh7iC;LK{~K>oul7dsYQanyLid@9Gh`RamPxuOQ%BbF}=m$@xCEbWlZ!D}UWl(E6k zlXa@r0>00O^5u>{_&zPo^-Qn;WAvGh6pjxp%tlOed>l3%vDJ3pw za!pg-(s-9S*)?75VZ_C|>K+Q#r5Eg)*pmL0+zgXAI%9(J`hpJ%iT97z`mSJP`@t&3 zb!>(}!xY>2Gjovg8t?ZGGBea9Mq%)kA&WwTy`reBowi#@FYue_$HI5b2|IPj>k@D7K|_b8A0 zO6fUAq9-zVoIK3Tx~om%@z47zvdjlm4vDN)_H?}eJ*?$`uTh8fB%b)KeSGOtTNfMf zu)p`SQuS!zXtgjb>SFCZB52grbn}UqPtp?KXLmSLG=+LTX6twRUb5T}_-ijG& zQW6VVE~_kCBr3re8Nuf{srFG3m%!RNiOq|@t})L~Svl#5ptOOZvr8eV!2 zc$GcdbR0xia7Ta79PVj72VKVfX%A>Gg zxpK?InFeiZxn3>ySg_(2Ti}XEj5Ul5yx~kq4I(T7LU&H@QPo%-q9UrnGos?CsT z$lz$IWwZ2g5n>fIaA^(Nvc<1q4_f>WRPX7H^ihZjEi$0KH7;bPlSHg(hF6&Lv)9Lf0kO#6DKQbwSo zd*EO9`Uws594}ZVxT>%n+8}gBjU_D7RFdIQ#<`Q+Z#7o%&bH0uU&FleP$5TNAhV*^ z(twgQslbPk0SB0m%FkNJVC&N7r6tI;=AD8-I77-z%~?ltoR9R^eEQBe-~G`0pM|qO z&pIVvkBG%x`Jjs^cLbWB2FW zr6Vsn>MovSaTHipHIbQDeU0AYPZ|mZFXc2JO_|eM#v8;pVPWSaMwd-5%<>J7X_=`m z?3Q?=Ef||1;lxw*prL$wB8%FNgENG?dYhb{h#NVG8y5WgA<3fe{yj+RNx%ixCC;)< znY}VBqO2OT&m_3~uJ)BGUo=fB)pHT&qA*6rXB{pYE}b!+2~!O0SCnY%(iL~$tGD?x zd6~rPKF3(mNJXUuJ?b1O2Neu?6it^L=LtBp+RY-HCrrU*QCBpNk4E327aP}z@vdf^ zp}{sWDJpT=EUs$_K?c)=-dvn)k+x9TQORkBfhW_EQ#nV@s-;LN8eDRaVDl5OQb=7e zwaJiqf#hyhQx*n?Wm3AU6+X2ywk{9}Q`Cz)+ox+H((oo#(_sR0?~L_aMLM}G&1MV< zvjshcSTC8Vwg`UR82+(&8M}%{7`M||Q?*Vmp}dlaEw3_#lwPeG9* zlROQ>JVoO!A6W9OYf(+t+(XY;92-p?%P6YhcgonIeE6k1zX8wHzT|wD}j~dNxH5@frmb~ZPyX)r7GbY4w9@Gd9n1A(3JNta|m=_avm4sTD zo=lN)Hfs^;aQKn7!{VLdLA^*d-^!YzN_NI^pftON5Ncot}E9VU){&dQqjE2%<+hRc*}iC zPxs}e4oJ-)H$L5ynoZ7nKK%hmpzKIT73V$%83UP(qCRH z*zitAswSxNUFhPCGKadG9a#zwUfwTZz_jp=`xde9W@{wx%02qZp)Mh)+w5_nf>l)| zTv6~qo0spo7>lr*Qx~#bRDkb#%KR^6rG9_W||=Mr?C`wn@Iy33ub{^k`FB z_)5b`P=1HEL+}Y3rVm^XtQ>1QN?d&%pEj7O2X2^X<6$b+)+D$n)OJ_lD*gF+Rw}#? z8-%YaKMUy8Olg=DV1LB3RluZIJ7l6GlYocTR~`eV7bS+lz1<6a)I4Y8Gn|QEru|TO z*0#RSEdjCa3RO+|Tg_CwSap53s3~zO>F2NtERJ2$NX}*3Du%+^vCWB8Pt-xv)NxDVCM5 zN&Id9qfJ|`hyB<7CUvIu!BVzEf{c$Q#NBeZXHqQ3^07aVLDx3ReoaH=k0SB6b+S|9 zBy3)^I81P2k(h8&SKB~w{qzgW57-sA9Emqh<2$G-#4^Vuv9U!$;Nq2oUxW`B%@I74 z75n0lkUOuwz>XEUjkk*A6`VYCX89V__&_jI6fgH~5jW7OarMS50mnAiJ zwh6KbU4Gz{$m5{m<5Vj=zhaJU8~btPSMxafgxOf`soBNZ|9+0;7)bhJ^|?iVPpU z=ifYPq2RYr#7R~5Vb+36Op91hN^4n4`5D+Gc&Gu~88OS!?6>U@5WBjfk0P9}z`N|zW!_BM+KxKC<( zDQvW07w3+>D|hWnVt(IRWVd9R#|g$)+&`)tIBoh4wAU!GH*-x=@zQT*pQyyA%;&L? zlWT5Mu;Sk&7x(4zZ}tj&sBE-dwXcD%d@{3-gVxFtz6S30%4_rFgR1(E-D)`h*-daU z+k{T5RqAV67$3fxTj?BTd+_(}`w^d%R+{ojPm$O(*Jkp>B`jsNM;=&m3Jp3D0LpOGI+E>&f!TlLxZbHb-ic4#m`Cn z+e=O5_iMN5Ixl2d+$8X-`Cn#cyGWY}c9p-wl=3h-m`sK}*Pps5;@)#^yYoB=K+(eN@_6a>s={&ReJdW&Qa^cx@l<6=_ zQIkj}Z>Jg$W0-$o-Vd=qJU$853yfT&Q@e#a9Ws*zEKC;%xGZsU(LP|L=BdNY#_A|+ zxlp>xVK%EZXR_OjFa@umgAA88icAr3Idt47^oVN9j1OneuV^_t=iDsov)Y}Df|_n8 zs7(A&da!!IYT}Bn&G5hqBTQy=Cc?l!wVYT@0tE+-YaEx>DlJooF=#U_}7WT zEMg3bOq`0rXHrDw@qg+Hy6v3dA;eI7ujEDX+mON^FO)*QvMc|pl33v((8Y2>_LIN* z?1u|fZZzb^dbqL(mh6+XFk7kfoVoYhg=;Mq?kwgz78P)q?RRQio+M`^Wg{-yBd;CCko9f+36TQ+j zSZiB$aYzYVljyHp!)uh%=CvsNW%6DX84Di!)(_Q3xCCa1sXta|er|K%)8R1r7bXRA zHHwQFS8y|(SRoQ9+%97|fhYa`JtyPCISx&g?1`;xm$$EZW~>~Mw^nk7Sm+L|qeai- z7T4}nc=)?PQE`T+i=zt@r&jI%nu`x*wj64_`SI<|0@3#hbDk^CWO3eb$hJRUaEi+^ zp8ktRHmitzoRFo)Eqx#)J&*T(GhioXH3 zt~^}mbfMDW*ZUmp6&vr%79270SE_mhb1E(Wob3#FPNU*SI?OZT1Ey( z3ptpW?4C0-2sliZk5iEN_3?mY<1)<%ouoxmla|g)xnRQjm?grQb8}URqoQErop!%1 zc7H-&Tk_7FS$gy?)8tDNH8omn>h?5ceA#ld=J|@Lg$F|mwoR6iWnEJ!D=3l}8DZIy zqP#0R=a*ow>w$viM-pPQ@2h`hW0qi7h;!jzaiD&Q##X!JjT;VR3H)PHkauwLaQz?r z8#c1$%{OvJ3LA0n|y%JBH*i}qjb!sep45n z71bA6EQ=I6n6!AW^|D?!C^*faYc~Zt8%}9CJ?F*a#(+0R4$M~MY_?VZ z@p~K7JL@ZIk2s8+xY$4=`lX}87~$P4rru?)g8DaGfHTNB6P2705biL#p37609M(2*a*}L@1qqx6H1zl_2CS{~^ zCtqh>q%WA!ukiA(kL5{4_ww?uT_4|kvu`}k$niZR;nUS!W(NgWB)>ZI9eec3nxovt zcq@qNB);s5aZVSx zGfU>oTyJKM;~*5jzT1t7JvAHmQ>l3 z4k?xC(|3I4usU2i|L{~d!ycR7K&Ba!cbTVF?hVa?E>My0-Y8xB^Wgo^)TO) zW(tZB(0FQaU~6D`Df2}e)dL?SSQ~xiE-zJ`eZ)w|Pt!}nE&8BeAln;rz9j~l9Up48 z3b{V0wVSjhA^haAHV1LlDhc_l0LFP&D^^5Q+zn8Pj}3K=`tp5!xKvrP$TjC3-lm7x z1J=5T3V&2TGCOz;e^uVBBbMQ-&mVQVW3Tu4>X%6@4UQ)tGdZ&`eyp4;=`%?nF<1Q5Vx*wX zZyp;Ou`Nb*%B0!c5+y;icNKW1H!*H_#{Qa}&C((MxwYek{T7WAsvNe2)L*u9TG+SY z&G|i7_rpnqb&iNKhp{fl^)txo}AIj_drJ@!oU2N-h~K`uRQ|a4%p_%K4!6F zzO?XC#|gy?YD~^?E?l-p6~rRi60coX{JcCO^4mn=mFinHwN$D#%4cyTo;=qd$Q$T+ zX@0}AgLeh^mWXlX^lvijX8o$i*ZgSqqqs#aQ9>LHUoIwmI^v+oB;eBVW5egTH;G55 zOHVK}N@riWXie}|yJb6iY#P}reRbvfv!fIzTv~a}XY-mVe94z4)av)|UwGz&-;*;w zuB{U$$waN3^Q%s`XV-3#sZaa9g-<^j_G3R&LCv%43pKptw>)T&Ih`!06coy$(H+ah zHF2KQh1)VM-_u$)d}0+{IjPme%~8?%xZvNLT#i;JFEl=4IFvC{cBA9YSifsd2^aMr z`OmRaIK3xBNAI%P^oooI>Ax99Tpt4dJFE4*dyp`-GblNHu|aaACzrAyOF)1KBZIn2 z%nxZ#eRcLpbrKzFs{Rdio8Qh+f2r_JkMk>w_h;w+DL%d*mdLxeFE*4{V!q<&(8|g? zTdv{R+t|hf4)YoRX>;sbzyCIS=AGFwVyFH^+X=CGKcDT;vY~|A|3~Ky3-+a5rOSh+ z$ZWh|zMA3A#AwG|j+uYB(B^HKW9dS=CG7V9!=}5ed@{hZt$b=F*v52`MKfTRK`LA4n)1o1MYNCw^IK zZh_|~_9F!uGbeF!DmC$5lZb3fap7kaQ-5K4qO*5iB8TW4wply3usb$K9LSbBHR;_M zr{2uYpIa8^yqaiIC2%1pr;Br8+r&jZ)0DjeX9OmEIwix$W)g8^a;1cXqrQvW1-&Bs zD~ShAO;A~qIl+qe0`G(0OOU%v^~fSs{=LdQ^YSE)Ou67+B^$Tv{*~B|?Cm}#1>Vw_i^6|&Rw$ZkBw3#oT(F_pCBaz0$Mz@w5m(CdN zDdn;K(IL8=ozE*nhmBW$U#zrQ}Ie z_Z(?}&nlcY#I2MP3$1kxoaUpjWaJ1WvW~gwH!1?UT`RPof~(MC8b+Gv_j# zd37dvotkp-vqk7cP`!tnkjPx2#<=k=mQHg+>~s5j!seV zP@HVqsQpUj*xYBX=#wF4!kFTGYvsd8Mq=zao zT$cA5TsI_auxof;{ovY-)ov}?Q5qZ6qa<#B^pbgTSm`lWaD+tTj0p7(XGIqO1&4xm zMo!6UTB*sMx;a8Qg?mEZ|7}To{1(OuTv(};z$WD=yhx}^K%j-ofyHRTv7RFhlfqO5 zCW)s>Fk0mFws>(Iaaq`s*tVy1gRgaLwm_nyyE5a{#K@K=U$wqh6328UPRRMS_ddA! z;#zmZjMkePv(z0988*yln`>d!$RQ-z8{xd@kjupdmpLsn{9_bdFSA@vcBxyJNuYJxfz_)P zEIl<%Wo1WysM!mXoQgsfhX#ck3`rdab5c!mV`94wEo|E5Bg^%H@2~^k6du!nDLfu8 z9NtKqabzsM=VtfmeJ`uSObH?P1<%u-c{IkY;@_Z^YC)bb6`r#~4mP@cI(*d1)8oiS&YN}> z)!AnrG^@m%aXwe17pioiBjSm*P5il>V@_@R-HyL_B_+;y_hYMoh>?Pet5FkwJF|nq z6p<4io-z^%F1utGG#or&Q}_S)#WF+9R3>s8I2`9@N^!B0VAE*SR$*$? zm@;Ad-OmN43PFlWTI}nsYgi?BeUClibb@8^zKf;~6TA8aLR?%NA1f_jGnwD#J-2IN z&g3fJhixz7Wn?T)=Ds%RdO2B4sBcn`Rj-rLfs}|#YZQ1oBgNT67o1oUYuUC&MV9rN zm#o>L1(Vm=2<2?=PAZnnxsc{^a^r?=R#y@Q+6*jL6kZbuUdZRMbYkubp_RtDhfQBR z=8UlJSboA;#_=8&=Hu_Nw1FStt0)bzGI+Hvs^iy-grCesxP zx0?=0-I&F@PP@6_iRHq#`xGW@$vHMDrD3LH^An>0vHlD87wp{_4d#CoQS@+iKjk7~ zWw!1i-`vaTKkdcWKH^}0`>(Z#(IA9>W?Q3)`qC*s{Z+nYd{gpaln;FQ?4I z+y4E@&d0wiBAO*Kre{9ui2ApW?a@lN|1NS|;`Rpan1^8S%`_t&+#Usl$gtopoypykOR=W?w z^R_GptB8~z&IUd%ovRflb)7MEikhO4yo^6VfqzRE^NsBWL2VD_eB|FZFXYU|6M@!; zS8VlTVKZLS{C4p~`8BsvuO{>y4$&*}T+XoKmGZ_JNlB$9?L#o+w(Rl4LR?R@m*7v@dFk92!*Of+r&35FXY%- zxm-F_Jvy8`OB{|ceiW0^3H*2RvjnRy17m@YgTv29i%~KF6M%niWX_ECL0;sBvd>F9UVONoDvn{Z}SH{+%NuZ zsuHJy7SqK)mtwSDe!O|*#oU*i6W7YL&H7PT5S)@6C!sM@V)Ttx4!h1 zsJ)#V7~C!R`Ax+R-xdMk36l29gcTQRGQ3G{=@6Q1o72ENuj+mLwN3VxZACwMceY-b zcbMH!;z-WAAekRLV(K;yKN3p~MP3~7SbTU%yZiy^kOPfsiNC(QN#(oI(25qC6SqSK{%-lRf5kvd<82m~{601eu9V z|Ckx7jGFRX?JhEKNGf!z^6(`-VfmA|vYf?idCx8Rq!xi530EgoZ)3KgMSkb9-^-WO zD(p*Npu+y-26NXO2d*+k#)S^Q7xf#jd6enk8YH!M!Q973D-=X*)&;cAPdxeVE|(QbHC*Ni zU1Zwy(qx9!Y~dhP2{XqPhptFXkXXbU!nU-V)0cJjVMhV6IkB@08Yl4@w4JzM<$6XZ znMw9UhR5-59!GiE&NT2E>@X0PX{g8!C|0ntc^6;Iq^c z&}^Q$h3R6|n{5tHrV5LQr$l%e^an2XN-&$zb$6Sw$CDEo#~GJ8NLam%Ie#p5roWP}JudBG+sxUX#_sr6c#f~S^G>VTPF5CSQ8gbfa!5~WHYk=>{*|z- zQ*Q6_$g+~f#jFx4zqW2VByc5E==Afu%|_aRw?!Tc&zPY2PUB`;L~M1<*~$AQw@;gV zs_$J{jA>t5!qRhn=I8u;HW!+Powm4{HTS}CvscFLmaIGij})0>gfeb%|N1&7V{aaB z!lc@mGG@DuC&!vtstT`c+&JUug9(cds!AmGOG?ZvQE*RBu0E`A(%4vMwdzZTEUm>y z-d&RnUNU*Ptl`Jx-i4g1$tK%t75#7ARQ!75=qI84wVjJy-|X!^EV1Flquj+IJm!sl zCp1}|1B;t;8csd)(i0J6K0BR}#pubzjk1R4cQkM332&TlH!Cu++eoY;!;U-WNYo8c z$*DI!?q%aBOyc-1{-jxH<3biG4tB{{!OMkDrw5c6E>?Jx&d$(n>ZGH~pMKDM&D)iH zCyE50H!Qo5Xxhe8y1=JA!C~`GqumMD77MOdp6B8EvPIlcs_BZn&y;&Q$r4|0K4i{& zx7)fyVCQ4qeYQuxN}iROv`6lWWt;wqHx`F}Ua;9G>B@X(!d)%n2k9$on)uUFT9-cE zlB;~RX8NKnHzc)}yIx zuk9wnS7^1lms#v$pyRFwXHTq3Es*+V%F7-rQd_j@`mFTYjyKb)+77p$DQsJ~My9$` zuzQ~~|ALAuR=Nibw@dG_T4E)Buw}ws`?(WOKZp{&!Q!%5(@fQ1bN)j8no9-OPbOYH zv+#1Pew+Dbj)TX8<#sz<=$&_GUFW=(OBbxQ1YatDa~1iVFXu3M(*#FPIIx&5rk3@gT4^A~Cju&FQRbd+?I@u8iaO_*!P%6feBwI^O+xvJ3T=KKcN>souhJW)PUz<9>%*oz|-?v~aS zWuXk;Hpp`Hd6dO6Zj5Lz@%HmDetN5_KqKLN$4PPKs26?H|@9}lP=*RA+w2{;e*pB1?@q(@H=0*t`X7*L)uB zxH-e;iA+?l#2n}LH7%z&b0@a4GC3Nzm~lJ^@a1GmJR04TcWCiUgQbeE?yT3GyiDrd zsqi~drWwmT+cTc+me6|OHobXq^4H@DSF`3aT%XUT5cKl5Fa)f85*erJyhf~Z?T?{%b z^UiUsu$6fEWYrfD(_o1(Q%=qr)^t1^z1)2>O-xs-V1vfh>T!Y2+-o?>!X ztNCKG-rDd$qmq~Vb~x3$c%9f=kZWR;_x=8!*BNJDB$a07uzB+7_U5%5;B?bm&}`E> zp|W^t+NCFfJ1kF{Coi6!jveeOy7VQrGjn(~lY~=v~aPm?yfpPydo;M_!+~d&rqPGcvyz9(a=9`S;-A zL{7IY_nF;PZaQycc#_-eo8lZlX|jpIvzqfqj&h%0ofLmwuGgAH*YeW+mG_LyOpVOc zBwTdOGhXXm@JLNAxoQ1TtRpcp(n27(lt)Q4a!q2yrmCL?C-xXcZjP3EDC78OhLclH zoD#xYamd*j`n{~#mm@d#cUkc2 zkiQETM!nvUAlsQcYg>u=*^mOQ-gw9I%{y7xC%*VFe}UEf5;+!ShJ+Q5wBqkDbX$t? zuIl+zxYWT-4>?vd+Pb= zPa}HNEL>!+xOuef-n~Vp;L^HVZ8y(*_VpZpGh6ZvZ}p0fMGJp=P4S#$8B-vUpr$F$ z_HNgvJ3K2iOxjBN3`{mEKbU){oKLushwoW%u(zqn;m}ZiKUdouhb0m`_Rl|X$)V-! z#}(zzyA+%pKdX3B40o(W|f zeViwG=Q?~V0n3ZSRHs1Y~zIob?=g-aOoYyh?=yj^C=~T|LSxJIz6@qK$*v5&h z`05<7`b1LSlS`aU%5#g1&t+H0vfSo*bJcfQUa{Rer4yxGJ6$x+UUomSq&#=#VmE2Y zYsSfv4=21*Ok2#x5Wx1}05>~h8kf%96NNVG4cKzGw|VZk@wCvRqjqZB8Kc{C)U1A3 zy!#V*d1VXBkysA3e^xi=h-bcaxYtrl_zoPGDKabtOQUnNgIZphaGI*P>Yp zAN>}TYkVl;s^Hi9z#`>n;y0KBhQGAgW|K4vh zaSsl@DBx+>u!~TV5PVxJ`LX-QwwbR*%I4h~QJWgD% zK5~>XE4;SNd}!{u@Y;mi0+kOYC35UkJDee9SFvCcgA4&7^Q9cj#1E@-F!{U zgT*b*lBc6Dw9Yk?D7kix?W&KGqlo}>i8{x{l$=9rmmITkvD}esC>-N|YR1h2K`I=5 z94l|%*gL^reqW=R-NE;b3l_C@YHD^VDJdx_XmQMRc0a_jSBFDJsAkU`VdZSMAKz!G zwNCi4K-cFv^Ns~elU_XRQsU1PzNv@The?)geE;R=y_d&?yI=bqu{LOmc;}>I(bd{^>Oht345PaAQzp(A zrd-tc*eep(C+XVR;HAXB3~>e&q2}s9=ee-J>-+6K(k!`1s^(e2TP`=I@D}Bo-oRF~_%^IrC2nd%7bNo5lu> zpPQdIyU5xJ8X7+>3f<-STtCCzDk06pVVTF?3m2RA$bb08ZR(NU%6LKlSd@nXi@BMk zkVwd{fH%%FcyF67e3SeQj*`Q(DkH@eL+?4 zVh8CHZIjw7{0=dBOSrET{kO($L&10Zz)cmo?^Gvb1Sz@v7Kzz#;n|utcZS4Ev$X4% zzMEmj?lAwbCHJL|d--^+Z?naA&lHNC-=r zO|6qmA8$VF{m|gWxs!=1jx`@A_9U`DvF%7=+jDQ;KlKZ5U;}Co9qu8WI{wpSzJ})?Z;zsLy#w$HP1e#yA2Qrt= zVA;edH@{IXgu(FBY%cZrsZF*%?_(Az2Uaz$@e^xJdnjPU({RdU>SXbTy-eqVCyTjg z|72`BuklDt<&b6b5yhibOJwBS8|H>K+RHF{hNK8i_~om|tl+XqvLR{CqH^U2``oJ8 zw|o+uH%HuA$>qhOstFcOnSxCXW}b`PETyD%-GnYMBpk4kVd6L-&{^UT?8wzCAkb8_ z;M?wuV;63fhiz0$R|vP)JFock@lL_Fih}dFyZ$&0xP-w;##Pdj+gIN_5-~o9$j8f6qzasSVeb3>UwE`4h}k8H$|m z+A*E`A=ScNJvro0s-;Y)!mJkOSN4vt4Q}Pi9Z~cWS?FxEid9a7FVV`$iIZcoi_Obx zQ>$GTepmXeap3#A8qMaED~ns}D{2=zDcqMnSyp=UZU}><;glcZPujO{DdUh%oF!sr zs3^!H{KO(q*qG;#%qBL2jatq|f=UO)grqJWZ1Z?9h0P#$<#vG@o_QUNb0!?t4E?o5 zCBoBGv*X4eT{h|MFAP%bJ*un!{)^jflD1!O$C>qU?fEwx>RQ^@Y?&CiB&SVd(vr58 zr5#cW3eL#5HWaNn!09gCquSrIm80$0zhj9SLB}Q@HEzw|XgP40K`|&yaKjp1{#fXVp7+*9ZiQ1YAxkQIm8OS)%K4 zwrjT68DoWmD>i$6sH-*Y66|hyz#ClMGSGFVT@?}a&0n9v}+0}OTRSAY4m5PIot9X8OUD3{(Nzcx*ySW}O15FfW#+EkE6W8kPD_P`m^LeDtxVj=6Jhk(L+nOiqJSln>~0s; z#?#VD7G_~C#f_~>PFXAqJl;F|T1Y!gtzm8qIUvN^%H|z5l{t!+O@@Q-Thi{!E1If# z<}^C+9>2MuDlssNZQ;a6W^96=1x|3BdSWY{=hnAmdAlFWlPPJ;E0wH~t4(>`Tl}Wgh2YWSf8B zoZ6fio@%=Gur9!oVBtySHOP38OdvU&Nsf99bdFJ%#ovE$>X#m^ZUMQ z6)jg$f4iW4kC0bTfGDUH>(aYoLJ`K(9~=pxp0YxV$z$23yq2$dzAS1iZl54 zOfWm_pK+<+s?5wX<;Ys4l{?ozG_gpvd9F8aof5ll-{qn{6^)iBjotzZQ8yAC+PfMT zy;yLF-zcy{Lga9^$Pum=BKGqNoCJO^OXgKM?5Y)`Wcs21?)RjF^Y?gfv6?bZ=*2gY z0NK@6yTm3>Ua+M{F;w@qA;&D$B$d=D)>9we{3H<5d1ZM*YBIxvoRr4a#V3T+-!FK& z;amR4-ifK9@@h-w2F(=u)O^L}oWO!AHj(XJ&v-cBZ#<~PE}~J?@hqUR;f+L7Lwmqq z8G8j2mIAw@>Y94rLhlHgEZz?lRF>J=CW*JAveTOSQ?$1BEVN2qx+a2ta zDwI67m~3g}_w*5FXA@@R&yxB!p<2~6?UQ9h$CQ4rJ^7jJk5XR0WwvYbjJN&95b<;J z>h`1wesVX%GIgYS{NvqS6Th`69C+%+65*L_AZg(&@hdolf3Jc+0_>7GD&W)l-3V- z@7X0T`QiI!shMNnndj*muV#C@#oXQ8_ayU^-w{j8br;tZ1U8)F_RTN4{klE#@Rr1r zXWwu8;w)#D@_PH*ufg-e_XVXW&dK2TwU$ZKqTZpU8<_$^r+ zsx`UfrsACiPbQfa9J_X<@Q`d(Pfm()N=R(!ddC|Vl{7ERXkbzicqFhwOYgDKM3>E9 zUgeFi$J-yNjF(M+h(^kSX{AnlVADnfaVpePvuip_L$%G);zIx z8RLZ-7e(O(xwGU-FQ0T*QahvGs2ITMc;xbw8=EIadzl6r8H)J2X(%@btCcbk+m$F9*7-0apaDyvyiiDlVJzX%;Uwn$(y73Bvm#s{+oDb za^TB5x1FS4#E_Oz8vTK=QgO@DXqbLD40E;u|r;bJd;-B2=OBTTZ(G@QpILjE4Hn7U9^D!(_;H*xwknC(&s=INC{I=#c z=9z*s^M#BB7q?xuRErb}F6Ez8*4Un+rYPjX(4U-Ec7{F9ufBdK3+o0M=E`sKOT8}? zai_VnX9ucsn0$XZTp zDc)QgXCPTE+@L${X2G(w7jG`+wn`t!du5eT5mAThSfLYw;z)~=TA@4WYo)hPM+lJBpMTNPN;dwfwnrupGR;mt!gC2V$2y<
z=zFfjb=UkES3fvXU@NWPwmmP>LVI$2;Eiloj=E!f?>0Ez`f|71$iQ{xVzr5PG9q*( zPg`^^{w%D0;_X|R#D?3-Vcsd7dgqgKb!1a?uk9*wTPAbGKxV_W!^=J#RKJIa@|ye`{iy0P?OL~2>l9=X1= zGUdGUxH4bdXxVV@M`oVj%gOtG7&JGV*gkmJA5d^EAYb~*n?UQ$FRc`3@je$iaK-Ly z#RE3BGKUPsmi@DmUaTqVJDupIz@E6|b~|sEr+nv(8&7AXRCn>LPrG*Z#Mbj}Tkobm zJ(wK*OhMUqdq@Z4<$DspRxrdyCI$@)Q%=I=T{w)J?9pl*_OvC+2|R}Gl6JfZd6cTUNaU!_6VWl6OQmIY}M$# z8CG^Wd)KEu3pN($Ihu%^J)Fm#$)Ypu(uq#_c}FW#lxFIEVCTqLa_iZ*L*+Uz6P6|O zz1*EV(Wgx42%o>~tvSX`X@R^u^Bhc69|{M@-sMYsUaa?CjxnrvshX{!&(xddMlp> z1>evr_&M`*8^`h*O`a1DKYp0?iYL6@uuAR0!oK+Jr5;iy_ z_R}DIV$}A2wbOjU27$aCrBBSHIb?31JaJCNcfr};4KwfaRxdKRFT1Em;KuHoy&o7K zdwD)tCd8l1+u2ZVd})^iNp&g4)ZTXLUt!HCejHDvK&^hIoaA&#h#wwrnmceBZuCZOB{Iu+(H5kmb|S+ zR#}C7=?rEjnQJyII$}D_lF5W)BEO4}v@EYqmk6_kI;Ww^j%Pf4F$Jq;JEt&gQqVOv znsrHGIy;Lq<8I}QqIW#GWxGEfStEVH{LQk>$F&a|8=hFI(ZE)q>6-M2S8<(+@f1_p z^Ub*iR}@@jE?#!*_@KC~C&vg+kg#>~1O>d2D$cn$|30y~**Md8fXdGrxGZ)|_e2?j2W2myy=hX_NXS zSyl7Y*VJ(7GHyS1b-f_*jbYnF-ZC_=Tt1_E+2zyhmiK-;nw$tP@bH3*!yuPG~o26V*)1Zf;e2=PeXsD>Okgw!{4HE4s`~npMW>Xk$ z&z!P=Ygv^Qqws`C*LX&5jv0zp%L>{H<_ca})5)yCwm4r!X&W1Z%o1)s4wf8+rxMIN zauwAVI4D}aWjVy?5g1|;Y|+7XC+T!)7<>T?MuyC$E|N`|7sfwUO8muTXyNra%WD(oq~5yG|WxBQsB+vUiYDm zV?tt`NUs)`%mj&cM~f#H8-6sGFu(3wJn@2mC5J;HOEC97)xYyXRwD5qB+6m4@eu)QkH<_`?EHDW< zyEa?nSeQ$z?=xkdZm(I~3Uip&bnb}1f9%0ClMfjko$4abe{QH^))r2_6BRP+&_|Vc49WzruKE;qs59a(CesfmNj9aetsXD4hpVgVud-q}8 z6HU6Bnr#|v;_6R~S_%T$oqbr_f__d&oG55yR%54;@x#E^*ty01GM7U3>svxiik3l* zGCZj(S>7^d2m7$c96Q1GB0edQGt;?4$$H^=wGF{rB@%?Acx`80b__Fgo^-@pWI>Js zo7suJqo;C=E>6s8Okp_JA$p>D5@$x>%2YvzQW?d0hf^Eg@(POR_NxE?T&gbDP2U1#TTCP68eQKYp0lGyY1}JGk;#d#W`7d(!3uF*mpGDaa_>+ zwS_^#)mv#UroJH)3x8H|%&)_b_ESi=gsds|gnw_?(3GRRq;?V)$=! zG6!fC#ilraXXbrTWUe{E_O$c__X&TSg`e`>aQWgC(J*~)vxGuZ`${$@)vIQ+N*ov$ z8;Er9Ka+HLIOD7A3AN_tt8+QzR5V=gBxnf=atY`taMc*BQ2gPW$kE{wmB%~EqhbS)Dg(6G*{e~+V+zy>ijE|c7*EFc-guH8Df6%3L zVu6eR7r%j0uR`Nj5ADbI;`5KY>C8GPt;2B0E0O2O!ovog_D35+npPy39cXe^Si|Mk zkY1Rr9D&&-~a0Sa*d*ci|0L1 z+`Ic-io=x+zj#;VzH(V~q$o-wn(cRqXdkOEOJcH1dsm&{`ADTl0a^a%+bHK@g?e{ z0t=5*o6;+W?B$w{3h&Fe7_=TZByuCUW`<0Yq>hBj5o5Lk%@U7NH?cS~@fr1Ma4rf` z4NqL5VstR9rWQ#y?lcSa=6I2UXb z>Y6y=W5SUP$sG?&Rg@ItQnMa)Z?dqK618FvWRT=7dMoh2O-#fzdctb^{Gw7>hNTtD z%L7_IP3eddmUQFfY&hof@60bswQ_TcPmLmf8THcd7q;@o1)Uayw zQED_|sa?{x)bYwP6%G+yZXYj^BNsL^PI{uNq<%t1-8t{v^Ly*mi+B}Vqh!$9luQ7r}1eY=e;RY1UhaCDwG`A zD9>qiIMm@n!=)yNjVF&a@K+T)`(10=sQmil=Oqd!y!j=6@;N-UaCNkszd$GCOxF_T zQwBC2v36QI$pQ!NTPY2Dr-BMiO zk@KFsZ+Hduf z|382D&;S4Z2Y=VU|N6iDTmAIE_D}y8pZscP|9$`Y``_w6)_s5YFaGrZ{ZGALGJdE{ z(x1*$v$nP>>zdn^?8rM31_uQkSqz+6xOznFe*QReYUUe3Cjo^^X(Fu}hQ{AGxFn1w zv}kegNEqBWtiooHERbPlD`fHYpRGy5WM_#(f2X+F+IxPUpDg%Gj`!oKK!s(OCtuKa z|HHm(RltGirw+}y*0Ju(1r1xNX$hK2f%aZ+f{x1bam?Ca85G>^!KU$(t)u^WdrrWK zD_brv^uGB^J&b`pSdhU~=7oy_Q;WuVMnT43J1mav;{M`)$)x}IqoDo4sZnN~#h=(F z{`AwA+}QRo#I)_%w)T>CvvZ2P3kw7nm}SPY^u3HREp5;~5xuwOUdD;p_D?_Rv|0!! z`!~sUoPD5d;?!B*%yz_zRnsgmWzAx~gRT*Z6LppCPMwLm?H29wVw*{bpz4e}uhUTrO~lkx5_Z zhMALe@6y=~_DhO1P8>1_(q1I!e!zn{<)F=Rfn$q*H|F>-Hi?)x^(nG{VZ5UHd4-c& z^wkp#4UI;6%Y$Y=xafSUimm$ipGWey>|_2eYA?vvVtDQ6r>+@$kV}FgB2++2xs|~v zK}SW|gQ;C(y`V{OSC!ApoWA=_;x0qh8?Fk~!H?O*hoT(a1yA@I|%X z$0|PdTjqa{EatK0QG73Wu{S7F%P{bSz^9*QPs-m9{!nsRbzY&jM=0~%2L-kL#c$jc z7P5*o?f%C3NXDNdt87||Ayc@riq5`A0;+N|e7&sWdBwlTG_9F(Ju-Zr`=g017kMh? zng+a9V!u&hDm>+jRD<~hITgp&DePA_FDv}x*LLu+U{8t32Ir->8$I6g@W%Z6?YdUj z?clAC57RTJXfj&I9SwFbJTm26@6{`9n`UeeNt%#ploz^Kh)cj@Rf?a-?*Ee(GaSDx z;{Njwd&rkk*AtuLJ8vj2cxQp;Tb1B#htCUhE%OZt$U1Z-iF10&bHPVa z<5-C0!E>ak^dHixNAzQ9oDYoRnzkarJ{k2&+p`kjnhG;;a)cIY%4TSj_Jn<&CN zg(Lolv}mj!%Oj17uT3S(Q)jjQy2QD0_Rat5(ji-TCbBv|;C8f}=```mf4}&}D-5T0 z`yE91va`nZTh>$|ptaW$91_5ImZP5jMZLzKP=@;R{00+c_qx< z@aD&n(|iFxlfETo8!K@;7^OdzxqWX&-TcDlf6w15UOSp&&H3Zxzxu=ftTv>bIFig* z)vw+de4@vNw|{|-{Ji5wZtVD$%wcDFpgGHVj?Ibrii|DcN_Q1x{yDC$;1Zhf;Zo(P z15au^8sB#HC}e%a7bXN*5uO+KPFW??%TLtRm3q(y)<;C_?q^sviIM&|6TcK zevrKOHIJzsOFSlUxlRZ%x%g5xqiBMgi^^Pu;tsQ>`Yi`vTT9luZFt6a>qyh$9FaYI z?T%79Du+20S{}0+w9K$mD&k;!P%IXb!D9x1rc7?gW+(D%P^r zSDvV~sxIs@blBk`V152tja7SUhtvEc6PubooIl!Ek=j(0R_3%_vHhvV!N8YF{m-~E zd<>pdwO*JxQLHeWS=hlokJE{N`8q*WT?UsUCdT@wED~M0j@&wNSh7?4pN*lC|Dg#F zU6u+O9hu%DX&7XvRO-|j!YbIm_V=mSev7(-M+r~39C@E_V-*NkF}HyKz!B#3oN1p} z6mK~HG1ADGccjK;!B4*vzi%C|NRiLH#2%{jXT^fwE&MZ78tNJrO;Gik$RT&Bi)r7_ zndda+$!j0RZ$J_lIW5Aovi*`c(R3uz3aq`p485peZ@0WW=u_7F-fN^>c%c* zzY_}EF0Pg^bMxW#tlu%)w|DcUgjvo$heai$WfX2roXE$htmvg{qS9_=-8RjOO+_F{ z#UoR4T8P4orVu~o6Yp%q;h*@t?dHBA-rN@uH*_B`VaB{M->dxG?&+I2hTD*Jnc=u+d7E9%hJFjQC zRcZ-lByE#2RV$B4>bI>}Cb#kHmdgTLou>M=@B$Vvm{t=i|vOrQ$jQt=F!>VS^6H{s$41>?G zyqN!Czw+~oKX-b`&(!&_vLb|IgNDZ2Eh>uybkkZc1fMf-Pj*}ou)3PViNWN+$9SRh zDqD0GY+^fOBG~Jy{K#0;zk4gvoxe?^$%DgiX3P5tOPxPRNpN^h zW;nyet)OzkS$_j#ZY6w z`-pAYRF0~I#lLvWq87YwW>#h9%`w%Q$l=H_OYf6Xe#cayPSyuEfgibU)5|0 z-_z^hETHq^ut3jo)h?sX!wP4Ud(66xjwu;59a*r-V^$KgN=MHon*}B(d0N~$rldKr z3Hk)H@HnK#?Pw6W;JuGEW|Nu;+YxcCnLZOvuK0H`BHJUGKk1;u`vBWjvm_f%{)wKN zWW?4lx1hlBz~jHKAKiGtpMLhlT|d=794DAh-cWt8h+ikB`Cs;8XIGz7zf^8Y2^$p} zEIPQr&C~hl`&)GjJ{*x1U>6ebGC0mr^Y_bE0p=aP9eIjJ<_K*OxXI;LuJAIUd}6$! zaKQno**}jtM9Iv)xs9!7kwWsb$dpNmm)z#RS6q>-aO~jh3$NU`4ozBE^C+TQ>i-gk zbA?$FFIf}g7(FX)@M%>t+B}(Zb;BlB$Immg^&-0Kt;*RJT+rIEz->#XOUOjlTiG1k ze;-Xe_i4wiin%hK-G4BFN{I^IDLh4;q4gEF&ewU9?e{HT@lEZMs&nMR4D$msFKiRsaB;!5 zc}qS$>{>6pg7N#E4CPf%xP0cntU7Y=jYIy%hQu4jdB!^5S@bMStBrV>7&nG1E2$;U z%?nv}E#+??W0%8uNu85o3MzsMZ9+WDY=e*3Oj@42uxVu@`$jRoMwvOYOZ*FFWK8*8 z#Z#c<&>7jnKap#pN>*7gxx)n-cLK&tw<~ zU%u_uY`p(^@PykkR}D}8yW++Z@J5#B;5OMOR~lY$+{}0+VjO zgWyqn5eLIqcJ&Eg3O>V5v;{LFc$HOm~&TFhFJ*0ANS zk_O+a1xJFr>Zg9lKXJuva*of%V3TKFtS68CcKFID$nbtb=qC$9!N5O4B3x6n3{|EC zIj#KS(dnun$-pnrbWmw4gTNAQrRE3ri{DjS%{NiMvH0o(p?Htq^+9!&wPlqCUu;ua z{#<Z))T;TCtXf(<3#0QaQ^Co$ixALT`GftaxY{IQD>8;+I z8bgw!F3c!iH=#67=yO_>@Sckd|5htkY?b4%|`O-I4F5_|5sm#Ja!d<~c4iPBjzXv*UNlVr|o_i#PmEa)~k)2$WWj zm0U8(PeGwC%Isi5;>pF~Yz5B8PMl^=nA6#L<6X1zx;&MO%h(hbw`j;386>7|2xMwL z@ap5TBdZPx9Pd~r;r-BLRc5J_P1Jf}A;~MnEuKBW>tk9;A2v0FG#68q#&kb_f|xs z`DFF%iXCPc)~MIJ$=@E z?VD$ZdsXOSV>z7*pE-C}w4WDZXwk%RG)NtoF&;@treg zt=UY=u9Cx|yqn%78TXi~s%k1_x%~B-RLJ+ZvO#p3i{=?sxBAa?2>(9ZAgR=Kq{&g3ga4-rqwOZeW$c$ut@yuIi8Iw=i=cEK z^XKEQ9XZzU)o;14d_MiJ|BHwJeNX4k|7x~cnpE7%k<+b^J0lO+EudZDF?3u1g zEB78di<;HZF1Jq!KeJo6(PmxF2+d%HNDzwK~vSTkr9j z=*Rrtn%9I^M4p~}dgh7eu^(mAKRQlvo6q_Cc-2}RRf~RY&dbXSx2wGQt2Z;HCB--M z$FBMOF>__tJIkJaNTPl|AVekLLaY<*k`^%lpX7 zpz_LZ(V^Dc?;m~XHRbiD=ga&;4Rv_i;~&iII{t9=j(^uUHQEj37KNp{{t5n5TK41K z^&^kUwy$p1)L`;UEfoqg}e&E7rfR_Fb%{j9k&Q(U}M^zhMraaNs{ zhu3YCv3hzg<$2{9zqN(2$wEJ#exFwy8>h9gW0J+4bc?h3HJ)GgWcy{A_rBV+@o4HJ z#qYxF@g5hnyu6<;_Ia`7h3!|9tBxB_Yp$Gq^xpgst*Uj)HqUil zD!cv4-uyMXzFw_dY4a@J&Uv!>(Brx3tKN1rCa-*KKF4C?vC6ve$X=z-oB1#A)vSH+ zIAG_QBM~pXUa4%_8S$KVhU?5nO6HT*3eTHlW^H--^KsMtNw>Vhc@mkLeeBwZOuJE2^P!`hhaC!CSczl^p@!Kn}OLJ#^yQVz5cHTFC z@#Fk`=3Czz&iVDcAZekEt`PMG0y`ex(gW`&0T0X-g)2~90ir%Ve~o8ZqRcvB(cVn>_6Bwvk9 zUcWoS6k>(`2mkMR#F5;mmE6aW6`-_1S!rXZXzlX+ukD|utTDesT|$}yCU@?Grr=D5$Y4F@f~FI!Bm;Y(+2ad2_k@F?TrJXy}F{fVEa zEfe)n7ij&R{Y9p0M5;9}bA<_Z-Y-!*vEXBeigE#CO^ZO0 z?y5$K30<|j-}ft;+~3JR!~F9H^{3_wZ>^T-7LD1t*}jMWLej%62i6(>YExY`-^*V6 zrKIFBrz-~w>fX$(_}&%gh3oMIoiKzr8BNsbL_ zER52}WUihO?ljb6+q=B*ry0W@&X!3x3>dFiUNv~3%9+D9>5z*8yQss0gC7O%Mg37} znK(1e?3vR2Z_@IA=IiU;*rwaE8aW?ugv;F5judpE1AYm?UgP{2IdP}&rd#aCAWXkuZT-EB|94(mZW9AZr;|BxoCbuLTyZ~{8=u8 z`UFt{+qT^L-OeI!Bzrn8Fh>~P6kd5gGf-rifBmuKX>$AjKVahg-tqrD!~8FfN)DeV ztT6cffpeo^M@nnT|7VXjxOA9HGbG&P|H@FtlyAR>Ut|8GvB>PU9Eex!sT`4v9E53l+}FSXZGvy z_A5+`HODgd?t5Mq%CzLgp$UQ>vQk`cS8{GI`TTQa{l*g*@4n04xAFYG-|y^x z?=!r+?bqE;;Ug*M3|5F8zA(%H8)Ksfx^vdv3jHX7$^9 z_hQ!lmh`VabMD)<+}(L+ye^3EUYnYJd!KalviGTZySLqadnft*ZryJI);mqAj#vA= zTT{Ab_Uq~4H!FU9pYZE@{&s8k%Vo97tN9n-%f7Yl_xA0(OYhzJ_U`k0i?_25u8+R& zU;X0i+i&ysTt9yHk^20adve_g*Q4JqzVups=kAl+el@VfZF_U`y50S<-&a{RPkp}k zY`W>o+_MR%Q#)NJpF8sWe$`v?b=SUEZ@;_mdv<>H-nXmw>-4yVIfq{Xc z%If9gs*`VTyl0#DeN9f-JhQmhJBwG%`QBT7V43Oht>3fau71ymudRJPKW{J7#kPC4 z&owO{d#-C>HG22+xbyBRn_oX)eYl-hR{Xy4yX}@7@oSQH#+}Vh0?fNL*ZeL!cYUtU zwOa`sYgfLVofIN=clYb(5w#zqZl^7sE%|WDg1LKdUYf@Gt}NnRWK_<<>HfmEmvZqn z)RqSQ(%+lu{l05^(7eZ?+txFk`sz66e)s|_E)j-{&lcZ3ANYDZ1IJt5cTq;qi@Ujb zQ&lgnV!d{AnSW_-#jDWgRi=}lyybLcVNhT(VNiB!P@KSWV3rXB)4Y(+zP_fm45qeH z4GgL#0tziG!h*IYEG8F1zWMZ;T*#`__$0X1R{6>ih72|b1_n-+jt*9nL$ei)szUw- zfAsCD@~U4ob9u)_vz2cHU!{Co`INV#YWbqNl@l8n1P<~tiF9(PDe!VIr5rW5(9^4Y z)qLfad6R|J0-qYpv{lI9wRK!z!obj}B)DLP!mK0)H4a|4S@YB!W|^E^;4f-xvwTuk zCCibMOD?`Nm9ZNgtFu55=gIDgLsOzsml6vcLW7 zr@J5gpZ#zD^m==BPNt4|YYLp&PfS{nvMPMC!3mi~!mAYjbNtlztN(oHJCF9Cw{r@X ze>)=oJh6wBQ=tFRkxM6Dyg8W3wLohkukZ@zAkGPvtej2(B0&KiDXRjWs5yECJz+{z znd-t6ec+J5EJd;PYMOqod)(%FPH6t~z$aQ~%89M>qz=T}opJROsyw~Sfh$Ccm5(!o zcge4(CW0QBD$Z;{cPy4a`WL@GitqgM|6%KYRe0VKc`E>Xbu1yR$lprp!Tz#4^7>tqr@VZ= zUYyG}A<0?l|E1dn5-~2RZo$cW{mnge4a>ckoo_Ok#x*5pe^u^%#WhK#N9QdHs5ou< z^PEoT5yw#R>LS0{FOP*j?Uz^m?&oVR_N+8&tCp+p_8AYtwoJ7-R@4$A@640B*z8pA z-tvz&mcAR}l2pqVUY`5Yy43WQ@0?iWh)=T?6qe^23EZg4y*foj=(hCD;~Dni>d$T6 zpZD#~7FfNqLg(4O^&vLDO;o08teDoCTG}OU5o6mDY<%FHir(^7KkrSR^11T$8Gjd^ zqBSL3Bu@%;eh(@<%-pko{`G_B|EFB^f8a0UJ2%?U@Y*zur?zbs@QS@G8^2zA zDpUP&-nLI^KfY9ol&G0kPFelqjnhxQt(jgTOsNhhEn=R$RfF z)y`n&U-VgWQ+DI(6VJSF9xq<;GS(xVBil#0^X$8-$%bE_CH_kMC|`bq{aWL``MJVY zZ?~nVwLSR!aEoKduH2xVPb#gP_iI^h&#;iKhe zeq+_k4_ zsb%-(yubVC`Q9rZ3g%gTiZ!TDl)rEK_f}2h|GTNb?Q>;=e>nU0)bX8*G0}Y5e2Pn5 z>OUXv?H@t<`~ACiitbTf8TM19=8nvj$I10mGaYtaN%fk1_^QPr{fj;Vt={T>`!-I$ z7sip6*IzxAk>PsV`q{^Qq<8PO%RTR1`nzJ)`d5=JpYQYbbiceVyU^yVvsp&%ybqVf zA9?L`joNqh_kzV+Z2$S+u6ds?y>3qO=a?&3Z@cPCnLjrY>wNb1d*<4lZKp~u#+HZL z#s2T^&VST0(br?aDvi~=ZEse;+4wzv>#t<5wHvff&eqr(^HykD^Vy|r=U1ue2EEXH zaYgO;-g9zizTDeBUp_AD$cX^!+h59)wT=~>y!c&8 zWTVG*qi~H!J2r`OC7fF@KW+QzFQ*E4l$9dc9TvS z`bY9bx!2Em54~ArzJ2Gr^hdpANgl;KhD&%C=iC;*C*0vaZ*RXzvFz8Y>DsT){{FQv z-2GMK!{<*$G~xuA_ddVNr+VwA@BKgicP}%=R4DSDl8JPG75e(>)m7i#?mHCtZAY=9 zWoGi`7d>y+Zp}HI>~4lZ(@*>C7m;JpJU$fAjRN{M`NV^IlVHBWF%&gBs6CX~AuZ z{1=a$zVB;j~{^ENN%YIJKcc|L6?;)Q{eEO`CWlBQP{J~nfaz`|p zmQ7fyR`M#|^-a+NcN4u{& zWf_aVe#N?a>F%E|*PFf8+3fN&PW5Hk#_G2Z4}ErT+pD>{^pbN(?4$W*NvEGZb=Eqx z=6hNz_y5{?F$aG(E%V!YdEqVj^mN(E!Y+|H9q+<@ziDkw_AzNP4wz_Tcm8|*@}JfF zU;fPFox1VRAt|%xcVmpB#JaJt!Q$HryTmtI$Wcv#}yF4viBFZ%WS`rr2O z+caa>r=uGl^oX5_IUM`roaWp4%NN;jbZP1D`hAr}--Y|{9-V^COFw^owJ1BiTan*u zpFmBV+fY3`HnK5tK7*>dp5+xv=pWU4kkw|XnB# z*H2b(7_Z6hp0-=c$@bE{ZY!g?D*I(uO|SEwZFRY>T_g5lb$H(omwG&isCZU3X*Qt>J7 z6_sDhDzq;?d2->2%FCx#7nAO7zbrAQn=Ld~CSrQ1?Usk0Q-5%+m|7vR%H2+Cj&s5) z_hV~qWskp>xwiJw+NzY&;Gh~S`>7VG;sTR`yEX+l=1l9z{N`8D)1`An)p_Xzjfhu2 zH)THA;gfXw&4$AUO~q^en0zf_4p*;eVrR^kvpRo$q3(v%kXssxe?)FAFKm_xdU)}8 z^qc6Eli=BEYCYP24cI<7Ke+U7^M4Da`uVL}S2|s5kl+4yRlP)c_3ruK!wy;3tbE7) zzojNykIivM=&q}iwwYU3`!=ppKCvfRbz4f&&U^h{VCP{Q>CIVqwV7P%hTUg-x2Xv5va@fTR-`GbJLmQa^bcA*n0od3!4we z-%aa^E}qF=dUJuvqi6TBWUh<2TuJ?J)NsDeTFc4gYOegUAH}-jm!sFru6o`g;n1>p zdd+^Z5(k67YXh~u9x;COw=ci^@BPj_7tXwnn_2I2|M~s*hJP-s72Lr3>vR3x(>rb- zKiIu0yW!#DTLpy~E6sc7H#Irk&aJe3Sv|dA-&RkC4*e^OnP!Frt=OFZs?EdW@4U74 zi@*F&x}Y?D`B&S#oq=^1wuZjR?>&08XY2KV3AYw2Rs8MwSGwfgHr?#~-*y<)Xz`lm zZ{7EF#=;kK^@L`uT2-h2_4drtxY{H8n@;f>xcf%dTt6IO@I6ZE@Wo@fe4c+L7W3`o z;`#MN?s@vN?PA|QNS!sf{Bvu4pDXvyU5$-z?UH=&SGnzCJH9vaXdc_|H{7wxi>7Z) zIn(sAzWB@o2?i@OmT6zRwyWjVMtc{xva;7z^Ig_& z4peXXp199-%h^IcW8;8XjLsk4+*ob$xTP^^`)dLAbu|;?ABruWkbYLaylSV@pHFK( zZ2i|4T4T8FlnnQVtb&Y#kyHJB5+#36_UsOpf3;R#V}nK-yO+P`x0$WBiBlKvS2(7A zM9!(_>qPMrhp$~_Y!ZCwnBD*7i_IdwrE6qAtSvQZpKX4;Tp(tXv&pj5^Fnkc=zProau{YB_;Ho z(-eEErDASwuCkxp8Za;V-ZsB=`T3!2RJ0*uQlZSEGHI(cng#)P0l$$&$t>Ba2 zzQ1?2WPZEkq-q=1?Yu{4>9?(iw`^LuV|Q|GS#fEQ%=6`Ug}a%nE@{_lnYjFCRN)9X zT=ripPyXAFn*W>s&VTs7fA){Szf*%PPjh~aDw@~RFTx+helN$K>ArtwtKGL$)=-gv zpY~^uHM2ci9p?E<@x;p2Q?I}LczyZRB)qz^?r|X;ByY((#b^0^sZs8}+ z+nsmk88mV@$#kDOwCI|#=AAq}E=K2T(%y~DvzLakH2y2>@nVp4bWMISC2i~ZCl{vl zzh1hdMy({jiTzml1c@Xrrqdct4v(9Dn8+OsaPmumZy zy9FiFl2X4$H9M-fvg&_b*}r87%% zL5GqO%R)_$ww9*M1uI(D+qNnQbpPI<=3(2Y*czzovf3+v#if_iVA2wAPXQi5r-_=b z#-;-Q&LxTl9ML(@5@tD}SCz-XWvz-(5Tn2pP9awxmQ8^sEgn-0gN!CD=~pZd(Q~-O7Fc!Xs%md%^ny;Ol_?!vni^ag3p(4F)YfP$Ix+2V`n~(wjSp9> zzA4z*l67jcv1T|=%p$I?&SsrChc+B$)=F5R&CO!+Bu7zY0^1`;rC!O*U^bIZogRaR z4VqG7bJDd9Rp*>KtkcYMV#dk^E7a1|W*aCQW}Y!xEYac-;QRJNd*9&WAz zJ|c-q{|-G!EB^PBHDNxF+ztgf=D*Lk=9%i&h%J357)646UptYiyu7v&tNfms%82sRaYLaxhJe-!d%n?_}{T}GCe3% zzOca6g2(NKeE*i5qwgCRX)JEYzh&@7w0-`92reZd&*eh?YG1F-xS=!c6VKCQR$;qd zEIlYSErz)x#k*^@X2|7iy|lF59j6#)1Tr>8t&z#r+%{{~<$rI^@R)N(@;hES_~i)a z$AI>`jhWY+;|>d)te9ZYa^$8F%p&t}sfF&L z-n+pp^)tJ-Kk2tz_wv7x;@p*X5rJzKR8*Diw2yWbDgT;z$o{;Pp>xxpX}1|R)v7xc z>#ttytjyQqHnn-h@<+-_GATFITDYekIUToV(uprut_!)WeOdD9w&ZJ`;QXg`&eOyG zTPY~t{g7?JZohry;|ue?m8#o|TZD!)@Z|Ei%vang{C)kc_}M*wmYH*eOHK{Y;caRA z^U+NAMw^zB+!-6c=~oI;k|m6;3$74*Y&S#XvrWaz@0nZe&Z>WCTFq@&_i3)}r7Ic@ zQA>Z`Ios%Ph}$L5Oi9q_+w&FyQ)}}op~KGKY zxIT!BTceoI)XC=XX5)z`(Jaz@ckcYIT2`Fj?EX+i!)4Sp3M>$ zYo9)8sz8X-YQ2pwp6%Zj=kw3y&8u4%9%m<)?(}|WvxV)FO6T`hCWU#Q)A)QNrOwWI zE>Y{YKq16~hx=fwt5)^4BoPC-&@Xe@J>NbTaqmlV-5!;$cJ>wcRS>)j17Y*Bb{b@^VCoO$>6L@A0)nk2jOvtnS){e_9B3@5?WTMyeoIAeZ?0N17Gybibs~C6b&lit3-v6KXf`uYb09`ZduD z1(jEB_5S$ix6p5=)~0n|j!!7&n(%J^^Ve0(d#s9TLc=_qg#2GzcT4L$lV@}AE%WTX z7rnv+ejK;8dC@qhz9nI5$A(_6#d0dsH=Me>k=f-^=R!kIrd@ND4Hj(hV!LYh%Sv{M z=k;q-ez%=k`Y!c7n?~5`f;8pC{3m>wj9ZsH5?Q3NN@LmL56}A5WaQgppG>biUvYNx zo1fkGBGT=XPER&Jzx$nYl+4cyXUe`$y?v~JWBu;fJx7~nu4d)?wOZ-;V#Wy~ZOPpQ z5k+E*b2*h(tvd1%OwlP9jU+Hmsi5R^`oxUHQ#(QWGdEARF;TUz<|{^Xp?+%Tcl@ko&58R^j3 z7H##A5rV#!yF>x$jjKUoTWqtj; zeQJrG(x!!%Hpgu%UdMI6|KnPtH|w^~++ysO?e$&p zJS)#s%EJ2U=Shybx>XNOX0WTPnmlZN!*}3?MDCoqbG4^`p0?lM`Y%_rCsDD}m=ESE zbaQAYt&z4p#FivcHsL$VHaiQOom{-lhUI^ozlw^ue>kK0v~yYbs&$vRjjN=V`#hU8 zsrX*)9^v`xO=Su!Hs`i*-a9FI>{Fxoh6n1O(q~Uqmsu|QOmv?|=of>-e|Ih7TJpCb zh5L`JzpSa{RhjVj&$2GEE=uJ-t{Le4$XQO!v8VI*-n}-z3caeo&N*_M=}c+5aD=7* zmD($smzmq%_saAIU#Xj1+k3$3&y}h=_1`D2s)ih~o$tTr@4VYKA&5C z`(YbR*VkDW>HpYOp8D&D@AL15=eecr76p{0#knl|zHQ^1cR#X{dDnflJG#VCdxg)$ z5538E@;7CkkY>5;y6EGQ;nmEz+K4d*zj!%yJ{GwcqZ`9jf*@lAF}z zqw2-&;_~Oh!M9oRm)f^o)-!#Ppq4&8+H%Iz<)62lur4?}!OAkhYt6pT%kP{tP;QlK zouqi9b#jxI!lI5nnby8vMCN5p{_=m;bdIO3rR8(%)F1u$v*W|X&+7Zv9gpKr{FHZ) zVWQcwA`LsGwTtIJ`5Yad-My6Ik$+x%zkNyp!<7pDg=VW)ygTl9q3TL^p>f~*w6(kV zRNsfFY`%FvVg9Qe`@77pGv00QIljY4t5V=--Rt5@>u$tO-IKp%liSp;%vRNktE=M9 zc>Qp9baFOj?_Jk+G@iI>d9qtw`r~BFNavc{X1*zC;M%yJa64T^@_xW zqf$9)Ts}>98!B1(bQ`jMDfX>kxo_CW(SKp~VTGr0YO-Q`tt=L(zF4X3-czvVdzGQ7 z=#gdFSzenTH(vbsWyQw!-m?zNPY0!@FZ4bYHLLf;gVPUO-#+B9S}7V5V%yc9s+M;` ze(%zU9X4sZR@}VFG-KnLU8P!If&v|SPbRFslC`?Cdh_Psx-ggD%FC?p^1MpCsAi>b zy4E@Pf%0_O&Ltx8bFE%znryph&ZN|Qz(yq^CigPqm0Mj|7gY*5!@EEI(zxKIF=dsi z)Adzrle}Xuhej@3@PWha;j(vIs(zlozuQ|*>_M#Pg=H5m9M}{1==g@ZA9q$Q{`-0F z)7r`{do?=LcZEsG^y-HQTrfDt?HQ!6=&Lx}FEcdtc5l`zy{&qOXNHD`P8RC*`#<6P zL<^%%&Dft)71QRiZ@U+H_Rrb(>sgsK(>B~V$F-%IN9#ayDBtY7g}IYWgs13V))&2L z^?~^TGfzD0RR5JNi3Snw@y9;aiLgHZDm$yDYPrSEnyvX?oxS=_UU2XJeM0{7cYc1J za<&gToSce^T*VLh_#G%w4MK&Kh-m)R6XH&!#-)0s!L1mpC zI+Hu^I%b~a(RZ8tJ3sO1<%eg!2ClyL^oMYil&Xk>o`Fc9qvM3)1C@TY5n|H|#4qcV zYA!P~LAlNWf}x?Jp$@al9bY!DS|{Zzb^Z>{83jnR%k5F3i{WuA>hv9ee&wQK{b6Qk@vr_9lw0?C$H>1 zX4&sYO#I#E-|BzMUikWF!9tVo`|NH9l^tDYqQ1*Y#7N#}^`cUxSEd|t@lX5erK%m~ zuTSzmufNya(fzR4>U$~YzZza!R4lxi%PPaCWOzMwmX)!Uf1+!Xi?!8 zp&z%q`gg55Yj&N>Yvp$B*x)s1Urn9i`LX$Ix?}Mlq12syIg(fN+%`!BAJ}%%Z2BWE z`z_~EXZzGOes>c)-aY@$8XLCA?RNqaqQi7q8t=4uyuY8sa9AwgwE5HGgPajI^QU%} z^}plqdg-RQ^x3!NM+$RKB{NlbDLr|n`^jFmSbBOnZ%A_V)zfyzCTr;ZSe2fB`rzs$ zjp_cPT}SU;+M2fd+gr!gcLRQhwYI;tc3*sR(~$)ZcZ=Me7e)1D{O;&Dv9)$=?xox5A@W3J9_dw8DdZ}l|mT_MHW7g=fL zz1i()Qo3&0)>(VFy#ftgpV{QzQTV8RZ`vb2EyHAf9_e+m#@E@S^F-Y&TQALMnsYQl zJdMA)O~psV{wQiYtJ6&{-tJ{b7MEsEZ>?f8auyAIa{$T#i3-1ca8&Z;>pt<~l& z|F5j&+WUIq!*!1Ycelw;pU9nYbJ2x!OQP@BykfcX!Rz&U*^j()wwy|tSM*F~(T&Rs zU(KnAown^<<)*%>?gh@Ny4!h|?4JBh?p(@;;BW1#&b?auGynXyH9L1Mz8L;1s9Ei8 z@3*@7cDp~zgk8|=IHmP$viGKikYYnHwg|L-7YCq^{ z=L#Nb+q(1aic6K5c5!?9ZUlVk(Jd%H8_nM6d_hC^={DuHyC=Qb*Vve<>wM^1#k1nO zUtQ9!Ke*QM-Y&XR?px`*llRZO@U%U?%m0Cm(Q`o&J@J#-vzIt8-)>^l)9igbV9ANl z8@F4gO=Ol(nk13K`cwEqV2#kzyP*l|f-f#u@t`qQ^uGU#C)qr|=Jl*IXe_DF+_BJS zTZlriq_NhYqEiu<+Dj5WD;hm+oiBRKZyY32@m9-eU-t58LE&m$GcLG)t$WnPdE{7B z*v_~O<#+B^ulUrrXm0549ltlPbFcYl`PK0BZ~LI^+VhWjf6aXR?(q)G$H|ff&n>pB zdv{lpGtqF9)WW-!;k;rF2FsG?#8keyKD%eu!QWR4)@?0%Z?wTi;EdOb&3asW^UoCg z-=A~K|GAZo(nd~;4f|%+{rZZKBKWvzB+?z4++euyot~ z$SrHSrrYe$o0s0W+vL)zovn2o&vzZ2c5K(0_nGox;-YU~nZH`=Zn>FpGWVMolXtOZ z?L50{>w(9wwztd`Z`NDi|9S=^NBQ0Kg(W@0H#dctPCaJS$YvX$t!y1v@Q|nT+YIND z`0dfZ%OC59aPaHFAc_ zdq3{7m-9=$)Hjp)VzQjuVmsSM2eoZ(1uy$H$C_hPkm-uF5aayat9H!d{2}wo;_2MX z&PVIDOOIr}HTv}^b>79~9<@#9R=zsAL18~n`=OoZOO!iGIas(72#PHo!l*8f=InAw$h>5S{$Wtyi}Y}vB*kbv4&ts>K0=?*FRP&GlT zEN4T8?U70S+!eb8mXs-q&1-h#%8m9eUy%Lx`roqG-EMQQIv%P{x}?y%_3wS-WY_#d zzs#zo9z{r<>hPVXQ#m_!#%t~FtYD`FFT&hoGbZ@$dU@>Z568U{mmV)Wp}JMfZ_*}L zCgHgMD_pJ@OggpiS;?YPJN-?PH+e>1ciz78gWj!onhuMuo+84nbAGSfUEbMOwRuzCv%?kMPgdQV@^Q|^nl}O`6k#U`ujMW+)iza{ytCIKgPzryLbPg3t3g(UwF54 z6`%OXUb#Ik*7B-xw3Fp^S=$n)sN>U@Rr757Wqw5I-hZ2@`CsM4Kb|%%Nzs;=SQs7= zu<RK68{4WpdnW#)LE125-}?Uh7jMpMTjTd?LqMy|)C*4kW~Hm|DV)0}%kR#j z%$`8wP4TM@{;k#R<%~;P5_ROtnQe#K`CT6btQ7TCQhO=euw_M?C$b2RbI7l{JG(tw@6MzfM2%#)3MiOrVsqvf<5qDeqL~ZDp+Yw`2FSS9!x6v|xT&k63!+2Fo`KgH^A) zzJ97#629TE5wpgdy&Us7_P)BOuN@xt}Szq19aT7oF5Vua%o6l8^h;Ol?WH`XRvZsFbvp>0B+XAMvY0d=hmJFBe*_dQ$)5jua=W z;;!?|g4e39Wu!%JI6XP7@-F+M#f^50O@BXE%PR5^cZ&Ozr@3Kf;>YSW>W?pcU%vm8 zO~vD*a$L2s-~OalZObd0w?^&fQJX(40+aS1u~u5|{C57nn8PL8&oBRIc5cbuw2cqv z-VIhPx>>99%Esboze94yL&Gos;@=)T$}V@OblbJen1t;%hJwlQ+sec$uT_a#9piO* z9C7AuiRp@oOAb`Bscvpuv${WG@1K&zldY~Co^5*lkjd=38BN>PxM@GyaJ6~e!?s(; z79R<6?>MWu!~E^-{K?H#x(}V!GhEmDd?nETM1aHVM^_&R%&F!&>Q~yf@43+zVE$^ffy)&-ByPl^>p29Nx8ViBI9wK(T4v8;*qw z7qvKOL?(E|*<3kp_W6N>_136_SsRx0a8EyNbaJuopQ3E9CE8~%8?yHqYQNPw-4W_~ z_1SX8wRxMjoZ?<~Yx9BY57t!|)`nLWtx@k$4q%$0%rz-!&4pjeiyqC|T$4MuXv%!{BU!F%j_a=txsV_MTQ&1qexu}y9h7N_M7y0(uC6v+j+Yl$j@J?`>Io-S=w7TO+UEeMQwOb8^_P6`AlgVz78`=6Mk4n zm*@qHygBBbV;2}5xNmM}^)sjV#BZ}2!4IC>jJ00xy&EUOwpK>1}^}X>Ydrq1^M^k6z#R_43i9>vnr8GPwyVb4H64>@}V7H?rzS)mCxQ zn;-9`=89RwX>7j|X`H!Yv5nl@YVNCXY-?_8?eN-V8?fVf`ZlwRS_`XX;?vIPZD)>c zzI`}j`yBn{U$2;~Te-ozTU6=z=XvUL_iJ0;wm6p^eDhx0i$?8UA@e)u?>>C3DWtK) z-|x^0t$RD;^vtgQVo#r}%jNmHkTKys@8p_kiZ33N9Z(FsFunU-R%6(z74!M`{V%?C zoLThJwiA7OcZgA}Y6OQ&2}&93R3Qjl`KAmh}%sp!xC{Ep+im1d?wkG@~rb$${5)o+$Ze{Ey?ugiGRDw!9?an`3L+)}-@yrycFy;)Q`ee;RS z`(-ZdTXDbBYO&Jl$_sOrY~A)+Y+>Q8?|E4<+h%>%RjFKZ^w-Y4*WbJQm`|^qTqWE7 zZ3 zmecg4r_RvQQD@dl&Q+UOPsKd@K6yz?YO!Lps*(h-I!mBA9DgP|K&t?(4Kl?$PWPi+*zMl?{QZyDXiM9VQYa?f_Tc2m> ze%-6OTpf9RQ$HVYnrm>?SA1g0anJ4ktwz1S^Y%+!VtjdA=kY={r}=WGFSLVs-1{GV zmAo}K?ub|Ij=Gn-tLA8an`z2d##!*~nPr%Un)RReXIJlD{D&n>!}R=Ni^(h1kK9vI zeROQg`IZyUr!1Z%FfDkR)VEC4kY!7sPI@ZDx;?n;mbT~Fl9lUjZ@M_^M2FyZN7kiR zuTDtc(y(Dte7|W;D)Xbe2On+b?wB5ScI}sV79Z7`8I4Qy?r{ZP+0t6QdS%J!i5{vS z=IjuN5&>&H_Prp#=%KO}Yh{N;T2 z9G{&9+iO%j0y?xmcY5@Fd*-}y{(X@SeW%_zmwq@-_A`0b|JL8U@weCvZEQ^S3RZIdk`Q?OnOurp$p)4tv_5U`W0}v-p}0i1 z{mLQ3sJ5J0D@?-JGMu-Wx#`by*ewvPXTLU1pa0?J*$?)=ux)*VlJFR`C* zN2vAumA*e?64@`c^3C}D!y==Z)6_*{;i|9*zocW57p~mX&e}a;UqtcsD)%Q5`?$mt z&U^G295C9jLhoREcJ7ay@@li@p6glW=H2W0OLnQv=xf=c5xvDa)yunBTXdtCyZF3c zYjZa4YYJ6j-m_z((fO1hov90bFI;+f(PrA6Q=2bFibq-atxLdfw)v|ii(j%%d0i*6so>_E zrbX-8QjaaXP*S$q=<;HF?uCp&ZOdEUvKjEKbupN_RqN7h89C=*7g4XDvfI|3{rY3N z?SrZDrQe*kr>~p1B+i#np{t@WPt>}&s_3#`4A-@UkUVpisr*5HXEwdg>e70?p-RQ0 z>1EH`>sATB)`Tr-3HiKR_3RVV==B`uRz1-Ebj<(gxfIKuvLj1&tLJ^)?I`$0BzRY( z{gHM4eLtFBT1!vc^s46V>T_T2ZNHlQv+$9{Q7vUxvuedBtrdx~S;42SOD;SjEM*wF z@?~pmOpry|FTv*)LbYBKrhS_j?VPS+t>LC}>~zJalb61%)tOT_<#+q12X%i$->$lu zrCX+Ee&qI)nI{6G9%cny`)4lS5>z!&da*_%)1McHlP+G^XR%s+uCvXGiwjkQ6J;*U zn-OQ(uvW=0l1WG<+&FZb#AW*jWf{tCO21YFJ}G|gE_;S$;}`$%CYH^DX_60G!+o0r zJ3g+*}U(bEv*L2}LwGGEaQWq||`usA>u{mcmS`@i% zo!RqY+l0!Vt_hQ$(OFJHC`c6K?wnZbvY+-2HjEI}3&b)oTSHo4*)ld4?Oy!9N+k#@$BTpPt zSTXl>!^?yj+vXZE^DonwWnwl*kXhuV$KCG0J(UkWt>SrStIfJd?B_!Uh-JZHZW$bjB?yI)5jtQ++t^^ zJUjKsE^|*x=8vkSyOZ0RpO}aKIu}({>h?4S45pT z?krn1{raL!Yt$PwmUdb_n30_;wEJe|^hqa{%EaZk9M_t-+K`b z(qr94S(i(viTFJcxwEUzaKp;?=iDM+B~Cn=xHBY=)p7d5oJ&VTjaR%XDm>L;SzY3H zY*QhpGw()CpKs-9@^yVTu6?&LyY=M5Z)dYZ%k#1~HLkc_$)WntVNc@R?b~BY4qiX{ zw#W5~d*0UT6OC#g+?74w5*>ZRnCBq( zJ*Q+pceAWgM`gK>zzo9}@qnm_ZM|Ql9fr@b%aZ)oR3Q? zJUOd#;nXW;hO;FeT#0)k{&tI=Wxdb)wM=Dw%Uh7w}GCiuHxwXQnBGzn6LdTK6 zZkuO*c)7QBu0{8QJC6eo_5Is1^_={wU0Y_(dcSe^iR-6lUtD)5W$)eCd4KxP?CrLD z_jlLzxIS5K8Nt<>97{WIhaYFWc3Gr&+oChM`>GR^zTNJb*lvAesde5D^X{*!{ns`m zuS!eE`*LQ&>D6jZI&Rkub4FXt^;FJXM__WQXHB5S1YecPYpCHiWv@1hxJ`h27; zAE_=iJX)EjyR%@8pR3=Gz)ncL zTLX{&JKXEJXUgQ)wTE}l3CoqgmbL4r#NLR@{%2ZWM7x}MRj}^NSGl*j)>UB%gW^HuQzNn>gYQrOSMztl+gZ9mn zyz273JL1&elG&YG*k^xzGUwoKBL_FN?`hlzza4v$w|6yH`L@T~gE$&JU7s9%c;^FCS z!Rdc`cXNn5IWTc~M_KsN)oi?K@o3m>P(pF`@u!iLTr!0 z_8>oj7ERxf%yp0L7ghRQ-4^+_Uoq}Ozm(hiPaKi1>VkaMUnYOQs%Dh;T&_NUUf+Lp zpVQLYJJaV{TW)@pwRV%?{c6v`!xFo1%-(BaTY0^8+s~9+KPTRse%sG<&K~vb_xs}W zkDABiMX5epk~g8ez_$PFvgDAN-MQb6zL;L&FMZzr?v4FT`SqJ!j~Q>jS>;-I<~P4{ z`H{@K^Zq>fvG82;`Qs)_0{ec=O7h8PiqN?e-|_LR=v0=gud?o*OV6_B@>TjE7ZX$N zEKql)^hf5ZoSV~4?>g~H&9>P#W0T>`zV^~HGdlJ!I)5s*>s-X;zOCOk=I}_|iaxF< z^wg|E>g2|)tLBGJs&G&5H+NV4v}n#lnHG-JWXV5{>ss~u{vXV}*xMD#7`fw0scFJ# z$NCqGO*;BFdzal7wylc_R=;ey(lVv!;{2ma)oeF)|DCdOsd8D$5obNCud8>7suc^q zYTF}u?1n_rfffNj?HKG{iJPuQN#<~`Q%xUAk@v#VEf_NP~8mWwWLST^zE zOZUV#-i@;Cxx`BbEn3ASnqrM+0ED4k-8Rb{M(=W+GCOaU{%HM ztnK@iz8qOualu5#PqPo(+t_{8dFsp28F_x8>W2>nxo>x^TyFxVk{`n0z4(lu5Z#;JK#=eAtZ4+H)FW%l6Cr}z%mb%2w#ay@5 zqWF`2NwQkX_3!hxm?_>p^Iq8UK>DfufwOl#Yj=8f@dumc#qFIzb#FUkwW>gD7p%o_jXOh;~nYD`4f2P4mp88> zF0c%rWYm-qwB+BF`Yb+{3FZ^K1$+`^mG3CFv$=aXsyxc#k#`q<@jtO^Um{l`hm!MpAqJs9w4!K2R=muCvCy|n$~(Nn&!^@CQ zJ3LsA)oQMudUDE-Z(nB{%{6-#o3C|jN&f67i%+*jl*^p=f3wcWeEOU}?|(CVe}AIJ zVSY@{m4)gjXEOS;h*fEZb^xxfs@sui7s< zF=S2u^qhSw_mj5zfQt5&svh*c|AZ8ln^wQ3^I!_z$icaQEl zbMxP7#~p=X>s%tvuQf7cEV{>O>a%vng=4+Zg~x8WD0ZCeXqW$!UnOqi!rdFC_}YHs zTDBSW9T%@Ga_p%wZ4U5G+M5!^Yhv4t2WDIiYk`A`*LmK+@9W|GgUGf zlX$N$(@DNIyK37BA2B{>)t<a*>7$95fWB_oL>M^!bSlQA2gMRf(vur7YK^U;ZKuF}aDlP9U=ibZxTUVBFS z#664Er~LX}32U-l@pBPfA|k~bvzg7;~e8uvU)US3ZYUque}-3#p|-znWQcl)fiN(nvx zkV`Hqlf;hAP?dhQaQWA-uTo~5_!P4~vG(As8oRFdudl99W+|Dzz#&6fS@p!9CHj>Q zW-QmZBBS0oW#&)cr3-mwc^o>H{IBBp>;CNWRrX+)PYRjKH<_|8lBw?7X~O+uM$w1# z7k$df{1O#cdhVE3TON2`xaZ#K2$e~m9CeecWRGpw?Jghw?8W;B?=Nmsn|GLv@zCjY zzu$C}HA*lu1|Jq_2@vdHl?o_w;`#l5@3}8uKdW4m*!RQNYnro_#_D)E!@>;9o>HaD zJIwe0SSD27DE;-lvqmLzb24**`-<$OJ5MIWaJCw2R~W1=RL;3@M8?o_(xbt{e|}S#Mc8uKm$s93#W*qsEiE(Npw9*r~=@rQy={ z8t3jYf1LLq<I`ke=Sy3;xRIM$GiN&5|+zV5C85w>2gKo&ZQl<7i-5= zO7{QIjJ^DG4V%)d)AITf(oOb`bw0l?m~WovCi|_m|9a9V!7tCZ^Zgdi-*)&yitpc- z3#ar>l2T%9I^C&c%f`kb@cW6N+T}Cz`7gPNJ9o14eaM&=!ql==#aQd%oI`7UzA3z` zIVyNmM9Hl1J-frXE|Xn?6HKZZPtTv*{G+ecA|RL}Q6$vUbCy6xb<(kH>Fh|)-9p`~ zVjkV7xWT9EHskHH;_5v-a@VI^)M{sPa9Q;A*1Ag^5%OZ)KenZPjjEEIrPwp^!itW` zY?iGeAC}K#ZuGd@q_~5_iR*$vsoqtgW~Q!p2Ue!EbTV~SI-T8fWzmg}%gz!vCi^7r z3cL8`-I7+OXRa$#oD#H-tHeZo+ZxPYs&D@>=*J?q86Elda~6~@3C=lR>C(1IH0VuE z@B6X?O9e!xTZG>}@TX1fKzogfk<^=uug%3R`Lz}&HKheSn052!)Bc5H8Hf7PUO5_!pdRY4Yp{j+)gm?Stsl1rVA(S&!;?xa}*2U71 zUqm7=PYBxZXlMVS$~9*;8*r>X*Vd}nx0&saO_9&(f7~}0E)hG-*ZZRN?fvKF6YbBu z`7C&T@p1VFI+C6-1=+{7tT^YJitqf$VLYvEfuZ9;r@(Mg;q_b{ou@YXKbd@_f^Wey zS?8ZUd<`2M+5`D+aH@DJBqS&%%$U)kFijkm&NhuA4*AXTCZFyrJpb}2x}~VU z=ERboNQpR8fv^9*xGr^h*HxLs-eM{@)xt4SKxqCci$a#Gt|AX#e*LolmbGKAP{)g( zdo&dlTvGG&pY1!GWb5MP*!LEP48FI5Z1}$26XYz}9le-%&gN}!JmfR@% zn(=dk%%V$TEN5ny`83qEtL-QX7d-h(*=*MJ+U}TNT9?A&)_k45X$fz$Qw9I8;|j<3 zihsAwn-VzbX7JvRFBZKFyDV!Gy7j#0lJ(bCtP1rjz3{cJ=JBkgx?B5mzDkBAuFn6u z|K_{;=r0wopS1E_w3YtUv(?Y~-&2V*tECJz+x=>9FO<_baBoeE#c{Pw9qroNRhgc9 zz2C|cRd$I>`EyZv+Yg&Wwb03vn>V}biXB^_e$Y5&d92lKmnXM=Etr!c+i~ot(OQHJD$AWot$}N!^wXdsjtu5SMRqKw$8p#T;cGVWozZCg z?hfAiy#^NL-V^)hI|&$9Mmz{OZ?yJ`TdS(ioZ>`x&n%Z?QGe`A_}zJ1F51X04=`;z zV%^HrX<>Ku%jjCn-u?W$+1-tg7zQrVQr{n6`1bSb2R>WQ-@SUJtGz$OI+J_B ztqb!ey(m(9`ssyx`+HdZ*N<0Q&ePu%%l}!o$`{69WJcOEExvhqzv>vynd1|aKRw^>Yv5Z@&2nn zNB=qg?f%5eUu^$K@7mDLVsD(`T)X+*4J(_VW4r z+xx6)@*jWvSu<;E+G~h`N0Zr5xW+B{|39<_A^op{~Gn< zV?F&f_9wVqiM5w^ueze`!JA~aBfqd!CHtHGQ+|cZVheQ~><_U`Z_{J^q4>g}VDj&$ z{~yWjKUTYet;6H%15ORTK;(38@X+G#giR(!%WuG{p%%j*=OqU1%3q&!7JBU7cDZs*n`!U9oPF!| zS#Zu!e{$|dVb~mAUA;Wh(jfayoFx){?=$3d&X|Oqoj?8Q%YS-O6YD2QJYIIZ>*e%& zmd-3G&d*;jur1sZ`1ru%BV}sm+9^%pB@f>=%E2 zC}>)EYqiR(JtBTKH=oYW=U0!l^Y2^7JL$oRr_W=%t#>HytGpw->95e9zjZTAhZ(FJch-rlV7zQukb zfAP=fH;pH;r7P97xd_prt{)?ic=%fR_tQwjkM+Z zy{N!;?yTD7!YkhP-I%puSB=?^&!2zl=WMpReDTqb%O}*?L;A?_XRwv$|xjnNj73&fV)dOOE`x{UhI3iXqT?=Kfu;Dveb_C;t-GRhnG7 z_QRsT)mFOaW~hBQyh}-DS%Eaii?Dr+pW0_+sGa3`R5*o0@rj3!mB3GJml+8wroXd1 zJ1043t-;gz1@xCL-BmY zY1hnd?CcKNboJc)=;!ty@{`Q|%q>^`aOLZMR=LzU6GJCX`(a{vHS$_tb9!3%fftuu zcWVFGbSFcY>%F*17e}2%lk)p#AEfS9cw3wNpZz0s%Dk@f-pkQg3YH>u>(KM>_ZU@7Fv2@-Fh1fB9K{kK zA%8t@&x=i^S+>&*Uwm8q?5anxtk|?UhvvDwf5oqO{Q4!WN`)Qr3x&^hetx3r5u;+% zmUz}9r1M;4WuarISF_^8Dj^ZRCXb~Do)y1(Vn3^1f`2C4Q|4QL4s}h;*;)L5y=UPX zRnd5(r5^GzvFy)6gLWk*bD#XRAbO&rNa(vW_m-*@{&N$vs!{WMmD1Mn^3&70t056( zoA_mHH-4;rbN{k>)QX+XtjB9qFYM6U@#NCuHT|}GBln)TtW|A(@Y-#$*`J@cUdUTj z@+~;J@KW^b*i;w&Oz~Nq&wNiMv+2)~I?Wl%ddzBPO7PmR!Rtegm0D(czdUC6IOpvz z=Y6*6`_G@=zWvsRe<{pivpVL^OkFthtH*KKb%Cwo5NkiE7yYOZHheyg+TVlm@Cx~G5S17v+M@ufNsKJ8<%X{FnBJom+hiznk39iT*9PqA~qv;rzvq&Ce{g=ls;(-#_1M z<(?%rY8T26?lE+^@G0EEf9XTs5T9A>A7?9xo?V|Gbi?!UR>!dJ8&^7%uD*Eu;G5I* zi&8GU`^(KWX4boMs^1Y{wofW_w_~YEzH(;;w+x=kr)LWeEx#Wj?Te{g=CWF_LND>(!rp z&bxU0kICcp;pH#h{Vcy|#e2=}aq+g^d!pTC@;}PvThy-ny4XDY3Y+Yr+68qIE1K#K zEPRu&h|B8w3N;=7qQA#_#3rwfS$Dawp-519@tGvCluP)nx{UTbEVqeyiZB~>5u3S z|NNi-pZ?{)ZAN)X3zL(Ei}I&K`d>UMxpyiDPAKb9e8W-CEu42HL@G&}?S;|i|6;C7 zp514gJi-5=cQU(mK|sKT*OOLQe9>AhCE&OJ@RLqHyYMgT7x%n6#x`@2{b$)D+&YmT zP6!EZ+R9+|B2Gq;Wnre1SAe}<9u+& zl(dR2(>>4kTvPluf5q`7KRN2wA5U6ZbAR%$wSu#&Cf|H2nB%5jSvkk{y~N&)S*s_O z9qO~SR_17bm)H>C!zvQ@$$+_M#haN1!HLd2Ayd1w4zE>f`fI{zu;6ZdrK^n;XTu!r z&qob^vEFcb!~EjtzR6$M_4YNKX|*)t(yRB(Epp~N`#W$Z|7WW+krUsmw)^!oO`2N! zk>yR{z2Xdk?eEk++?g@Y<>r=-g@4tjYHW938}Z9*veb;30yWpY#Z2e^dtbJ?`vTvt z6ITT~pD%njjZN9@fi(Aq$St$1nD`Y6-amVo-}ha0;tm&2*QTWm|JW_R?+RO1=&a%w z71y}3)FiC=LOP$|8ScXjGm2j6b0=ghDbbK{aoNS&&@19?sUxypZOKMf%Tt%1ov~|I ze7y4X0{yD0%b(Pmr*ArS;6ley$7z91o10ue@N&x*x?IrVGxCtjcyLI*N~(>=!{wk< z^Uh@lZmHd~eY$Ky_sQKZoB}r=yS|Z}?igYy?r9yomFvNVW6=khes(`Tzvt%6?TK5h zr)TBcyM*)GwQHWKm{;qN&2wfAYrAbt_o7E^Leu!ICONXN=vT~9a<%aMGT~Q$!|~*A z3Wu66u1#O;e=2cCt#Dym5}%Re_T68tyx)B|GL^~ua`l_G<4=yuO+9mS*Wv$3wfFmH ze@|I@?*09io{0C_(cgSaZu%Up`F^HYydqaR`0JLH_0yMy@lD@yUTW{AP467m2D8^p zWldh9|ERv8clr;xgj|?&dtR<%UlQ+CapQHj6Wh#cq;7GG&K134wJ*CQAnohp;Ps-1Sf}3V)y;np zU;4$;@>9{Fv$}IjV!eY|r~V1(%lxqW&DFPlM#fJAC2VT9-}|+FYx;B>@l2C{xj|nZ zuc$b)ufRjo%*W-b>kE^b{H1L*ksi}G=5<`R6S2J>6X@)DQ)1l;H?OUE+oCou*89eD zBmef)PbY(pIvy!!Di2t!IVWsh_>x%sqbH z>u2LV=doeTz23aWNAFL~4E(F09)reA@l- zI<%Sor{26<%kiOh+rQ2uJ5H}+6V+V4 zWbV!>LhxlTb{of*jW)c0wDxNH zZ_&3%EX}x5_G#*$#x-V7C&o>>Ijybl!qLV9N}G)${{H@$&i`JkBWgZ>`Qhu&YQI0R zeI|Hu*ToB;>szjz&p4(kneyZ@`^)937k!yGi`E=?A-HSc^sFHgMEwBuZ#mgbDxNlf>Y#o}ie^LP{lg}-32`4=aiuU)Y* zPCZKWw`JBZTbq|BE1ed+{IVi@)*X$x-k)x5xqe#Z^vgfxKiB8q$cXQ+!!Y zEYvxc%G$K!=d-<57t2;%t_%2?n;Q}|MI=z;!j+)Q%UmDrm@POn;C_AT+BFh|g%KJ? z_fPNC)O;yp`<%tTiiYP6p`WRLF=}unNzHhI7s;D0{yYH;E z%Ex~HjXG2QCkM{oz1DKUZUyUM7vAdpC%w_?WoB;u=aVv*Hghs=duZAGdG6lC4{}?! zzKWg5S$+O`#Hxd;7ao4Snzq?XfAI^OD@shV|0DMlJb9^7v_bmQ0^fhU%jYyck@NJB z73OtaP&}bjA@x_^gXUck^ExJ}UF9lKduYdYAZdB&q>ec!E}Q%+ig3`e5%H{&^3ae@ zYg)TGIxoLt#|8r(Jtx__3?G`;_mzM1J!ov`t@^ut&4sKatx3)QWHwsuy*K4T_NvU7 zy9-bLcK_hL=UU)w>)8oM8#0w9d|9*Q#^y`%9+#S~*kw)fyYb{qZ%FNqw`WbR=kV{I zxL`w20GmR2q*;WfiAeX0UjfX|SUy*Jlpo&w{?-%KZI?vZWF8(qBvWn0;&TH=hS82Tsu_-+6ecvGaxzq6hU+TwKc5^xp_-_~gaV5P)uwG7fPP&|9 z_>v1v0w?xgeo}0F%FC=Hta^X8eAG~VzCgmm^?yD5ZoZ)_V<<|Xk`5gJb9jq@2 zS!^SFL3#D_e@F6*-zHh?TF~uSCFB@(sNlQ!zxii>{g3}r-}`^_+r9gq+4nmCnetyb z@{ZFBwkN!g4BRgI1&IHuxxyZ&AipcC_QR~_3AvB|XT4ATVDg{&z2)Tt?q!`TGinyU z*dzEzk|SH>%u55YZgm%*cg-ES&%cW_PqVx`$BQ{?=ZtKg16OBMo@iXITc4sT{psib zI$e?1XIDI%TNWKrW!IDU``IL}$-&tt#a_9E)s}CZc)P?QXy=qnh6gs=Z?XLr|Ke=CW_Lkz@V2TXrX%aS9{&5sr(eC%wwUwz zzRQ&xW!q$0dQQ%K?Bv$s%Q#N3uEY^9j6NigZ-R3nz-imk$8{^eiQtrxFa>3#Q+^HQGK z_buk#XxmU({$a}^iR5)3H=PX-{^)w(`8AVhM&pi!e?EAKL;xc4_wVG2|iKE{4?O4JKKY45!;M5 zUb%AP!2bvynN1!VJGtg8jDIb>HKgHGAWw;ckMjhP_@k||)9p8UB)?qp?Ctu~ryuef zR`oA`&2%b6V)Gv%Hwk&B`KJ3d=J)tF_@7c=<0afMMJ>I>Z@s@<;u*~%zTztxa{rd6 zUEn#sk9B$ZqYrc4?GqykzZBi-h_l@Px;-U%ONXJrKKuKH2mD{|bL}X8V838v+~vKl zXI164c75@5Wy$5N{`GG&%f;Je=cm7l;r-XUL)O`5fo6cLQj@R4TL0edY$M(Wg{QqL7{ZeE^vF(Tjl`6DaE zU-MrjI61YS=I~^4=q_H(e1GSU*KdPvz7%(RxBL4JdB#6B-|NE{TyvOvg!k&Q)1uuW z=5ITGiwdU9zVrQ!gw1n_Df}+ZOQT$;OW#U(_@?y`XRzy(srM5qbb{X$PQ5xYlk2y) z^5nh=58O92=hm#YE}UcLV|?)0j+mwc2b0(s4@m8ubB>Q|k=C-yvsr`99$na2bV}mM zeU%?<4#~T-`t>&K=IKt};A+~h!S+>lHv{voD_)}fK?_RPuP&Xx%cd~1qAoAKGIrBn zZ?kne|3vufT7H(F`)U4kO;`1*iN^n)ITdAfzxz_}dX)Q0Pm}x8?8R2Mm7n~X672KR z#!q8$$CTD2@4T9v`JXN`otB$xf6~75qsz+K%&%QdvX-mvdv*0_{Oq&7B_^A;y-sVG z9JTk=XSdiXu}92acfHMwcD+*d(`Au&@6}$0LiJzYH!P2u-l($1>J8Ug-tVOx(OK$G zzRh=ZTxYkcv&xQVTOFeF}FpX(vJQyw_HRIf^_(L8c zp|iHk-?8GP)V%$NZ|WOAo-@6_EljS%{^Z}k*2(>%c@ItI_jNyNFuQtxKc;!s{8Y9;m{>l~{r!u0 ze{L*roFZ^EkVRwFw^z4UujcW|YFCuKrTx77crAn1(M=AAEE111es&d|k&z}YzG{>1I?XI2NDj|`b%Wb9PB$htxVXyh_qTB1td)?yj^2I7GcUExD4O)|}ahW%{ z;AQ%$DK-zgcsSY4bY49A__FJ#{I->66?~d@pNQD}Lv;IfhqbR3iUu`oUaNgRM0K~m z{5r8uZ=V0LGXC;-5dz@6X(B+;s>AaGE zkfqGV<*tSeEs)f~w#0^0dEiR2R&i^7Pf2%AFf7w(Q>gZtt_)XV3j+Upn4r{OnPf;LbT2wpyLM z%KL(s&gF0XJ8#Dq5w%XOLiH0W?!xcC>t5JWo~a{$&VIf822O#8S>F7wI|3$7kUyI} z>3_+DjBw`mK9O=kLFeerJX6}bV$uvX7Ch&Bw&L2)jQhU~E#qHoRmhVuo&InBORLh- zsd4|Cu64;Cv+p~q;TDxOZGsK^J?l@etL3kh{P@rKsaD}$q2(?s?nTGjZ&huNF!&;6 z^x?moW$H<0PvI}jO7c<-wI@^lmQ)}4XJYquis1>bFYyR>G1 zv77Cyf4?p|E2*!3I5$O*C9VH_O6I-GGat0D|6)2&aIkHGf#DIU`0LNE&Pb5B)O0+S zAxCP1(BH#vTO?Z8Lh9}K)DQOC>N`0H$n-zlaK*+zL_WrP<&}lrlSI^fU9M_7X=$wL zTy)o5X|mwPpT&|}KFP09dGvbiv?H!|U8#!ac0c`Nyq59)-=O82qi4Q(7;`;m?cB=w z{Q`FqSs$-+KCnA+L)NSZ9lN)bM>Ox9xt}ZInABa1!-jv|qx0{7*(o|nW^IxoyZt2L z(+&Y*s`c#-uO2Qc+w>+kYIV;B+vvhIhmxmO<}A}>HCi}}U~M$LS)QSnf3tyClr zH-pI5NQ<)z53E~e?qJp;;L95%)a6{swq1;Gku`(Wi6jRjVJ(qnHwHGAZUr~KNC}Tu zJ5pu^&a>IM`$wC&q4u|DdkmK))qZd+Ub^JK%I>?K$~NkpQtc%vu?3!7(SmAABf6|K zqQ9NFv{Ot$T3f@LG2r)Z0b4E==kJR1gP-y1&3STOTJQAD7yIv&+iwfk@nc)un|J79 zw%YG*?$+Kj4H4)Wn$UE6=a!YIG^cgQ1Vg+XJ<^8La*rTTJKZj3Z)eI&3 z#X9Uk^DLS`p)0C>UU?mpV(2p<&}M}{QfVO*6iJ#X#M9>)a5(fTx-t8JoSC^>eRl_ zP48R2Kb$({+|gCr4`>_@TiR4y^keFgr;`tvPN-I>y>Q33Y{_lkRcl`Q*A&nC^1pTK z@h!qXW9|4D_uczDQ+kEp9pb? zmtaq_#4*pmf!E$FUVGC`D&WmxMl-1mJtlz;Ns%IvZLTK4zON6Pwne6~xz3QBA;~)7 zf(6e+fr%a`yNuK`q8C!)~k2HU+bJN34LrK@AGjw=X1c|7abUfAW-OBMs zrOVXyUF{izoLq7D?_Z@3A6#Lf=-BCaX2DlumP)q8FLVMIn=HMQZmH(FJ#l8XIjW|1ASWmo>)ylC5= zljl3-9++%NQ``GzA{+NfDdz&;Qz$?y1R zfxwCYM~l9%+|BQP-H~-X-^*sj%Ko#L-}FlJbLN1B2krigu~agy_~&!_VTYu(@(Ml2 zJKE>2L_41GeV5u1(ju_H%K3Zk|A@MkQ@s@K-aGV(@s{2Rh0wg3R}&28l*=g1TcLfW z_mra6)QoK9<0hX}Ze9i+8GborL zcs+viE~D9hUA5&Cmp$BM(H+X=?C-mVWtVAT;8ji|lLMUJ6L%(Muj4By+HkG7+s{$3 zpkA&*_P`?^_et+$+~g9axSnmi{bMqJz|iM zCqBuOt_T>oZ}7XjNN6X=^ra0gEN{8OmWZ>ci>o~@@M3xJJu^Hb$8^qTC6?fm=l481 zS;(jO$e+z$XA0-`o=DnY5eIDLx%i(i5%*LL1)}Ozu?OCl!ilsPLeU5y_!JBQ3ALjgcWE0+>_rG$! z%hk0ZpC*4S|JC?xQsV|ccO@-dwF|eqv>Swe*WBQ0yTn+@T_lobFUK(}XgzfSs)ragMjadS|P7mVT zWLy;1JqkD+dR(GQ>*e){MXJ8HjvVOZ5WOavQW&>#=kuSv?ou)ev6re7_ZB{Vd~==U zX2Ud>z?uD9-Ym0WcK$A(weZ$2`5V*EUs|zBOG)dM!5sN&yZ0S6Ron8DUu&Nkt}m?51B`9uS#$ zZo_7>&?9PgPF)P2@3 zS;(KWLGs5$!+55aEBvQco=Hwz_D*(Z8o$Ek66ME99KILLyHq*5<<3745Ro`~q<;6L zZ5J1*Pf%``STLPkz~8cAB13o1xznkA@~TIR7+>B_G9N0*2=)=UGF!I8M!)fCP2|i4 zuWj-(SKRx|wp=+Pg#U$t+k%SIeE+fqDwNf@mRtxGnyAUa?#}Z4xf<^wsXn{CjLA(B zFNFiF#H%z5c}0?X_~jIzWTqG~_D(YvxGXv)x@^X0(eU++No+4$??t)z#`gI;Uq5q| zU+ioyR}zCW#?ur(`}Lu6nXMAEiq73G)h&=x-(&(?~YfOXZRG=6ZvU)_}C7$`?QBEnKC=KjBu#q16{Quo)|xJ8ER4^$O;E zxU}r6b;oX@mu8Q8iZom@m4)XW`Jwc_f&Jv$!uPRNOzg5hzxKIIn8y{MfnKE+Jswl%IKl z<`Y%8?gh8UwKM7c5Ln=}f#eE(Ts6Q+3#$K4BsqxZ_JD}-V>d6eL3;Yv` z&RQ1iIev=yyV)~`maJ^9z3uFQaP^`-A+KwH3wl56CO--x$z#qS)ctyG)a^B-VMZZ&rM95fYGal#dp= zDA#5Dxbu9MhVsKZb_RAPRU0hXHEcErsdu%hY2I=O@H%--_C1r|*()0g`&d=XBw5aF zVG20*@pw`pTLJ`6*r${YI6rTN% zo8PGMffDC-xqZ!-+nE^I1TBv=OzFI5@anzsz4f)cZg-D-ULwiE%yVz~-2?A>{DWG{ z4qYnSH03PstcT7k!!J6YPOnjpclP?2we+##=hRD4yX0!@3oHLJU7P*gYLC@@hl)}U zmkVcH6-A~BcpMB=@!5CZ!0uRWku3}JEslfi2j@;+(_sBzH&4Id70VR~Uyi%*%noo+ zug`DDF|)2cexY=ZV%wq#Z`WMRd^E}9$P_cy?Yb<>-@kq#`qh>1h59#F<`?Nd?(LTp z$bGZmy^BHfwe=Z274vShHsrO~-{b%IXKsJ(Og^5(pDU&JFiEj*?R-_sAe+!8=*!t6 z#c=1Y^V1(w7xLZ6y6%xBP*mn`zf9%#%ZEIj&p5VkPkr<>z~fB+iMjqB#-==6{l9K# zn58>zmB|QXS6;+&LM7UOb4J$h_g{iQCnP<1}eXC)!VD)LQ=KG%|e@;B$ zx5xQmBZH5+^`|tGTLxJfCXRoMJj^8ioZB_i#MyE4>o56dIe*SR_VVf5LbCGt6OEboTjyN6 zmmpvN^w)+XpD$O|8p@sCy7PKG)ANjn(zjhaR@tbYaz5RAdZDA&16%gUDNjNJ9F#S( z`TJD1Tx|2QT*Fi9zryC2VuO>DL9(7;P*Z>RBjc;#ArU{OQllM z>ecMCSQJWD-2Av<_UF<+q9)72C%)r5l+D^7y~d<>u^hMZuJ_yvJJwrdHajWxPE%XR zd(T-f@V@rW3mKR8Eh|i!k!#>Kmnr#?pZ3;?NlfB0Zfe%?F6;>gwmyHHHIDw6QP;d6 zZ^DPzf3LqKg=bOU0YymxstR*USee;Z4R)$(I?AWn$@4QDH5qXjk21m|3H+*d(eAJ3> z_M(0dS3XC;Q>)w3XA;t4qP3~@G3(JG< zZvkT6?PpY#-b%MAiq4$1H*NQhRV^Gn0gWd#BO4WFaLVxI>l+pH^H``Qt?5^v@+aY2 zMdYf**G)2bzTT+(*JZ}@_gAiJ|Ae*#kICH!Dkmqsuw>eACvCEvwar5CnFE*5Gur~j zN0)wD7#bxmGg}pQtm9YS-Hu9O>7;+34IXZryqERM(W3nK_dm4VZZrBfzx#}=RKW$k zuhxI>y6w&VeW@%`oB7tge;Y18R8n!uv7UItd^_JpS^kzqj0+|)E#X)svG1{=RZ-IN z9)(#gO}#g?zOs4D>PYA+TX%!QL(xm~08g_GZ-PccktUmzv;gCtQ2*ksftRGrWIn_h zt_XSC$RWjG%No_^ebf?=boB|f1Y@5A%FPth#wCrBJsnFHQvFUo^MQ464ri5he?W|>*QzN)hZ^}8Bcs$AeLR- zKE*GkAU#=S#|3k}n|vo7Prm%Ze98UnrGUMBm*&m2u6$XVm+^gqx4=uKbAPQD$TuG9 zO1v#4!NGb}!eX{_q{7P0%-+wKpBX$p@o~c4&Xc(>6(0LGi(O=~VvacQqx0{RuOFFH za(g1&?@F5crZ7G4Yx%acvF;e7@RDb2!g-Ue4gM{>&{aOc?*)%1Ih@1P(5$Q&U^D6YhwGbdYmTp(e6;h-ikCd{ez7z6%sUvdNRqqUF!6uzn_oXt zuJ!Pp_^5h#&YlYIL)8Z*p42G^Ts3Zy2{p9ZJ|N_pq;fx_g@Y z;>^5oJD+N$56|YPtFg-V9s)K z&JLn;CS03ZpHjGP`}0*tVpI4NYkK->ByY+~oZj>L%`G+g%D2~#=WS1{Zg}O&Qq!NL zJCbV6_nPvrqa<!2dz{TpOdK4Rbo3j|xp?L^uhE$+{PEI- z*FMPYXsAkj!z6CgDed}tmG27n$z~TF-po2-bGu_><6b_lphSnrOLLl@*PJ-N@qL#5 zzRJCIU*42+n>Bny8Df=pE;-P-r0QCa@7&LRyH1v}hfO+gVY~T^G_#Es zg?H0rPVHM#y|tr%RlovU%jVb33c<&mkGXv3WIUv{IQ*>mQBm)s){8!_%H1IFL~$?6 z@*Uxi84I5)Exh!gQ_h89Q;Ax?Qd7yY&1YEO94wVC_~FkWd#J@GddI|lmf!!BBptZe znK|Lpqe2HgHtzl@P7jK}Bg3>i1tl$K z?<_dMcPXO4q1{q?cKj1<>!ts@-D~y!Yff4?CFJ&oOy|o?*BLZw{m(fG&sCdJ%TUs| z=VON2#%rf^G#8jQ<_O$uaz4_yczT+~3SL+CZ#PzMzUrsO|IEYYg}6r9*ORL6I5L*H zpRrC{8YJkkq~Q@)^-oE~CGI<(u$^={VZq3}(=6-D-X$L@Db%f*U%5o%lZD!44fXC9$LnRk9}UYsb>d%Q zechUOcQ!lz@NH#masPW;`_P||xlw7Mp)5<94Oe9>vS-_Ka!(?^y}-joTr*gIMICeN zighqKn!?=d{mJTpb7FY%yb4o6sVC;ojiVLS9+;$fI&ui@FTY8Ckj=kD}Q@*@6)l{nR>T_|6Pfgwy&VY-|6ku(8W@L zCl4<;c0>IA!e6~jE7>n3rE-Nin(EaXe$bmH_T-;#|F`M?ZZiM&o}akpdi&weY^|LF z2X9Hp>D}erX}C~`um6bRkwXdAcAvK0{Fxpj|MQX)TS%(Ybe6g4d$zP}QW7|DX>CpD3(3Wt9y7s(Yr zty!P>@1I)7yk?K`9S*)Obv+sr4r;6pk~{rle|Va<=6a8HD-3h>Urjz)d+bB>sl#Q# zDf_#=AHK^vg(6)2sNw{eR)7%de(NWqk|(k;nh>t(ED~kT_MTK5_R; zXEeWW^qNxR_tCH3`@8!D>37Rs+&sMWXQb}AaEqGF>E<7DdiSeJ)gBD3n;1C#ZP>)l z@6jiAN?rMr{Ug+VZ+v0+`!#=eKP_*6sF{^@=~l(HnEAb{pDdg8v*_<0eh$Yc>n@(P ze(mS{>!vIyf%5-hFC@^cSn0(N?zgF+^q;qp`7QEm7 zuyy}D_ELB5Wj_j2b|(ct%v<-%8h>AN>x=(5J~emKu% zcKOla2dgHT?)!SSM(~l%;@F=~ab^`2RujH)G1V%pV9#2-N`9xy9?RhUm3QuVpBKCu zWaPxTd2#QvO2OyHU3DLZdu(3+enHodpR2{UFOHv;eg4w9J2ufrv+u=xIld|Cq>5&% z@v_$CtL@)JeS3Q8Ykcp8ia^)>i&m^#74^&Dly*$vuPjO#;QK`b?4NQE`Ip)OkVfWs|h#X&;LHlc5%at`g2p1zh+M=`0srG z^y~GhLEm4WsQEGTe7)@P*Sn|K&5&00Sr8TC`TfX>O95X#T~A*4aNbOL&o)+%-tadc zE3QO;mVI)OOXJ^7%O3|lri;yew#3Dc`P!|DgLQM9{`URrk0B|#k1EYK%zgD=zwHNOO7mxqJ@pgr$@^WkPq!6FD@oYvuJmu? zk3T7P^6^HwuWhBXy(TclmB??BZ|L}4zDJR9%S-8b4>{%(G%70V{?VVfaR02Ftt)3g zNSwpwF=2j-FKcatGRwE^$=|j+e8@VzsMcVI6YJ79vnDBiKT~k+ruNU$J}r^7-7{`B z%ug)4pqAEhQShE&sk?mtzy9N%<}+;02xU^{=g-9 zmqY9~-RW&|T)$dt)vARqS8uOkJhyP|d!v|pX&s9_R<)F3?Q*cpg@G@b+dZXOF-w z!`+SSE8j`o+i=5_>p;xmUCCOi6W1oW-uO4wFY&Oj2nZUBNSBl?RK9V{@~*J=jXH-5 zhF7Ex7oS}-tJoup%PMovmV0x`+1nZ3l<^!m=->FdMZzIjSnAt?;-CNhzrLKm_os#3 zZr+&lPtMAmo2e|Z|MWlOe>yP>@AmAzuj06Vlg`>`38|3H-fRAMF|FAe|MkaWAKynt zJsO^JmhMa*M~*Lhs-DB0naSk zRWtasYUSqan{j^wMOW~qOWzBgtJU4+P-Y~c(!zfEIA6H$muE5?3Jr4wuZE|DuUEI! z7cIzBP2@=1w>5HOt;8|Qy{GSNeG_#hn(O3~rikfUK2dJ-wk}qYPpLjST`uw7w~Tv_ z?@deHcGBYJELClZn|+hYUb;>HxTUiBL*rlOd+tkq-PfOFBvzAD@ms@|^?nccKBY?M zW6#)HP43w_hzs91Y%sm&zL}!fGN=gukxYXroWS zp(M_f1qWs(Ypm3iNW6UGi|z8|&PtANPY3ijZ_qrYIcr&F&BDdAWI274mvz52Qc+xc z=Wqn?2ZqNz*Ei%zrBxZPE87*x7v*|5f6wNl%IobXDNc+QHS5{k5pcmkm0wToIs=Ql zQ($w{<$WK#XR|+6TN$XdT{@@OZtt@i^HW)N1>L)35%?$-8QX5-1ecI@k{|LPp(Uv@@M%H4olrB z%kNJWb$`n6ZwmkNFGY42KF98FyVe~sYsJM9zvJI`ep}>ZBCu6OFPoj&8~cwCEW1s1A!$sZ&@sw z$s;snV!)YuS!Ofp8Xrho7dV{X=x{p1DI$;e_AQC4tg1pSyOU{cCll?cI!26q=b?{VLIb79K|mKOV?MRD0K z!b%ls)*QxbHr#P>F;sBTye7`_?w-VMC9~vpdNak+gws+dN+i3?n2_*j#>&PSoh=U& zHPjbnx-Kc>USh?*;{B5vxqL?7pIt3lDoZ9AS9WEZ&5%{xV8F-qs8jY?%fcjSkGQ@z zmPyg6x5~NdH?TJdFi&QBT>f`K#~u!&H9qM!he`~s518m@%x08O-(&HE<>}MY*;>1v zJ8xKiUud@Z9IoyaTb@0Xd%seV@xrbd4DT=H@igjr>SUC%M`$)JQ~TmMr_2slhH-ySJZX z{rja)7+!Q<^<{6*JHvCh_U^H(Zy(GPaZ(kU!Xb1jSf%8##yf@sYJw-)c}}Wo<@;<@ zY}l9Yl(w!T{&y97+@Ti-nbZwq1%5EE6>oSizVVgn!$PBuNs2Z?p-bI2EIBJ%%EwnE z^9sE(tomNQdEYDd_uEC5GYv)egj_9Dyz^TW+;V~$7Bp_uR?XSYA$53( z=Cc#`*EBNE6<#N#qR^Q+BVo!?-^L4{l%Mm5&xmcG`!rxJr$dG8J>R7q7j~WRvYyP( zyrF4U!}+iTC70Uex8I4sG1-6k_dfpMJ~{3R7o+3)U)G2mUz05tJ?+r?FOCfVugBZ& zf3ec<^g@C6TV^Kh=2t#=N`4}{SBA~f)<}UC>(kT3<}+z7m^GtmrAB?5f9UF6&tzA+ z$B1Vxyx{k1|D6plbw&Qnzak-XQqJq?zg)V-_on}R`ZDDuhM$6VoOz%wu};N9%+BA|Y_}wwuhl+RpYnN{TXjiZsAOPA>2|kGJ#t*Ci+b4>85X&5 zh|Fl#uz(qe^+Hvq%Q;a{T`+L9<3XGRhU;*`Fi(N$nrN8 za&}B!#oqE=wpMm6ORW3nvUJ-yip!ckoyzu1QfVmfm^{_lfaTaWw@4HYO8(2G3uc zHJd7B)Ac+{8UkD_dv~(g>A9|C{9eVde{w+(TlxaV*Iir^3XThcQW?x<{mFRCro7th z@2&=eY=&vsy2s&?>s`#jmz^7CG8_RNC{_@PrH$vqTlLWTDSiRlm!7m;kp6drXnK%S_FTPXB@ZxWo@M%NH z)nD~-g$e=IVFFH>0+%Y5FI-T|RkgO~gz4$~b55Q+b=YcelIW7ntNr+WePcgLt~}bK zz39v{@8|wNb5+=7P_Q)D{4R&hwrsCG3Qql7TW?(Q4Zi(bt?A|*g-Y+k zA4TQ{&f0o-qw_J2(7jzV7H@f*yFTzmdQtvm871hRecJR12PUgluE>~3B6l)r1gws!2LrGZrTILBG4x1;A?lWxv{*;uwBEjUcqg~^~*MmEv_;nPLKDd9DDs=W* zRM4S3xlZkPl#uYOmz=X|6q^nx?ch5U*!acq*y~jt=w~D5&JPS%lT(n zxmUXc1W)8*v|~ZA1+lrr+|Pe$%szbU&ushJ*|SVMrL)1s;gai-sXbfNoKufWcs9td4AA$S zeMmL_&EXgCBzSMJPwKyNMb1f6&?ulElI_|5gNL}+dz3KXTKHCS9 z8?`qlm>+yIYs15m8|xWBD%+%@ZDbA?aYb8^W}STQ@*Z?QtDhNP~>Q>T`R z4i{Pk+1dR<7}we@;+|2mx+c-nJn_gw(G#b|Uu24;=_(4nORR1`Fa7ZO`*rzBffH0R zvV@k)EK%O*ThhkBTRx{ia*i%L$D4I;UnqW+lx9@%G!$N9-_gD}{+^Nv`&o}5p5OmD zy`O%rJ@@jF!Qn#+auplG1ceObQrX1%8D8!B6jays{zHxOVCQ3y~xboe9$`w%eC#2qyL0oyx@;BEcBFe9F zNp!e!OPva@5O6W$FWf!nWwG{UEyY<2Hw7nFnR>IXj_?w&yj6cE{r8><9elMj4{|AmC46y6v78YoY!on) z(d(hY6RtOLGdPNQ7xo_7!87&H1Q{L&;XKVnD@-!)EeQDTbkNYTYV$(DN(q*J$#4I( zr|nS<(Cx@m@k=lIX*HGMO`}1pGlxjq-^7EL-|;(DGQW?`5=dRH&nsRuvHU3SqhGyaYBeBULcykDsE?z!$`Y2}4Z8}H{HW6oW5saN5MhxD7yG(l_I z4=QS39&Y&?$sKh&qxGxOsNrcYPpzIwJv z8+N)$7q0ze^h`MT&ckhvNf%`1bond^w49LeX8SLW(|NtuZ?x^1xWM9u;~m+`s{S(V zw}qE{uZZX`dS3bDxkk8i=Y$FEo;?m{E-4!DTu|f`5YRcO62|G`C=&Sm@YbjMTK8uA zt31u;3OG7FuQalvFD+I-=y8(TE|HwScWwCox+{C$XubVOTF*Jt;z`sF4iSm2f}`?P zac!HK``kX7EaVW}%ISKWk7)**g|OXMgAxy^Am`#P$F>g}_ok;^o-VQ~eVN1~2c{tX zIZJXP>scBvF)n!|^po$&<+h&qOw-G5{E;=w)j#KNmx=6@Q2p5c@xR!YER*k?PSRZA zLCZu<3fJTu?GHMo|F~Z7!nCU2bE$)?5l5wryfj0~$r)_1A|9q6wKiAyi z#q*NFEz{=8O$syW`f$W%Zs&Y0L9SK8H)M~nF<4sOpJo(gYmo2rPTXyFl7u8L+m-Fy zt8`Dc`DLmu)Ud64{Nt$^`$`eE@|o?z(=TboEK(0i+r`E2?6t0R@|RKjwJsy`X4wai#Uk zMgN$hsyggm>{;NN^!BcQ-7iDMjYa`EFFQ~2Rw@Ssoqc+6?}e5u1}}kt+ie+54rb@( zSR@#4d~NObSWsLc*8FXy>_mCbv@qY<<*u7NG#Zu~$vF8m$S@>%NiF6vDrRSXrD!Yb zzsx@S*M=XDKgG=t35(Qtc`i+yYo6uDtY@AkXO8RoK0SQEe}~7{;|o5YU^%ogR9NX3 z^N|o?zA4{j+*x_P^f6znnRIv=XQ1ZBG9H}}uAE#62~oDQ2T$9ms2vD?)*yTAL(XUE z$TK%KoO9fxw18P(t1)W9bB4Q~XWM1AEa|j5b#jhvbV5Rgm*0F_@t}o*S2S#9uub{w zWhfHR8YJti{h@Wq?Uja%b#K}^cXB5+6>L4P%=)3PBaij9w#1{5&$BtB)nBg3sofDX zaeDgMq`qXXISCR5?o+26i{fc^J-to($S(t#&TkI?dw2Ui=ifNNh~bgkk_1!vvnH&p zmZ|sKavmFQVt&^mH^ch(2Z48;cl=|!m`{BYc$)mZV3&}%n~L`;kBU~|J>O0TM`YSo zF>82D6S=!3M0a6h{F*>T7KxK?!eZY=xu^4pZF>6EMN>H5GVv4Z0pEXqipq<=DQd6> zGM+x}J!!pwZ$s3A;#vC_rzt-3Oam9nUUfPj^QdpGluj3WjH?`&sm z$g=tHD%MNn)gsfLqJ}Hh6IfbS38z`7R9~*YeR+0`!1OT9qpbYrWd1W&nU@F1Fx-AC zajr@5{^=u6uH4H>h@0luy(Rt1idB_Ld+Y1vL!~! z$9>f7g;>|-9qDMwwO-h>I9lRhSCC@ZY~cj0i;@rfSY27(Z8&VTIrMJh%svrUb)5?@ zZWpQiv%2YaaSg-tcJm#rzu$;myI9&;(%miMapbK|2#@uoH`C@GVqLTJA$D?VUEy9M&%_R$Gn})2MCREtIqQrmWti;2-v)T;% z1HvQb1X}y)9$fao;!_%TveztAm%v4bOl8tN8=Y74+;KPd3TS&``HVSGIzi z#I0Qy7Wv&g+*1}1`C!$g6%DS9Q@A#1?o(S*G3(;#!@Y0S^UmDc%Rfimb?ferOxA~_ z->p&&yjyW5Z}$u0h1hmF>|h8i$U=~Ud>w|!EwV6<4b(yql;Wz+Me<)lPZ zJ~j3!C29)HcoGp1(CjI2LHY8eX=*phB=n>UH*_&FnN4i?y^1Zu_E3i2=L=QOm%YD# zH9tnGhyTeG{>A#npRW9H`Q0SV;vre~xnc1M3;m12i&^+{TXr_B6%~EGXOc_Tgoo-< zMjH(d8y;3E*lcvNnf2O+t1YKa1*Ay0EjZz()Rdsf*wB>q(@AE}i}GpDKH2WJDQxQf zyupBT_p)opx31n8FL0qoCnHmF+vG-#NuJKHjb#Jb>SOh{JmDsH#IB&k#9^nh~UuW0YxLlM}nYWAK z;-XN$&6WRtvlp?pND4i^Tc2*SKyIl}*NTo+i_S;fmwfXiz4Ad{Nb|lf#={}kSl%8o z{q$#Y@45voyo^8G#UHiK;b2I*IcM|qzR7bp3F$0&e3418eMiH*Pp4H`Bg3y9cHl8F zf5Q2$*GqHCtO?tto;4Ldci_6Xc+#BX4uU@npZ^a(pk7$xa86{3BE!uy%!?aO+&=EQ zO4K{z<|5(A!O|N7UM_O}UKPIkw${n8+>gS)>Spe4?pZUPKiYrwoRYI{;deiD%)I%g zK5!rMPYv}_pQ_b7i{s#x0uH}v zReaSohVM1XmslTFoYWqF@2&8o1Fs_#6}zwR{HOi1`Ow9dmusAgPlR%w-(OLmrTlvl zo71mFRsz-vArnLHu-442y`k`!p-iICoZXLO@5VO&B|2A3Sx;pxRhxV#C`os6qN&Y| zBOX=d%d!(~d;`yT)ihslK4kC?c^*rsgim-f$%DSKA@-fmZL$cjBm z?P~kXV_rH7rl0(L?a%!sAAZDhZayTFcK`I#%@)3yT61SyIymP^#eVPT_d9jk?wUH~`aqHZ|Y|S6>W%jcF&h363zMZ?`oxfODxX9+brPDRl+B?cuPSOq*-P^b2*$tg- zcTXg>9yi=pZQZ%cuz=&$lg<{$5dGL8Ksa!I_a=)^7ZO`{OcgqC zV%s#m$Gv-4oXma7^36(<8m~EfEZ1I9F^z{uLwebU=?*h?B=py`1WF_?sAiZ~aBvIf znq+sE12-H#ecU0zCi6+Oz%47U`QZ00%FfQ2Js$58H4kp+IwmGtdCl$I+&kO8<*#{H zou*|hlcm+gx?9G2mcWPaPG;xQ4ov*Zm%QIU_rYt+#zTuU6aHSVy=B~a)NuLcaSvQOAEbCG)HM*gBPicn4q9u8mZ+OiM z8Xj~y#T4F9Vi7QMwy*uzab$g(z?QSzl^=?-g&uA=-BZaDkpAkFstO1 z)=63Gdivhd&Zp)A-w*dzN~!(Ym8ordyye#G8K)maER@Wh{G#L0d?U-$)u-;vxt^hM zbj}IY$&H37?;15Yj3Q0f>TeAAoD*}x`~B=0Gd+&_XXIStjr${c*ks>_8*X`CR~|7)TopE>j>FKW1 zwbIQcRJXl8E`9L0vX{h#=IEUzhN63nV;xrV9h;*!Vb;tg2ls4U*8|7JK>{ad zoGMc_d@fiz_smq?sr%ilza)K(e0$G3+&%Yo@jTYLJ8vh?b$#2HaCN?|d$MqN@xEu; zIn4Y1ez;`pY|y1$AvKwo#Z#&%L3WaJ_a2|0G0##(Rvfmr>e-Q);#jDYP$aQy-MUyd zfeF_F+byF+o><?eMns8`f7PRP3I-$|LFaqszTzhq-4doqN+0VYJak%}nID zTf)|jQ$-6-t(0LG^6fp|rW~_wg_XF3ZrM{-wNuP1cPT!Y(yV9A?IGJ$wnoNG(NXs3 zJWZZmM{caiUGcJV8gobWgL9Ji=FMOao{d4*_#?dCnW#!;*CT z?(*H0SiWH2oN4X`-zP`=T{FA+^ReYbrn_c4DuSoymOgy)ca?n&?By6xw6pX+8{dhO6Fdt%5&00q(!D-fk|uExqzI^CCxLr&h&+)vv|)|_Pkwf`ab(e%I)Hi zNxSyV-LUJqarvItoH{Pnmk;zx$8Gp_QevlsvgRYrE1yqw-);DK;cH)l`H!?skGC4U zb710P=Rf*p>-3Q6JW|ozY6)FDIq$yb=I)hK>x$Wzcb>t1dcub{$BOT%{CU_OlK1A? zr9%=b(J$SkT?KaBQ@dW|xjs1KkXp05;ws;*I#>66cE0c|K}O)&iOB*RtF?EZU&8%9 zQIBI`cT{t2#kK9vu3c1qoYSme#IDF}!nmkCEBA$R^9Ivf`P16fW~n7{w74}SSSU0% zG8InQ>f+T2xO2h}&;7o>OaXH`h0-oExI6kZM&|}iU6jD=m>_;2y6Mt-mb2Up zF@{?3?!YAIclYZ!6 z->37bKtiFUJ;I{how1zZhy248JX8MNeV#FY!xKZc>9yoa6FsJ7Ex#!(p zMO>G9Y!qpBr})*yOMCSXY~TB%L%Pa=eImniu~Xk1{5eIK7u$z&_}~5JIPZ73?$+cJ z4RQ=ly-jZ%>%=}VCNc1KWUa68IP>PtmhVr`%+@is^J3fm=|%3dCt8fPPpTgV`Of6o z%5gA>h3U-POG}^q>@NQ+vE0VS_Sd6=dx9+DYVkdyX=c;S@5`GX-llTt)Op?0%yV;N zlox(p`&{J7&YQ8DEOu)MN8a-hd5B?9h&UMB#?ox9TnGjf&Uh zR@MnA88*o^G8bHGUw&OyM~3fi@9dJ4xdGC1SN2JCS`_;TxT|5cf8|Zt!nV2#Lgzdt;4$b^sk!l ztUfhY_$3%Z7*;66%BVyrpAA{;@NT0>ROaG$M|5ot1>b!;>BF_gWk%9V1-VY{J!WEi zXoIn0Q_MUYhszdsJQLWP+&h|&@E?ACH0Iu)L$MDxmDD;!Q%OPPqy&1JH8aIaIBwU_d&!k zX!-Q(_kT+AHSk_NvvG1++ymVcXI*!nv5e!{Ty&&5pIuD;e9OyOlIM**x2_QJSz~rs zoR2ARcE+SM1!wt(##8NM&3NFwW8 z!OApGqwxrv@TABlJ%tnVa~hkJ7c-yH$PDICy2&$XqrxRA^A3%lA5^4Vca&<2Y+APQ z^7e{y=hIS+Z?4C@v?z1$72!R^_UC-ckv)!DHG4v0-?k**$^0WxeC+I;_r1!>HF1Vf z)7e&=T;Cs{#I3R6K&PZmz~glDt(LB5E+^e~xx4NmA8(t{_!(r|{#+I`#Yu0kRzSc6E zA#gk0(|PSQpF8iFwywUEy84wz^?}!^sf+clPh|V9ppp2(jPsstQsO0HC6lerfs9UP zbWC{!MOjr(7zFx$5D4b@I`zf^-%ka1|B7o(tkh`1a+Kj625ANl! z2sbD+S#TAC7&rR zr^pKtUE}u#$DLY=ucuiHXho;HKa!X}t!y(y8i!%&(cj+|V zcX3!9@asYCqgv|}>&0h_mADscxg6NbP+QcvNHj$?QNh}G@3Hl*XAP_-ZH#S?udbQk zpWLP!&##-&v^_z1zFd?})d}r>sR%Wwp2pZ?!JD4B zrS=KQKV1KmJ?D>mwRg=XRh4(z)!SblJiw#kcl&!u(H6xwAB`1k+Y>74G!AjHISC0T z{K!;i4t>HR@--%9%Z3G(44tL?j|k`+g~pHy|hmvWs1Qs zie$CocF3ts|&m&&=cV}%}=moj@5d%?IuAPhv!M@3R%vW@%4qtoHV{Sudg+%*Grnj zFjd9j;wE7Ztzu@5A_IjJ$F*g2pY6&q&Q`KUU!VGtAw6ifXdm-}P-hK9w9KB$*w9OeF>BVCH-D)Qp7OZud*yB8} zO(bAeuAAfJ$M=sdV%*4Lb~fH`o%*b~K`DyIXU|%__jOFjdo~Yi4a0*AmoeX)_~LuT ztcNp{84g_$`+Z>Z<{7mPL5}^^ztfs8%w|^37P!#Q_-oC~Ck4;`7dsVAa*9iGQ7zuU zse16|scnaw`ke(9$uepBxF!^R&n}vI(rVVnh2@h{ZH#vx9Ma>RB;c#T1t{ z9X8CzH>~(-+y4B}{0Rp>Nv*B^Y+ojF!dcazeR>)Dw57LgR(^1r7xVDIra1~P1e{z` zTw^b4`{;*;$pn2}vn3&9cXLpB;j!kv+swz$p3mfERb@EL;?g58$l}o0$mVpCQRq^G zB!{8WAt7xZ4)?~>Cu&_Jb$$nDWypzq*t_3MQIyf+!rssK-*5Ciw&ANcU5!Mfsn0E zo8Q-1`e@nP|DBlLl;O|0`}cVrjWb7%Xu7UFqA@8@R^~R_O-B{)hTn5q7b(PFQjcuB z?QpBJXJ_ghp9hLNa(vEq`8FJAm||e2G()FYfa%iIJ<0o63)+}i5^`E+FUXnUVWnIs zr!mXsM8DmO%VsS9-kVE2UogYc#i_z0QRBjViCM;RHhn8J_?O9=w4R@O+~&Z=RTH)q zdun(xpYVKkx@g{`FApr|v(9r{7;w*yAvn|3EGw7bj1`twKO4%Isc zI17DrpHIu*XlVDug!Rpfvb~;+w;5hLiZ#raaAT34)A%{-^5y#GYb9@4jo!^>OkAnf z_rG}iX7=~(dlzpx!=iD1s@@OINAvFA?fsr$Di%jIiaR(#*E z&Pg<0brM5bTBM4or_qa^pk-W3ZCq#0a9`0n>$143FbDVaE4L)MCth2~(>v9m`h4ck z{zmR^!L5^(7Poo54RHTdq3F^vku5W@pRqHeBybV?iiw6>OpESG^%%C4X$ChOT=qmk z?Z6|pnSmSvasoZ(d@_!`!Fo>bO{}*m`l!59c-+h@WOCqAN}5UFl$O9HFDI;MQuI|? zJ@2L9g1jYJtCOo0dRXpBt1K#(SaB}MLiHG%+P_#!8zr$C_PI|OFWqO_%pzgj)uv&{ z(8E%0$(Xu&VqPXQ|Jz3YfD4){gq`2~OkKkC^R1Kv&$PxILnhOkiBTI~yE4D+Sm1R^ zdsB}5N>BE$r=~n<2eTw`1{L3mBS z@46tDozs;xE;i4I%<@?)^4cvSCGe$z+3(7io_sf@gsalHp4s{w*0y-%)Z2E!??ScD z*Lg43UA3sGV!Y1l?ryn3+RY%rK_$r0RLJ)8Jy#K*RzV|`Nf$1Lv|JH2HDGi(=;*1U zbfc+t1>cG2FL9hV+b*&+Es4I#-XeI^;?1cW-&_t(oO5U9xALpPn^yg`kK8Mn&^XO$ zo15j^7q(4vH&|$tF!lVB_{frdv}WGYNwr>PWe;WQFPHxP8};YdM&k(fHg=EBJV_zn zp!~z)`Ia9QR?cf?DS!EGYUe^rQ^jk0)j6CJ_C)D5iL1srEnf85U!hG&G&ypTs*;uA zuinctYSV-IL@vm46g)oCBM|r@?xXPA{Cl60=I$3X6*N4!BDQh4+nrk-@_U3lQ(Il)0A*nnfHqSG5Tg(D6=^EW>VsnOWzQn+EZR9zI0W~On}^S~ACvqC1u zNXRUnm@=npMw5k+(qz>`2CJkb)B+lnf+7<-6E;3wJfU#SgJTQICU;5jg}8IT*M zzq1u8gtKNHQSv`kd+EpChuZgq9eg~N3axX!HsjoEg|kvqDwoF|>sps>zvyFgCX?lb zc`;?Yi|!owW6jKNDXHiDi}Tsm_$Hajt4tI**-xHMJ8)d7)qatbETfXgm#;q+I$!wl zPyELJbK}v^N-F8sb7Nyx?Na+c=kHCqEobK5vAr8Ix90ZUSIcb}_+rf44&M~{+5Knc zBmw6QwlD9kvOch)oq=tI3cH)2V#+SlHi4OXsaX>a=m7J%wy7?4TN*BXnku0X{CgIktK$RvfU-#<{Axa`8vmL%npSUFrV{a1ILa}% z^~gQV3$hLse3zHV9F1l6>Qdp}63f`u_~}M;Vw*JI{2MnK9WHfxh_vd*=y|Z}bKQ&B zJNeQCiN))>lq(qGLfCj~#2D`$T=kH(S(r^l-&?@VRKelL{op1&ZiWW}*KRRCzB=bY z+O->M{b!6A9431A&aMsNyI8o>*PqXJSH}LU!rKL&%&%y<{d(Ty5{LHHfzLZ4ekN^k zop1eSLHYI2KVO^gPG!8fw=*O7yw!;xC&U^{4(s#>***NW=T~?7ff+}%F1Jqay`B{m zn~>nQR`s^h#=TKO%npf@xZZr{aD1>zH2lz+)e}~CPrjRTZ-?RuoA`&aOJ+VZ?z%7a zXYP+Z^ZIsA%6Zz;Jmq)TXJudK%@rOG+YJR~nO{FI^!t#q)4or<{FW)xJF^zvS#ZSk zisfG2&0lh(wyynp`UO|4o%9Wz-%F(eEMlhJ7V$Z{)c9moNedE?)8|d ze!x&F>37ueZ^rjC+fSVA-?=2re#N%cN(E`vKH4W(e7;JrcsS#fntpGm+=7_QJm*!f zoO_B~ZEaO2SkB)0Pj6~X*DQX{#~y4GzGXjt{*TYr{qWkl8T=c+skq;@kz!mVmeJVM zG-=wTnVu_E)fOo%)$nMUqL|USic@0+!_pNK7J5Z_XfBzkxN>R6f>oKBObrXY7*hHr>s>r(4Y1)_dV@Xz%2xn1!AV4A!5W5AIjVXuG30v9!|ROu{qA z&#qfOw~F$tl@_}&;l#2n7ZMILc9y%ypW;q%-g7%4*h^qnmRRW3ZJ85qu!l@|W$jlV zCdhW7OMTjrX%pP0F3@28vVZZxdgJ zGmF=d-VpKS`h`a)5|2!0by(6PvBJs3yzPxar2jJ8nf0DGru&(1W>eSxvEiABkylYz%d;ZWR#n^l$O4Y)opTyZ#2F4H=*&pi zaY%`&rP3hg>fz^yQ=d0oyc}V9CE;D!Q66Vk#WSB?$FE;wwdBaL_SctQ_LM>W zCTjQ^3#~k)Ea}+4Zh0(A>XpDw_o!)Goz!1#*ic}nDcfA8u_5KLmq^43|C)t7;#L;FKm`&nWkYxj7=!S7x19@UI8f zqSsBXvP?KqXf8Q*V%1UOj#Bmlg+uG6_16hIC0w7It-V6@7FW*(;TOF+-cM&SJQ8$V zktp&=^Uf8+mrHeYRa1l$-fprE-jbTmlCZB~dNae)C!0O1)s?U1BnM9PNK5hc=FsN+ zwk@=g;pBokt==u~4+O1U<9wk+wV~K7sCw`JIhV3{_GztTyy7C4Z0op$=R{9Z#?R*t zsq(CG>q^%hR?0Cj5?o~Xw%2p=%5&KwY?+d(MWzvbd7)Z)JRyg9RgxER@pSZ*xE@@y zbcsY)hvpG4&x?1(M3-H7@hJJh!Ql0?+fEuB7c-!+$ZKf0q4RLwrq)lfQop6d9`9wiC#L@M>GngD7VX#R2;jWSc$;ZafJ%_(i)N;% z4(5w9LwI#XUGudu4SFF73)?tCcmr~${_9)5 z%Tu&Bdph1?x^z_OhR2k}>o8Tq9{NY)_kB+}KFiIuNm=X8&@c}zq&9Bwx6z4wiRj^L$ zUmSjI;WUO7$;=857ihfY7SwdHx#0dn>Cc2f4R2=a`-i%%Lmj?l9$dFTXhOrnNoE3? z#kW-yPN+TkdSjFKa^pPf19zk+oHa<=XS~xp!lI(<8PgBBDCTvdT}wq4I!s;vbiuJB zKNGV&FJF!5s1Cj?U+!I+>)CuO``FQ?`}*S<53b$EAotE`ip>H0JpzszDT#a&%xPUvwV5X^DHBoLj!=mCPBQIg`26RHMSOimtZw{<;ywcZzXKq9~J#+(cEzBOUpV{DRK7 zF#5Adcsfpyd%XU6$)wJC_HO&;<~#e}lzQCHQyJzb=dkMm+<9r_-p-88SAo@-k?JyPewXVnWgz9`;M(#h~UlHJlGc92Oa#k)dSCiiJ< zz+S(d$98lZ98@^D>+~ym7u&imhojE$Y*&|6v^X?j!$u!=mPYkg+)8B&`W$S2)-V?| zr`a+qUt99G`JWb8*#5*4@jhLOK zH9IF`e{|nbo>|i-966;eoAD$y^W}W;BZAU*XPx*lxkbx~H`Dud#@y2TP1%fGtB&iG ze%9VS!=h;K?i zo6x}W!tYj9kTI8>-wch~o?|Yx+>d0oo|(h_M%C_&NmSE;25sXHW?wlR_%{60cUUpo z)mI~>$f9b`L{1jz3ycfhe*L%YN+^)$448c;ORAG+hx)V{h5SQpUHWj7{vMj=nF1Qx125|>bYkAZ$i2(8BWccTV*>+~d3P901vBPm2fX6p;hA%q znz%CS>Z!WmM|D-4yb0y5mWp9volIx8Pn9rA8toZiK1rO=;CWF}0$ z{^ohh&g{5+<$K>wAK?^npSf62n2oDu(}4}kT9W4WxNW|{?HW2yu0g=4Z^ESnZyrS< z=M$zbJ^mNB{n_5UV#d|fl1UcFgC-q&qOwFQ!tiPH_O3F%%k+@RIEkLyFog zKV_jkS1(?@y4lf+S>mS84+&8r!<++$5>%BUn_4HiPSWZ+wx&th`Yrq88!1y+rW`S0 z5qMYF=}~Us6PL^`rp478DY)OX{n?FFzBL(^4?)C_Fgxe;9@vq{k)c|m20l# zzTD(L<@5VUhjy9L4LOgPb2KN-3Y#Z%GC)@Ve6{q$i8i}iqxbYY-lc9oNi~L;^boG(=*5G>6DlbxCcHz&tPh%Y&D-CWh@_mAc4c$srI_A0-c zXxMkkl=r}4$;H{L>aAWCJ5|}R*YV5F_{8$@@O*8Ca*-*Cx7$1!c@2E-cqua|JzBKo z<}z<(bHzE#g4YF?`1@zJa5rU&a?ZQnBodiiN4w2wuiHKo;R?#7~z2%v9?!&rCW{B= zY?~7uC$xp|iEUOA(@9t!kYVydJwhTuEjw(JyOYYJNBWzZ97VM}A{}{}c(+cNwx#XG z25mN0z9YAuIL z_EuHv@80%w@`Y&|ewSvO&$;8-HCy0Xmzjjug2kPleM{nf0)^K|Y?Rx7E~)9I3#Svq z0+yv(TCN%HCsR0mnMA#|Fu5#Txx&+%i9z(Fw3y2qz0?NgZ5#L_3Y))sbi7PJrcjbbtLq@Y%`xgpvb`pMMPcv1lI0 z!yo>0+Gpq`OkR0r;pes-e!p3n{Dpm5IX%}r0+tES<=xx({HMyg#QgU*@+(Z{U#n=2 zyxgJx;@Bed=%vNREid|xB{br-GFlJOAu#I>XAjNLZuc zO@k4`?+ZC^|1MfL+m1u{Ud_rY|BQ=SMGif@$NBxo&jWw<>D8Pb#cXAl^xS@n zvlcEa&U4b7r8Zn!Bb+0t^<*LA2Ihu`zR{(#gjQZ`-*EJS$C3rV-*GGq)Ckzv$K06o z%wkT1-FN$A)1TZEDJpn1*J`c=o2Q4*HaA@tQA49wMF);t$$6LyZlG z(j#U>_I7E#@?ksFc|?Pkbq=e*B_541m4!y9zIr@6tCPud%4xEo$ack9vI@*{qSO0N z%WPSuP&0Y1r3Bw9ryV^#ibaQyGU#f5P+)iNuvK4>WE65wYD?p$Ou@w^nT$;yH?})} zDxbSbZU^7G{>NYEcm4jf5fro_X3F^3iI&%=V_p z70i1pwmW7%OWCDdk`@0ovd5MqvvS>WL4~#gy)*YWxhGFa6s^1!&)Ctt^Kf^{xy&_A z?UphYGM4T_Yc-Fwd3?;CuFLr6TQjG*u1Abv{*3*h{lUJ6xO3*VJUPxV!MS|F6m9iX z&R;oK51-!Uv!3;PM{fGO-h-Yid4-SNDQBE=a^j}K30G!av*j+@v*e*}eVscCZ&=FH zM4>vX?8_T3o0y*KO)hdVbi1g|Hl54!z=gyuHL?$)6>ggIEz!3*9&)BK#c$5@58Fj9 z%{nQ#MPVnK+J%3wZ)@I5OR)8l*<&8|S-J0l7E9x_v&+iwc3({U=x}ABKx1KM%=R1+ z`)wizgmYQsCo{5qcCDS47&IkFEG#K0w^v!j>2K$OzX>bKBpiFyCKkff^0FmZ}Yhx-PpAcguKPa}qfGdU+HwhCV5*rIIH{viFR zu=<;>Ic-vHUmng?m~-KpT#{1R5l0PMmzDC2^(^Kx0teqZY6=I*d~lGf((Vx9c360? z_5Ut*;{*2vjQu8Ge?29K^RW}(CFk>r>mDWVn!|E&ulKc!f+k_ll{lNcloS=VvMk^* zjN(0zC$R5>)t7*o`_#DaGP#A%`7u3GG(2qb*C&iSO9fAOD6_m|JyUUij@YA5_ljMa zTvfsx9a>zbU1HuF9}-Zg7hsagSL&SNRK(G-=c}6IB$3T2RmJQ(EH23lGI}#R@(3yF zI<R$rrYLAHlQ430X$cKha#R-jTx^|c<&?FI zYt|y=#AE@LZlMWI3GPg_@`7D~o=cf0UhkY#)*bX^Qj7fhcQd3TRsQuwxwJ4ok@I)v zz1DB3)n1g6Fh#!YfQhKG*M&Qu@9tA-+|$s#MyWwgl`qCttYwRE;Fe;B&yMdVyKi>)Urp@FupWXW=NZQ4g$zktavjX=CyZbAT+o|h5>}pJB zxho`NBl;%!^<#m2_ckAX`ET;2MYu);zaUk-2kMffEPc3;KTXr>^ zSQYX7Voj6W%Zd5{6|;A*n|IUm>dD>yCwk@Dy~R$fo9dY&HHobM~n~e?26t2!mbIRPP-=w^nccYE6+S3g!Su8cLxfW~}S;3pR z%urE8>Gh5aeJA&bA9tJ?xXy2$v-*KawQ@|Crfgw9tR|}c(c$qso5nib*==3<6JES% zwk|#s#iJ;3;l?2zW3I%RfqgwcR7I`U3B^wdY4c#?pTsM>ki~>|$}6rU-?-NJl>Mfi z`e!*^(lk|;JGt;0b=AIPJzSA#bzJa@x>S#a4c`K-6^oiWRq|WjJTRQZ+I;Tcyj|x{ z$;pa^rOvWFzkjWn)t9rDx#!oP$n}b!q_foP=wFv_Mc)t4y(%cX=kuh!9l{41O6T5L z%Ic`KX2YK-rk)i_zW2N)2Ww2^5OTb7puxdIE$RN#X$);1l@G5oFh5Z7Y*Atk;M>@I zt}eZ6dBXtmf#z3kDgu{xUtg2H z=jEIG7fVZflHNrM-DnbGRuRw3xPC>t@B38cmr_E%8k>?h|LuRv-F_~2{nanie{dLG z7pnU0wtf=NGS}o65jq+c#M=Iy% zrCq*rc5PmLsKmx1GHT_qP_e3+_Z?GDZa(zrw2H|SjoDGxpWeTr)SfBytjzktL8+HN zj0N7%e;SOJq&I&)YgDwNw(i{tkCygC?=Mj^SQiAUL@ICb-J8%=6DU-+u;^TGRsPSH zN)y;!t~6bAow_M-$&cs$Z5F-?Ey`!nT6_QiLWfl4J(ylaD3yC zPaf~Yb6PyyE0SAet_YsAe&@l`D$=<^mO1kL=JaR%PniUaC9ve zHsMdlGdJtRF~z#5@9<%^OyD}1u*Y$t$`0>|Y;t0)mU0{TbL!(HzEtgX<-D_~WX;^| zUSWw3OUr^gJA30UKRAA@|3FR9yxZTO{5Zel?77mi;NjO{IdMf;@BWZ2y>`|&X` zJHkZ1G=6sW`90r0>|)!YCm>)*t}jX{k}!_pJrCvKACe0#tj;NJ;wr4F7wTHn|x`ObZUqDY{iBX@7Xf^xkB9XnID{S z^-=hdk>j~}d30O&xCgv zm{>^Wvuku{WKEbkLrZCuwsGDTBf&MA%M^`xCba0hOq)KR?diQcOive_>}EgWWVJD~ zljqhK>%GB_7w)R{=`(ChymaN1iA150&}A+`#b<76yc|nnSI={tm}t~g@wa5@*-ML3 z9L$m?Ojfy)5|NN8Y7r!~z*F&x!x4=cQhz3IQqI5SxFlZTXM2L@Ohbl_DJc;r!X7Dn zT)1U&$Yibjt6vNerQ>Sw>> zR$KIP#_E}_oT4Wxh2LMRUCH<$ep&bQw<{R$i?DJXS@n(a64Rtr3b$|l+~&E{x#;Nv zX2%jSbz;W}S$w*1O)DT&lX%kN1Mos=v3dE1hjzM{69*SV z%{{K2KYCf^`n?4_I?p=<%|ABnxUxbQ%h`(M_s$-)?2}Q*P;&qE&^K%A;tZSL|77d- zP03wcyRnKVZr;)99L=%C>`li6RTuF@*rrdouwPUEk%Yy9NqzI)P2D{C=*-O~QqK;) zNjT|mBG-N^ki{i%(d7>d+BY;tH26F@e3Ri<_Z>NwvJlS?ixMu_lmxVV;@`eu`vn!t z&B0Tyw5+(~xapC@BLVKnh^k!^UVlHOfAqxsf*)FE5~_A*9(gSIeuB=&vW55cWMeEMp+fKD9&N{;`vRNXTx&c)h(TO+d}M`8KyS1DRs7f zXt|LUeoxAm_3@*s#{mYu>G#x<5L&UeoJyeD3G{|ZOG z>z(zhq_!{fJzyriMenhc_~UDHy`BlkO|)1cb%ON)`yB2|%d9Ug|1_23%XW*Kd7SFq z9G%xL9m$^MsyAh?pFY@j;JAZj&Baakwy!(0bM-FOYhO(~93H1Eo|~9I>v~M~`=3$A z$}(PNElRQSJGI5qPRwdqeyq4*y=9;-kBOR<&N4HP*U2ef{Vj$qSEpM~7Jqfda?|}) zw@Ljc0ly_$LZm}oR9th`OTJX4C=hU;u+p^aRiNspySaM`U2hZqN>y3L5GFy3W zm-5tIZho1UUac3LE$x4JhIrZ372lruz5ApPZe5j@Ej>L?G<(LrIgi`(3@a3;$eVF{ zL{Bpi2;ePyW)>H6Zj$GR`rwYn^FS01) z%qZKjD@1SNr6b%6Yp)zE+VpCzMcZiu=M9nks~+tP6Wz8rusR||H_kM(!&NQB#W+vs z&7@Qj-#|y7i;f)b`8G9ke($|~QO0b=U7_vU5+}6HP|{yI$5%S`{`7fdv&%cRGj_2zyHA^c-yD7G#Rav`%hK|2OVf(pc$?EUc=e2bOo=m>fxLvg? z+qHAa#;IbxkG{;h81R_srP}#hJ!`v7FXc{h(LeSn%UHlDXr*b@v@X6BzbeHInY@|DZY<|%B=`lu|} z`|#78T?;w`&T-@a{nuk!y7>C*}$iypx!1eNf4^OPX6i*Y}^#`PF<6c(+}S z$~f9`B5${~hsS>b*LOlJ$uFm}U99^jGSAuMqR%V84NvU4%se@zpI)r_lJO`|$SsdO z&dvCiO5t3Q3A>J$T-%ad@S@Ra5!>X0*JD>pslGOM-FSD?tTlepSuQsZc^SW5a&@If zc2ne5QQOKnRYjIXlYGs;rTn@lHS^nQi=F3!xegaLB}yIJ_B51hPN-=^(wsxf8Lq2L z;#9HfX%{;7<&l7S!%kuGA{FnAzP$>OH$)c%9@3oAAp39SCzeNP@@tlER;sID->!GM z?6B&oc2+i*rsVJX$&H&gU5R=A@PI*lUWwY|eNQ`=^BMSW(rse>>L9%0=H=5ny*o@9 zQ%alWUSx_5VYq&L?t_`>YI0|+pF9fmVo{HfkUlV5Q;#!CMPW*`Wt)NFTD{z~V&&|) z)2nxJG)sgF^F@1{U`sykdMF|3_>QTTnVSu7v&^<&xh1yNd~>3!THx`v6BpMt$V@eG z-r~Ia0^@a&P*>;7ZLh?`oZXj9m78+@HP6LA(p+2Y?^agyfBVjM?d_KK%U9a>m9myh zJblWJFFUYxUTWi%n3PKvGaoE_zRK79UjB{hQgKeZGz*U}Z(rFmApS92G8>4&YH=J|K?*;2EG7fX!(r5=5y zA)vzI_w96tgR-&;2ctsmJk~!R2Mm8zWjXcTnfUfw?h$_xwjI}AuGY2cmRxn8`?Qwz z7r$^p^UA57Prn|~-gL@2a;?C&+Sl7Yc`WOQ?YJ0n^i1T$SB-`e@iX`?W%4f*w$9=8 zNSGZbmr~m#-MVh8^5mdbs@zw+@=8@aE~Gfh9*^r=@_iR`Kw(jz)ijO+*NuFCSyUI4 zNghr=UbJnEX+Veycj~dZ>220~+NS3{S6GzA6|hSDxZ^>$l^UJb^sXPXVK@@J*J_@w zSbwD3(KkWA4^FZB({3T}RKoC4w38zwiT&9zqm3P%W_v_j_I#NZ&MmS^W*yJ2fR6@k zEuY!gbB}fGzTnd6a>bLO`oml4c86)3I4h2P`20oiexX$D4pBu<7fp#kfphZ}PkjyJ z7O*a3_nG)+RZn6Ft3!dZM5i%>vVfsRw8-0VzBd65$A3)bKiqmC+GJj(7n66Jl1+w> zmjTuQ&09IBeP<*bF~W^rbnn=9@ZY9?{6km+X;JD#`0R5kdB^ZORd zBjp`z7OVMBJ=wvs==?g_j<3(HRat(!O7R}#F6Pp*a(SZul!q^2$KJHkyP=J1)AHOS zc@BHFz2u);vbjU2l-G+Z%wbjBq*vNZyVtzfsUUCY+Q~PkN3mC}plr!m_F38Pr9m!} z4y3O*rlZLAu$w=ZMfXb4lKJa`m2%pd^e!=;DQt}AJLSiCM?`(&y-SJ0UEAdX5_MyK zy?vV&5PH4Clv9GC^273*?qVlz8g>RvQdG}cUsNYApLSWw+P|SlZcS+Qktdv5M;3Tg z2(W2A+F@j|@Vv8R&F>~&5bJm-hb{iXTJ_{CGEw;6T@ z2|F(5$n<&|UOH|$#kT$N&)Or^%pd1lNuF5v{M}5s`eoNX+B^1%>*+pZ-{&P8#r;_G z&@;iyMxVl>?=1XSzW?&HrEd*qPyQ7;ZTrmc$!uzWUU#qgbTe5x$5cX~RZ?w7!_1@1 zqGlq!9PN$gI`XuC>^0^{yRB?^IXYa4xy-6-lg)-U9~UE?wM-(jMYsw~wAFij1-DKX zIw~%)9H%tV+)$D;b~sd1G6`8Nt%sdTo4jY;Vo>&FwL)HqH-NZ&{R7 zykh#%wNo<|=_>RT#@*h0^{Wx5U(}MT9eJUFe$FZRhsx789XCu?lh_z@^sAdix}?!w zyENXDFZGl2%FnKf&-M}Xm3pdqyX)44ypm}am&(j`@AlmL+vn!yu<5E>RxCRbb9T;h z9)qpAE;C-}B%Nn^tf!{6vv7W#?3K$D|@(Q1m;Zql$dz(obaL# z0q3U(Tx#{&UK{XJ?WUx-(6z*+zFQ?sb(T8MIl`s4;KjR0!I&pEj~&xb%?RzdB(Z5z zOY`)WE4n+Yi$2##-1}9o_I2CUJvt$cZVzUjV9~qPdEm|An`^sj#9m(KWxE#gT~vDC z$t{gP1)fdava^QizCnKV{zwVAH=mET@7)@CBkt^sEXgBPEeUy9pPqBf6yZ8`tJQ}8 zM98i4HSfMYqqiZ&6sE?ZMEgY znRUA_zM2)a!=@_5&DgK?!q>WOH+fSN=jx=}gt$J6Df2LQo-ohgqiD(z5%1z|Nwo*P z8xs6B&+(b5^Cm@qmES>|JEjxUCPXegY}wqg^;SS*>d?)S1=V^i^_q8x4 zAH$5kImK)9nOm+c$~((g0|w1GG^l~G5Z!|8znC0W8Ri|!u)g~ z@07z^c3eMT9pN`2VZ-BO@tdF9JscSqTip$uojZHC&`qX>HeM!)w4FP4%Y?6JTX|(c zY(5u9cEhgO%+d{GUxs5u!U0ug+4NTO!imetLdmtoYJOV z(Qf&jWE$J89uPba@$PlQz$U8hxfh=JdkVHHiwW-3&&T*?+Ra> zR!Ay7Z*VnYEMkrIp3vW8Ul(e(!g1+$hdoYeUUTQ|dc(0{v(AhI2hJ2EDsMLQF%Fw_ zYH@=7kr$c=eI@?H`1rZx{!o6z;b8k=z4^))T4DKbxr{`V7k6(kl5{Vgt@*Y`X5t|i zR`ZUk+BEl$DbF1@CO%ke=P{#^NoCP21;@%zMO%5TEWIs!%c_eWO_&;`>G1wYaoTbA z{-|DVPrd3L(n1z1`ou)p!}8ufZP#;`GRiheJnR}`>FU;8rDSMgW@fg<&2-fyD{+g* z`Q{Rj3oe|vw|#AgvD-D!UrAPe~$5f#J4LJkm35pJD9HzK5Is{DVe#LB@C3X3YowLIZzXh)~174jy zXyxY6mZ}`!w3taWuxC>}vwo{ggZ{%0JaMt%vveh&&WMliEsooJVvC4%(^-xayLWzn z|5ZGI{n6!p9^a3t_-91gca_RGg&s&>#!#dx&nI&I*Z=f?{h$4>|9}6t z|J(lS|MP$6T>spD%}Z&j<*Mby-14_CKK$KRcXDR>Q-jy1C3fiNysnV+zxil&gaG4I zPA3!2cL{bEn(uvFaKZBDgS?2SC?OHm3eB&{PF1eLJmTz6w$Jt8;8qaxISynjXN}6)Pj;)uDWV6Lw+jXV6N|JM@lc2uVbsx!$2esc4 z&ZnIJyua#1t-9`GPT7Y(%8X|$XSzMwWU#BWm4BusdxDH~RY`%-tcWd&4|OHh2h7>c z8ry%iLz?&C`^NRYxhth6PEh0!Ht>sLnaySOF!o@H?wwb!H@@SO_SN^kR2ac{`C&u# z4#VuP2OKtSbklI3D{T5J?}o_n5B5{O_Pw{ctmDE^s{V!D@luV!MuoDo4<_u8{5$oR z|Mz=&6AB+W%5k2bB=lN5BfV7ToOh3r_YUDKcBW!Y^@-wh{!ZYX(0oek0LQN*7c@^a zF$A>rWqQA6K5*#lZzh|0Dj}06FJYVz@F?)D_@=;)4kf=9A&LLf*}WIEH47gtS;Dl7i+X4;$6{$CWdaxfe`1ZGMw^HW4;^T7_RKGKFsg;EtI=qrC@?BT(tTmjk7(d=f z)43nwamDNFg+ej=1vePJZggm2)$RBr)Ouy!Pj{!zW1iRhd@YYznOf9H_N@u(QLbV! zkvEhuVdTE>(|P3{nZ=P3i;n)eV0`Rn53jMtgIjZt=-N2gB|P4u6||4XP;%0LwPgES zht)VHd^_A|{yzDv6Z^ACitcw6-s>BDE>Vvsuj{=8!$E0 zwW_qTtRk^-&Z|NTU*_FArZ_B{#i{5Qu~Tqr;zP8l9wmDj1XxrV|F;zi$AAB}sZiYck)m=Sb4FjEyM#k$>Lj;^2ETbM zXLTI@w1E8_^NlHrOzh8?ckeiGVJ7E&N9Uy0BbLs`iY4qjYGoz5etq=c%im+OZ>!z( zx7#%=0{eta*o87StgLE3H+|B(o@AlMNoR_fPHq-D%*fTHc;?KcfK!S~*07}}2B!E= zXgG2}H_PtjCV@+3iU$J)!=o?BJz&oYsJm0@@JZ!h=`VPo^u4yhtBdBc~+ z`_hbSL&F#Lubja@;rHJ9xOwgq%s+nrvDJFQqauyc)WBfxiD@!2*F7tlB!6bC+;9 zOY+T~#bEVRPT{Mcz+Yo;0Y?V$j+%)tJUnb3O?NzXZV~SxrkUTI1Uy>QBce19=t=L{ zk;kFtRhS`LFoB;<)z#u4`y93#g=L-7nJ*~1R{ctw8~W|^c@qtm3vVPCq8jVYbQM^> z$*xSwx8nU8KZ8|hise6n+p*5`J_)zlB&emt$+l=H3SEf2?3C@WaoZmGTa|tJnvXA< z{*Sz}>@Mpq8Q%4lGUuOPjnS!nts(V-~*}uXuf( zuttFE$SSrQO>#mCYnODWIh4zY{9KUwuk-!aluCwQyVGCae10mX@W;-CBM;w9yR?XZ zOVgK^3AenqTKu{bx^c&ttt9zaWb#kc33mp;E~g2x9dwynWxEfu}P|yt$i{l@s5ky;tgr1 zwuCL1&%E-LqT%O+jNF4#w`FTSwWz55llv1|XuV?FiO3gb ztGpi^Vz~WMnmK3blq-uw0yRC4EU?xW(`%gdAbv}T_1;3Mh<%%CR`;*mepf_~D_yqv z%R#=+>%;y|EzZpT%v8g{@Q+DD^PJ}2GcMYm*Pk%_IJuNzso%cEzZR`v`6zO!-DTE- zDIHe=TU=_Gmy{jupS>~gnqA@2hNFKAY?dfA7D=a8)K;+X$-lK!Go+KxQH5*qJ+qoM zHO`I>ZO5!LWepg%b};{Xq^QKTta-&fK1RFbcCO75?E84Std=%RXprasS^wkz@_&(! z>;Kz-{y*)l|G%AzlLEE~Yl;{(K56vfR0`0H3RMzv(#YWcTzCET|4qMdJ$m}BK2o*1 z?*Ecc!fy-?a~krWs^;atw?Xdl)g|nQ#a!%pm_Hsb56?;x?{(NRMPzMO&NlDaA8hV3 z{+pv;(0%@~^w-WS-k-&Gh #include #include +#include +#include -extern void __abort(void) __dead2; - -void -__attribute__ ((noreturn)) -__chk_fail (void) -{ - const char message[] = "[%d] detected buffer overflow"; - - syslog(LOG_CRIT, message, getpid()); - - __abort(); -} diff --git a/src/libc/secure/memcpy_chk.c b/src/libc/secure/memcpy_chk.c index 6f2e06ba6..fcc562221 100644 --- a/src/libc/secure/memcpy_chk.c +++ b/src/libc/secure/memcpy_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,14 +23,19 @@ #include #include - -extern void __chk_fail (void) __attribute__((__noreturn__)); +#include "secure.h" void * __memcpy_chk (void *dest, const void *src, size_t len, size_t dstlen) { if (__builtin_expect (dstlen < len, 0)) - __chk_fail (); + __chk_fail_overflow (); + + /* On OS X, memcpy has supported overlapping buffers for many years. + * While technically, this will catch buggy code, we should not abort. + * if (__builtin_expect (__chk_assert_no_overlap != 0, 1)) + * __chk_overlap(dest, len, src, len); + */ return memcpy (dest, src, len); } diff --git a/src/libc/secure/memmove_chk.c b/src/libc/secure/memmove_chk.c index 60ede5ad6..a2ebdb20e 100644 --- a/src/libc/secure/memmove_chk.c +++ b/src/libc/secure/memmove_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,14 +23,13 @@ #include #include - -extern void __chk_fail (void) __attribute__((__noreturn__)); +#include "secure.h" void * __memmove_chk (void *dest, const void *src, size_t len, size_t dstlen) { if (__builtin_expect (dstlen < len, 0)) - __chk_fail (); + __chk_fail_overflow (); return memmove (dest, src, len); } diff --git a/src/libc/secure/memset_chk.c b/src/libc/secure/memset_chk.c index ed4b2edf8..364f3a07b 100644 --- a/src/libc/secure/memset_chk.c +++ b/src/libc/secure/memset_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,14 +23,13 @@ #include #include - -extern void __chk_fail (void) __attribute__((__noreturn__)); +#include "secure.h" void * __memset_chk (void *dest, int val, size_t len, size_t dstlen) { if (__builtin_expect (dstlen < len, 0)) - __chk_fail (); + __chk_fail_overflow (); return memset (dest, val, len); } diff --git a/src/libc/secure/secure.c b/src/libc/secure/secure.c deleted file mode 100644 index a88f524e0..000000000 --- a/src/libc/secure/secure.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "secure.h" -#include -#include -#include -#include -#include - -extern void __abort(void) __dead2; -extern void __chk_fail (void) __attribute__((__noreturn__)); - -void __chk_fail_overflow (void) __attribute__((__noreturn__)) -{ - __chk_fail(); -} - -void __chk_fail_overlap (void) __attribute__((__noreturn__)) -{ - const char message[] = "[%d] detected illegal buffer overlap"; - - syslog(LOG_CRIT, message, getpid()); - - __abort(); -} - -void __chk_overlap (const void *a, size_t an, const void *b, size_t bn) -{ - if (((uintptr_t)a) <= ((uintptr_t)b)+bn && ((uintptr_t)b) <= ((uintptr_t)a)+an) - __chk_fail_overlap(); -} - diff --git a/src/libc/secure/secure.h b/src/libc/secure/secure.h index 07bafc614..669b3435a 100644 --- a/src/libc/secure/secure.h +++ b/src/libc/secure/secure.h @@ -34,6 +34,6 @@ extern void __chk_fail_overlap (void) __attribute__((__noreturn__)); extern void __chk_overlap (const void *a, size_t an, const void *b, size_t bn); /* Do we avoid the overlap check for older APIs? */ -extern int __chk_assert_no_overlap; +extern uint32_t __chk_assert_no_overlap; #endif diff --git a/src/libc/secure/snprintf_chk.c b/src/libc/secure/snprintf_chk.c index ef45ead36..3b982b1f3 100644 --- a/src/libc/secure/snprintf_chk.c +++ b/src/libc/secure/snprintf_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -25,24 +25,21 @@ #include #include #include - -extern void __chk_fail (void) __attribute__((__noreturn__)); -extern int __snprintf_chk (char * __restrict, size_t, int, size_t, - const char * __restrict, ...); +#include "secure.h" int -__snprintf_chk (char *s, size_t maxlen, int flags, size_t len, +__snprintf_chk (char *dest, size_t len, int flags, size_t dstlen, const char *format, ...) { va_list arg; int done; - if (__builtin_expect (maxlen > len, 0)) - __chk_fail (); + if (__builtin_expect (dstlen < len, 0)) + __chk_fail_overflow (); va_start (arg, format); - done = vsnprintf (s, maxlen, format, arg); + done = vsnprintf (dest, len, format, arg); va_end (arg); diff --git a/src/libc/secure/sprintf_chk.c b/src/libc/secure/sprintf_chk.c index cf4a95656..f16c83a21 100644 --- a/src/libc/secure/sprintf_chk.c +++ b/src/libc/secure/sprintf_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -25,26 +25,23 @@ #include #include #include - -extern void __chk_fail (void) __attribute__((__noreturn__)); -extern int __sprintf_chk (char * __restrict, int, size_t, - const char * __restrict, ...); +#include "secure.h" int -__sprintf_chk (char *s, int flags, size_t len, const char *format, ...) +__sprintf_chk (char *dest, int flags, size_t dstlen, const char *format, ...) { va_list arg; int done; va_start (arg, format); - if (len > (size_t) INT_MAX) - done = vsprintf (s, format, arg); + if (__builtin_expect (dstlen > (size_t) INT_MAX, 0)) + done = vsprintf (dest, format, arg); else { - done = vsnprintf (s, len, format, arg); - if (done >= 0 && (size_t) done >= len) - __chk_fail (); + done = vsnprintf (dest, dstlen, format, arg); + if (__builtin_expect(done >= 0 && (size_t) done >= dstlen, 0)) + __chk_fail_overflow (); } va_end (arg); diff --git a/src/libc/secure/stpcpy_chk.c b/src/libc/secure/stpcpy_chk.c index d33c7af34..c45272167 100644 --- a/src/libc/secure/stpcpy_chk.c +++ b/src/libc/secure/stpcpy_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,16 +23,19 @@ #include #include +#include "secure.h" -extern void __chk_fail (void) __attribute__((__noreturn__)); - -void * +char * __stpcpy_chk (char *dest, const char *src, size_t dstlen) { - size_t len = strlen (src); + char *retval = stpcpy(dest, src); // Returns a pointer to the \0 + size_t len = retval - dest + 1; if (__builtin_expect (dstlen < len, 0)) - __chk_fail (); + __chk_fail_overflow (); + + if (__builtin_expect (__chk_assert_no_overlap != 0, 1)) + __chk_overlap(dest, len, src, len); - return memcpy (dest, src, len + 1) + len; + return retval; } diff --git a/src/libc/secure/stpncpy_chk.c b/src/libc/secure/stpncpy_chk.c index acbc60018..5ad321f3f 100644 --- a/src/libc/secure/stpncpy_chk.c +++ b/src/libc/secure/stpncpy_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Apple Inc. All rights reserved. + * Copyright (c) 2010-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,15 +23,27 @@ #include #include +#include "secure.h" -extern void __chk_fail (void) __attribute__((__noreturn__)); - -void * +char * __stpncpy_chk (char *restrict dest, char *restrict src, size_t len, size_t dstlen) { + size_t n; + char *retval; + if (__builtin_expect (dstlen < len, 0)) - __chk_fail (); + __chk_fail_overflow (); + + retval = stpncpy (dest, src, len); // Normally returns a pointer to the \0 + n = retval - dest + 1; + + // Check if it's pointing to the location after the buffer after not writing \0 + if (n == len + 1) + n--; + + if (__builtin_expect (__chk_assert_no_overlap != 0, 1)) + __chk_overlap(dest, n, src, n); - return stpncpy (dest, src, len); + return retval; } diff --git a/src/libc/secure/strcat_chk.c b/src/libc/secure/strcat_chk.c index e0ace2b22..7445ab3ba 100644 --- a/src/libc/secure/strcat_chk.c +++ b/src/libc/secure/strcat_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,28 +24,21 @@ #include #include #include - -extern void __chk_fail (void) __attribute__((__noreturn__)); +#include "secure.h" char * -__strcat_chk (char *__restrict s, const char *__restrict append, - size_t slen) +__strcat_chk (char *__restrict dest, const char *__restrict append, + size_t dstlen) { - char *save = s; - - /* Advance to the end. */ - for (; *s; ++s) - if (__builtin_expect (slen-- == 0, 0)) - __chk_fail (); - - do - { - /* Append the string. Make sure we check before writing. */ - if (__builtin_expect (slen-- == 0, 0)) - __chk_fail (); + size_t len1 = strlen(dest); + size_t len2 = strlen(append); - } while (*s++ = *append++); + if (__builtin_expect (dstlen < len1 + len2 + 1, 0)) + __chk_fail_overflow (); - return save; + if (__builtin_expect (__chk_assert_no_overlap != 0, 1)) + __chk_overlap(dest, len1 + len2 + 1, append, len2 + 1); + memcpy(dest + len1, append, len2 + 1); + return dest; } diff --git a/src/libc/secure/strcpy_chk.c b/src/libc/secure/strcpy_chk.c index dd3df206a..9b15f226a 100644 --- a/src/libc/secure/strcpy_chk.c +++ b/src/libc/secure/strcpy_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,16 +23,19 @@ #include #include +#include "secure.h" -extern void __chk_fail (void) __attribute__((__noreturn__)); - -void * +char * __strcpy_chk (char *restrict dest, char *restrict src, size_t dstlen) { - size_t len = strlen (src); + // stpcpy returns a pointer to the \0 + size_t len = stpcpy(dest, src) - dest + 1; if (__builtin_expect (dstlen < len, 0)) - __chk_fail (); + __chk_fail_overflow (); + + if (__builtin_expect (__chk_assert_no_overlap != 0, 1)) + __chk_overlap(dest, len, src, len); - return memcpy (dest, src, len + 1); + return dest; } diff --git a/src/libc/secure/strlcat_chk.c b/src/libc/secure/strlcat_chk.c index 5eb434ee9..d7174a3fd 100644 --- a/src/libc/secure/strlcat_chk.c +++ b/src/libc/secure/strlcat_chk.c @@ -26,14 +26,15 @@ #include "secure.h" size_t -__strlcat_chk (char *restrict dest, char *restrict src, - size_t len, size_t dstlen) +__strlcat_chk(char *restrict dest, char *restrict src, + size_t len, size_t dstlen) { size_t initial_srclen; size_t initial_dstlen; - if (__builtin_expect (dstlen < len, 0)) + if (__builtin_expect (dstlen < len, 0)) { __chk_fail_overflow (); + } initial_srclen = strlen(src); initial_dstlen = strnlen(dest, len); @@ -45,7 +46,7 @@ __strlcat_chk (char *restrict dest, char *restrict src, __chk_overlap(dest, initial_srclen + initial_dstlen + 1, src, initial_srclen + 1); memcpy(dest+initial_dstlen, src, initial_srclen + 1); } else { - __chk_overlap(dest, initial_srclen + initial_dstlen + 1, src, len - initial_dstlen - 1); + __chk_overlap(dest, len, src, len - initial_dstlen - 1); memcpy(dest+initial_dstlen, src, len - initial_dstlen - 1); dest[len-1] = '\0'; } diff --git a/src/libc/secure/strncat_chk.c b/src/libc/secure/strncat_chk.c index fb0cff51b..184023cf3 100644 --- a/src/libc/secure/strncat_chk.c +++ b/src/libc/secure/strncat_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,36 +23,24 @@ #include #include - -extern void __chk_fail (void) __attribute__((__noreturn__)); +#include "secure.h" char * -__strncat_chk (char *restrict dest, const char *restrict src, - size_t len, size_t dstlen) +__strncat_chk (char *restrict dest, const char *restrict append, + size_t len, size_t dstlen) { - char *s1 = dest; - const char *s2 = src; + size_t len1 = strlen(dest); + size_t len2 = strnlen(append, len); - /* Advance to the end. */ - while (*s1 != 0) - { - if (__builtin_expect (dstlen-- == 0, 0)) - __chk_fail (); - s1++; - } + if (__builtin_expect (dstlen < len1 + len2 + 1, 0)) + __chk_fail_overflow (); - /* Append the string. */ - while (len > 0) - { - if (__builtin_expect (dstlen-- == 0, 0)) - __chk_fail (); - if ((*s1 = *s2++) == 0) - break; - s1++; - len--; - } - *s1 = 0; + if (__builtin_expect (__chk_assert_no_overlap != 0, 1)) + __chk_overlap(dest, len1 + len2 + 1, append, len2 + 1); - return dest; + /* memmove() all but the NUL, since it might not actually be NUL */ + memcpy(dest + len1, append, len2); + dest[len1 + len2] = '\0'; + return dest; } diff --git a/src/libc/secure/strncpy_chk.c b/src/libc/secure/strncpy_chk.c index df4420d1e..e8f70053d 100644 --- a/src/libc/secure/strncpy_chk.c +++ b/src/libc/secure/strncpy_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,15 +23,26 @@ #include #include +#include "secure.h" -extern void __chk_fail (void) __attribute__((__noreturn__)); - -void * +char * __strncpy_chk (char *restrict dest, char *restrict src, size_t len, size_t dstlen) { + size_t n; + if (__builtin_expect (dstlen < len, 0)) - __chk_fail (); + __chk_fail_overflow (); + + // stpncpy normally returns a pointer to the \0 + n = stpncpy (dest, src, len) - dest + 1; + + // Check if it's pointing to the location after the buffer after not writing \0 + if (n == len + 1) + n--; + + if (__builtin_expect (__chk_assert_no_overlap != 0, 1)) + __chk_overlap(dest, n, src, n); - return strncpy (dest, src, len); + return dest; } diff --git a/src/libc/secure/vsnprintf_chk.c b/src/libc/secure/vsnprintf_chk.c index f9e67408b..02a0e11ee 100644 --- a/src/libc/secure/vsnprintf_chk.c +++ b/src/libc/secure/vsnprintf_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -25,21 +25,18 @@ #include #include #include - -extern void __chk_fail (void) __attribute__((__noreturn__)); -extern int __vsnprintf_chk (char * __restrict, size_t, int, size_t, - const char * __restrict, va_list arg); +#include "secure.h" int -__vsnprintf_chk (char *s, size_t maxlen, int flags, size_t len, +__vsnprintf_chk (char *dest, size_t len, int flags, size_t dstlen, const char *format, va_list arg) { int done; - if (maxlen > len) - __chk_fail (); + if (__builtin_expect (dstlen < len, 0)) + __chk_fail_overflow (); - done = vsnprintf (s, maxlen, format, arg); + done = vsnprintf (dest, len, format, arg); return done; } diff --git a/src/libc/secure/vsprintf_chk.c b/src/libc/secure/vsprintf_chk.c index a2ca79b11..9d321d426 100644 --- a/src/libc/secure/vsprintf_chk.c +++ b/src/libc/secure/vsprintf_chk.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2007-2013 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -25,24 +25,21 @@ #include #include #include - -extern void __chk_fail (void) __attribute__((__noreturn__)); -extern int __vsprintf_chk (char * __restrict, int, size_t, - const char * __restrict, va_list arg); +#include "secure.h" int -__vsprintf_chk (char *s, int flags, size_t len, const char *format, +__vsprintf_chk (char *dest, int flags, size_t dstlen, const char *format, va_list arg) { int done; - if (len > (size_t) INT_MAX) - done = vsprintf (s, format, arg); + if (__builtin_expect (dstlen > (size_t) INT_MAX, 0)) + done = vsprintf (dest, format, arg); else { - done = vsnprintf (s, len, format, arg); - if (done >= 0 && (size_t) done >= len) - __chk_fail (); + done = vsnprintf (dest, dstlen, format, arg); + if (__builtin_expect (done >= 0 && (size_t) done >= dstlen, 0)) + __chk_fail_overflow (); } return done; diff --git a/src/libc/stdio/CMakeLists.txt b/src/libc/stdio/CMakeLists.txt index 0633f702b..081298e98 100644 --- a/src/libc/stdio/CMakeLists.txt +++ b/src/libc/stdio/CMakeLists.txt @@ -7,8 +7,13 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsd include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../gdtoa/FreeBSD") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../gdtoa") +include_directories("${CMAKE_CURRENT_SOURCE_DIR}/FreeBSD") set(stdio_sources + xprintf_all_in_one.c + xprintf_comp.c + xprintf_domain.c + xprintf_exec.c FreeBSD/asprintf.c FreeBSD/clrerr.c FreeBSD/dprintf.c diff --git a/src/libc/stdio/FreeBSD/_flock_stub.c b/src/libc/stdio/FreeBSD/_flock_stub.c index 07e02fd44..a556da385 100644 --- a/src/libc/stdio/FreeBSD/_flock_stub.c +++ b/src/libc/stdio/FreeBSD/_flock_stub.c @@ -58,19 +58,7 @@ __weak_reference(_funlockfile, funlockfile); void _flockfile(FILE *fp) { - pthread_t curthread = _pthread_self(); - - if (fp->_fl_owner == curthread) - fp->_fl_count++; - else { - /* - * Make sure this mutex is treated as a private - * internal mutex: - */ - _pthread_mutex_lock(&fp->_fl_mutex); - fp->_fl_owner = curthread; - fp->_fl_count = 1; - } + _pthread_mutex_lock(&fp->_fl_mutex); } /* @@ -85,52 +73,16 @@ _flockfile_debug_stub(FILE *fp, char *fname, int lineno) int _ftrylockfile(FILE *fp) { - pthread_t curthread = _pthread_self(); int ret = 0; - if (fp->_fl_owner == curthread) - fp->_fl_count++; - /* - * Make sure this mutex is treated as a private - * internal mutex: - */ - else if (_pthread_mutex_trylock(&fp->_fl_mutex) == 0) { - fp->_fl_owner = curthread; - fp->_fl_count = 1; - } - else + if (_pthread_mutex_trylock(&fp->_fl_mutex) != 0) ret = -1; + return (ret); } void _funlockfile(FILE *fp) { - pthread_t curthread = _pthread_self(); - - /* - * Check if this file is owned by the current thread: - */ - if (fp->_fl_owner == curthread) { - /* - * Check if this thread has locked the FILE - * more than once: - */ - if (fp->_fl_count > 1) - /* - * Decrement the count of the number of - * times the running thread has locked this - * file: - */ - fp->_fl_count--; - else { - /* - * The running thread will release the - * lock now: - */ - fp->_fl_count = 0; - fp->_fl_owner = NULL; - _pthread_mutex_unlock(&fp->_fl_mutex); - } - } + _pthread_mutex_unlock(&fp->_fl_mutex); } diff --git a/src/libc/stdio/FreeBSD/fclose.c b/src/libc/stdio/FreeBSD/fclose.c index 91df68a90..e38bbbf69 100644 --- a/src/libc/stdio/FreeBSD/fclose.c +++ b/src/libc/stdio/FreeBSD/fclose.c @@ -49,8 +49,7 @@ fclose(FILE *fp) { int r; - if (!__sdidinit) - __sinit(); + pthread_once(&__sdidinit, __sinit); if (fp == NULL) { errno = EFAULT; @@ -72,7 +71,7 @@ fclose(FILE *fp) FREELB(fp); fp->_file = -1; fp->_r = fp->_w = 0; /* Mess up if reaccessed. */ - __sfprelease(fp); /* Release this FILE for reuse. */ FUNLOCKFILE(fp); + __sfprelease(fp); /* Release this FILE for reuse. */ return (r); } diff --git a/src/libc/stdio/FreeBSD/fflush.c b/src/libc/stdio/FreeBSD/fflush.c index 5db1a1c61..986682673 100644 --- a/src/libc/stdio/FreeBSD/fflush.c +++ b/src/libc/stdio/FreeBSD/fflush.c @@ -130,11 +130,13 @@ __sflush(FILE *fp) if (t <= 0) { /* 5340694: reset _p and _w on EAGAIN */ if (t < 0 && errno == EAGAIN) { - if (p > fp->_p) /* some was written */ + if (p > fp->_p) { + /* some was written */ memmove(fp->_p, p, n); - fp->_p += n; - if (!(fp->_flags & (__SLBF|__SNBF))) - fp->_w -= n; + fp->_p += n; + if (!(fp->_flags & (__SLBF|__SNBF))) + fp->_w -= n; + } } fp->_flags |= __SERR; return (EOF); diff --git a/src/libc/stdio/FreeBSD/findfp.c b/src/libc/stdio/FreeBSD/findfp.c index 6cade0b42..1f515abd0 100644 --- a/src/libc/stdio/FreeBSD/findfp.c +++ b/src/libc/stdio/FreeBSD/findfp.c @@ -54,7 +54,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/findfp.c,v 1.34 2009/12/05 19:31:38 ed Ex #include "local.h" #include "glue.h" -int __sdidinit; +pthread_once_t __sdidinit; #if !TARGET_OS_EMBEDDED #define NDYNAMIC 10 /* add ten more whenever necessary */ @@ -72,9 +72,8 @@ int __sdidinit; ._write = __swrite, \ ._extra = __sFX + file, \ } -#define __sFXInit {.fl_mutex = PTHREAD_MUTEX_INITIALIZER} /* set counted */ -#define __sFXInit3 {.fl_mutex = PTHREAD_MUTEX_INITIALIZER, .counted = 1} +#define __sFXInit3 {.fl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER, .counted = 1} static int __scounted; /* streams counted against STREAM_MAX */ static int __stream_max; @@ -115,24 +114,16 @@ static struct glue *lastglue = &__sglue; static struct glue * moreglue(int); -static spinlock_t thread_lock = _SPINLOCK_INITIALIZER; -#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock) -#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock) - -#if NOT_YET -#define SET_GLUE_PTR(ptr, val) atomic_set_rel_ptr(&(ptr), (uintptr_t)(val)) -#else -#define SET_GLUE_PTR(ptr, val) ptr = val -#endif +static pthread_mutex_t filelist_lock = PTHREAD_MUTEX_INITIALIZER; +#define FILELIST_LOCK() do { pthread_mutex_lock(&filelist_lock); } while(0) +#define FILELIST_UNLOCK() do { pthread_mutex_unlock(&filelist_lock); } while(0) static struct glue * moreglue(n) int n; { struct glue *g; - static FILE empty; FILE *p; - static struct __sFILEX emptyx = __sFXInit; struct __sFILEX *fx; g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) + @@ -146,9 +137,9 @@ moreglue(n) g->iobs = p; while (--n >= 0) { - *p = empty; + bzero(p, sizeof(*p)); p->_extra = fx; - *p->_extra = emptyx; + INITEXTRA(p); p++, fx++; } return (g); @@ -164,36 +155,38 @@ __sfp(int count) int n; struct glue *g; - if (!__sdidinit) - __sinit(); + pthread_once(&__sdidinit, __sinit); if (count) { if (__scounted >= __stream_max) { - THREAD_UNLOCK(); - errno = EMFILE; - return NULL; + if (__scounted >= (__stream_max = sysconf(_SC_STREAM_MAX))){ + errno = EMFILE; + return NULL; + } } OSAtomicIncrement32(&__scounted); } /* * The list must be locked because a FILE may be updated. */ - THREAD_LOCK(); + FILELIST_LOCK(); for (g = &__sglue; g != NULL; g = g->next) { for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) if (fp->_flags == 0) goto found; } - THREAD_UNLOCK(); /* don't hold lock while malloc()ing. */ + FILELIST_UNLOCK(); /* don't hold lock while malloc()ing. */ if ((g = moreglue(NDYNAMIC)) == NULL) return (NULL); - THREAD_LOCK(); /* reacquire the lock */ - SET_GLUE_PTR(lastglue->next, g); /* atomically append glue to list */ + FILELIST_LOCK(); /* reacquire the lock */ + lastglue->next = g; /* atomically append glue to list */ lastglue = g; /* not atomic; only accessed when locked */ fp = g->iobs; found: fp->_flags = 1; /* reserve this slot; caller sets real flags */ - THREAD_UNLOCK(); + FILELIST_UNLOCK(); + + /* _flags = 1 means the FILE* is in use, and this thread owns the object while it is being initialized */ fp->_p = NULL; /* no current pointer */ fp->_w = 0; /* nothing to read or write */ fp->_r = 0; @@ -222,7 +215,13 @@ __sfprelease(FILE *fp) OSAtomicDecrement32(&__scounted); fp->_counted = 0; } + + pthread_mutex_destroy(&fp->_extra->fl_mutex); + + /* Make sure nobody else is enumerating the list while we clear the "in use" _flags field. */ + FILELIST_LOCK(); fp->_flags = 0; + FILELIST_UNLOCK(); } /* @@ -247,10 +246,10 @@ f_prealloc(void) for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next) /* void */; if ((n > 0) && ((g = moreglue(n)) != NULL)) { - THREAD_LOCK(); - SET_GLUE_PTR(lastglue->next, g); + FILELIST_LOCK(); + lastglue->next = g; lastglue = g; - THREAD_UNLOCK(); + FILELIST_UNLOCK(); } } @@ -274,25 +273,20 @@ _cleanup() void __sinit() { - THREAD_LOCK(); - if (__sdidinit == 0) { #if !TARGET_OS_EMBEDDED - int i; + int i; #endif - /* Make sure we clean up on exit. */ - __cleanup = _cleanup; /* conservative */ - __stream_max = sysconf(_SC_STREAM_MAX); - __scounted = 3; /* std{in,out,err} already exists */ -#if !TARGET_OS_EMBEDDED - /* Set _extra for the usual suspects. */ - for (i = 0; i < FOPEN_MAX - 3; i++) { - usual[i]._extra = &usual_extra[i]; - INITEXTRA(&usual[i]); - } -#endif + /* Make sure we clean up on exit. */ + __cleanup = _cleanup; /* conservative */ + __stream_max = sysconf(_SC_STREAM_MAX); + __scounted = 3; /* std{in,out,err} already exists */ - __sdidinit = 1; +#if !TARGET_OS_EMBEDDED + /* Set _extra for the usual suspects. */ + for (i = 0; i < FOPEN_MAX - 3; i++) { + usual[i]._extra = &usual_extra[i]; + INITEXTRA(&usual[i]); } - THREAD_UNLOCK(); +#endif } diff --git a/src/libc/stdio/FreeBSD/fopen.3 b/src/libc/stdio/FreeBSD/fopen.3 index 3bb0c0f8b..ab304e9b4 100644 --- a/src/libc/stdio/FreeBSD/fopen.3 +++ b/src/libc/stdio/FreeBSD/fopen.3 @@ -140,15 +140,11 @@ Any created files will have mode as modified by the process' umask value (see .Xr umask 2 ) . +.\" C11 §7.21.5.3p7 .Pp -Reads and writes may be intermixed on read/write streams in any order, -and do not require an intermediate seek as in previous versions of -.Em stdio . -This is not portable to other systems, however; -.Tn ANSI C -requires that -a file positioning function intervene between output and input, unless -an input operation encounters end-of-file. +Reads and writes may be intermixed on read/write streams in any order; however, +a file positioning function must be called when switching between output and +input, unless an input operation encounters end-of-file. .Pp The .Fn fdopen diff --git a/src/libc/stdio/FreeBSD/fread.c b/src/libc/stdio/FreeBSD/fread.c index 544d94a77..b02257b8b 100644 --- a/src/libc/stdio/FreeBSD/fread.c +++ b/src/libc/stdio/FreeBSD/fread.c @@ -58,23 +58,22 @@ fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) return (ret); } -size_t -__fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) +/* + * The maximum amount to read to avoid integer overflow. INT_MAX is odd, + * so it make sense to make it even. We subtract (BUFSIZ - 1) to get a + * whole number of BUFSIZ chunks. + */ +#define MAXREAD (INT_MAX - (BUFSIZ - 1)) + +/* __fread0: int sized, with size = 1 */ +static inline int +__fread0(void * __restrict buf, int count, FILE * __restrict fp) { - size_t resid; + int resid; char *p; int r, ret; - size_t total; - /* - * ANSI and SUSv2 require a return value of 0 if size or count are 0. - */ - if ((resid = count * size) == 0) - return (0); - ORIENT(fp, -1); - if (fp->_r < 0) - fp->_r = 0; - total = resid; + resid = count; p = buf; /* first deal with anything left in buffer, plus any ungetc buffers */ while (resid > (r = fp->_r)) { @@ -87,7 +86,7 @@ __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) break; else if (ret) { /* no more input: return partial result */ - return ((total - resid) / size); + return (count - resid); } } /* @@ -101,7 +100,7 @@ __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) size_t n; save = fp->_bf; - fp->_bf._base = p; + fp->_bf._base = (unsigned char *)p; fp->_bf._size = resid; while (fp->_bf._size > 0) { if ((ret = __srefill1(fp)) != 0) { @@ -110,7 +109,7 @@ __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) fp->_bf = save; fp->_p = fp->_bf._base; /* fp->_r = 0; already set in __srefill1 */ - return ((total - resid) / size); + return (count - resid); } fp->_bf._base += fp->_r; fp->_bf._size -= fp->_r; @@ -130,7 +129,7 @@ __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) resid -= r; if (__srefill1(fp)) { /* no more input: return partial result */ - return ((total - resid) / size); + return (count - resid); } } (void)memcpy((void *)p, (void *)fp->_p, resid); @@ -139,3 +138,29 @@ __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) } return (count); } + +size_t +__fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) +{ + size_t resid; + int r, ret; + size_t total; + + /* + * ANSI and SUSv2 require a return value of 0 if size or count are 0. + */ + if ((resid = count * size) == 0) + return (0); + ORIENT(fp, -1); + if (fp->_r < 0) + fp->_r = 0; + + for (total = resid; resid > 0; buf += r, resid -= r) { + r = resid > INT_MAX ? MAXREAD : (int)resid; + if ((ret = __fread0(buf, r, fp)) != r) { + count = (total - resid + ret) / size; + break; + } + } + return (count); +} diff --git a/src/libc/stdio/FreeBSD/freopen.c b/src/libc/stdio/FreeBSD/freopen.c index 3451106f9..b4013040f 100644 --- a/src/libc/stdio/FreeBSD/freopen.c +++ b/src/libc/stdio/FreeBSD/freopen.c @@ -70,11 +70,10 @@ freopen(file, mode, fp) return (NULL); } + pthread_once(&__sdidinit, __sinit); + FLOCKFILE(fp); - if (!__sdidinit) - __sinit(); - /* * If the filename is a NULL pointer, the caller is asking us to * re-open the same file with a different mode. We allow this only @@ -195,8 +194,8 @@ finish: memset(&fp->_mbstate, 0, sizeof(mbstate_t)); if (f < 0) { /* did not get it after all */ - __sfprelease(fp); /* set it free */ FUNLOCKFILE(fp); + __sfprelease(fp); /* set it free */ errno = sverrno; /* restore in case _close clobbered */ return (NULL); } @@ -221,8 +220,8 @@ finish: * open. */ if (f > SHRT_MAX) { - __sfprelease(fp); /* set it free */ FUNLOCKFILE(fp); + __sfprelease(fp); /* set it free */ errno = EMFILE; return (NULL); } diff --git a/src/libc/stdio/FreeBSD/fseek.c b/src/libc/stdio/FreeBSD/fseek.c index 24c424e52..9f45c9b35 100644 --- a/src/libc/stdio/FreeBSD/fseek.c +++ b/src/libc/stdio/FreeBSD/fseek.c @@ -60,8 +60,7 @@ fseek(fp, offset, whence) int serrno = errno; /* make sure stdio is set up */ - if (!__sdidinit) - __sinit(); + pthread_once(&__sdidinit, __sinit); FLOCKFILE(fp); ret = _fseeko(fp, (off_t)offset, whence, 1); @@ -81,8 +80,7 @@ fseeko(fp, offset, whence) int serrno = errno; /* make sure stdio is set up */ - if (!__sdidinit) - __sinit(); + pthread_once(&__sdidinit, __sinit); FLOCKFILE(fp); ret = _fseeko(fp, offset, whence, 0); diff --git a/src/libc/stdio/FreeBSD/fwrite.c b/src/libc/stdio/FreeBSD/fwrite.c index b1910c19b..09eae8374 100644 --- a/src/libc/stdio/FreeBSD/fwrite.c +++ b/src/libc/stdio/FreeBSD/fwrite.c @@ -43,6 +43,13 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/fwrite.c,v 1.13 2009/07/12 13:09:43 ed Ex #include "fvwrite.h" #include "libc_private.h" +/* + * The maximum amount to write to avoid integer overflow (especially for + * uio_resid in struct __suio). INT_MAX is odd, so it make sense to make it + * even. We subtract (BUFSIZ - 1) to get a whole number of BUFSIZ chunks. + */ +#define MAXWRITE (INT_MAX - (BUFSIZ - 1)) + /* * Write `count' objects (each size `size') from memory to the given file. * Return the number of whole objects written. @@ -53,9 +60,10 @@ fwrite(buf, size, count, fp) size_t size, count; FILE * __restrict fp; { - size_t n; + size_t n, resid; struct __suio uio; struct __siov iov; + int s; /* * ANSI and SUSv2 require a return value of 0 if size or count are 0. @@ -65,20 +73,27 @@ fwrite(buf, size, count, fp) if (n == 0) return (0); #endif - iov.iov_base = (void *)buf; - uio.uio_resid = iov.iov_len = n; uio.uio_iov = &iov; uio.uio_iovcnt = 1; FLOCKFILE(fp); ORIENT(fp, -1); - /* - * The usual case is success (__sfvwrite returns 0); - * skip the divide if this happens, since divides are - * generally slow and since this occurs whenever size==0. - */ - if (__sfvwrite(fp, &uio) != 0) - count = (n - uio.uio_resid) / size; + + for (resid = n; resid > 0; buf += s, resid -= s) { + s = resid > INT_MAX ? MAXWRITE : (int)resid; + iov.iov_base = (void *)buf; + uio.uio_resid = iov.iov_len = s; + + /* + * The usual case is success (__sfvwrite returns 0); + * skip the divide if this happens, since divides are + * generally slow and since this occurs whenever size==0. + */ + if (__sfvwrite(fp, &uio) != 0) { + count = (n - resid + s - uio.uio_resid) / size; + break; + } + } FUNLOCKFILE(fp); return (count); } diff --git a/src/libc/stdio/FreeBSD/getdelim.c b/src/libc/stdio/FreeBSD/getdelim.c index 8faa92d4a..02ff26dfe 100644 --- a/src/libc/stdio/FreeBSD/getdelim.c +++ b/src/libc/stdio/FreeBSD/getdelim.c @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/getdelim.c,v 1.3 2009/10/04 19:43:36 das Exp $"); #include "namespace.h" +#include #include #include #include @@ -96,9 +97,16 @@ static int sappend(char ** __restrict dstp, size_t * __restrict dstlenp, size_t * __restrict dstcapp, char * __restrict src, size_t srclen) { + size_t tmp; + + /* avoid overflowing the result length */ + if (os_add3_overflow(srclen, *dstlenp, 1, &tmp)) { + errno = EOVERFLOW; + return (-1); + } /* ensure room for srclen + dstlen + terminating NUL */ - if (expandtofit(dstp, srclen + *dstlenp + 1, dstcapp)) + if (expandtofit(dstp, tmp, dstcapp)) return (-1); memcpy(*dstp + *dstlenp, src, srclen); *dstlenp += srclen; diff --git a/src/libc/stdio/FreeBSD/getline.3 b/src/libc/stdio/FreeBSD/getline.3 index ddefe70d8..11e1e893b 100644 --- a/src/libc/stdio/FreeBSD/getline.3 +++ b/src/libc/stdio/FreeBSD/getline.3 @@ -22,9 +22,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/stdio/getline.3,v 1.2 2009/04/06 13:50:04 das Exp $ +.\" $FreeBSD: src/lib/libc/stdio/getline.3,v 1.5 2012/03/29 05:02:12 eadler Exp $ .\" -.Dd March 29, 2009 +.Dd November 30, 2010 .Dt GETLINE 3 .Os .Sh NAME @@ -53,23 +53,23 @@ function is equivalent to with the newline character as the delimiter. The delimiter character is included as part of the line, unless the end of the file is reached. -The caller may provide a pointer to a malloc buffer for the line in +.Pp +The caller may provide a pointer to a malloced buffer for the line in .Fa *linep , and the capacity of that buffer in -.Fa *linecapp ; -if -.Fa *linecapp -is 0, then -.Fa *linep -is treated as -.Dv NULL . -These functions may expand the buffer as needed, as if via -.Fn realloc , -and update +.Fa *linecapp . +These functions expand the buffer as needed, as if via +.Fn realloc . +If +.Fa linep +points to a +.Dv NULL +pointer, a new buffer will be allocated. +In either case, .Fa *linep and .Fa *linecapp -accordingly. +will be updated accordingly. .Sh RETURN VALUES The .Fn getdelim @@ -77,7 +77,8 @@ and .Fn getline functions return the number of characters written, excluding the terminating -.Dv NULL . +.Dv NUL +character. The value \-1 is returned if an error occurs, or if end-of-file is reached. .Sh EXAMPLES The following code fragment reads lines from a file and @@ -110,7 +111,7 @@ No delimiter was found in the first characters. .El .Pp -These functions may also fail for any of the errors specified for +These functions may also fail due to any of the errors specified for .Fn fgets and .Fn malloc . diff --git a/src/libc/stdio/FreeBSD/gets.c b/src/libc/stdio/FreeBSD/gets.c index 5c3d64f8d..7dda9fb81 100644 --- a/src/libc/stdio/FreeBSD/gets.c +++ b/src/libc/stdio/FreeBSD/gets.c @@ -53,7 +53,7 @@ gets(buf) int c; char *s; static int warned; - static char w[] = + static const char w[] = "warning: this program uses gets(), which is unsafe.\n"; FLOCKFILE(stdin); diff --git a/src/libc/stdio/FreeBSD/local.h b/src/libc/stdio/FreeBSD/local.h index 88e143cef..51262bc81 100644 --- a/src/libc/stdio/FreeBSD/local.h +++ b/src/libc/stdio/FreeBSD/local.h @@ -35,6 +35,7 @@ #include #include "xlocale_private.h" +#include "xprintf_private.h" #include /* for off_t */ #include #include @@ -51,6 +52,15 @@ extern int _swrite(FILE *, char const *, int); extern fpos_t _sseek(FILE *, fpos_t, int); extern int _ftello(FILE *, fpos_t *); extern int _fseeko(FILE *, off_t, int, int); +extern int _vasprintf(printf_comp_t __restrict, printf_domain_t __restrict, + char ** __restrict, locale_t __restrict, + const char * __restrict, __va_list); +extern int _vdprintf(printf_comp_t __restrict, printf_domain_t __restrict, + int, locale_t __restrict, const char * __restrict, va_list); +extern int _vsnprintf(printf_comp_t __restrict, printf_domain_t __restrict, + char * __restrict, size_t n, locale_t __restrict, + const char * __restrict, __va_list); + extern int __fflush(FILE *fp); extern void __fcloseall(void); extern wint_t __fgetwc(FILE *, locale_t); @@ -84,15 +94,13 @@ extern int __vfwscanf(FILE * __restrict, locale_t, const wchar_t * __restrict, __va_list); extern size_t __fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp); -extern int __sdidinit; +extern pthread_once_t __sdidinit; /* hold a buncha junk that would grow the ABI */ struct __sFILEX { unsigned char *up; /* saved _p when _p is doing ungetc data */ pthread_mutex_t fl_mutex; /* used for MT-safety */ - pthread_t fl_owner; /* current owner */ - int fl_count; /* recursive lock count */ int orientation:2; /* orientation for fwide() */ int counted:1; /* stream counted against STREAM_MAX */ mbstate_t mbstate; /* multibyte conversion state */ @@ -100,17 +108,15 @@ struct __sFILEX { #define _up _extra->up #define _fl_mutex _extra->fl_mutex -#define _fl_owner _extra->fl_owner -#define _fl_count _extra->fl_count #define _orientation _extra->orientation #define _mbstate _extra->mbstate #define _counted _extra->counted + + #define INITEXTRA(fp) do { \ (fp)->_extra->up = NULL; \ - (fp)->_extra->fl_mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; \ - (fp)->_extra->fl_owner = NULL; \ - (fp)->_extra->fl_count = 0; \ + (fp)->_extra->fl_mutex = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER; \ (fp)->_extra->orientation = 0; \ memset(&(fp)->_extra->mbstate, 0, sizeof(mbstate_t)); \ (fp)->_extra->counted = 0; \ diff --git a/src/libc/stdio/FreeBSD/makebuf.c b/src/libc/stdio/FreeBSD/makebuf.c index 17e45e2c3..85bb73a75 100644 --- a/src/libc/stdio/FreeBSD/makebuf.c +++ b/src/libc/stdio/FreeBSD/makebuf.c @@ -47,7 +47,12 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/makebuf.c,v 1.6 2007/01/09 00:28:07 imp E #include "libc_private.h" #include "local.h" -#define MAXBUFSIZE (1 << 16) +#ifdef FEATURE_SMALL_STDIOBUF +# define MAXBUFSIZE (1 << 12) +#else +# define MAXBUFSIZE (1 << 16) +#endif + #define TTYBUFSIZE 4096 /* diff --git a/src/libc/stdio/FreeBSD/mktemp.3 b/src/libc/stdio/FreeBSD/mktemp.3 index f55ceef02..d4072c631 100644 --- a/src/libc/stdio/FreeBSD/mktemp.3 +++ b/src/libc/stdio/FreeBSD/mktemp.3 @@ -9,7 +9,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -26,22 +26,31 @@ .\" SUCH DAMAGE. .\" .\" @(#)mktemp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/mktemp.3,v 1.22 2007/01/09 00:28:07 imp Exp $ .\" -.Dd February 11, 1998 +.Dd December 18, 2015 .Dt MKTEMP 3 .Os .Sh NAME -.Nm mkdtemp , +.Nm mktemp , .Nm mkstemp , +.Nm mkdtemp , .Nm mkstemps , -.Nm mktemp +.Nm mkostemp , +.Nm mkostemps .Nd make temporary file name (unique) .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In unistd.h .Ft char * +.Fo mktemp +.Fa "char *template" +.Fc +.Ft int +.Fo mkstemp +.Fa "char *template" +.Fc +.Ft char * .Fo mkdtemp .Fa "char *template" .Fc @@ -50,14 +59,16 @@ .Fa "char *template" .Fa "int suffixlen" .Fc -.In stdlib.h .Ft int -.Fo mkstemp +.Fo mkostemp .Fa "char *template" +.Fa "int oflags" .Fc -.Ft char * -.Fo mktemp +.Ft int +.Fo mkostemps .Fa "char *template" +.Fa "int suffixlen" +.Fa "int oflags" .Fc .Sh DESCRIPTION The @@ -97,22 +108,45 @@ This avoids the race between testing for a file's existence and opening it for use. .Pp The +.Fn mkdtemp +function makes the same replacement to the template as in +.Fn mktemp +and creates the template directory, mode 0700. +.Pp +The +.Fn mkostemp +function +is like +.Fn mkstemp +but allows specifying additional +.Xr open 2 +flags (defined in +.In fcntl.h ) . +The permitted flags are +.Dv O_APPEND , +.Dv O_SHLOCK , +.Dv O_EXLOCK +and +.Dv O_CLOEXEC . +.Pp +The .Fn mkstemps -function acts the same as -.Fn mkstemp , -except it permits a suffix to exist in the template. +and +.Fn mkostemps +functions act the same as +.Fn mkstemp +and +.Fn mkostemp +respectively, +except they permit a suffix to exist in the template. The template should be of the form .Pa /tmp/tmpXXXXXXsuffix . The .Fn mkstemps -function -is told the length of the suffix string. -.Pp -The -.Fn mkdtemp -function makes the same replacement to the template as in -.Fn mktemp -and creates the template directory, mode 0700. +and +.Fn mkostemps +functions +are told the length of the suffix string. .Sh RETURN VALUES The .Fn mktemp @@ -122,9 +156,11 @@ functions return a pointer to the template on success and .Dv NULL on failure. The -.Fn mkstemp -and +.Fn mkstemp , +.Fn mkostemp , .Fn mkstemps +and +.Fn mkostemps functions return \-1 if no suitable file could be created. If either call fails an error code is placed in the global variable @@ -132,7 +168,9 @@ If either call fails an error code is placed in the global variable .Sh ERRORS The .Fn mkstemp , -.Fn mkstemps +.Fn mkostemp , +.Fn mkstemps , +.Fn mkostemps , and .Fn mkdtemp functions @@ -145,8 +183,25 @@ The pathname portion of the template is not an existing directory. .El .Pp The +.Fn mkostemp +and +.Fn mkostemps +functions +may also set +.Va errno +to the following value: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa oflags +argument is invalid. +.El +.Pp +The .Fn mkstemp , +.Fn mkostemp , .Fn mkstemps , +.Fn mkostemps and .Fn mkdtemp functions @@ -157,9 +212,11 @@ to any value specified by the function. .Pp The -.Fn mkstemp -and +.Fn mkstemp , +.Fn mkostemp , .Fn mkstemps +and +.Fn mkostemps functions may also set .Va errno @@ -180,7 +237,7 @@ A common problem that results in a core dump is that the programmer passes in a read-only string to .Fn mktemp , .Fn mkstemp , -.Fn mkstemps , +.Fn mkstemps or .Fn mkdtemp . This is common with programs that were developed before @@ -193,12 +250,6 @@ with an argument of will result in a core dump due to .Fn mkstemp attempting to modify the string constant that was given. -If the program in question makes heavy use of that type -of function call, you do have the option of compiling the program -so that it will store string constants in a writable segment of memory. -See -.Xr gcc 1 -for more information. .Sh LEGACY SYNOPSIS .Fd #include .Pp @@ -212,6 +263,25 @@ is necessary and sufficient for all functions. .Xr open 2 , .Xr stat 2 , .Xr compat 5 +.Sh STANDARDS +The +.Fn mkstemp +and +.Fn mkdtemp +functions are expected to conform to +.St -p1003.1-2008 . +The +.Fn mktemp +function is expected to conform to +.St -p1003.1-2001 +and is not specified by +.St -p1003.1-2008 . +The +.Fn mkostemp , +.Fn mkstemps +and +.Fn mkostemps +functions do not conform to any standard. .Sh HISTORY A .Fn mktemp @@ -233,6 +303,11 @@ function first appeared in .Ox 2.4 , and later in .Fx 3.4 . +The +.Fn mkostemp +and +.Fn mkostemps +functions appeared in OS X 10.12. .Sh BUGS This family of functions produces filenames which can be guessed, though the risk is minimized when large numbers of @@ -249,6 +324,8 @@ and opening it for use particularly dangerous from a security perspective. Whenever it is possible, .Fn mkstemp +or +.Fn mkostemp should be used instead, since it does not have the race condition. If .Fn mkstemp diff --git a/src/libc/stdio/FreeBSD/mktemp.c b/src/libc/stdio/FreeBSD/mktemp.c index 30dc90113..c96757655 100644 --- a/src/libc/stdio/FreeBSD/mktemp.c +++ b/src/libc/stdio/FreeBSD/mktemp.c @@ -10,7 +10,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -31,7 +31,6 @@ static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.32 2010/02/28 13:31:29 jh Exp $"); #include "namespace.h" #include @@ -43,64 +42,119 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.32 2010/02/28 13:31:29 jh Ex #include #include #include +#include #include "un-namespace.h" +#define ALLOWED_MKOSTEMP_FLAGS (O_APPEND | O_SHLOCK | O_EXLOCK | O_CLOEXEC) + char *_mktemp(char *); -static int _gettemp(char *, int *, int, int); +typedef enum { + FTPP_DONE, FTPP_TRY_NEXT, FTPP_ERROR +} find_temp_path_progress_t; + +/* A contract for actions that find_temp_path performs for every path from + * the template. + * + * If the desired path was found, set result and return FTPP_DONE. + * If an IO/FS error ocurred, set errno and return FTPP_ERROR. + * Otherwise return FTPP_TRY_NEXT. + */ +typedef find_temp_path_progress_t (*find_temp_path_action_t)( + char *path, void *ctx, void *result); + +static int find_temp_path(char *path, int slen, bool stat_base_dir, + find_temp_path_action_t action, void *action_ctx, void *action_result); + +static find_temp_path_progress_t _mkostemps_action( + char *path, void *ctx, void *result); +static find_temp_path_progress_t _mktemp_action( + char *path, void *ctx, void *result); +static find_temp_path_progress_t _mkdtemp_action( + char *path, void *ctx, void *result); +static find_temp_path_progress_t _mkstemp_dprotected_np_action( + char *path, void *ctx, void *result); static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; int -mkstemps(path, slen) - char *path; - int slen; +mkostemps(char *path, int slen, int oflags) +{ + int fd; + if (oflags & ~ALLOWED_MKOSTEMP_FLAGS) { + errno = EINVAL; + return -1; + } + return (find_temp_path(path, slen, TRUE, _mkostemps_action, &oflags, &fd) ? fd : -1); +} + +int +mkstemps(char *path, int slen) { int fd; - return (_gettemp(path, &fd, 0, slen) ? fd : -1); + return (find_temp_path(path, slen, TRUE, _mkostemps_action, NULL, &fd) ? fd : -1); } int -mkstemp(path) - char *path; +mkostemp(char *path, int oflags) +{ + int fd; + if (oflags & ~ALLOWED_MKOSTEMP_FLAGS) { + errno = EINVAL; + return -1; + } + return (find_temp_path(path, 0, TRUE, _mkostemps_action, &oflags, &fd) ? fd : -1); +} + +int +mkstemp(char *path) { int fd; - return (_gettemp(path, &fd, 0, 0) ? fd : -1); + return (find_temp_path(path, 0, TRUE, _mkostemps_action, NULL, &fd) ? fd : -1); } char * -mkdtemp(path) - char *path; +mkdtemp(char *path) { - return (_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); + return (find_temp_path(path, 0, TRUE, _mkdtemp_action, NULL, NULL) ? + path : (char *)NULL); } char * -_mktemp(path) - char *path; +_mktemp(char *path) { - return (_gettemp(path, (int *)NULL, 0, 0) ? path : (char *)NULL); + return (find_temp_path(path, 0, FALSE, _mktemp_action, NULL, NULL) ? + path : (char *)NULL); } __warn_references(mktemp, "warning: mktemp() possibly used unsafely; consider using mkstemp()"); char * -mktemp(path) - char *path; +mktemp(char *path) { return (_mktemp(path)); } +int +mkstemp_dprotected_np(char *path, int class, int dpflags) +{ + int fd; + int ctx[2] = { class, dpflags }; + + return (find_temp_path(path, 0, TRUE, _mkstemp_dprotected_np_action, &ctx, &fd) ? fd : -1); +} + +/* For every path matching a given template, invoke an action. Depending on + * the progress reported by action, stops or tries the next path. + * Returns 1 if succeeds, 0 and sets errno if fails. + */ static int -_gettemp(path, doopen, domkdir, slen) - char *path; - int *doopen; - int domkdir; - int slen; +find_temp_path(char *path, int slen, bool stat_base_dir, + find_temp_path_action_t action, void *action_ctx, void *action_result) { char *start, *trv, *suffp, *carryp; char *pad; @@ -109,7 +163,7 @@ _gettemp(path, doopen, domkdir, slen) uint32_t rand; char carrybuf[MAXPATHLEN]; - if ((doopen != NULL && domkdir) || slen < 0) { + if (slen < 0) { errno = EINVAL; return (0); } @@ -141,7 +195,7 @@ _gettemp(path, doopen, domkdir, slen) /* * check the target directory. */ - if (doopen != NULL || domkdir) { + if (stat_base_dir) { for (; trv > path; --trv) { if (*trv == '/') { *trv = '\0'; @@ -159,25 +213,23 @@ _gettemp(path, doopen, domkdir, slen) } for (;;) { - if (doopen) { - if ((*doopen = - _open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) - return (1); - if (errno != EEXIST) - return (0); - } else if (domkdir) { - if (mkdir(path, 0700) == 0) - return (1); - if (errno != EEXIST) - return (0); - } else if (lstat(path, &sbuf)) - return (errno == ENOENT); + switch (action(path, action_ctx, action_result)) { + case FTPP_DONE: + return (1); + case FTPP_ERROR: + return (0); // errno must be set by the action + default: + ; // FTPP_TRY_NEXT, fall-through + } /* If we have a collision, cycle through the space of filenames */ for (trv = start, carryp = carrybuf;;) { /* have we tried all possible permutations? */ - if (trv == suffp) - return (0); /* yes - exit with EEXIST */ + if (trv == suffp) { + /* yes - exit with EEXIST */ + errno = EEXIST; + return (0); + } pad = strchr(padchar, *trv); if (pad == NULL) { /* this should never happen */ @@ -199,3 +251,57 @@ _gettemp(path, doopen, domkdir, slen) } /*NOTREACHED*/ } + +static find_temp_path_progress_t +_mkostemps_action(char *path, void *ctx, void *result) +{ + int oflags = (ctx != NULL) ? *((int *) ctx) : 0; + int fd = _open(path, O_CREAT|O_EXCL|O_RDWR|oflags, 0600); + if (fd >= 0) { + *((int *) result) = fd; + return FTPP_DONE; + } + return (errno == EEXIST) ? + FTPP_TRY_NEXT : + FTPP_ERROR; // errno is set already +} + +static find_temp_path_progress_t +_mktemp_action(char *path, void *ctx __unused, void *result __unused) +{ + struct stat sbuf; + if (lstat(path, &sbuf)) { + // stat failed + return (errno == ENOENT) ? + FTPP_DONE : // path is vacant, done + FTPP_ERROR; // errno is set already + } + return FTPP_TRY_NEXT; +} + +static find_temp_path_progress_t +_mkdtemp_action(char *path, void *ctx __unused, void *result __unused) +{ + if (mkdir(path, 0700) == 0) + return FTPP_DONE; + return (errno == EEXIST) ? + FTPP_TRY_NEXT : + FTPP_ERROR; // errno is set already +} + +static find_temp_path_progress_t +_mkstemp_dprotected_np_action(char *path, void *ctx, void *result) +{ + int class = ((int *) ctx)[0]; + int dpflags = ((int *) ctx)[1]; + int fd = open_dprotected_np(path, O_CREAT|O_EXCL|O_RDWR, class, dpflags, 0600); + if (fd >= 0) { + *((int *) result) = fd; + return FTPP_DONE; + } + return (errno == EEXIST) ? + FTPP_TRY_NEXT : + FTPP_ERROR; // errno is set already +} + + diff --git a/src/libc/stdio/FreeBSD/printf.3 b/src/libc/stdio/FreeBSD/printf.3 index 031d7f7c2..850fa989e 100644 --- a/src/libc/stdio/FreeBSD/printf.3 +++ b/src/libc/stdio/FreeBSD/printf.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.64 2009/12/02 07:51:25 brueffer Exp $ +.\" $FreeBSD$ .\" .Dd December 2, 2009 .Dt PRINTF 3 @@ -97,7 +97,7 @@ write output to the given file descriptor; and .Fn vsnprintf write to the character string -.Fa s ; +.Fa str ; and .Fn asprintf and @@ -118,20 +118,6 @@ string that specifies how subsequent arguments .Xr stdarg 3 ) are converted for output. .Pp -These functions return the number of characters printed -(not including the trailing -.Ql \e0 -used to end output to strings) or a negative value if an output error occurs, -except for -.Fn snprintf -and -.Fn vsnprintf , -which return the number of characters that would have been printed if the -.Fa n -were unlimited -(again, not including the final -.Ql \e0 ) . -.Pp The .Fn asprintf and @@ -159,25 +145,29 @@ and .Fn vsnprintf functions will write at most -.Fa n Ns \-1 +.Fa size Ns \-1 of the characters printed into the output string (the -.Fa n Ns \'th +.Fa size Ns 'th character then gets the terminating .Ql \e0 ) ; if the return value is greater than or equal to the -.Fa n +.Fa size argument, the string was too short and some of the printed characters were discarded. -The output is always null-terminated. +The output is always null-terminated, unless +.Fa size +is 0. .Pp The .Fn sprintf and .Fn vsprintf functions -effectively assume an infinite -.Fa n . +effectively assume a +.Fa size +of +.Dv INT_MAX + 1. .Pp For those routines that write to a user-provided character string, that string and the format strings should not overlap, as the @@ -286,7 +276,7 @@ number produced by a signed conversion. A .Cm + overrides a space if both are used. -.It Sq Cm ' +.It So "'" Sc (apostrophe) Decimal conversions .Cm ( d , u , or @@ -500,7 +490,7 @@ The .Vt double argument is rounded and converted in the style .Sm off -.Oo \- Oc Ar d Li \&. Ar ddd Li e \\*[Pm] Ar dd +.Oo \- Oc Ar d Li \&. Ar ddd Li e \(+- Ar dd .Sm on where there is one digit before the decimal-point character @@ -576,7 +566,7 @@ The .Vt double argument is rounded and converted to hexadecimal notation in the style .Sm off -.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \\*[Pm] Oc Ar d , +.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \(+- Oc Ar d , .Sm on where the number of digits after the hexadecimal-point character is equal to the precision specification. @@ -720,6 +710,21 @@ In no case does a non-existent or small field width cause truncation of a numeric field; if the result of a conversion is wider than the field width, the field is expanded to contain the conversion result. +.Sh RETURN VALUES +These functions return the number of characters printed +(not including the trailing +.Ql \e0 +used to end output to strings), +except for +.Fn snprintf +and +.Fn vsnprintf , +which return the number of characters that would have been printed if the +.Fa size +were unlimited +(again, not including the final +.Ql \e0 ) . +These functions return a negative value if an error occurs. .Sh EXAMPLES To print a date and time in the form .Dq Li "Sunday, July 3, 10:02" , @@ -759,82 +764,11 @@ char *newfmt(const char *fmt, ...) return (p); } .Ed -.Sh SECURITY CONSIDERATIONS -The -.Fn sprintf -and -.Fn vsprintf -functions are easily misused in a manner which enables malicious users -to arbitrarily change a running program's functionality through -a buffer overflow attack. -Because -.Fn sprintf -and -.Fn vsprintf -assume an infinitely long string, -callers must be careful not to overflow the actual space; -this is often hard to assure. -For safety, programmers should use the -.Fn snprintf -interface instead. -For example: -.Bd -literal -void -foo(const char *arbitrary_string, const char *and_another) -{ - char onstack[8]; - -#ifdef BAD - /* - * This first sprintf is bad behavior. Do not use sprintf! - */ - sprintf(onstack, "%s, %s", arbitrary_string, and_another); -#else - /* - * The following two lines demonstrate better use of - * snprintf(). - */ - snprintf(onstack, sizeof(onstack), "%s, %s", arbitrary_string, - and_another); -#endif -} -.Ed -.Pp -The -.Fn printf -and -.Fn sprintf -family of functions are also easily misused in a manner -allowing malicious users to arbitrarily change a running program's -functionality by either causing the program -to print potentially sensitive data -.Dq "left on the stack" , -or causing it to generate a memory fault or bus error -by dereferencing an invalid pointer. -.Pp -.Cm %n -can be used to write arbitrary data to potentially carefully-selected -addresses. -Programmers are therefore strongly advised to never pass untrusted strings -as the -.Fa format -argument, as an attacker can put format specifiers in the string -to mangle your stack, -leading to a possible security hole. -This holds true even if the string was built using a function like -.Fn snprintf , -as the resulting string may still contain user-supplied conversion specifiers -for later interpolation by -.Fn printf . -.Pp -Always use the proper secure idiom: -.Pp -.Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);" .Sh COMPATIBILITY The conversion formats .Cm \&%D , \&%O , and -.Cm %U +.Cm \&%U are not standard and are provided only for backward compatibility. The effect of padding the @@ -910,14 +844,14 @@ first appeared in the .Tn GNU C library. These were implemented by -.An Peter Wemm Aq peter@FreeBSD.org +.An Peter Wemm Aq Mt peter@FreeBSD.org in .Fx 2.2 , but were later replaced with a different implementation from -.An Todd C. Miller Aq Todd.Miller@courtesan.com -for -.Ox 2.3 . +.Ox 2.3 +by +.An Todd C. Miller Aq Mt Todd.Miller@courtesan.com . The .Fn dprintf and @@ -930,3 +864,74 @@ The family of functions do not correctly handle multibyte characters in the .Fa format argument. +.Sh SECURITY CONSIDERATIONS +The +.Fn sprintf +and +.Fn vsprintf +functions are easily misused in a manner which enables malicious users +to arbitrarily change a running program's functionality through +a buffer overflow attack. +Because +.Fn sprintf +and +.Fn vsprintf +assume an infinitely long string, +callers must be careful not to overflow the actual space; +this is often hard to assure. +For safety, programmers should use the +.Fn snprintf +interface instead. +For example: +.Bd -literal +void +foo(const char *arbitrary_string, const char *and_another) +{ + char onstack[8]; + +#ifdef BAD + /* + * This first sprintf is bad behavior. Do not use sprintf! + */ + sprintf(onstack, "%s, %s", arbitrary_string, and_another); +#else + /* + * The following two lines demonstrate better use of + * snprintf(). + */ + snprintf(onstack, sizeof(onstack), "%s, %s", arbitrary_string, + and_another); +#endif +} +.Ed +.Pp +The +.Fn printf +and +.Fn sprintf +family of functions are also easily misused in a manner +allowing malicious users to arbitrarily change a running program's +functionality by either causing the program +to print potentially sensitive data +.Dq "left on the stack" , +or causing it to generate a memory fault or bus error +by dereferencing an invalid pointer. +.Pp +.Cm %n +can be used to write arbitrary data to potentially carefully-selected +addresses. +Programmers are therefore strongly advised to never pass untrusted strings +as the +.Fa format +argument, as an attacker can put format specifiers in the string +to mangle your stack, +leading to a possible security hole. +This holds true even if the string was built using a function like +.Fn snprintf , +as the resulting string may still contain user-supplied conversion specifiers +for later interpolation by +.Fn printf . +.Pp +Always use the proper secure idiom: +.Pp +.Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);" diff --git a/src/libc/stdio/FreeBSD/printfcommon.h b/src/libc/stdio/FreeBSD/printfcommon.h index 27141e6d6..889b12ec2 100644 --- a/src/libc/stdio/FreeBSD/printfcommon.h +++ b/src/libc/stdio/FreeBSD/printfcommon.h @@ -130,7 +130,7 @@ io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep, { int p_len; - p_len = ep - p; + p_len = (int)(ep - p); if (p_len > len) p_len = len; if (p_len > 0) { @@ -168,7 +168,7 @@ __ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs) switch (base) { case 10: if (val < 10) { /* many numbers are 1 digit */ - *--cp = to_char(val); + *--cp = (CHAR)to_char(val); return (cp); } /* @@ -295,7 +295,7 @@ exponent(CHAR *p0, int exp, CHAR fmtch) *p++ = '0'; *p++ = to_char(exp); } - return (p - p0); + return (int)(p - p0); } #endif /* !NO_FLOATING_POINT */ diff --git a/src/libc/stdio/FreeBSD/printflocal.h b/src/libc/stdio/FreeBSD/printflocal.h index f57e8e9f9..89b24a221 100644 --- a/src/libc/stdio/FreeBSD/printflocal.h +++ b/src/libc/stdio/FreeBSD/printflocal.h @@ -35,7 +35,13 @@ /* * Defining here VECTORS for all files that include this header () */ -#define VECTORS +#ifndef VECTORS +#define VECTORS +typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; +#ifdef __SSE2__ +#define V64TYPE +#endif /* __SSE2__ */ +#endif /* VECTORS */ /* * Flags used during conversion. @@ -68,13 +74,6 @@ /* Size of the static argument table. */ #define STATIC_ARG_TBL_SIZE 8 -#ifdef VECTORS -typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; -#ifdef __SSE2__ -#define V64TYPE -#endif /* __SSE2__ */ -#endif /* VECTORS */ - union arg { int intarg; u_int uintarg; diff --git a/src/libc/stdio/FreeBSD/refill.c b/src/libc/stdio/FreeBSD/refill.c index 8d42bbb6e..7daa06294 100644 --- a/src/libc/stdio/FreeBSD/refill.c +++ b/src/libc/stdio/FreeBSD/refill.c @@ -69,8 +69,7 @@ __srefill0(FILE *fp) { /* make sure stdio is set up */ - if (!__sdidinit) - __sinit(); + pthread_once(&__sdidinit, __sinit); ORIENT(fp, -1); diff --git a/src/libc/stdio/FreeBSD/rewind.c b/src/libc/stdio/FreeBSD/rewind.c index 3dc282d75..33aea2f55 100644 --- a/src/libc/stdio/FreeBSD/rewind.c +++ b/src/libc/stdio/FreeBSD/rewind.c @@ -49,8 +49,7 @@ rewind(FILE *fp) int serrno = errno; /* make sure stdio is set up */ - if (!__sdidinit) - __sinit(); + pthread_once(&__sdidinit, __sinit); FLOCKFILE(fp); if (_fseeko(fp, (off_t)0, SEEK_SET, 1) == 0) { diff --git a/src/libc/stdio/FreeBSD/tmpfile.c b/src/libc/stdio/FreeBSD/tmpfile.c index 3f1679ff9..1efbca7cf 100644 --- a/src/libc/stdio/FreeBSD/tmpfile.c +++ b/src/libc/stdio/FreeBSD/tmpfile.c @@ -13,7 +13,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -48,7 +48,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/tmpfile.c,v 1.10 2007/01/09 00:28:07 imp #include "un-namespace.h" FILE * -tmpfile() +tmpfile(void) { sigset_t set, oset; FILE *fp; @@ -63,6 +63,9 @@ tmpfile() if (tmpdir == NULL) tmpdir = _PATH_TMP; + if (*tmpdir == '\0') + return (NULL); + (void)asprintf(&buf, "%s%s%s", tmpdir, (tmpdir[strlen(tmpdir) - 1] == '/') ? "" : "/", TRAILER); if (buf == NULL) diff --git a/src/libc/stdio/FreeBSD/ungetc.c b/src/libc/stdio/FreeBSD/ungetc.c index fc8ddb152..287fa0227 100644 --- a/src/libc/stdio/FreeBSD/ungetc.c +++ b/src/libc/stdio/FreeBSD/ungetc.c @@ -92,8 +92,8 @@ ungetc(int c, FILE *fp) { int ret; - if (!__sdidinit) - __sinit(); + pthread_once(&__sdidinit, __sinit); + FLOCKFILE(fp); ORIENT(fp, -1); ret = __ungetc(c, fp); diff --git a/src/libc/stdio/FreeBSD/vasprintf.c b/src/libc/stdio/FreeBSD/vasprintf.c index d872a9e13..81f5172d4 100644 --- a/src/libc/stdio/FreeBSD/vasprintf.c +++ b/src/libc/stdio/FreeBSD/vasprintf.c @@ -37,12 +37,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vasprintf.c,v 1.19 2008/04/17 22:17:54 jh #include #include "local.h" -int -vasprintf_l(str, loc, fmt, ap) - char **str; - locale_t loc; - const char *fmt; - __va_list ap; +__private_extern__ int +_vasprintf(printf_comp_t __restrict pc, printf_domain_t __restrict domain, char ** __restrict str, locale_t __restrict loc, const char * __restrict fmt, __va_list ap) { int ret; FILE f; @@ -50,7 +46,6 @@ vasprintf_l(str, loc, fmt, ap) f._extra = &ext; INITEXTRA(&f); - NORMALIZE_LOCALE(loc); f._file = -1; f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = (unsigned char *)malloc(128); @@ -62,7 +57,7 @@ vasprintf_l(str, loc, fmt, ap) f._bf._size = f._w = 127; /* Leave room for the NUL */ f._orientation = 0; memset(&f._mbstate, 0, sizeof(mbstate_t)); - ret = __vfprintf(&f, loc, fmt, ap); + ret = __v2printf(pc, domain, &f, loc, fmt, ap); if (ret < 0) { free(f._bf._base); *str = NULL; @@ -75,10 +70,13 @@ vasprintf_l(str, loc, fmt, ap) } int -vasprintf(str, fmt, ap) - char **str; - const char *fmt; - __va_list ap; +vasprintf_l(char ** __restrict str, locale_t __restrict loc, const char * __restrict fmt, __va_list ap) +{ + return _vasprintf(XPRINTF_PLAIN, NULL, str, loc, fmt, ap); +} + +int +vasprintf(char ** __restrict str, const char * __restrict fmt, __va_list ap) { - return vasprintf_l(str, __current_locale(), fmt, ap); + return _vasprintf(XPRINTF_PLAIN, NULL, str, __current_locale(), fmt, ap); } diff --git a/src/libc/stdio/FreeBSD/vdprintf.c b/src/libc/stdio/FreeBSD/vdprintf.c index 5625bd6c4..c1b03c980 100644 --- a/src/libc/stdio/FreeBSD/vdprintf.c +++ b/src/libc/stdio/FreeBSD/vdprintf.c @@ -38,8 +38,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vdprintf.c,v 1.1 2009/03/04 03:38:51 das #include "local.h" -int -vdprintf_l(int fd, locale_t loc, const char * __restrict fmt, va_list ap) +__private_extern__ int +_vdprintf(printf_comp_t __restrict pc, printf_domain_t __restrict domain, int fd, locale_t __restrict loc, const char * __restrict fmt, va_list ap) { FILE f; unsigned char buf[BUFSIZ]; @@ -48,8 +48,6 @@ vdprintf_l(int fd, locale_t loc, const char * __restrict fmt, va_list ap) f._extra = &ext; INITEXTRA(&f); - NORMALIZE_LOCALE(loc); - if (fd > SHRT_MAX) { errno = EMFILE; return (EOF); @@ -66,13 +64,19 @@ vdprintf_l(int fd, locale_t loc, const char * __restrict fmt, va_list ap) f._orientation = 0; bzero(&f._mbstate, sizeof(f._mbstate)); - if ((ret = __vfprintf(&f, loc, fmt, ap)) < 0) + if ((ret = __v2printf(pc, domain, &f, loc, fmt, ap)) < 0) return (ret); return (__fflush(&f) ? EOF : ret); } +int +vdprintf_l(int fd, locale_t __restrict loc, const char * __restrict fmt, va_list ap) +{ + return _vdprintf(XPRINTF_PLAIN, NULL, fd, loc, fmt, ap); +} + int vdprintf(int fd, const char * __restrict fmt, va_list ap) { - return vdprintf_l(fd, __current_locale(), fmt, ap); + return _vdprintf(XPRINTF_PLAIN, NULL, fd, __current_locale(), fmt, ap); } diff --git a/src/libc/stdio/FreeBSD/vfprintf.c b/src/libc/stdio/FreeBSD/vfprintf.c index 28673b4ae..701e2ab99 100644 --- a/src/libc/stdio/FreeBSD/vfprintf.c +++ b/src/libc/stdio/FreeBSD/vfprintf.c @@ -70,7 +70,9 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.90 2009/02/28 06:06:57 das #include "printflocal.h" static int __sprint(FILE *, locale_t, struct __suio *); +#if 0 static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0); +#endif static char *__wcsconv(wchar_t *, int, locale_t); __private_extern__ const char *__fix_nogrouping(const char *); @@ -166,6 +168,7 @@ __sprint(FILE *fp, locale_t loc __unused, struct __suio *uio) return (err); } +#if 0 /* * Helper function for `fprintf to unbuffered unix file': creates a * temporary buffer. We only work on write-only files; this avoids @@ -206,6 +209,7 @@ __sbprintf(FILE *fp, locale_t loc, const char *fmt, va_list ap) fp->_flags |= __SERR; return (ret); } +#endif /* * Convert a wide character string argument for the %ls format to a multibyte @@ -275,14 +279,8 @@ vfprintf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, va_ { int ret; - NORMALIZE_LOCALE(loc); FLOCKFILE(fp); - /* optimise fprintf(stderr) (and other unbuffered Unix files) */ - if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) - ret = __sbprintf(fp, loc, fmt0, ap); - else - ret = __vfprintf(fp, loc, fmt0, ap); + ret = __xvprintf(XPRINTF_PLAIN, NULL, fp, loc, fmt0, ap); FUNLOCKFILE(fp); return (ret); } @@ -291,7 +289,12 @@ int vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) { - return vfprintf_l(fp, __current_locale(), fmt0, ap); + int ret; + + FLOCKFILE(fp); + ret = __xvprintf(XPRINTF_PLAIN, NULL, fp, __current_locale(), fmt0, ap); + FUNLOCKFILE(fp); + return ret; } /* @@ -458,19 +461,15 @@ __vfprintf(FILE *fp, locale_t loc, const char *fmt0, va_list ap) val = GETARG (int); \ } -#if 0 // xprintf pending API review - if (__use_xprintf == 0 && getenv("USE_XPRINTF")) - __use_xprintf = 1; - if (__use_xprintf > 0) - return (__xvprintf(fp, loc, fmt0, ap)); -#endif - + /* The following has been moved to __v2printf() */ +#if 0 /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ if (prepwrite(fp) != 0) { errno = EBADF; return (EOF); } ORIENT(fp, -1); +#endif convbuf = NULL; fmt = (char *)fmt0; @@ -891,11 +890,11 @@ fp_common: if (flags & LONGINT) { wchar_t *wcp; - if (convbuf != NULL) - free(convbuf); - if ((wcp = GETARG(wchar_t *)) == NULL) + free(convbuf); + if ((wcp = GETARG(wchar_t *)) == NULL) { + convbuf = NULL; cp = "(null)"; - else { + } else { convbuf = __wcsconv(wcp, prec, loc); if (convbuf == NULL) { fp->_flags |= __SERR; @@ -1391,8 +1390,7 @@ error: if (dtoaresult != NULL) freedtoa(dtoaresult); #endif - if (convbuf != NULL) - free(convbuf); + free(convbuf); if (__sferror(fp)) ret = EOF; if ((argtable != NULL) && (argtable != statargtable)) diff --git a/src/libc/stdio/FreeBSD/vfscanf.c b/src/libc/stdio/FreeBSD/vfscanf.c index a3f9f3e87..618961e9c 100644 --- a/src/libc/stdio/FreeBSD/vfscanf.c +++ b/src/libc/stdio/FreeBSD/vfscanf.c @@ -156,7 +156,7 @@ __svfscanf_l(FILE * __restrict fp, locale_t loc, const char * __restrict fmt0, v int mb_cur_max; /* `basefix' is used to avoid `if' tests in the integer scanner */ - static short basefix[17] = + static const short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; NORMALIZE_LOCALE(loc); @@ -326,8 +326,10 @@ literal: case 'n': { + if (flags & SUPPRESS) /* ??? */ + continue; void *ptr = va_arg(ap, void *); - if ((ptr == NULL) || (flags & SUPPRESS)) /* ??? */ + if (ptr == NULL) continue; else if (flags & SHORTSHORT) *(char *)ptr = nread; diff --git a/src/libc/stdio/FreeBSD/vfwprintf.c b/src/libc/stdio/FreeBSD/vfwprintf.c index 31764a911..f623fff3e 100644 --- a/src/libc/stdio/FreeBSD/vfwprintf.c +++ b/src/libc/stdio/FreeBSD/vfwprintf.c @@ -771,8 +771,7 @@ reswitch: switch (ch) { prec = dtoaend - dtoaresult; if (expt == INT_MAX) ox[1] = '\0'; - if (convbuf != NULL) - free(convbuf); + free(convbuf); ndig = dtoaend - dtoaresult; cp = convbuf = __mbsconv(dtoaresult, -1, loc); freedtoa(dtoaresult); @@ -815,8 +814,7 @@ reswitch: switch (ch) { fp_begin: if (prec < 0) prec = DEFPREC; - if (convbuf != NULL) - free(convbuf); + free(convbuf); if (flags & LONGDBL) { fparg.ldbl = GETARG(long double); dtoaresult = @@ -955,11 +953,11 @@ fp_common: } else { char *mbp; - if (convbuf != NULL) - free(convbuf); - if ((mbp = GETARG(char *)) == NULL) + free(convbuf); + if ((mbp = GETARG(char *)) == NULL) { + convbuf = NULL; cp = L"(null)"; - else { + } else { convbuf = __mbsconv(mbp, prec, loc); if (convbuf == NULL) { fp->_flags |= __SERR; @@ -1256,7 +1254,7 @@ number: if ((dprec = prec) >= 0) break; \ } \ ret += vlen; \ - PRINT(vstr, vlen); \ + PRINT((const CHAR *) vstr, vlen); \ free(vstr); \ } while (0) #else /* !V64TYPE */ @@ -1285,7 +1283,7 @@ number: if ((dprec = prec) >= 0) break; \ } \ ret += vlen; \ - PRINT(vstr, vlen); \ + PRINT((const CHAR *) vstr, vlen); \ free(vstr); \ } while (0) #endif /* V64TYPE */ @@ -1455,8 +1453,7 @@ done: FLUSH(); error: va_end(orgap); - if (convbuf != NULL) - free(convbuf); + free(convbuf); if (__sferror(fp)) ret = EOF; if ((argtable != NULL) && (argtable != statargtable)) diff --git a/src/libc/stdio/FreeBSD/vfwscanf.c b/src/libc/stdio/FreeBSD/vfwscanf.c index bba07f273..61b868aa3 100644 --- a/src/libc/stdio/FreeBSD/vfwscanf.c +++ b/src/libc/stdio/FreeBSD/vfwscanf.c @@ -166,7 +166,7 @@ __vfwscanf(FILE * __restrict fp, locale_t loc, const wchar_t * __restrict fmt, int mb_cur_max = MB_CUR_MAX_L(loc); /* `basefix' is used to avoid `if' tests in the integer scanner */ - static short basefix[17] = + static const short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; nassigned = 0; @@ -346,8 +346,10 @@ literal: case 'n': { + if (flags & SUPPRESS) /* ??? */ + continue; void *ptr = va_arg(ap, void *); - if ((ptr == NULL) || (flags & SUPPRESS)) /* ??? */ + if (ptr == NULL) continue; else if (flags & SHORTSHORT) *(char *)ptr = nread; diff --git a/src/libc/stdio/FreeBSD/vsnprintf.c b/src/libc/stdio/FreeBSD/vsnprintf.c index 5f9a2958f..4b2914463 100644 --- a/src/libc/stdio/FreeBSD/vsnprintf.c +++ b/src/libc/stdio/FreeBSD/vsnprintf.c @@ -42,9 +42,8 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vsnprintf.c,v 1.24 2008/04/17 22:17:54 jh #include #include "local.h" -int -vsnprintf_l(char * __restrict str, size_t n, locale_t loc, const char * __restrict fmt, - __va_list ap) +__private_extern__ int +_vsnprintf(printf_comp_t __restrict pc, printf_domain_t __restrict domain, char * __restrict str, size_t n, locale_t __restrict loc, const char * __restrict fmt, __va_list ap) { size_t on; int ret; @@ -54,12 +53,18 @@ vsnprintf_l(char * __restrict str, size_t n, locale_t loc, const char * __restri f._extra = &ext; INITEXTRA(&f); - NORMALIZE_LOCALE(loc); on = n; if (n != 0) n--; +#if defined(__i386__) + /* don't corrupt the output buffer at all if the size underflowed */ + if (n > INT_MAX) + on = n = 0; +#else if (n > INT_MAX) n = INT_MAX; +#endif + /* Stdio internals do not deal correctly with zero length buffer */ if (n == 0) { if (on > 0) @@ -73,15 +78,21 @@ vsnprintf_l(char * __restrict str, size_t n, locale_t loc, const char * __restri f._bf._size = f._w = n; f._orientation = 0; memset(&f._mbstate, 0, sizeof(mbstate_t)); - ret = __vfprintf(&f, loc, fmt, ap); + ret = __v2printf(pc, domain, &f, loc, fmt, ap); if (on > 0) *f._p = '\0'; return (ret); } +int +vsnprintf_l(char * __restrict str, size_t n, locale_t __restrict loc, const char * __restrict fmt, + __va_list ap) +{ + return _vsnprintf(XPRINTF_PLAIN, NULL, str, n, loc, fmt, ap); +} int vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt, __va_list ap) { - return vsnprintf_l(str, n, __current_locale(), fmt, ap); + return _vsnprintf(XPRINTF_PLAIN, NULL, str, n, __current_locale(), fmt, ap); } diff --git a/src/libc/stdio/FreeBSD/vsprintf.c b/src/libc/stdio/FreeBSD/vsprintf.c index 9b85352cb..9ec7b246a 100644 --- a/src/libc/stdio/FreeBSD/vsprintf.c +++ b/src/libc/stdio/FreeBSD/vsprintf.c @@ -51,14 +51,13 @@ vsprintf_l(char * __restrict str, locale_t loc, const char * __restrict fmt, __v f._extra = &ext; INITEXTRA(&f); - NORMALIZE_LOCALE(loc); f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; f._orientation = 0; memset(&f._mbstate, 0, sizeof(mbstate_t)); - ret = __vfprintf(&f, loc, fmt, ap); + ret = __v2printf(XPRINTF_PLAIN, NULL, &f, loc, fmt, ap); *f._p = 0; return (ret); } diff --git a/src/libc/stdio/FreeBSD/wprintf.3 b/src/libc/stdio/FreeBSD/wprintf.3 index d1c34986d..12a3bea71 100644 --- a/src/libc/stdio/FreeBSD/wprintf.3 +++ b/src/libc/stdio/FreeBSD/wprintf.3 @@ -31,18 +31,14 @@ .\" .\" @(#)printf.3 8.1 (Berkeley) 6/4/93 .\" FreeBSD: src/lib/libc/stdio/printf.3,v 1.47 2002/09/06 11:23:55 tjr Exp -.\" $FreeBSD: src/lib/libc/stdio/wprintf.3,v 1.6 2007/01/09 00:28:08 imp Exp $ +.\" $FreeBSD$ .\" .Dd July 5, 2003 .Dt WPRINTF 3 .Os .Sh NAME -.Nm fwprintf , -.Nm swprintf , -.Nm vfwprintf , -.Nm vswprintf , -.Nm vwprintf , -.Nm wprintf +.Nm wprintf , fwprintf , swprintf , +.Nm vwprintf , vfwprintf , vswprintf .Nd formatted wide character output conversion .Sh LIBRARY .Lb libc @@ -50,49 +46,23 @@ .In stdio.h .In wchar.h .Ft int -.Fo fwprintf -.Fa "FILE *restrict stream" -.Fa "const wchar_t *restrict format" -.Fa ... -.Fc +.Fn fwprintf "FILE * restrict stream" "const wchar_t * restrict format" ... .Ft int -.Fo swprintf -.Fa "wchar_t *restrict ws" -.Fa "size_t n" -.Fa "const wchar_t *restrict format" -.Fa ... -.Fc +.Fn swprintf "wchar_t * restrict ws" "size_t n" "const wchar_t * restrict format" ... .Ft int -.Fo wprintf -.Fa "const wchar_t *restrict format" -.Fa ... -.Fc +.Fn wprintf "const wchar_t * restrict format" ... .In stdarg.h -.In stdio.h -.In wchar.h .Ft int -.Fo vfwprintf -.Fa "FILE *restrict stream" -.Fa "const wchar_t *restrict format" -.Fa "va_list arg" -.Fc +.Fn vfwprintf "FILE * restrict stream" "const wchar_t * restrict" "va_list ap" .Ft int -.Fo vswprintf -.Fa "wchar_t *restrict ws" -.Fa "size_t n" -.Fa "const wchar_t *restrict format" -.Fa "va_list arg" -.Fc +.Fn vswprintf "wchar_t * restrict ws" "size_t n" "const wchar_t *restrict format" "va_list ap" .Ft int -.Fo vwprintf -.Fa "const wchar_t *restrict format" -.Fa "va_list arg" -.Fc +.Fn vwprintf "const wchar_t * restrict format" "va_list ap" .Sh DESCRIPTION The .Fn wprintf family of functions produces output according to a -.Fa format , +.Fa format as described below. The .Fn wprintf @@ -135,9 +105,18 @@ The .Fn swprintf and .Fn vswprintf -functions will fail if +functions return the number of characters written (not including the terminating +null wide character). +These functions will fail (returning a negative value and setting +.Va errno +appropriately) if .Fa n -or more wide characters were requested to be written, +or more wide characters were requested to be written. +.Pp +The other functions return the number of wide characters printed on success, or +a negative value on faiure, setting +.Va errno +to indicate the error. .Pp The format string is composed of zero or more directives: ordinary @@ -412,7 +391,7 @@ The .Vt double argument is rounded and converted in the style .Sm off -.Oo \- Oc Ar d Li \&. Ar ddd Li e \\*[Pm] Ar dd +.Oo \- Oc Ar d Li \&. Ar ddd Li e \(+- Ar dd .Sm on where there is one digit before the decimal-point character @@ -488,7 +467,7 @@ The .Vt double argument is converted to hexadecimal notation in the style .Sm off -.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \\*[Pm] Oc Ar d , +.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \(+- Oc Ar d , .Sm on where the number of digits after the hexadecimal-point character is equal to the precision specification. @@ -627,6 +606,9 @@ field is expanded to contain the conversion result. .Sh SECURITY CONSIDERATIONS Refer to .Xr printf 3 . +.Sh ERRORS +Refer to +.Xr printf 3 . .Sh SEE ALSO .Xr btowc 3 , .Xr fputws 3 , @@ -647,7 +629,7 @@ the .Fn fwprintf , .Fn swprintf , .Fn vwprintf , -.Fn vfwprintf , +.Fn vfwprintf and .Fn vswprintf functions diff --git a/src/libc/stdio/FreeBSD/wsetup.c b/src/libc/stdio/FreeBSD/wsetup.c index ea1b9e885..b0bdfb448 100644 --- a/src/libc/stdio/FreeBSD/wsetup.c +++ b/src/libc/stdio/FreeBSD/wsetup.c @@ -51,8 +51,7 @@ __swsetup(fp) FILE *fp; { /* make sure stdio is set up */ - if (!__sdidinit) - __sinit(); + pthread_once(&__sdidinit, __sinit); /* * If we are not writing, we had better be reading and writing. diff --git a/src/libc/stdio/FreeBSD/xprintf.c b/src/libc/stdio/FreeBSD/xprintf.c new file mode 100644 index 000000000..772155de5 --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf.c @@ -0,0 +1,1199 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdio/xprintf.c,v 1.9 2010/03/11 17:03:32 jhb Exp $ + */ + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +//#define MACHTIME +#ifdef MACHTIME +#include +#endif // MACHTIME + +#ifdef XPRINTF_PERF +#include +#endif /* XPRINTF_PERF */ + +#include "local.h" +#include "xprintf_private.h" +#include "xprintf_domain.h" +#include "fvwrite.h" + +/* + * Defining XPRINTF_DEBUG allows the __private_extern__ variable __use_xprintf + * to be set so that regular printf variants will use the extensible printf + * code path. This is normally off, and is only used to test the extensible + * printf code in the conformance tests. + */ +#ifdef XPRINTF_DEBUG +#include +int __use_xprintf = 0; +#endif + +/* private stuff -----------------------------------------------------*/ + +union arg { + int intarg; + long longarg; + intmax_t intmaxarg; +#ifndef NO_FLOATING_POINT + double doublearg; + long double longdoublearg; +#endif + wint_t wintarg; + char *pchararg; + wchar_t *pwchararg; + void *pvoidarg; +#ifdef VECTORS + VECTORTYPE vectorarg; + unsigned char vuchararg[16]; + signed char vchararg[16]; + unsigned short vushortarg[8]; + signed short vshortarg[8]; + unsigned int vuintarg[4]; + signed int vintarg[4]; + float vfloatarg[4]; +#ifdef V64TYPE + double vdoublearg[2]; + unsigned long long vulonglongarg[2]; + long long vlonglongarg[2]; +#endif /* V64TYPE */ +#endif /* VECTORS */ +}; + +/* + * Macros for converting digits to letters and vice versa + */ +#define to_digit(c) ((c) - '0') +#define is_digit(c) (((unsigned)to_digit(c)) <= 9) + +/* various globals ---------------------------------------------------*/ + +__private_extern__ const char __lowercase_hex[17] = "0123456789abcdef?"; /*lint !e784 */ +__private_extern__ const char __uppercase_hex[17] = "0123456789ABCDEF?"; /*lint !e784 */ + +#define PADSIZE 16 +static char blanks[PADSIZE] = + {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; +static char zeroes[PADSIZE] = + {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; + +/* printing and padding functions ------------------------------------*/ + +#define NIOV 8 + +struct __printf_io { + FILE *fp; + struct __suio uio; + struct __siov iov[NIOV]; + struct __siov *iovp; +}; + +static void +__printf_init(struct __printf_io *io) +{ + + io->uio.uio_iov = io->iovp = &io->iov[0]; + io->uio.uio_resid = 0; + io->uio.uio_iovcnt = 0; +} + +__private_extern__ void +__printf_flush(struct __printf_io *io) +{ + + __sfvwrite(io->fp, &io->uio); + __printf_init(io); +} + +__private_extern__ int +__printf_puts(struct __printf_io *io, const void *ptr, int len) +{ + + +#if 0 + if (io->fp->_flags & __SERR) + return (0); +#endif + if (len == 0) + return (0); + io->iovp->iov_base = __DECONST(void *, ptr); + io->iovp->iov_len = len; + io->uio.uio_resid += len; + io->iovp++; + io->uio.uio_iovcnt++; + if (io->uio.uio_iovcnt >= NIOV) + __printf_flush(io); + return (len); +} + +__private_extern__ int +__printf_pad(struct __printf_io *io, int howmany, int zero) +{ + int n; + const char *with; + int ret = 0; + + if (zero) + with = zeroes; + else + with = blanks; + + if ((n = (howmany)) > 0) { + while (n > PADSIZE) { + ret += __printf_puts(io, with, PADSIZE); + n -= PADSIZE; + } + ret += __printf_puts(io, with, n); + } + return (ret); +} + +__private_extern__ int +__printf_out(struct __printf_io *io, const struct printf_info *pi, const void *ptr, int len) +{ + int ret = 0; + + if ((!pi->left) && pi->width > len) + ret += __printf_pad(io, pi->width - len, pi->pad == '0'); + ret += __printf_puts(io, ptr, len); + if (pi->left && pi->width > len) + ret += __printf_pad(io, pi->width - len, pi->pad == '0'); + return (ret); +} + + +/* percent handling -------------------------------------------------*/ + +__private_extern__ int +__printf_arginfo_pct(const struct printf_info *pi __unused, size_t n __unused, int *argt __unused) +{ + + return (0); +} + +__private_extern__ int +__printf_render_pct(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg __unused) +{ + + return (__printf_puts(io, "%", 1)); +} + +/* 'n' ---------------------------------------------------------------*/ + +__private_extern__ int +__printf_arginfo_n(const struct printf_info *pi, size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_POINTER; + return (1); +} + +/* + * This is a printf_render so that all output has been flushed before it + * gets called. + */ + +__private_extern__ int +__printf_render_n(FILE *io __unused, const struct printf_info *pi, const void *const *arg) +{ + + if (pi->is_char) + **((signed char **)arg[0]) = (signed char)pi->sofar; + else if (pi->is_short) + **((short **)arg[0]) = (short)pi->sofar; + else if (pi->is_long) + **((long **)arg[0]) = pi->sofar; + else if (pi->is_long_double) + **((long long **)arg[0]) = pi->sofar; + else if (pi->is_intmax) + **((intmax_t **)arg[0]) = pi->sofar; + else if (pi->is_ptrdiff) + **((ptrdiff_t **)arg[0]) = pi->sofar; + else if (pi->is_quad) + **((quad_t **)arg[0]) = pi->sofar; + else if (pi->is_size) + **((size_t **)arg[0]) = pi->sofar; + else + **((int **)arg[0]) = pi->sofar; + + return (0); +} + +/* dynamic array handling -------------------------------------------------*/ +#define ARRAYDELTA 8 + +struct array { +#ifdef XPRINTF_PERF + struct array *next; +#endif /* XPRINTF_PERF */ + void *data; + int itemsize; + int max; +}; + +#ifdef XPRINTF_PERF +__private_extern__ +#else /* !XPRINTF_PERF */ +static +#endif /* !XPRINTF_PERF */ +void +arrayfree(struct array *a) +{ + if(a) free(a->data); +} + +static void * +arrayget(struct array *a, int i) +{ + if (i >= a->max) { + int oldsize = a->max * a->itemsize; + int newmax = i + ARRAYDELTA; + int newsize = newmax * a->itemsize; + void *newdata = realloc(a->data, newsize); + if(!newdata) return NULL; + bzero(newdata + oldsize, newsize - oldsize); + a->data = newdata; + a->max = newmax; + } + return a->data + i * a->itemsize; +} + +static struct array * +arrayinit(struct array *a, int itemsize) +{ + a->data = CALLOC(ARRAYDELTA, itemsize); + if(!a->data) return NULL; + a->itemsize = itemsize; + a->max = ARRAYDELTA; + return a; +} + +/* dynamic array caching -------------------------------------------------*/ +/* + * Normally, dynamic array structures are created on the stack, and array + * itself is freshly allocated, and then freed when no longer needed. When + * the XPRINTF_PERF macro is defined, the dynamic array structures associated + * with all-in-one printf variants are not freed, but store in a cache for + * later use (dynamic array structures used for compile/execute continue to + * be freed after they are no longer needed). This means there should be + * at most one structure in the cached per thread that actually used the + * all-in-one printf variant. + * + * The amount of memory that is cached is fairly small, totally about 1K + * for three structures used by a format string using ten conversion + * specifiers. This is too small for purgeable memory. + * + * However, we do flush these caches in case we every are unable to allocate + * memory, and retry the allocation, just in case. + */ +#ifdef XPRINTF_PERF +static OSQueueHead arg_type_queue = OS_ATOMIC_QUEUE_INIT; +static OSQueueHead printf_info_queue = OS_ATOMIC_QUEUE_INIT; +static OSQueueHead union_arg_queue = OS_ATOMIC_QUEUE_INIT; + +#define DEFINE_DEQUEUE(which, type) \ +static struct array * \ +which ## _dequeue(void) \ +{ \ + struct array *a = (struct array *)OSAtomicDequeue(&which ## _queue, offsetof(struct array, next)); \ + \ + if (a) { \ + bzero(a->data, a->max * a->itemsize); \ + return a; \ + } \ + a = (struct array *)MALLOC(sizeof(*a)); \ + if (!a) return NULL; \ + if (!arrayinit(a, sizeof(type))) { \ + free(a); \ + return NULL; \ + } \ + return a; \ +} + +#define DEFINE_ENQUEUE(which) \ +__private_extern__ void \ +which ## _enqueue(struct array *a) \ +{ \ + if (!a) return; \ + OSAtomicEnqueue(&which ## _queue, a, offsetof(struct array, next)); \ +} + +#define DEFINE_FLUSH(which) \ +static void \ +which ## _flush(void) \ +{ \ + struct array *a; \ + while((a = (struct array *)OSAtomicDequeue(&which ## _queue, offsetof(struct array, next))) != NULL) { \ + arrayfree(a); \ + free(a); \ + } \ +} + +DEFINE_DEQUEUE(arg_type, int) +DEFINE_ENQUEUE(arg_type) +DEFINE_FLUSH(arg_type) +DEFINE_DEQUEUE(printf_info, struct printf_info) +DEFINE_ENQUEUE(printf_info) +DEFINE_FLUSH(printf_info) +DEFINE_DEQUEUE(union_arg, union arg) +DEFINE_ENQUEUE(union_arg) +DEFINE_FLUSH(union_arg) + +static void +flush_queues(void) +{ + arg_type_flush(); + printf_info_flush(); + union_arg_flush(); +} + +__private_extern__ void * +xprintf_calloc(size_t count, size_t size) +{ + void *x = calloc(count, size); + if(!x) { + flush_queues(); + x = calloc(count, size); + } + return x; +} + +__private_extern__ void * +xprintf_malloc(size_t size) +{ + void *x = malloc(size); + if(!x) { + flush_queues(); + x = malloc(size); + } + return x; +} + +#if 0 +void +show_queues(void) +{ + struct array *a; + printf("arg_type:"); + while((a = (struct array *)OSAtomicDequeue(&arg_type_queue, offsetof(struct array, next))) != NULL) printf("\n%p", a); + printf("\nprintf_info:"); + while((a = (struct array *)OSAtomicDequeue(&printf_info_queue, offsetof(struct array, next))) != NULL) printf("\n%p", a); + printf("\nunion_arg:"); + while((a = (struct array *)OSAtomicDequeue(&union_arg_queue, offsetof(struct array, next))) != NULL) printf("\n%p", a); + printf("\n"); +} +#endif +#endif /* XPRINTF_PERF */ + +/* -------------------------------------------------------------------------*/ + +__private_extern__ int +__printf_comp(printf_comp_t restrict pc, printf_domain_t restrict domain) +{ + struct printf_info *pi, *pil; + const char *fmt; + int ch, pii; + int *argt; + int nextarg; + int maxarg; + int ret = 0; + int n; +#ifndef XPRINTF_PERF + struct array piarr, argtarr; +#endif /* XPRINTF_PERF */ + struct array *pa, *aa; + + fmt = pc->fmt; + maxarg = 0; + nextarg = 1; +#ifdef XPRINTF_PERF + pa = printf_info_dequeue(); +#else /* !XPRINTF_PERF */ + pa = arrayinit(&piarr, sizeof(*pi)); +#endif /* !XPRINTF_PERF */ + if (!pa) { +#ifdef XPRINTF_PERF + flush_queues(); +#endif /* XPRINTF_PERF */ + return EOF; + } +#ifdef XPRINTF_PERF + pc->pa = pa; + aa = arg_type_dequeue(); +#else /* !XPRINTF_PERF */ + aa = arrayinit(&argtarr, sizeof(*argt)); +#endif /* !XPRINTF_PERF */ + if (!aa) { + arrayfree(pa); +#ifdef XPRINTF_PERF + free(pa); + flush_queues(); +#endif /* XPRINTF_PERF */ + return EOF; + } +#ifdef XPRINTF_PERF + pc->aa = aa; +#endif /* XPRINTF_PERF */ + for (pii = 0; ; pii++) { + pi = arrayget(pa, pii); + if (!pi) { + ret = EOF; + goto error; + } + pil = pi; + if (*fmt == '\0') + break; + pil = pi + 1; + pi->prec = -1; + pi->pad = ' '; +#ifdef VECTORS + pi->vsep = 'X'; /* Illegal value, changed to defaults later. */ +#endif /* VECTORS */ + pi->begin = pi->end = fmt; + while (*fmt != '\0' && *fmt != '%') + pi->end = ++fmt; + if (*fmt == '\0') + break; + fmt++; + for (;;) { + pi->spec = *fmt; + switch (pi->spec) { + case ' ': + /*- + * ``If the space and + flags both appear, the space + * flag will be ignored.'' + * -- ANSI X3J11 + */ + if (pi->showsign == 0) { + pi->space = 1; + pi->signchar = ' '; + } + fmt++; + continue; + case '#': + pi->alt = 1; + fmt++; + continue; +#ifdef VECTORS + case ',': case ';': case ':': case '_': + pi->vsep = pi->spec; + fmt++; + continue; +#endif /* VECTORS */ + case '.': + pi->prec = 0; + fmt++; + if (*fmt == '*') { + fmt++; + /* Look for *nn$ and deal with it */ + n = 0; + while (*fmt != '\0' && is_digit(*fmt)) { + n *= 10; + n += to_digit(*fmt); + fmt++; + } + if (*fmt == '$') { + if ((n + 1) > maxarg) + maxarg = (n + 1); + fmt++; + } else n = nextarg++; + pi->get_prec = n; + argt = (int *)arrayget(aa, n); + if (!argt) { + ret = EOF; + goto error; + } + *argt = PA_INT; + continue; + } + while (*fmt != '\0' && is_digit(*fmt)) { + pi->prec *= 10; + pi->prec += to_digit(*fmt); + fmt++; + } + continue; + case '-': + pi->left = 1; + fmt++; + continue; + case '+': + pi->showsign = 1; + pi->signchar = '+'; + fmt++; + continue; + case '*': + fmt++; + /* Look for *nn$ and deal with it */ + n = 0; + while (*fmt != '\0' && is_digit(*fmt)) { + n *= 10; + n += to_digit(*fmt); + fmt++; + } + if (*fmt == '$') { + if ((n + 1) > maxarg) + maxarg = (n + 1); + fmt++; + } else n = nextarg++; + pi->get_width = n; + argt = (int *)arrayget(aa, n); + if (!argt) { + ret = EOF; + goto error; + } + *argt = PA_INT; + continue; + case '%': + fmt++; + break; + case '\'': + pi->group = 1; + fmt++; + continue; + case '0': + /*- + * ``Note that 0 is taken as a flag, not as the + * beginning of a field width.'' + * -- ANSI X3J11 + */ + pi->pad = '0'; + fmt++; + continue; + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + n = 0; + while (*fmt != '\0' && is_digit(*fmt)) { + n *= 10; + n += to_digit(*fmt); + fmt++; + } + if (*fmt == '$') { + if (nextarg > maxarg) + maxarg = nextarg; + nextarg = n; + fmt++; + } else + pi->width = n; + continue; +#if 0 + case 'D': + case 'O': + case 'U': + pi->spec += ('a' - 'A'); + pi->is_intmax = 0; + if (pi->is_long_double || pi->is_quad) { + pi->is_long = 0; + pi->is_long_double = 1; + } else { + pi->is_long = 1; + pi->is_long_double = 0; + } + fmt++; + break; +#endif + case 'j': + pi->is_intmax = 1; + fmt++; + continue; + case 'q': + pi->is_long = 0; + pi->is_quad = 1; + fmt++; + continue; + case 'L': + pi->is_long_double = 1; + fmt++; + continue; + case 'h': + fmt++; + if (*fmt == 'h') { + fmt++; + pi->is_char = 1; + } else { + pi->is_short = 1; + } + continue; + case 'l': + fmt++; + if (*fmt == 'l') { + fmt++; + pi->is_long_double = 1; + pi->is_quad = 0; + } else { + pi->is_quad = 0; + pi->is_long = 1; + } + continue; + case 't': + pi->is_ptrdiff = 1; + fmt++; + continue; + case 'v': +#ifdef VECTORS + pi->is_vec = 1; +#endif /* VECTORS */ + fmt++; + continue; + case 'z': + pi->is_size = 1; + fmt++; + continue; + default: + fmt++; + break; + } + if (printf_tbl_in_range(pi->spec)) { + switch(domain->type[printf_tbl_index(pi->spec)]) { + /* ignore PRINTF_DOMAIN_UNUSED until later */ + case PRINTF_DOMAIN_FLAG: + errx(1, "Unexpected flag: %c", pi->spec); + case PRINTF_DOMAIN_GLIBC_API: + case PRINTF_DOMAIN_FBSD_API: + /* + * Insure that there are always + * __PRINTFMAXARG available. + */ + if (!arrayget(aa, nextarg + __PRINTFMAXARG - 1)) { + ret = EOF; + goto error; + } + pi->context = domain->tbl[printf_tbl_index(pi->spec)].context; + pi->loc = pc->loc; + ch = domain->tbl[printf_tbl_index(pi->spec)].arginfo( + pi, __PRINTFMAXARG, arrayget(aa, nextarg)); + if (ch > 0) + pi->arg[0] = (void *)(long)nextarg; + if (ch > 1) + pi->arg[1] = (void *)(long)(nextarg + 1); + nextarg += ch; + break; + } + } + break; + } + } + if (nextarg > maxarg) + maxarg = nextarg; + pc->argt = aa->data; + pc->pi = pa->data; + pc->pil = pil; + pc->maxarg = ch = maxarg; + if (ch < 1) ch = 1; +#ifdef XPRINTF_PERF + pc->ua = union_arg_dequeue(); + if (!pc->ua) { + ret = EOF; + goto error; + } + if (!arrayget(pc->ua, ch)) { + union_arg_enqueue(pc->ua); + ret = EOF; + goto error; + } + pc->args = pc->ua->data; +#else /* !XPRINTF_PERF */ + pc->args = (union arg *)malloc(ch * sizeof(*pc->args)); + if (!pc->args) { + ret = EOF; + goto error; + } +#endif /* !XPRINTF_PERF */ + for (pi = pc->pi; pi < pil; pi++) { + if (pi->arg[0]) pi->arg[0] = &pc->args[(long)pi->arg[0]]; + if (pi->arg[1]) pi->arg[1] = &pc->args[(long)pi->arg[1]]; + } +#if 0 + fprintf(stderr, "fmt0 <%s>\n", fmt0); + fprintf(stderr, "pil %p\n", pil); +#endif + pc->domain = domain; + + return (ret); +error: + arrayfree(pa); + arrayfree(aa); +#ifdef XPRINTF_PERF + free(pa); + free(aa); + flush_queues(); +#endif /* XPRINTF_PERF */ + return (ret); +} + +__private_extern__ int +__printf_exec(printf_comp_t restrict pc, FILE * restrict fp, va_list ap) +{ + struct printf_info *pi; + int ch; + int ret = 0; + int n; + struct __printf_io io; + + __printf_init(&io); + io.fp = fp; + + for (ch = 1; ch < pc->maxarg; ch++) { +#if 0 + fprintf(stderr, "arg %d %x\n", ch, pc->argt[ch]); +#endif + switch(pc->argt[ch]) { + case PA_CHAR: + pc->args[ch].intarg = (char)va_arg (ap, int); + break; + case PA_INT: + pc->args[ch].intarg = va_arg (ap, int); + break; + case PA_INT | PA_FLAG_SHORT: + pc->args[ch].intarg = (short)va_arg (ap, int); + break; + case PA_INT | PA_FLAG_LONG: + pc->args[ch].longarg = va_arg (ap, long); + break; + case PA_INT | PA_FLAG_INTMAX: + pc->args[ch].intmaxarg = va_arg (ap, intmax_t); + break; + case PA_INT | PA_FLAG_QUAD: + pc->args[ch].intmaxarg = va_arg (ap, quad_t); + break; + case PA_INT | PA_FLAG_LONG_LONG: + pc->args[ch].intmaxarg = va_arg (ap, long long); + break; + case PA_INT | PA_FLAG_SIZE: + pc->args[ch].intmaxarg = va_arg (ap, size_t); + break; + case PA_INT | PA_FLAG_PTRDIFF: + pc->args[ch].intmaxarg = (unsigned long)va_arg (ap, ptrdiff_t); + break; + case PA_WCHAR: + pc->args[ch].wintarg = va_arg (ap, wint_t); + break; + case PA_POINTER: + pc->args[ch].pvoidarg = va_arg (ap, void *); + break; + case PA_STRING: + pc->args[ch].pchararg = va_arg (ap, char *); + break; + case PA_WSTRING: + pc->args[ch].pwchararg = va_arg (ap, wchar_t *); + break; + case PA_DOUBLE: +#ifndef NO_FLOATING_POINT + pc->args[ch].doublearg = va_arg (ap, double); +#endif + break; + case PA_DOUBLE | PA_FLAG_LONG_DOUBLE: +#ifndef NO_FLOATING_POINT + pc->args[ch].longdoublearg = va_arg (ap, long double); +#endif + break; +#ifdef VECTORS + case PA_VECTOR: + pc->args[ch].vectorarg = va_arg (ap, VECTORTYPE); + break; +#endif /* VECTORS */ + default: + errx(1, "argtype = %x (fmt = \"%s\")\n", + pc->argt[ch], pc->fmt); + } + } + for (pi = pc->pi; pi < pc->pil; pi++) { +#if 0 + fprintf(stderr, "pi %p", pi); + fprintf(stderr, " spec '%c'", pi->spec); + fprintf(stderr, " args %d", + ((uintptr_t)pi->arg[0] - (uintptr_t)pc->args) / sizeof pc->args[0]); + if (pi->width) fprintf(stderr, " width %d", pi->width); + if (pi->pad) fprintf(stderr, " pad 0x%x", pi->pad); + if (pi->left) fprintf(stderr, " left"); + if (pi->showsign) fprintf(stderr, " showsign"); + if (pi->signchar) fprintf(stderr, " signchar 0x%x", pi->signchar); + if (pi->prec != -1) fprintf(stderr, " prec %d", pi->prec); + if (pi->is_char) fprintf(stderr, " char"); + if (pi->is_short) fprintf(stderr, " short"); + if (pi->is_long) fprintf(stderr, " long"); + if (pi->is_long_double) fprintf(stderr, " long_double"); + fprintf(stderr, "\n"); + fprintf(stderr, "\t\"%.*s\"\n", pi->end - pi->begin, pi->begin); +#endif + if (pi->get_width) { + pi->width = pc->args[pi->get_width].intarg; + /*- + * ``A negative field width argument is taken as a + * - flag followed by a positive field width.'' + * -- ANSI X3J11 + * They don't exclude field widths read from args. + */ + if (pi->width < 0) { + pi->left = 1; + pi->width = -pi->width; + } + } + if (pi->get_prec) + pi->prec = pc->args[pi->get_prec].intarg; + ret += __printf_puts(&io, pi->begin, pi->end - pi->begin); + if (pi->spec) { + if (!printf_tbl_in_range(pi->spec)) goto unused; + switch(pc->domain->type[printf_tbl_index(pi->spec)]) { + case PRINTF_DOMAIN_UNUSED: + unused: + { + char unknown = pi->spec; + ret += __printf_out(&io, pi, &unknown, 1); + break; + } + case PRINTF_DOMAIN_GLIBC_API: + __printf_flush(&io); + pi->sofar = ret; + ret += ((printf_function *)pc->domain->tbl[printf_tbl_index(pi->spec)].render)( + fp, pi, (const void *)pi->arg); + break; + case PRINTF_DOMAIN_FBSD_API: + pi->sofar = ret; + n = ((printf_render *)pc->domain->tbl[printf_tbl_index(pi->spec)].render)( + &io, pi, (const void *)pi->arg); + if (n < 0) + io.fp->_flags |= __SERR; + else + ret += n; + break; + } + } + } + __printf_flush(&io); + return (ret); +} + +__private_extern__ int +__v2printf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt, va_list ap) +{ + struct _printf_compiled spc; + int ret, saverrno; + + /* + * All the printf family (including extensible printf variants) funnel + * down to this point. So we can do common work here, and then fork + * out to the appropriate handler. + */ + /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ + if (prepwrite(fp) != 0) { + errno = EBADF; + return (EOF); + } + ORIENT(fp, -1); + + if (pc == XPRINTF_PLAIN) { + NORMALIZE_LOCALE(loc); +#ifdef XPRINTF_DEBUG + if (!__use_xprintf) +#endif + return __vfprintf(fp, loc, fmt, ap); +#ifdef XPRINTF_DEBUG + xprintf_domain_init(); + domain = xprintf_domain_global; +#endif + } else if (pc) { + pthread_mutex_lock(&pc->mutex); + pthread_rwlock_rdlock(&pc->domain->rwlock); + ret = __printf_exec(pc, fp, ap); + saverrno = errno; + pthread_rwlock_unlock(&pc->domain->rwlock); + pthread_mutex_unlock(&pc->mutex); + errno = saverrno; + return ret; + } + if (!domain) { + errno = EINVAL; + return EOF; + } + xprintf_domain_init(); + bzero(&spc, sizeof(spc)); + spc.fmt = fmt; + DEFAULT_CURRENT_LOCALE(loc); + XL_RETAIN(loc); + spc.loc = loc; + /* + * We don't need to lock the printf_comp_t mutex, since the + * printf_comp_t was just created on the stack, and is private. + */ + pthread_rwlock_rdlock(&domain->rwlock); + if (__printf_comp(&spc, domain) < 0) { + saverrno = errno; + pthread_rwlock_unlock(&domain->rwlock); + XL_RELEASE(loc); + errno = saverrno; + return EOF; + } + ret = __printf_exec(&spc, fp, ap); + saverrno = errno; + pthread_rwlock_unlock(&domain->rwlock); + XL_RELEASE(loc); + +#ifdef XPRINTF_PERF + printf_info_enqueue(spc.pa); + arg_type_enqueue(spc.aa); + union_arg_enqueue(spc.ua); +#else /* !XPRINTF_PERF */ + free(spc.pi); + free(spc.argt); + free(spc.args); +#endif /* !XPRINTF_PERF */ + errno = saverrno; + return ret; +} + +extern int __fflush(FILE *fp); + +/* + * Helper function for `fprintf to unbuffered unix file': creates a + * temporary buffer. We only work on write-only files; this avoids + * worries about ungetc buffers and so forth. + */ +static int +__v3printf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt, va_list ap) +{ + int ret; + FILE fake; + struct __sFILEX extra; + unsigned char buf[BUFSIZ]; + + fake._extra = &extra; + INITEXTRA(&fake); + + /* copy the important variables */ + fake._flags = fp->_flags & ~__SNBF; + fake._file = fp->_file; + fake._cookie = fp->_cookie; + fake._write = fp->_write; + fake._orientation = fp->_orientation; + fake._mbstate = fp->_mbstate; + + /* set up the buffer */ + fake._bf._base = fake._p = buf; + fake._bf._size = fake._w = sizeof(buf); + fake._lbfsize = 0; /* not actually used, but Just In Case */ + + /* do the work, then copy any error status */ + ret = __v2printf(pc, domain, &fake, loc, fmt, ap); + if (ret >= 0 && __fflush(&fake)) + ret = EOF; + if (fake._flags & __SERR) + fp->_flags |= __SERR; + return (ret); +} + +__private_extern__ int +__xvprintf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt0, va_list ap) +{ + int ret; + + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) + ret = __v3printf(pc, domain, fp, loc, fmt0, ap); + else + ret = __v2printf(pc, domain, fp, loc, fmt0, ap); + return ret; +} + +/* extending ---------------------------------------------------------*/ + +// No global domain support +#if 0 +int +register_printf_function(int spec, printf_function *render, printf_arginfo_function *arginfo) +{ + return register_printf_domain_function(NULL, spec, render, arginfo); +} + +__private_extern__ int +register_printf_render(int spec, printf_render *render, printf_arginfo_function *arginfo) +{ + return register_printf_domain_render(NULL, spec, render, arginfo); +} + +int +register_printf_render_std(const char *specs) +{ + return register_printf_domain_render_std(NULL, specs); +} +#endif + +#ifdef VECTORS +/* vector support ----------------------------------------------------*/ + +#define PRINTVECTOR(_io, _pi, _arg, _cnt, _type, _elem, _render, _ret) { \ + int i; \ + _type a, *ap; \ + a = (_type)(_arg)->_elem[0]; \ + ap = &a; \ + (_ret) += _render((_io), (_pi), (const void *)&ap); \ + for(i = 1; i < (_cnt); i++) { \ + (_ret) += __printf_puts((_io), (_pi)->begin, (_pi)->end - (_pi)->begin); \ + a = (_type)(_arg)->_elem[i]; \ + (_ret) += _render((_io), (_pi), (const void *)&ap); \ + } \ +} + +#define PRINTVECTOR_P(_io, _pi, _arg, _cnt, _elem, _render, _ret) { \ + int i; \ + void * a, *ap; \ + a = (void *)(uintptr_t)(_arg)->_elem[0]; \ + ap = &a; \ + (_ret) += _render((_io), (_pi), (const void *)&ap); \ + for(i = 1; i < (_cnt); i++) { \ + (_ret) += __printf_puts((_io), (_pi)->begin, (_pi)->end - (_pi)->begin); \ + a = (void *)(uintptr_t)(_arg)->_elem[i]; \ + (_ret) += _render((_io), (_pi), (const void *)&ap); \ + } \ +} + +__private_extern__ int +__xprintf_vector(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + char vsep; /* Vector separator character. */ + const union arg *argp; + int ret = 0; + struct printf_info info = *pi; + + argp = arg[0]; + vsep = pi->vsep; + if (vsep == 'X') { + if (pi->spec == 'c') + vsep = '\0'; + else + vsep = ' '; + } + info.begin = info.end = &vsep; + if (vsep) info.end++; + info.is_vec = 0; + + if (pi->is_short) { + if (pi->spec == 'p') { + PRINTVECTOR_P(io, &info, argp, 8, vushortarg, __printf_render_ptr, ret); + } else { + PRINTVECTOR(io, &info, argp, 8, unsigned int, vushortarg, __printf_render_int, ret); + } + } else if (pi->is_long) { + info.is_long = 0; + if (pi->spec == 'p') { + PRINTVECTOR_P(io, &info, argp, 4, vuintarg, __printf_render_ptr, ret); + } else { + PRINTVECTOR(io, &info, argp, 4, unsigned int, vuintarg, __printf_render_int, ret); + } +#ifdef V64TYPE + } else if (pi->is_long_double) { + switch (pi->spec) { + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + info.is_long_double = 0; + PRINTVECTOR(io, &info, argp, 2, double, vdoublearg, __printf_render_float, ret); + break; + case 'p': + info.is_long_double = 0; + PRINTVECTOR_P(io, &info, argp, 2, vulonglongarg, __printf_render_ptr, ret); + break; + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + PRINTVECTOR(io, &info, argp, 2, unsigned long long, vulonglongarg, __printf_render_int, ret); + break; + default: + /* + * The default case should never + * happen. + */ + case 'c': + info.is_long_double = 0; + PRINTVECTOR(io, &info, argp, 16, unsigned int, vuchararg, __printf_render_chr, ret); + } +#endif /* V64TYPE */ + } else { + switch (pi->spec) { + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + PRINTVECTOR(io, &info, argp, 4, double, vfloatarg, __printf_render_float, ret); + break; + default: + /* + * The default case should never + * happen. + */ + case 'p': + PRINTVECTOR_P(io, &info, argp, 16, vuchararg, __printf_render_ptr, ret); + break; + case 'd': + case 'i': + case 'u': + case 'o': + case 'x': + case 'X': + info.is_char = 1; + PRINTVECTOR(io, &info, argp, 16, unsigned int, vuchararg, __printf_render_int, ret); + break; + case 'c': + PRINTVECTOR(io, &info, argp, 16, unsigned int, vuchararg, __printf_render_chr, ret); + } + } + return ret; +} +#endif /* VECTORS */ diff --git a/src/libc/stdio/FreeBSD/xprintf_errno.c b/src/libc/stdio/FreeBSD/xprintf_errno.c new file mode 100644 index 000000000..83bd01980 --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf_errno.c @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdio/xprintf_errno.c,v 1.1 2006/01/25 12:45:24 phk Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "printf.h" +#include "xprintf_private.h" + +__private_extern__ int +__printf_arginfo_errno(const struct printf_info *pi __unused, size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_INT; + return (1); +} + +__private_extern__ int +__printf_render_errno(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg) +{ + int ret, error; + char buf[64]; + const char *p; + + ret = 0; + error = *((const int *)arg[0]); + if (error >= 0 && error < sys_nerr) { + p = strerror(error); + return (__printf_out(io, pi, p, strlen(p))); + } + sprintf(buf, "errno=%d/0x%x", error, error); + ret += __printf_out(io, pi, buf, strlen(buf)); + __printf_flush(io); + return(ret); +} diff --git a/src/libc/stdio/FreeBSD/xprintf_float.c b/src/libc/stdio/FreeBSD/xprintf_float.c new file mode 100644 index 000000000..9f4c60e62 --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf_float.c @@ -0,0 +1,445 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdio/xprintf_float.c,v 1.1 2005/12/16 18:56:38 phk Exp $ + */ + +#include +#include "xlocale_private.h" +#include +#include +#include +#include +#include + +#define dtoa __dtoa +#define freedtoa __freedtoa + +#include +#include +#include "gdtoa.h" +#include "floatio.h" +#include "printf.h" +#include "xprintf_private.h" +#include + +/* + * The size of the buffer we use as scratch space for integer + * conversions, among other things. Technically, we would need the + * most space for base 10 conversions with thousands' grouping + * characters between each pair of digits. 100 bytes is a + * conservative overestimate even for a 128-bit uintmax_t. + */ +#define BUF 100 + +#define DEFPREC 6 /* Default FP precision */ + + +/* various globals ---------------------------------------------------*/ + + +/* padding function---------------------------------------------------*/ + +#define PRINTANDPAD(p, ep, len, with) do { \ + n2 = (ep) - (p); \ + if (n2 > (len)) \ + n2 = (len); \ + if (n2 > 0) \ + ret += __printf_puts(io, (p), n2); \ + ret += __printf_pad(io, (len) - (n2 > 0 ? n2 : 0), (with)); \ +} while(0) + +/* misc --------------------------------------------------------------*/ + +extern const char *__fix_nogrouping(const char *str); + +#define to_char(n) ((n) + '0') + +static int +exponent(char *p0, int expo, int fmtch) +{ + char *p, *t; + char expbuf[MAXEXPDIG]; + + p = p0; + *p++ = fmtch; + if (expo < 0) { + expo = -expo; + *p++ = '-'; + } + else + *p++ = '+'; + t = expbuf + MAXEXPDIG; + if (expo > 9) { + do { + *--t = to_char(expo % 10); + } while ((expo /= 10) > 9); + *--t = to_char(expo); + for (; t < expbuf + MAXEXPDIG; *p++ = *t++) + ; + } + else { + /* + * Exponents for decimal floating point conversions + * (%[eEgG]) must be at least two characters long, + * whereas exponents for hexadecimal conversions can + * be only one character long. + */ + if (fmtch == 'e' || fmtch == 'E') + *p++ = '0'; + *p++ = to_char(expo); + } + return (p - p0); +} + +/* 'f' ---------------------------------------------------------------*/ + +__private_extern__ int +__printf_arginfo_float(const struct printf_info *pi, size_t n, int *argt) +{ + assert (n > 0); +#ifdef VECTORS + if (pi->is_vec) + argt[0] = PA_VECTOR; + else { +#endif /* VECTORS */ + argt[0] = PA_DOUBLE; + if (pi->is_long_double) + argt[0] |= PA_FLAG_LONG_DOUBLE; +#ifdef VECTORS + } +#endif /* VECTORS */ + return (1); +} + +/* + * We can decompose the printed representation of floating + * point numbers into several parts, some of which may be empty: + * + * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ + * A B ---C--- D E F + * + * A: 'sign' holds this value if present; '\0' otherwise + * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal + * C: cp points to the string MMMNNN. Leading and trailing + * zeros are not in the string and must be added. + * D: expchar holds this character; '\0' if no exponent, e.g. %f + * F: at least two digits for decimal, at least one digit for hex + */ + +__private_extern__ int +__printf_render_float(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + int prec; /* precision from format; <0 for N/A */ + char *dtoaresult; /* buffer allocated by dtoa */ + char expchar; /* exponent character: [eEpP\0] */ + char *cp; + int expt; /* integer value of exponent */ + int signflag; /* true if float is negative */ + char *dtoaend; /* pointer to end of converted digits */ + char sign; /* sign prefix (' ', '+', '-', or \0) */ + int size; /* size of converted field or string */ + int ndig; /* actual number of digits returned by dtoa */ + int expsize; /* character count for expstr */ + char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ + int nseps; /* number of group separators with ' */ + int nrepeats; /* number of repeats of the last group */ + const char *grouping; /* locale specific numeric grouping rules */ + int lead; /* sig figs before decimal or group sep */ + long double ld; + double d; + int realsz; /* field size expanded by dprec, sign, etc */ + int dprec; /* a copy of prec if [diouxX], 0 otherwise */ + char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */ + int prsize; /* max size of printed field */ + int ret; /* return value accumulator */ + const char *decimal_point; /* locale specific decimal point */ + int decimal_point_len; /* length of locale specific decimal point */ + int n2; /* XXX: for PRINTANDPAD */ + const char *thousands_sep; /* locale specific thousands separator */ + int thousands_sep_len; /* length of locale specific thousands separator */ + char buf[BUF]; /* buffer with space for digits of uintmax_t */ + const char *xdigs; + int flag; + +#ifdef VECTORS + if (pi->is_vec) return __xprintf_vector(io, pi, arg); +#endif /* VECTORS */ + + prec = pi->prec; + ox[1] = '\0'; + sign = pi->signchar; + flag = 0; + ret = 0; + + thousands_sep = localeconv_l(pi->loc)->thousands_sep; + thousands_sep_len = strlen(thousands_sep); + grouping = NULL; + if (pi->group) + grouping = __fix_nogrouping(localeconv_l(pi->loc)->grouping); + decimal_point = localeconv_l(pi->loc)->decimal_point; + decimal_point_len = strlen(decimal_point); + dprec = -1; + + switch(pi->spec) { + case 'a': + case 'A': + if (pi->spec == 'a') { + ox[1] = 'x'; + xdigs = __lowercase_hex; + expchar = 'p'; + } else { + ox[1] = 'X'; + xdigs = __uppercase_hex; + expchar = 'P'; + } + if (prec >= 0) + prec++; + if (pi->is_long_double) { + ld = *((long double *)arg[0]); + dtoaresult = cp = + __hldtoa(ld, xdigs, prec, + &expt, &signflag, &dtoaend); + } else { + d = *((double *)arg[0]); + dtoaresult = cp = + __hdtoa(d, xdigs, prec, + &expt, &signflag, &dtoaend); + } + if (prec < 0) + prec = dtoaend - cp; + if (expt == INT_MAX) + ox[1] = '\0'; + goto fp_common; + case 'e': + case 'E': + expchar = pi->spec; + if (prec < 0) /* account for digit before decpt */ + prec = DEFPREC + 1; + else + prec++; + break; + case 'f': + case 'F': + expchar = '\0'; + break; + case 'g': + case 'G': + expchar = pi->spec - ('g' - 'e'); + if (prec == 0) + prec = 1; + break; + default: + assert(pi->spec == 'f'); + } + + if (prec < 0) + prec = DEFPREC; + if (pi->is_long_double) { + ld = *((long double *)arg[0]); + dtoaresult = cp = + __ldtoa(&ld, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + } else { + d = *((double *)arg[0]); + dtoaresult = cp = + dtoa(d, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + if (expt == 9999) + expt = INT_MAX; + } +fp_common: + if (signflag) + sign = '-'; + if (expt == INT_MAX) { /* inf or nan */ + if (*cp == 'N') { + cp = (pi->spec >= 'a') ? "nan" : "NAN"; + sign = '\0'; + } else + cp = (pi->spec >= 'a') ? "inf" : "INF"; + size = 3; + flag = 1; + goto here; + } + ndig = dtoaend - cp; + if (pi->spec == 'g' || pi->spec == 'G') { + if (expt > -4 && expt <= prec) { + /* Make %[gG] smell like %[fF] */ + expchar = '\0'; + if (pi->alt) + prec -= expt; + else + prec = ndig - expt; + if (prec < 0) + prec = 0; + } else { + /* + * Make %[gG] smell like %[eE], but + * trim trailing zeroes if no # flag. + */ + if (!pi->alt) + prec = ndig; + } + } + if (expchar) { + expsize = exponent(expstr, expt - 1, expchar); + size = expsize + prec; + if (prec > 1 || pi->alt) + ++size; + } else { + /* space for digits before decimal point */ + if (expt > 0) + size = expt; + else /* "0" */ + size = 1; + /* space for decimal pt and following digits */ + if (prec || pi->alt) + size += prec + 1; + if (grouping && expt > 0) { + /* space for thousands' grouping */ + nseps = nrepeats = 0; + lead = expt; + while (*grouping != CHAR_MAX) { + if (lead <= *grouping) + break; + lead -= *grouping; + if (*(grouping+1)) { + nseps++; + grouping++; + } else + nrepeats++; + } + size += nseps + nrepeats; + } else + lead = expt; + } + +here: + /* + * All reasonable formats wind up here. At this point, `cp' + * points to a string which (if not flags&LADJUST) should be + * padded out to `width' places. If flags&ZEROPAD, it should + * first be prefixed by any sign or other prefix; otherwise, + * it should be blank padded before the prefix is emitted. + * After any left-hand padding and prefixing, emit zeroes + * required by a decimal [diouxX] precision, then print the + * string proper, then emit zeroes required by any leftover + * floating precision; finally, if LADJUST, pad with blanks. + * + * Compute actual size, so we know how much to pad. + * size excludes decimal prec; realsz includes it. + */ + realsz = dprec > size ? dprec : size; + if (sign) + realsz++; + if (ox[1]) + realsz += 2; + + prsize = pi->width > realsz ? pi->width : realsz; + + /* right-adjusting blank padding */ + if (pi->pad != '0' && pi->left == 0) + ret += __printf_pad(io, pi->width - realsz, 0); + + /* prefix */ + if (sign) + ret += __printf_puts(io, &sign, 1); + + if (ox[1]) { /* ox[1] is either x, X, or \0 */ + ox[0] = '0'; + ret += __printf_puts(io, ox, 2); + } + + /* right-adjusting zero padding */ + if (pi->pad == '0' && pi->left == 0) + ret += __printf_pad(io, pi->width - realsz, 1); + + /* leading zeroes from decimal precision */ + ret += __printf_pad(io, dprec - size, 1); + + if (flag) + ret += __printf_puts(io, cp, size); + else { + /* glue together f_p fragments */ + if (!expchar) { /* %[fF] or sufficiently short %[gG] */ + if (expt <= 0) { + ret += __printf_puts(io, "0", 1); + if (prec || pi->alt) + ret += __printf_puts(io, decimal_point, decimal_point_len); + ret += __printf_pad(io, -expt, 1); + /* already handled initial 0's */ + prec += expt; + } else { + PRINTANDPAD(cp, dtoaend, lead, 1); + cp += lead; + if (grouping) { + while (nseps>0 || nrepeats>0) { + if (nrepeats > 0) + nrepeats--; + else { + grouping--; + nseps--; + } + ret += __printf_puts(io, thousands_sep, thousands_sep_len); + PRINTANDPAD(cp,dtoaend, + *grouping, 1); + cp += *grouping; + } + if (cp > dtoaend) + cp = dtoaend; + } + if (prec || pi->alt) + ret += __printf_puts(io, decimal_point, decimal_point_len); + } + PRINTANDPAD(cp, dtoaend, prec, 1); + } else { /* %[eE] or sufficiently long %[gG] */ + if (prec > 1 || pi->alt) { + buf[0] = *cp++; + memcpy(buf + 1, decimal_point, decimal_point_len); + ret += __printf_puts(io, buf, decimal_point_len + 1); + ret += __printf_puts(io, cp, ndig-1); + ret += __printf_pad(io, prec - ndig, 1); + } else /* XeYYY */ + ret += __printf_puts(io, cp, 1); + ret += __printf_puts(io, expstr, expsize); + } + } + /* left-adjusting padding (always blank) */ + if (pi->left) + ret += __printf_pad(io, pi->width - realsz, 0); + + __printf_flush(io); + if (dtoaresult != NULL) + freedtoa(dtoaresult); + + return (ret); +} diff --git a/src/libc/stdio/FreeBSD/xprintf_hexdump.c b/src/libc/stdio/FreeBSD/xprintf_hexdump.c new file mode 100644 index 000000000..0e90ad7c8 --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf_hexdump.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdio/xprintf_hexdump.c,v 1.1 2005/12/16 18:56:38 phk Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include "printf.h" +#include "xprintf_private.h" + +__private_extern__ int +__printf_arginfo_hexdump(const struct printf_info *pi, size_t n, int *argt) +{ + + assert(n >= 2); + argt[0] = PA_POINTER; + argt[1] = PA_INT; + return (2); +} + +__private_extern__ int +__printf_render_hexdump(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + unsigned char *p; + unsigned u, l, j, a; + char buf[100], *q; + int ret; + + if (pi->width > 0 && pi->width < 16) + l = pi->width; + else + l = 16; + p = *((unsigned char **)arg[0]); + u = *((unsigned *)arg[1]); + + ret = 0; + a = 0; + while (u > 0) { + q = buf; + if (pi->showsign) + q += sprintf(q, " %04x", a); + for (j = 0; j < l && j < u; j++) + q += sprintf(q, " %02x", p[j]); + if (pi->alt) { + for (; j < l; j++) + q += sprintf(q, " "); + q += sprintf(q, " |"); + for (j = 0; j < l && j < u; j++) { + if (p[j] < ' ' || p[j] > '~') + *q++ = '.'; + else + *q++ = p[j]; + } + for (; j < l; j++) + *q++ = ' '; + *q++ = '|'; + } + if (l < u) + j = l; + else + j = u; + p += j; + u -= j; + a += j; + if (u > 0) + *q++ = '\n'; + ret += __printf_puts(io, buf + 1, q - (buf + 1)); + __printf_flush(io); + } + return (ret); +} diff --git a/src/libc/stdio/FreeBSD/xprintf_int.c b/src/libc/stdio/FreeBSD/xprintf_int.c new file mode 100644 index 000000000..fb644511d --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf_int.c @@ -0,0 +1,498 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdio/xprintf_int.c,v 1.2 2005/12/22 14:23:54 cognet Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "printf.h" +#include "xprintf_private.h" + +/* private stuff -----------------------------------------------------*/ + +union arg { + int intarg; + u_int uintarg; + long longarg; + u_long ulongarg; + intmax_t intmaxarg; + uintmax_t uintmaxarg; +}; + +/* + * Macros for converting digits to letters and vice versa + */ +#define to_char(n) ((n) + '0') + +/* various globals ---------------------------------------------------*/ + +/* + * The size of the buffer we use for integer conversions. + * Technically, we would need the most space for base 10 + * conversions with thousands' grouping characters between + * each pair of digits: 39 digits for 128 bit intmax_t plus + * 20 grouping characters (which may be multibyte). + * Use a bit more for better alignment of stuff. + */ +#define BUF 128 + +/* misc --------------------------------------------------------------*/ + +extern const char *__fix_nogrouping(const char *str); + +/* + * Convert an unsigned long to ASCII for printf purposes, returning + * a pointer to the first character of the string representation. + * Octal numbers can be forced to have a leading zero; hex numbers + * use the given digits. + */ +static char * +__ultoa(u_long val, char *endp, int base, const char *xdigs, + int needgrp, const char *thousep, int thousep_len, const char *grp) +{ + char *cp = endp; + long sval; + int ndig; + + /* + * Handle the three cases separately, in the hope of getting + * better/faster code. + */ + switch (base) { + case 10: + if (val < 10) { /* many numbers are 1 digit */ + *--cp = to_char(val); + return (cp); + } + ndig = 0; + /* + * On many machines, unsigned arithmetic is harder than + * signed arithmetic, so we do at most one unsigned mod and + * divide; this is sufficient to reduce the range of + * the incoming value to where signed arithmetic works. + */ + if (val > LONG_MAX) { + *--cp = to_char(val % 10); + ndig++; + sval = val / 10; + } else + sval = val; + do { + *--cp = to_char(sval % 10); + ndig++; + /* + * If (*grp == CHAR_MAX) then no more grouping + * should be performed. + */ + if (needgrp && ndig == *grp && *grp != CHAR_MAX + && sval > 9) { + cp -= thousep_len; + memcpy(cp, thousep, thousep_len); + ndig = 0; + /* + * If (*(grp+1) == '\0') then we have to + * use *grp character (last grouping rule) + * for all next cases + */ + if (*(grp+1) != '\0') + grp++; + } + sval /= 10; + } while (sval != 0); + break; + + case 8: + do { + *--cp = to_char(val & 7); + val >>= 3; + } while (val); + break; + + case 16: + do { + *--cp = xdigs[val & 15]; + val >>= 4; + } while (val); + break; + + default: /* oops */ + assert(base == 16); + } + return (cp); +} + + +/* Identical to __ultoa, but for intmax_t. */ +static char * +__ujtoa(uintmax_t val, char *endp, int base, const char *xdigs, + int needgrp, const char *thousep, int thousep_len, const char *grp) +{ + char *cp = endp; + intmax_t sval; + int ndig; + + switch (base) { + case 10: + if (val < 10) { + *--cp = to_char(val % 10); + return (cp); + } + ndig = 0; + if (val > INTMAX_MAX) { + *--cp = to_char(val % 10); + ndig++; + sval = val / 10; + } else + sval = val; + do { + *--cp = to_char(sval % 10); + ndig++; + /* + * If (*grp == CHAR_MAX) then no more grouping + * should be performed. + */ + if (needgrp && *grp != CHAR_MAX && ndig == *grp + && sval > 9) { + cp -= thousep_len; + memcpy(cp, thousep, thousep_len); + ndig = 0; + /* + * If (*(grp+1) == '\0') then we have to + * use *grp character (last grouping rule) + * for all next cases + */ + if (*(grp+1) != '\0') + grp++; + } + sval /= 10; + } while (sval != 0); + break; + + case 8: + do { + *--cp = to_char(val & 7); + val >>= 3; + } while (val); + break; + + case 16: + do { + *--cp = xdigs[val & 15]; + val >>= 4; + } while (val); + break; + + default: + abort(); + } + return (cp); +} + + +/* 'd' ---------------------------------------------------------------*/ + +__private_extern__ int +__printf_arginfo_int(const struct printf_info *pi, size_t n, int *argt) +{ + assert (n > 0); + argt[0] = PA_INT; +#ifdef VECTORS + if (pi->is_vec) + argt[0] = PA_VECTOR; + else +#endif /* VECTORS */ + if (pi->is_ptrdiff) + argt[0] |= PA_FLAG_PTRDIFF; + else if (pi->is_size) + argt[0] |= PA_FLAG_SIZE; + else if (pi->is_long) + argt[0] |= PA_FLAG_LONG; + else if (pi->is_intmax) + argt[0] |= PA_FLAG_INTMAX; + else if (pi->is_quad) + argt[0] |= PA_FLAG_QUAD; + else if (pi->is_long_double) + argt[0] |= PA_FLAG_LONG_LONG; + else if (pi->is_short) + argt[0] |= PA_FLAG_SHORT; + else if (pi->is_char) + argt[0] = PA_CHAR; + return (1); +} + +__private_extern__ int +__printf_render_int(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + const union arg *argp; + char buf[BUF]; + char *p, *pe; + char ns, l; + int rdx, sign, zext, ngrp; + const char *nalt, *digit; + const char *thousands_sep; /* locale specific thousands separator */ + int thousands_sep_len; /* locale specific thousands separator length */ + const char *grouping; /* locale specific numeric grouping rules */ + uintmax_t uu; + int ret; + +#ifdef VECTORS + if (pi->is_vec) return __xprintf_vector(io, pi, arg); +#endif /* VECTORS */ + + ret = 0; + nalt = NULL; + digit = __lowercase_hex; + ns = '\0'; + pe = buf + sizeof buf - 1; + + if (pi->group) { + thousands_sep = localeconv_l(pi->loc)->thousands_sep; + thousands_sep_len = strlen(thousands_sep); + grouping = __fix_nogrouping(localeconv_l(pi->loc)->grouping); + ngrp = 1; + } else { + thousands_sep = NULL; + thousands_sep_len = 0; + grouping = NULL; + ngrp = 0; + } + + switch(pi->spec) { + case 'd': + case 'i': + rdx = 10; + sign = 1; + break; + case 'X': + digit = __uppercase_hex; + /*FALLTHOUGH*/ + case 'x': + rdx = 16; + sign = 0; + break; + case 'u': + case 'U': + rdx = 10; + sign = 0; + break; + case 'o': + case 'O': + rdx = 8; + sign = 0; + break; + default: + fprintf(stderr, "pi->spec = '%c'\n", pi->spec); + assert(1 == 0); + } + argp = arg[0]; + + if (sign) + ns = pi->signchar; + + if (pi->is_long_double || pi->is_quad || pi->is_intmax || + pi->is_size || pi->is_ptrdiff) { + if (sign && argp->intmaxarg < 0) { + uu = -argp->intmaxarg; + ns = '-'; + } else + uu = argp->uintmaxarg; + } else if (pi->is_long) { + if (sign && argp->longarg < 0) { + uu = (u_long)-argp->longarg; + ns = '-'; + } else + uu = argp->ulongarg; + } else if (pi->is_short) { + if (sign && (short)argp->intarg < 0) { + uu = -(short)argp->intarg; + ns = '-'; + } else + uu = (unsigned short)argp->uintarg; + } else if (pi->is_char) { + if (sign && (signed char)argp->intarg < 0) { + uu = -(signed char)argp->intarg; + ns = '-'; + } else + uu = (unsigned char)argp->uintarg; + } else { + if (sign && argp->intarg < 0) { + uu = (unsigned)-argp->intarg; + ns = '-'; + } else + uu = argp->uintarg; + } + if (uu <= ULONG_MAX) + p = __ultoa(uu, pe, rdx, digit, ngrp, thousands_sep, thousands_sep_len, grouping); + else + p = __ujtoa(uu, pe, rdx, digit, ngrp, thousands_sep, thousands_sep_len, grouping); + + l = 0; + if (uu == 0) { + /*- + * ``The result of converting a zero value with an + * explicit precision of zero is no characters.'' + * -- ANSI X3J11 + * + * ``The C Standard is clear enough as is. The call + * printf("%#.0o", 0) should print 0.'' + * -- Defect Report #151 + */ + ; + if (pi->prec == 0 && !(pi->alt && rdx == 8)) + p = pe; + } else if (pi->alt) { + if (rdx == 8) + *--p = '0'; + if (rdx == 16) { + if (pi->spec == 'x') + nalt = "0x"; + else + nalt = "0X"; + l += 2; + } + } + l += pe - p; + if (ns) + l++; + + /*- + * ``... diouXx conversions ... if a precision is + * specified, the 0 flag will be ignored.'' + * -- ANSI X3J11 + */ + if (pi->prec > (pe - p)) + zext = pi->prec - (pe - p); + else if (pi->prec != -1) + zext = 0; + else if (pi->pad == '0' && pi->width > l && !pi->left) + zext = pi->width - l; + else + zext = 0; + + l += zext; + + while (zext > 0 && p > buf) { + *--p = '0'; + zext--; + } + + if (l < BUF) { + if (ns) { + *--p = ns; + } else if (nalt != NULL) { + *--p = nalt[1]; + *--p = nalt[0]; + } + if (pi->width > (pe - p) && !pi->left) { + l = pi->width - (pe - p); + while (l > 0 && p > buf) { + *--p = ' '; + l--; + } + if (l) + ret += __printf_pad(io, l, 0); + } + } else { + if (!pi->left && pi->width > l) + ret += __printf_pad(io, pi->width - l, 0); + if (ns != '\0') + ret += __printf_puts(io, &ns, 1); + else if (nalt != NULL) + ret += __printf_puts(io, nalt, 2); + if (zext > 0) + ret += __printf_pad(io, zext, 1); + } + + ret += __printf_puts(io, p, pe - p); + if (pi->width > ret && pi->left) + ret += __printf_pad(io, pi->width - ret, 0); + __printf_flush(io); + return (ret); +} + +/* 'p' ---------------------------------------------------------------*/ + +__private_extern__ int +__printf_arginfo_ptr(const struct printf_info *pi __unused, size_t n, int *argt) +{ + + assert (n > 0); +#ifdef VECTORS + if (pi->is_vec) + argt[0] = PA_VECTOR; + else +#endif /* VECTORS */ + argt[0] = PA_POINTER; + return (1); +} + +__private_extern__ int +__printf_render_ptr(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + struct printf_info p2; + uintmax_t u; + const void *p; + +#ifdef VECTORS + if (pi->is_vec) return __xprintf_vector(io, pi, arg); +#endif /* VECTORS */ + + /*- + * ``The argument shall be a pointer to void. The + * value of the pointer is converted to a sequence + * of printable characters, in an implementation- + * defined manner.'' + * -- ANSI X3J11 + */ + u = (uintmax_t)(uintptr_t) *((void **)arg[0]); + p2 = *pi; + + p2.spec = 'x'; + p2.alt = 1; + p2.is_long_double = 1; + p = &u; + return (__printf_render_int(io, &p2, &p)); +} diff --git a/src/libc/stdio/FreeBSD/xprintf_private.h b/src/libc/stdio/FreeBSD/xprintf_private.h new file mode 100644 index 000000000..5f24296a4 --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf_private.h @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/include/printf.h,v 1.5 2011/03/06 17:45:37 pjd Exp $ + */ + +#ifndef _XPRINTF_PRIVATE_H_ +#define _XPRINTF_PRIVATE_H_ + +#include +#include + +#ifndef VECTORS +#define VECTORS +typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE; +#ifdef __SSE2__ +#define V64TYPE +#endif /* __SSE2__ */ +#endif /* !VECTORS */ + +/* FreeBSD extension */ +struct __printf_io; +typedef int printf_render(struct __printf_io *, const struct printf_info *, const void *const *); + +#if 0 +int register_printf_render(int spec, printf_render *render, printf_arginfo_function *arginfo); +#endif + +/* + * Unlike register_printf_domain_function(), register_printf_domain_render() + * doesn't have a context pointer, because none of the internal rendering + * functions use it. + */ +int register_printf_domain_render(printf_domain_t, int, printf_render *, printf_arginfo_function *); + +/* xprintf.c */ +extern const char __lowercase_hex[17]; +extern const char __uppercase_hex[17]; + +void __printf_flush(struct __printf_io *io); +int __printf_puts(struct __printf_io *io, const void *ptr, int len); +int __printf_pad(struct __printf_io *io, int n, int zero); +int __printf_out(struct __printf_io *io, const struct printf_info *pi, const void *ptr, int len); + +int __v2printf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt0, va_list ap); +int __xvprintf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt0, va_list ap); +extern int __use_xprintf; + +printf_arginfo_function __printf_arginfo_pct; +printf_render __printf_render_pct; + +printf_arginfo_function __printf_arginfo_n; +printf_function __printf_render_n; + +#ifdef VECTORS +printf_render __xprintf_vector; +#endif /* VECTORS */ + +#ifdef XPRINTF_PERF +#define CALLOC(x,y) xprintf_calloc((x),(y)) +#define MALLOC(x) xprintf_malloc((x)) +void *xprintf_calloc(size_t, size_t) __attribute__((__malloc__)); +void *xprintf_malloc(size_t) __attribute__((__malloc__)); +#else /* !XPRINTF_PERF */ +#define CALLOC(x,y) calloc((x),(y)) +#define MALLOC(x) malloc((x)) +#endif /* !XPRINTF_PERF */ + +/* xprintf_domain.c */ +void __xprintf_domain_init(void); +extern pthread_once_t __xprintf_domain_once; +#ifdef XPRINTF_DEBUG +extern printf_domain_t xprintf_domain_global; +#endif +#ifdef XPRINTF_PERF +struct array; /* forward reference */ +void arrayfree(struct array *); +#endif + +#define xprintf_domain_init() pthread_once(&__xprintf_domain_once, __xprintf_domain_init) + +/* xprintf_errno.c */ +printf_arginfo_function __printf_arginfo_errno; +printf_render __printf_render_errno; + +/* xprintf_float.c */ +printf_arginfo_function __printf_arginfo_float; +printf_render __printf_render_float; + +/* xprintf_hexdump.c */ +printf_arginfo_function __printf_arginfo_hexdump; +printf_render __printf_render_hexdump; + +/* xprintf_int.c */ +printf_arginfo_function __printf_arginfo_ptr; +printf_arginfo_function __printf_arginfo_int; +printf_render __printf_render_ptr; +printf_render __printf_render_int; + +/* xprintf_quoute.c */ +printf_arginfo_function __printf_arginfo_quote; +printf_render __printf_render_quote; + +/* xprintf_str.c */ +printf_arginfo_function __printf_arginfo_chr; +printf_render __printf_render_chr; +printf_arginfo_function __printf_arginfo_str; +printf_render __printf_render_str; + +/* xprintf_time.c */ +printf_arginfo_function __printf_arginfo_time; +printf_render __printf_render_time; + +/* xprintf_vis.c */ +printf_arginfo_function __printf_arginfo_vis; +printf_render __printf_render_vis; + +#ifdef XPRINTF_PERF +struct array; /* forward reference */ +#endif /* XPRINTF_PERF */ +struct _printf_compiled { + pthread_mutex_t mutex; +#ifdef XPRINTF_PERF + struct array *aa; + struct array *pa; + struct array *ua; +#endif /* XPRINTF_PERF */ + const char *fmt; + printf_domain_t domain; + locale_t loc; + struct printf_info *pi; + struct printf_info *pil; + int *argt; + union arg *args; + int maxarg; +}; + +#define XPRINTF_PLAIN ((printf_comp_t)-1) + +int __printf_comp(printf_comp_t restrict, printf_domain_t restrict); +int __printf_exec(printf_comp_t restrict, FILE * restrict, va_list); + +#ifdef XPRINTF_PERF +void arg_type_enqueue(struct array *); +void print_info_enqueue(struct array *); +void union_arg_enqueue(struct array *); +#endif /* XPRINTF_PERF */ + +#endif /* !_XPRINTF_PRIVATE_H_ */ diff --git a/src/libc/stdio/FreeBSD/xprintf_quote.c b/src/libc/stdio/FreeBSD/xprintf_quote.c new file mode 100644 index 000000000..a1a4c3e68 --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf_quote.c @@ -0,0 +1,99 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdio/xprintf_quote.c,v 1.2 2006/03/02 08:53:45 phk Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "printf.h" +#include "xprintf_private.h" + +__private_extern__ int +__printf_arginfo_quote(const struct printf_info *pi __unused, size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_POINTER; + return (1); +} + +__private_extern__ int +__printf_render_quote(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg) +{ + const char *str, *p, *t, *o; + char r[5]; + int i, ret; + + str = *((const char *const *)arg[0]); + if (str == NULL) + return (__printf_out(io, pi, "\"(null)\"", 8)); + if (*str == '\0') + return (__printf_out(io, pi, "\"\"", 2)); + + for (i = 0, p = str; *p; p++) + if (isspace(*p) || *p == '\\' || *p == '"') + i++; + if (!i) + return (__printf_out(io, pi, str, strlen(str))); + + ret = __printf_out(io, pi, "\"", 1); + for (t = p = str; *p; p++) { + o = NULL; + if (*p == '\\') + o = "\\\\"; + else if (*p == '\n') + o = "\\n"; + else if (*p == '\r') + o = "\\r"; + else if (*p == '\t') + o = "\\t"; + else if (*p == ' ') + o = " "; + else if (*p == '"') + o = "\\\""; + else if (isspace(*p)) { + sprintf(r, "\\%03o", *p); + o = r; + } else + continue; + if (p != t) + ret += __printf_out(io, pi, t, p - t); + ret += __printf_out(io, pi, o, strlen(o)); + t = p + 1; + } + if (p != t) + ret += __printf_out(io, pi, t, p - t); + ret += __printf_out(io, pi, "\"", 1); + __printf_flush(io); + return(ret); +} diff --git a/src/libc/stdio/FreeBSD/xprintf_str.c b/src/libc/stdio/FreeBSD/xprintf_str.c new file mode 100644 index 000000000..a563c3f4d --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf_str.c @@ -0,0 +1,201 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdio/xprintf_str.c,v 1.1 2005/12/16 18:56:38 phk Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "printf.h" +#include "xprintf_private.h" + +/* + * Convert a wide character string argument for the %ls format to a multibyte + * string representation. If not -1, prec specifies the maximum number of + * bytes to output, and also means that we can't assume that the wide char. + * string ends is null-terminated. + */ +static char * +__wcsconv(wchar_t *wcsarg, int prec, locale_t loc) +{ + static const mbstate_t initial; + mbstate_t mbs; + char buf[MB_LEN_MAX]; + wchar_t *p; + char *convbuf; + size_t clen, nbytes; + + /* Allocate space for the maximum number of bytes we could output. */ + if (prec < 0) { + p = wcsarg; + mbs = initial; + nbytes = wcsrtombs_l(NULL, (const wchar_t **)&p, 0, &mbs, loc); + if (nbytes == (size_t)-1) + return (NULL); + } else { + /* + * Optimisation: if the output precision is small enough, + * just allocate enough memory for the maximum instead of + * scanning the string. + */ + if (prec < 128) + nbytes = prec; + else { + nbytes = 0; + p = wcsarg; + mbs = initial; + for (;;) { + clen = wcrtomb_l(buf, *p++, &mbs, loc); + if (clen == 0 || clen == (size_t)-1 || + (int)(nbytes + clen) > prec) + break; + nbytes += clen; + } + } + } + if ((convbuf = MALLOC(nbytes + 1)) == NULL) + return (NULL); + + /* Fill the output buffer. */ + p = wcsarg; + mbs = initial; + if ((nbytes = wcsrtombs_l(convbuf, (const wchar_t **)&p, + nbytes, &mbs, loc)) == (size_t)-1) { + free(convbuf); + return (NULL); + } + convbuf[nbytes] = '\0'; + return (convbuf); +} + + +/* 's' ---------------------------------------------------------------*/ + +__private_extern__ int +__printf_arginfo_str(const struct printf_info *pi, size_t n, int *argt) +{ + + assert (n > 0); + if (pi->is_long || pi->spec == 'C') + argt[0] = PA_WSTRING; + else + argt[0] = PA_STRING; + return (1); +} + +__private_extern__ int +__printf_render_str(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + const char *p; + wchar_t *wcp; + char *convbuf; + int l; + + if (pi->is_long || pi->spec == 'S') { + wcp = *((wint_t **)arg[0]); + if (wcp == NULL) + return (__printf_out(io, pi, "(null)", 6)); + convbuf = __wcsconv(wcp, pi->prec, pi->loc); + if (convbuf == NULL) + return (-1); + l = __printf_out(io, pi, convbuf, strlen(convbuf)); + __printf_flush(io); + free(convbuf); + return (l); + } + p = *((char **)arg[0]); + if (p == NULL) + return (__printf_out(io, pi, "(null)", 6)); + l = strlen(p); + if (pi->prec >= 0 && pi->prec < l) + l = pi->prec; + return (__printf_out(io, pi, p, l)); +} + +/* 'c' ---------------------------------------------------------------*/ + +__private_extern__ int +__printf_arginfo_chr(const struct printf_info *pi, size_t n, int *argt) +{ + + assert (n > 0); +#ifdef VECTORS + if (pi->is_vec) + argt[0] = PA_VECTOR; + else +#endif /* VECTORS */ + if (pi->is_long || pi->spec == 'C') + argt[0] = PA_WCHAR; + else + argt[0] = PA_INT; + return (1); +} + +__private_extern__ int +__printf_render_chr(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + int i; + wint_t ii; + unsigned char c; + static const mbstate_t initial; /* XXX: this is bogus! */ + mbstate_t mbs; + size_t mbseqlen; + char buf[MB_CUR_MAX_L(pi->loc)]; + +#ifdef VECTORS + if (pi->is_vec) return __xprintf_vector(io, pi, arg); +#endif /* VECTORS */ + + if (pi->is_long || pi->spec == 'C') { + int ret; + ii = *((wint_t *)arg[0]); + + mbs = initial; + mbseqlen = wcrtomb_l(buf, (wchar_t)ii, &mbs, pi->loc); + if (mbseqlen == (size_t) -1) + return (-1); + ret = __printf_out(io, pi, buf, mbseqlen); + __printf_flush(io); + return ret; + } + i = *((int *)arg[0]); + c = i; + i = __printf_out(io, pi, &c, 1); + __printf_flush(io); + return (i); +} diff --git a/src/libc/stdio/FreeBSD/xprintf_time.c b/src/libc/stdio/FreeBSD/xprintf_time.c new file mode 100644 index 000000000..050fd4949 --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf_time.c @@ -0,0 +1,123 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdio/xprintf_time.c,v 1.6 2011/03/06 19:47:46 pjd Exp $ + */ +#include +#include +#include +#include +#include +#include +#include "printf.h" +#include "xprintf_private.h" + +__private_extern__ int +__printf_arginfo_time(const struct printf_info *pi, size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_POINTER; + return (1); +} +#define MINUTE 60 +#define HOUR (60 * MINUTE) +#define DAY (24 * HOUR) +#define YEAR (365 * DAY) + +__private_extern__ int +__printf_render_time(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + char buf[100]; + char *p; + struct timeval *tv; + struct timespec *ts; + time_t *tp; + intmax_t t, tx; + int i, prec, nsec, ret; + + if (pi->is_long) { + tv = *((struct timeval **)arg[0]); + t = tv->tv_sec; + nsec = tv->tv_usec * 1000; + prec = 6; + } else if (pi->is_long_double) { + ts = *((struct timespec **)arg[0]); + t = ts->tv_sec; + nsec = ts->tv_nsec; + prec = 9; + } else { + tp = *((time_t **)arg[0]); + t = *tp; + nsec = 0; + prec = 0; + } + if (pi->is_long || pi->is_long_double) { + if (pi->prec >= 0) + prec = pi->prec; + if (prec == 0) + nsec = 0; + } + + p = buf; + if (pi->alt) { + tx = t; + if (t >= YEAR) { + p += sprintf(p, "%jdy", t / YEAR); + t %= YEAR; + } + if (tx >= DAY && (t != 0 || prec != 0)) { + p += sprintf(p, "%jdd", t / DAY); + t %= DAY; + } + if (tx >= HOUR && (t != 0 || prec != 0)) { + p += sprintf(p, "%jdh", t / HOUR); + t %= HOUR; + } + if (tx >= MINUTE && (t != 0 || prec != 0)) { + p += sprintf(p, "%jdm", t / MINUTE); + t %= MINUTE; + } + if (t != 0 || tx == 0 || prec != 0) + p += sprintf(p, "%jds", t); + } else { + p += sprintf(p, "%jd", (intmax_t)t); + } + if (prec != 0) { + for (i = prec; i < 9; i++) + nsec /= 10; + p += sprintf(p, ".%.*d", prec, nsec); + } + ret = __printf_out(io, pi, buf, p - buf); + __printf_flush(io); + return (ret); +} diff --git a/src/libc/stdio/FreeBSD/xprintf_vis.c b/src/libc/stdio/FreeBSD/xprintf_vis.c new file mode 100644 index 000000000..013d0b09f --- /dev/null +++ b/src/libc/stdio/FreeBSD/xprintf_vis.c @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/stdio/xprintf_vis.c,v 1.2 2006/01/25 12:45:24 phk Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "printf.h" +#include "xprintf_private.h" + +__private_extern__ int +__printf_arginfo_vis(const struct printf_info *pi, size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_POINTER; + return (1); +} + +__private_extern__ int +__printf_render_vis(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + char *p, *buf; + unsigned l; + int ret; + + ret = 0; + p = *((char **)arg[0]); + if (p == NULL) + return (__printf_out(io, pi, "(null)", 6)); + if (pi->prec >= 0) + l = pi->prec; + else + l = strlen(p); + buf = MALLOC(l * 4 + 1); + if (buf == NULL) + return (-1); + if (pi->showsign) + ret = strvisx(buf, p, l, VIS_WHITE | VIS_HTTPSTYLE); + else if (pi->pad == '0') + ret = strvisx(buf, p, l, VIS_WHITE | VIS_OCTAL); + else if (pi->alt) + ret = strvisx(buf, p, l, VIS_WHITE); + else + ret = strvisx(buf, p, l, VIS_WHITE | VIS_CSTYLE | VIS_OCTAL); + ret += __printf_out(io, pi, buf, ret); + __printf_flush(io); + free(buf); + return(ret); +} diff --git a/src/libc/stdio/xprintf.3 b/src/libc/stdio/xprintf.3 new file mode 100644 index 000000000..fba50aec1 --- /dev/null +++ b/src/libc/stdio/xprintf.3 @@ -0,0 +1,64 @@ +.Dd Aug 19, 2012 +.Dt XPRINTF 3 +.Os Darwin +.Sh NAME +.Nm asxprintf , dxprintf , fxprintf , sxprintf , xprintf , +.Nm vasxprintf , vdxprintf , vfxprintf , vsxprintf , vxprintf +.Nd extensible printf +.Sh SYNOPSIS +.In printf.h +.Ft int +.Fn asxprintf "char ** restrict ret" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ... +.Ft int +.Fn dxprintf "int fd" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ... +.Ft int +.Fn fxprintf "FILE * restrict stream" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ... +.Ft int +.Fn sxprintf "char * restrict str" "size_t size" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ... +.Ft int +.Fn xprintf "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ... +.In stdarg.h +.Ft int +.Fn vasxprintf "char ** restrict ret" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap" +.Ft int +.Fn vdxprintf "int fd" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap" +.Ft int +.Fn vfxprintf "FILE * restrict stream" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap" +.Ft int +.Fn vsxprintf "char * restrict str" "size_t size" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap" +.Ft int +.Fn vxprintf "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap" +.Sh DESCRIPTION +These extensible printf (see +.Xr xprintf 5 ) +variants behave like their normal printf counterparts +(see +.Xr printf 3 ) +without +.Sq Li x +in the name (except +.Fn sxprintf +and +.Fn vsxprintf +behave like +.Fn snprintf +and +.Fn vsnprintf , +respectively). +.Pp +The +.Va domain +argument must be a pointer to a printf domain structure, as returned by one of +the functions described in +.Xr xprintf_domain 3 . +The +.Va loc +argument should be an extended locale (see +.Xr xlocale 3 ) +or NULL, which means to use the current locale in effect (either the per-thread +locale if set, or the global locale by default). +.Sh SEE ALSO +.Xr printf 3 , +.Xr xlocale 3 , +.Xr xprintf_domain 3 , +.Xr xprintf 5 diff --git a/src/libc/stdio/xprintf.5 b/src/libc/stdio/xprintf.5 new file mode 100644 index 000000000..442f504e9 --- /dev/null +++ b/src/libc/stdio/xprintf.5 @@ -0,0 +1,533 @@ +.Dd Aug 19, 2012 +.Dt XPRINTF 5 +.Os Darwin +.Sh NAME +.Nm xprintf +.Nd extensible printf +.Sh SYNOPSIS +.In printf.h +.Ft "typedef int" +.Fn printf_arginfo_function "const struct printf_info *info" "size_t n" "int *argtypes" +.Ft "typedef int" +.Fn printf_function "FILE *stream" "const struct printf_info *info" "const void *const *args" +.Sh DESCRIPTION +The standard +.Xr printf 3 +family of routines provides a convenient way to convert one or more arguments +to various forms for output, under the control of a format string. +The format string may contain any number of conversion specifications, which +start with the +.Sq Li % +character and end with a conversion specifier character (like +.Sq Li d +or +.Sq Li f ) , +with conversion flag characters in-between. +.Pp +Extensible printf is an enhancement that allows adding new (user-defined) +conversion specifiers, or modifying/removing existing ones. +The implementation of extensible printf in Mac OS X is derived from the +FreeBSD version, which is based on the one in GNU libc (GLIBC). +Documentation for the GLIBC version is available at: +.Pp +.Li http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html +.Pp +The main problem with the usual forms of extensible printf is that +changes to +.Xr printf 3 +are program-wide. +But this is unsafe, since frameworks, +libraries or some other thread could change printf behavior in ways +unexpected by the main program, or the latter could unexpectedly affect the +former. +.Pp +So instead, the implementation used in Mac OS X makes +changes to conversion specifiers within printf domains, +which are independent structures containing the specifier definitions. +These domains are created as described in +.Xr xprintf_domain 3 , +and once set up, it can be passed to a +.Xr xprintf 3 +variant along with the format string and arguments to generate output. +The standard +.Xr printf 3 +behavior is never affected. +.Pp +To define a new conversion specifier, two function typedefs are defined, and +the user must provide two functions based on these typedefs. +These functions will get called from extensible printf while processing +the corresponding conversion specification. +.Pp +During the first of three phases of extensible printf processing, the format +string is parsed, and for each conversion specification, a +.Vt struct printf_info +is created, containing the option flags specified in the +conversion specification as well as other settings. +Important fields in +.Vt struct printf_info +are: +.Bl -tag -width ".Va is_long_double" +.It Va alt +Boolean value whether the +.Sq Li # +flag was specified. +.It Va context +A +.Vt void * +pointer to arbitrary data specified in the original call to +.Xr register_printf_domain_function 3 . +.It Va group +Boolean value whether the +.Sq Li ' +flag was specified. +.It Va is_char +Boolean value whether the +.Sq Li hh +flag was specified. +.It Va is_intmax +Boolean value whether the +.Sq Li j +flag was specified. +.It Va is_long +Boolean value whether the +.Sq Li l +flag was specified. +.It Va is_long_double +Boolean value whether the +.Sq Li L +or +.Sq Li ll +flags were specified. +.It Va is_ptrdiff +Boolean value whether the +.Sq Li t +flag was specified. +.It Va is_quad +Boolean value whether the +.Sq Li q +flag was specified. +.It Va is_short +Boolean value whether the +.Sq Li h +flag was specified. +.It Va is_size +Boolean value whether the +.Sq Li z +flag was specified. +.It Va is_vec +Boolean value whether the +.Sq Li v +flag was specified. +.It Va left +Boolean value whether the +.Sq Li - +flag was specified. +.It Va loc +The extended locale (see +.Xr xlocale 3 ) +specified by the extensible printf caller (never +.Dv NULL ) . +.It Va pad +The padding character; either +.Sq Li 0 +or space. +.It Va prec +The value of the optional precision. +-1 means the precision was unspecified. +.It Va showsign +Boolean value whether the +.Sq Li + +flag was specified. +.It Va signchar +The sign character, either +.Sq Li + , +space or zero if none. +.It Va space +Boolean value whether the space flag was specified. +.It Va spec +The specifier character itself. +.It Va vsep +The separator character between vector items (using the +.Sq Li v +flag). +Can be any one of the four characters +.Dq Li ,:;_ +or +.Sq Li X +if no separator character was specified (meaning that a space is used as the +separator, unless the specifier is +.Sq Li c , +in which case no separator is used). +.It Va width +The value of the minimum field width (defaults to zero). +.El +.Pp +All other structure fields are either unused or private (and shouldn't be +used). +.Pp +This +.Vt struct printf_info +structure is then passed to the corresponding +.Nm printf_arginfo_function +callback function. +The callback function should return the number of consecutive arguments the +specifier handles, including zero (the maximum number of consecutive arguments +a single specifier can handle is +.Dv __PRINTFMAXARG , +which is currently set to 2, but could be increased in the future if there is +need). +.Pp +The callback function is also passed an integer array and the length of that +array; the length will typically be +.Dv __PRINTFMAXARG . +The function should fill out the array up to the number of arguments it expects, +using the following values: +.Bl -tag -width ".Dv PA_POINTER" +.It Dv PA_CHAR +The argument type is an +.Vt int +cast to a +.Vt char . +.It Dv PA_DOUBLE +The argument type is a +.Vt double . +OR-ing +.Dv PA_DOUBLE +with +.Dv PA_FLAG_LONG_DOUBLE +specifies a +.Vt "long double" +type. +.It Dv PA_FLOAT +(Defined but unused; best to avoid, since +.Vt float +is automatically promoted to +.Vt double +anyways.) +.It Dv PA_INT +The argument type is +.Vt int +(either signed or unsigned). +The size can be adjusted by OR-ing the following values to +.Dv PA_INT : +.Bl -tag -width ".Dv PA_FLAG_LONG_LONG" +.It Dv PA_FLAG_INTMAX +The integer is the size of a +.Vt intmax_t . +.It Dv PA_FLAG_LONG +The integer is the size of a +.Vt long . +.It Dv PA_FLAG_LONG_LONG +The integer is the size of a +.Vt "long long" . +.It Dv PA_FLAG_PTRDIFF +The integer is the size of a +.Vt ptrdiff_t . +.It Dv PA_FLAG_QUAD +The integer is the size of a +.Vt quad_t +(deprecated). +.It Dv PA_FLAG_SHORT +The integer is the size of a +.Vt short . +.It Dv PA_FLAG_SIZE +The integer is the size of a +.Vt size_t . +.El +.It Dv PA_POINTER +The argument type is a pointer type, cast to a +.Vt "void *" . +.It Dv PA_STRING +The argument type is a null-terminated character string +.Vt ( "char *" ) . +.It Dv PA_VECTOR +The argument type is an AltiVec or SSE vector (16 bytes). +.It Dv PA_WCHAR +The argument type is a +.Vt wchar_t . +.It Dv PA_WSTRING +The argument type is a null-terminated wide character string +.Vt ( "wchar_t *" ) . +.El +.Pp +After the +.Nm printf_arginfo_function +returns, phase 2 of extensible printf processing involves converting the +argument according to the types specified by the returned type array. +Note that positional arguments are dealt with here as well. +.Pp +Then in phase 3, output is generated, either from the text in-between the +conversion specifications, or by calling the so-called rendering functions +associated with each conversion specifier (with typedef +.Nm printf_function ) . +The rendering function is passed the same +.Vt struct printf_info +structure, as well as an array of pointers to each of the arguments converted +in phase 2 that it is responsible for. +The callback should write its output to the provided output +stdio stream, and then return the number of characters written. +.Sh EXAMPLE +Here is an example that demonstrates many of the features of extensible printf: +.Bd -literal +#include +#include +#include +#include +#include +#include + +/* The Coordinate type */ +typedef struct { + double x; + double y; +} Coordinate; + +#define L (1 << 0) +#define P (1 << 1) + +/* The renderer callback for Coordinate */ +static int +print_coordinate (FILE *stream, const struct printf_info *info, + const void *const *args) +{ + const Coordinate *c; + int width, ret, which = 0; + char fmt[32]; + char *bp, *cp, *ep; + /* The optional coordinate labels */ + const char **labels = (const char **)info->context; + + /* Get the argument pointer to a Coordinate */ + c = *((const Coordinate **) (args[0])); + + /* Set up the format string */ + cp = fmt; + if(info->alt) *cp++ = '('; + bp = cp; + if(labels) { + which |= L; + *cp++ = '%'; + *cp++ = 's'; + } + *cp++ = '%'; + if(info->group) *cp++ = '\e''; + *cp++ = '*'; + if(info->prec >= 0) { + which |= P; + *cp++ = '.'; + *cp++ = '*'; + } + *cp++ = 'l'; + *cp++ = 'f'; + ep = cp; + if(info->alt) *cp++ = ','; + *cp++ = ' '; + while(bp < ep) *cp++ = *bp++; + if(info->alt) *cp++ = ')'; + *cp = 0; + + width = info->left ? -info->width : info->width; + + /* Output to the given stream */ + switch(which) { + case 0: + ret = fprintf_l(stream, info->loc, fmt, width, c->x, width, c->y); + break; + case L: + ret = fprintf_l(stream, info->loc, fmt, labels[0], width, c->x, + labels[1], width, c->y); + break; + case P: + ret = fprintf_l(stream, info->loc, fmt, width, info->prec, c->x, + width, info->prec, c->y); + break; + case (L | P): + ret = fprintf_l(stream, info->loc, fmt, labels[0], width, + info->prec, c->x, labels[1], width, info->prec, + c->y); + break; + } + + return ret; +} + +/* The arginfo callback for Coordinate */ +static int +coordinate_arginfo (const struct printf_info *info, size_t n, + int *argtypes) +{ + /* We always take exactly one argument and this is a pointer to the + structure.. */ + if (n > 0) + argtypes[0] = PA_POINTER; + return 1; +} + +int +main (void) +{ + Coordinate mycoordinate = {12345.6789, 3.141593}; + printf_domain_t domain; + locale_t loc; + const char *labels[] = {"x=", "y="}; + + /* Set up a domain to add support for Coordinate conversion */ + domain = new_printf_domain(); + if(!domain) + err(1, "new_printf_domain"); + /* Set up an extended locale to test locale support */ + loc = newlocale(LC_ALL_MASK, "uk_UA.UTF-8", NULL); + if(!loc) + err(1, "newlocale"); + + /* Register the callbacks for Coordinates in the domain */ + register_printf_domain_function (domain, 'C', print_coordinate, + coordinate_arginfo, NULL); + + /* Print the coordinate using the current locale (C). */ + xprintf(domain, NULL, "|%'C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'14C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'-14.2C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'#C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'#14C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'#-14.2C|\en", &mycoordinate); + + printf("-------------\en"); + /* Reregister the callbacks, specifying coordinate labels + * and setting the global locale (notice thousands separator) */ + register_printf_domain_function (domain, 'C', print_coordinate, + coordinate_arginfo, labels); + if(setlocale(LC_ALL, "en_US.UTF-8") == NULL) + errx(1, "setlocale"); + + /* Reprint with labels */ + xprintf(domain, NULL, "|%'C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'14C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'-14.2C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'#C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'#14C|\en", &mycoordinate); + xprintf(domain, NULL, "|%'#-14.2C|\en", &mycoordinate); + + printf("-------------\en"); + /* Now print with the test locale (notice decimal point and + * thousands separator) */ + xprintf(domain, loc, "|%'C|\en", &mycoordinate); + xprintf(domain, loc, "|%'14C|\en", &mycoordinate); + xprintf(domain, loc, "|%'-14.2C|\en", &mycoordinate); + xprintf(domain, loc, "|%'#C|\en", &mycoordinate); + xprintf(domain, loc, "|%'#14C|\en", &mycoordinate); + xprintf(domain, loc, "|%'#-14.2C|\en", &mycoordinate); + + return 0; +} +.Ed +.Pp +This example defines a Coordinate type, that consists of a pair of doubles. +We create a conversion specifier that displays a Coordinate type, either just +as two floating point numbers, or with the +.Sq Li # +(alternate form) flag, as parenthesized numbers separated by a comma. +Note the use of +.Nm printf_l +to do the actual output; this is using regular printf from within an extensible +printf renderer callback. +The use of +.Nm printf_l +also insures correct handling of extended locales. +.Pp +The output of the programs looks like: +.Bd -literal +|12345.678900 3.141593| +| 12345.678900 3.141593| +|12345.68 3.14 | +|(12345.678900, 3.141593)| +|( 12345.678900, 3.141593)| +|(12345.68 , 3.14 )| +------------- +|x=12,345.678900 y=3.141593| +|x= 12,345.678900 y= 3.141593| +|x=12,345.68 y=3.14 | +|(x=12,345.678900, y=3.141593)| +|(x= 12,345.678900, y= 3.141593)| +|(x=12,345.68 , y=3.14 )| +------------- +|x=12 345,678900 y=3,141593| +|x= 12 345,678900 y= 3,141593| +|x=12 345,68 y=3,14 | +|(x=12 345,678900, y=3,141593)| +|(x= 12 345,678900, y= 3,141593)| +|(x=12 345,68 , y=3,14 )| +.Ed +.Pp +Notice: +.Bl -bullet +.It +Field width, precision and left adjustment are applied to each of the numbers. +.It +The alternate form, using parenthesized numbers separated by a comma. +.It +In the second group of six, the thousands separator corresponds to the +global locale setting +.Pq Li en_US.UTF-8 . +.It +The second and third group have a label for each number, provide through +the user-defined context argument. +.It +The third group has the decimal point and thousands separator of the extended +locale argument +.Pq Li uk_UA.UTF-8 . +.El +.Sh PERFORMANCE +Because of the three phase processing of extensible printf, as well as the +use of two callbacks for each conversion specifier, performance is +considerably slower than the one pass, highly optimized regular +.Xr printf 3 . +Recursive use of +.Xr printf 3 +from within an extensible printf renderer callback +(as in the +.Sx EXAMPLE +above) adds additional overhead. +.Pp +To ameliorate some of this slowness, the concept of separate compilation +and execution phases has be added to extensible printf. +The functions in +.Xr xprintf_comp 3 +allow the creation of pre-compiled extensible printf structures (performing +phase one of extensible printf processing). +These pre-compiled structures can then be passed to the printf variants in +.Xr xprintf_exec 3 +to produce the actual output (performing phases 2 and 3). +The compilation phase need only be done once, while execution can be performed +any number of times. +.Pp +A simple example of use is: +.Bd -literal + printf_comp_t pc = new_printf_comp(domain, loc, "%d: %C\en"); + for(i = 0; i = sizeof(coords) / sizeof(*coords); i++) { + xprintf_exec(pc, i, &coords[i]); + } + free_printf_comp(pc); +.Ed +.Pp +Here, +.Va coords +is a array containing +.Vt Coordinate +structures that are to be printed and the +.Va domain +and +.Va loc +variables are as from +.Sx EXAMPLE +above. +(Error checking on the return value from +.Fn new_printf_comp +is not shown). +.Sh SEE ALSO +.Xr printf 3 , +.Xr xlocale 3 , +.Xr xprintf 3 , +.Xr xprintf_comp 3 , +.Xr xprintf_domain 3 , +.Xr xprintf_exec 3 diff --git a/src/libc/stdio/xprintf_all_in_one.c b/src/libc/stdio/xprintf_all_in_one.c new file mode 100644 index 000000000..69b719403 --- /dev/null +++ b/src/libc/stdio/xprintf_all_in_one.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#define __va_list __darwin_va_list + +#include +#include +#include +#include + +int +asxprintf(char ** __restrict ret, printf_domain_t __restrict domain, + locale_t __restrict loc, const char * __restrict format, ...) +{ + int iret; + va_list ap; + + va_start(ap, format); + iret = _vasprintf(NULL, domain, ret, loc, format, ap); + va_end(ap); + return iret; +} + +int +dxprintf(int fd, printf_domain_t __restrict domain, locale_t __restrict loc, + const char * __restrict format, ...) +{ + int ret; + va_list ap; + + va_start(ap, format); + ret = _vdprintf(NULL, domain, fd, loc, format, ap); + va_end(ap); + return ret; +} + +int +fxprintf(FILE * __restrict stream, printf_domain_t __restrict domain, + locale_t __restrict loc, const char * __restrict format, ...) +{ + int ret; + va_list ap; + + va_start(ap, format); + ret = __xvprintf(NULL, domain, stream, loc, format, ap); + va_end(ap); + return ret; +} + +int +sxprintf(char * __restrict str, size_t size, printf_domain_t __restrict domain, + locale_t __restrict loc, const char * __restrict format, ...) +{ + int ret; + va_list ap; + + va_start(ap, format); + ret = _vsnprintf(NULL, domain, str, size, loc, format, ap); + va_end(ap); + return ret; +} + +int +xprintf(printf_domain_t __restrict domain, locale_t __restrict loc, + const char * __restrict format, ...) +{ + int ret; + va_list ap; + + va_start(ap, format); + ret = __xvprintf(NULL, domain, stdout, loc, format, ap); + va_end(ap); + return ret; +} + +int +vasxprintf(char ** __restrict ret, printf_domain_t __restrict domain, + locale_t __restrict loc, const char * __restrict format, va_list ap) +{ + return _vasprintf(NULL, domain, ret, loc, format, ap); +} + +int +vdxprintf(int fd, printf_domain_t __restrict domain, locale_t __restrict loc, + const char * __restrict format, va_list ap) +{ + return _vdprintf(NULL, domain, fd, loc, format, ap); +} + +int +vfxprintf(FILE * __restrict stream, printf_domain_t __restrict domain, + locale_t __restrict loc, const char * __restrict format, va_list ap) +{ + return __xvprintf(NULL, domain, stream, loc, format, ap); +} + +int +vsxprintf(char * __restrict str, size_t size, printf_domain_t __restrict domain, + locale_t __restrict loc, const char * __restrict format, va_list ap) +{ + return _vsnprintf(NULL, domain, str, size, loc, format, ap); +} + +int +vxprintf(printf_domain_t __restrict domain, locale_t __restrict loc, + const char * __restrict format, va_list ap) +{ + return __xvprintf(NULL, domain, stdout, loc, format, ap); +} diff --git a/src/libc/stdio/xprintf_comp.3 b/src/libc/stdio/xprintf_comp.3 new file mode 100644 index 000000000..2e0af35f7 --- /dev/null +++ b/src/libc/stdio/xprintf_comp.3 @@ -0,0 +1,66 @@ +.Dd Aug 19, 2012 +.Dt XPRINTF_COMP 3 +.Os Darwin +.Sh NAME +.Nm free_printf_comp , new_printf_comp +.Nd extensible printf compilation +.Sh SYNOPSIS +.In printf.h +.Ft void +.Fn free_printf_comp "printf_comp_t pc" +.Ft printf_comp_t +.Fn new_printf_comp "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict fmt" +.Sh DESCRIPTION +To ameliorate some of the slowness caused by the extra overhead in +extensible printf (see +.Xr xprintf 5 ) , +a compile/execute mechanism has been created. +The +.Fn new_printf_comp +function compiles the given format string, along with a printf domain +(see +.Xr xprintf_domain 3 ) +and an extended locale +(see +.Xr xlocale 3 ) , +and returns a +.Ft printf_comp_t +structure. +The domain may not be +.Dv NULL , +but the locale can be +.Dv NULL , +which means to use the current locale, either the per-thread locale if it +was set, or else the global locale. +Because the +.Ft printf_comp_t +structure records the domain and locale, care should be taken if either +of these are changed. +.Pp +Once a +.Ft printf_comp_t +structure is created, it can be passed to one of the extensible printf +execution variants, described in +.Xr xprintf_exec 3 , +along with the necessary arguments. +Creating the +.Ft printf_comp_t +structure needs to be done only once, but it can be passed +to extensible printf execution variants any number of times. +.Pp +When the +.Ft printf_comp_t +structure is no longer needed, it should be passed to +.Fn free_printf_comp +to release internal memory. +.Sh RETURN VALUES +The +.Fn new_printf_comp +function returns the new structure, or +.Dv NULL +on error (usually NULL domain or out of memory condition). +.Sh SEE ALSO +.Xr xlocale 3 , +.Xr xprintf_domain 3 , +.Xr xprintf_exec 3 , +.Xr xprintf 5 diff --git a/src/libc/stdio/xprintf_comp.c b/src/libc/stdio/xprintf_comp.c new file mode 100644 index 000000000..6f5b549e3 --- /dev/null +++ b/src/libc/stdio/xprintf_comp.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include "xprintf_domain.h" +#include "xprintf_private.h" + +void +free_printf_comp(printf_comp_t pc) +{ + if(!pc) return; + XL_RELEASE(pc->loc); +#ifdef XPRINTF_PERF + arrayfree(pc->pa); + free(pc->pa); + arrayfree(pc->aa); + free(pc->aa); + arrayfree(pc->ua); + free(pc->ua); +#else /* !XPRINTF_PERF */ + free(pc->pi); + free(pc->argt); + free(pc->args); +#endif /* !XPRINTF_PERF */ + pthread_mutex_destroy(&pc->mutex); + free(pc); +} + +printf_comp_t +new_printf_comp(printf_domain_t restrict domain, locale_t loc, const char * restrict fmt) +{ + int ret, saverrno; + printf_comp_t restrict pc; + + if(!domain) { + errno = EINVAL; + return NULL; + } + pc = MALLOC(sizeof(*pc) + strlen(fmt) + 1); + if(!pc) return NULL; + bzero(pc, sizeof(*pc)); + pc->mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + pc->fmt = (const char *)(pc + 1); + strcpy((char *)pc->fmt, fmt); + DEFAULT_CURRENT_LOCALE(loc); + XL_RETAIN(loc); + pc->loc = loc; + xprintf_domain_init(); + pthread_rwlock_rdlock(&domain->rwlock); + ret = __printf_comp(pc, domain); + saverrno = errno; + pthread_rwlock_unlock(&domain->rwlock); + if(ret < 0) { + XL_RELEASE(loc); + pthread_mutex_destroy(&pc->mutex); + free(pc); + errno = saverrno; + return NULL; + } + return pc; +} diff --git a/src/libc/stdio/xprintf_domain.3 b/src/libc/stdio/xprintf_domain.3 new file mode 100644 index 000000000..2336c46cb --- /dev/null +++ b/src/libc/stdio/xprintf_domain.3 @@ -0,0 +1,219 @@ +.Dd Aug 19, 2012 +.Dt XPRINTF_DOMAIN 3 +.Os Darwin +.Sh NAME +.Nm copy_printf_domain , free_printf_domain , new_printf_domain , +.Nm register_printf_domain_function , register_printf_domain_render_std +.Nd extensible printf domains +.Sh SYNOPSIS +.In printf.h +.Ft printf_domain_t +.Fn copy_printf_domain "printf_domain_t domain" +.Ft void +.Fn free_printf_domain "printf_domain_t domain" +.Ft printf_domain_t +.Fn new_printf_domain void +.Ft int +.Fn register_printf_domain_function "printf_domain_t domain" "int spec" "printf_function *render" "printf_arginfo_function *arginfo", "void *context" +.Ft int +.Fn register_printf_domain_render_std "printf_domain_t domain" "const char *specs" +.Sh DESCRIPTION +A printf domain is an extensible printf (see +.Xr xprintf 5 ) +structure defining a set of conversion specifiers that +will be used in calls to the routines discussed in +.Xr xprintf 3 +and +.Xr xprintf_comp 3 . +Domains can be modified independently of one another, and do not affect the +behavior of the normal printf calls in +.Xr printf 3 . +.Pp +To create a new domain, call +.Fn new_printf_domain ; +the standard POSIX conversion specifiers are defined by default. +To make a copy of an existing domain, use +.Fn copy_printf_domain . +When a domain is no longer needed, call +.Fn free_printf_domain +to release the associated memory. +.Pp +The +.Fn register_printf_domain_function +function is used to add, modify or remove conversion specifiers for a +given domain. +The +.Fa spec +argument is the specifier character, which can be any printable (non-control) +ASCII character, +except for those characters that are used as flag/option characters. +The set of flag/option characters includes the space character, and the +following: +.Pp +.Dl # $ ' * + \&, - \&. 0 1 2 3 4 5 6 7 8 9 \&: \&; L _ h j l q t v z +.Pp +Two user-defined callback function must also be given; see +.Xr xprintf 5 +for a description of these callback functions and an example of use. +Setting either or both callbacks to +.Dv NULL +deletes the given specifier from the domain. +Note that while it is permissible to redefine the standard conversion +specifiers, it is not usually recommended as it may cause confusion. +.Pp +The +.Fn register_printf_domain_render_std +function is used to add pre-defined conversion specifiers to the given domain. +The +.Fa specs +argument is a null-terminated C string containing one or more of the following +specifier characters: +.Bl -tag -width ".Li H" +.It Li H +Hex dump. +The +.Sq Li H +specifier takes two arguments; the first is a pointer to the data to +dump, while the second argument is the length of the data, given as type +.Vt unsigned . +Normally, 16 characters are displayed per line, as pairs of hex characters +separated by spaces. +Specifying a field width less than 16 will display that number of characters +per line. +Setting the +.Sq Li + +(showsign) flag will prefix each line with the hex offset of the beginning +character in that line. +Setting the +.Sq Li # +(alternate form) flag will postfix an ASCII representation to each line, with +.Sq Li \&. +representing non-printable characters. +.It Li M +Errno. +The +.Sq Li M +specifier displayed the text representation of the given +.Vt int +argument, expected to be a valid +.Va errno +value (as returned by +.Xr strerror 3 ) . +Invalid errno values are represent by the +.Dq Li errno= +string followed by the decimal and hex values of the argument. +.It Li Q +Quoted. +The +.Sq Li Q +specifier displays a null-terminated string argument as a C string, with +leading and trailing double quotes. +Newlines, carriage-returns and tabs are represented by +.Sq Li \en , +.Sq Li \er +and +.Sq Li \et , +respectively, while backslashes and double quotes are preceeded with a +backslash. +All other whitespace characters not including space itself (those in which +.Xr isspace 3 +returns true) are displayed as octal escape sequences (a backslash followed by +three octal digits). +All other characters print as themselves. +.It Li T +time_t/timeval/timespec. +The +.Sq Li T +specifier displays the three types of time values as a single decimal value. +The argument should be a pointer to the time value to be converted. +Setting the appropriate flags indicates which type is indicated: +.Bl -tag -width ".Pq none" +.It Li ll +The +.Sq Li ll +(long long) flag indicates the argument points to a +.Vt struct timespec +structure. +The default precision is 9. +.It Li l +The +.Sq Li l +(long) flag indicates the argument points to a +.Vt struct timeval +structure. +The default precision is 6. +.It Pq none +By default, the argument points to a +.Vt time_t +value. +The default precision is 0 (the fractional part is not displayed). +.El +.Pp +If the +.Sq Li # +(alternate form) flag is specified, the value is displayed in years, days, +hours, minutes and seconds, as in: +.Dq Li 3y123d21h59m59s.987654 +(zero values are not displayed at all). +Note that the years are 365 days (no leap days). +.It Li V +String vis. +The +.Sq Li V +specifier uses +.Xr strvisx 3 +to display the null-terminated C string argument. +The precision value can be used to limit the amount of the string that is +processed (defaults to the entire string). +.Pp +Flag values can be used to obtain different encodings: +.Bl -tag -width "(none)" +.It Li + +The +.Sq Li + +(showsign) flag uses the +.Dq Li VIS_WHITE | VIS_HTTPSTYLE +flag value to +.Xr strvisx 3 . +.It Li 0 +The +.Sq Li 0 +(leading zero) flag uses the +.Dq Li VIS_WHITE | VIS_OCTAL +flag value to +.Xr strvisx 3 . +.It Li # +The +.Sq Li # +(alternate form) flag uses the +.Dq Li VIS_WHITE +flag value to +.Xr strvisx 3 . +.It Pq none +The default flag value to +.Xr strvisx 3 +is +.Dq Li VIS_WHITE | VIS_CSTYLE | VIS_OCTAL . +.El +.El +.Sh RETURN VALUES +The +.Fn new_printf_domain +and +.Fn copy_printf_domain +functions return the new domain, or +.Dv NULL +on failure (usually out of memory condition). +.Pp +The +.Fn register_printf_domain_function +and +.Fn register_printf_domain_render_std +return zero on success and \-1 on failure (usually due to an improper specifier +character or out of memory condition). +.Sh SEE ALSO +.Xr printf 3 , +.Xr strvisx 3 , +.Xr xprintf 3 , +.Xr xprintf_comp 3 , +.Xr xprintf 5 diff --git a/src/libc/stdio/xprintf_domain.c b/src/libc/stdio/xprintf_domain.c new file mode 100644 index 000000000..70c8d32f9 --- /dev/null +++ b/src/libc/stdio/xprintf_domain.c @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include "xprintf_domain.h" +#include "xprintf_private.h" + +/* These are flag characters and can never be used as conversion specifiers */ +static const char _printf_tbl_flags[] = "#$'*+,-.0123456789:;L_hjlqtvz"; + +struct _printf_tbl_defaults_fbsd { + const char *spec; + printf_arginfo_function *arginfo; + printf_render *render; +}; +static struct _printf_tbl_defaults_fbsd _printf_tbl_defaults_fbsd[] = { + {"%", __printf_arginfo_pct, __printf_render_pct}, + {"AEFGaefg", __printf_arginfo_float, __printf_render_float}, + {"Cc", __printf_arginfo_chr, __printf_render_chr}, + {"DOUXdioux", __printf_arginfo_int, __printf_render_int}, + {"Ss", __printf_arginfo_str, __printf_render_str}, + {"p", __printf_arginfo_ptr, __printf_render_ptr}, +}; +struct _printf_tbl_defaults_glibc { + const char *spec; + printf_arginfo_function *arginfo; + printf_function *render; +}; +static struct _printf_tbl_defaults_glibc _printf_tbl_defaults_glibc[] = { + {"n", __printf_arginfo_n, __printf_render_n}, +}; + +static printf_domain_t xprintf_domain_default; +#ifdef XPRINTF_DEBUG +__private_extern__ printf_domain_t xprintf_domain_global = NULL; +#endif + +__private_extern__ pthread_once_t __xprintf_domain_once = PTHREAD_ONCE_INIT; + +__private_extern__ void +__xprintf_domain_init(void) +{ + xprintf_domain_default = (printf_domain_t)calloc( +#ifdef XPRINTF_DEBUG + 2, +#else + 1, +#endif + sizeof(*xprintf_domain_default)); + if(xprintf_domain_default == NULL) + LIBC_ABORT("No memory"); + + xprintf_domain_default->rwlock = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER; + { + const char *cp; + for(cp = _printf_tbl_flags; *cp; cp++) + xprintf_domain_default->type[printf_tbl_index(*cp)] = PRINTF_DOMAIN_FLAG; + } + { + struct _printf_tbl_defaults_fbsd *d = _printf_tbl_defaults_fbsd; + int n = sizeof(_printf_tbl_defaults_fbsd) / sizeof(*_printf_tbl_defaults_fbsd); + for(; n > 0; d++, n--) { + for(const char *cp = d->spec; *cp; cp++) { + xprintf_domain_default->type[printf_tbl_index(*cp)] = PRINTF_DOMAIN_FBSD_API; + xprintf_domain_default->tbl[printf_tbl_index(*cp)] = (struct _printf_tbl){d->arginfo, d->render, NULL}; + } + } + } + { + struct _printf_tbl_defaults_glibc *d = _printf_tbl_defaults_glibc; + int n = sizeof(_printf_tbl_defaults_glibc) / sizeof(*_printf_tbl_defaults_glibc); + for(; n > 0; d++, n--) { + for(const char *cp = d->spec; *cp; cp++) { + xprintf_domain_default->type[printf_tbl_index(*cp)] = PRINTF_DOMAIN_GLIBC_API; + xprintf_domain_default->tbl[printf_tbl_index(*cp)] = (struct _printf_tbl){d->arginfo, d->render, NULL}; + } + } + } +#ifdef XPRINTF_DEBUG + xprintf_domain_global = xprintf_domain_default + 1; + *xprintf_domain_global = *xprintf_domain_default; +#endif +} + +printf_domain_t +copy_printf_domain(printf_domain_t src) +{ + printf_domain_t restrict copy; + + if(!src) { + errno = EINVAL; + return NULL; + } + copy = (printf_domain_t)MALLOC(sizeof(*copy)); + if(!copy) return NULL; + xprintf_domain_init(); + pthread_rwlock_rdlock(&src->rwlock); + *copy = *src; + pthread_rwlock_unlock(&src->rwlock); + copy->rwlock = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER; + return copy; +} + +void +free_printf_domain(printf_domain_t d) +{ + if(!d) return; + pthread_rwlock_destroy(&d->rwlock); + free(d); +} + +printf_domain_t +new_printf_domain(void) +{ + printf_domain_t restrict d; + + xprintf_domain_init(); + + d = (printf_domain_t)MALLOC(sizeof(*d)); + if(!d) return NULL; + *d = *xprintf_domain_default; + return d; +} + +int +register_printf_domain_function(printf_domain_t d, int spec, printf_function *render, printf_arginfo_function *arginfo, void *context) +{ + xprintf_domain_init(); + + if(!d || !printf_tbl_in_range(spec)) { + errno = EINVAL; + return -1; + } + xprintf_domain_init(); + + switch(d->type[printf_tbl_index(spec)]) { + case PRINTF_DOMAIN_FLAG: + errno = EINVAL; + return -1; + default: + pthread_rwlock_wrlock(&d->rwlock); + if(!render || !arginfo) { + d->type[printf_tbl_index(spec)] = PRINTF_DOMAIN_UNUSED; + } else { + d->type[printf_tbl_index(spec)] = PRINTF_DOMAIN_GLIBC_API; + d->tbl[printf_tbl_index(spec)] = (struct _printf_tbl){arginfo, render, context}; + } + pthread_rwlock_unlock(&d->rwlock); + } + + return 0; +} + +__private_extern__ int +register_printf_domain_render(printf_domain_t d, int spec, printf_render *render, printf_arginfo_function *arginfo) +{ + xprintf_domain_init(); + + if(!d || !printf_tbl_in_range(spec)) { + errno = EINVAL; + return -1; + } + xprintf_domain_init(); + + switch(d->type[printf_tbl_index(spec)]) { + case PRINTF_DOMAIN_FLAG: + errno = EINVAL; + return -1; + default: + pthread_rwlock_wrlock(&d->rwlock); + if(!render || !arginfo) { + d->type[printf_tbl_index(spec)] = PRINTF_DOMAIN_UNUSED; + } else { + d->type[printf_tbl_index(spec)] = PRINTF_DOMAIN_FBSD_API; + d->tbl[printf_tbl_index(spec)] = (struct _printf_tbl){arginfo, render, NULL}; + } + pthread_rwlock_unlock(&d->rwlock); + } + + return 0; +} + +int +register_printf_domain_render_std(printf_domain_t d, const char *specs) +{ + int ret = 0; + + for (; *specs != '\0'; specs++) { + switch (*specs) { + case 'H': + ret = register_printf_domain_render(d, *specs, + __printf_render_hexdump, + __printf_arginfo_hexdump); + break; + case 'M': + ret = register_printf_domain_render(d, *specs, + __printf_render_errno, + __printf_arginfo_errno); + break; + case 'Q': + ret = register_printf_domain_render(d, *specs, + __printf_render_quote, + __printf_arginfo_quote); + break; + case 'T': + ret = register_printf_domain_render(d, *specs, + __printf_render_time, + __printf_arginfo_time); + break; + case 'V': + ret = register_printf_domain_render(d, *specs, + __printf_render_vis, + __printf_arginfo_vis); + break; + default: + errno = EINVAL; + return (-1); + } + if(ret < 0) return ret; + } + return (0); +} diff --git a/src/libc/stdio/xprintf_domain.h b/src/libc/stdio/xprintf_domain.h new file mode 100644 index 000000000..dd8a1179f --- /dev/null +++ b/src/libc/stdio/xprintf_domain.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __XPRINTF_DOMAIN_H_ +#define __XPRINTF_DOMAIN_H_ + +#include +#include +#include + +#define PRINTF_TBL_FIRST '!' +#define PRINTF_TBL_LAST '~' +#define PRINTF_TBL_SIZE (PRINTF_TBL_LAST - PRINTF_TBL_FIRST + 1) + +#define printf_tbl_index(x) ((x) - PRINTF_TBL_FIRST) +#define printf_tbl_in_range(x) ((x) >= PRINTF_TBL_FIRST && (x) <= PRINTF_TBL_LAST) + +enum { + PRINTF_DOMAIN_UNUSED = 0, + PRINTF_DOMAIN_GLIBC_API, + PRINTF_DOMAIN_FBSD_API, + PRINTF_DOMAIN_FLAG, +}; +#define printf_domain_fbsd_api(d,x) ((d)->type[x] == PRINTF_DOMAIN_FBSD_API) +#define printf_domain_flag(d,x) ((d)->type[x] == PRINTF_DOMAIN_FLAG) +#define printf_domain_glibc_api(d,x) ((d)->type[x] == PRINTF_DOMAIN_GLIBC_API) +#define printf_domain_unused(d,x) ((d)->type[x] == PRINTF_DOMAIN_UNUSED) + +struct _printf_tbl { + printf_arginfo_function *arginfo; + void *render; /* either typedef printf_function or printf_render */ + void *context; +}; +struct _printf_domain { + pthread_rwlock_t rwlock; + char type[PRINTF_TBL_SIZE]; + struct _printf_tbl tbl[PRINTF_TBL_SIZE]; +}; + +__BEGIN_DECLS +__END_DECLS + +#endif /* __XPRINTF_DOMAIN_H_ */ diff --git a/src/libc/stdio/xprintf_exec.3 b/src/libc/stdio/xprintf_exec.3 new file mode 100644 index 000000000..5a6640800 --- /dev/null +++ b/src/libc/stdio/xprintf_exec.3 @@ -0,0 +1,57 @@ +.Dd Aug 19, 2012 +.Dt XPRINTF_EXEC 3 +.Os Darwin +.Sh NAME +.Nm asxprintf_exec , dxprintf_exec , fxprintf_exec , sxprintf_exec , +.Nm xprintf_exec , vasxprintf_exec , vdxprintf_exec , vfxprintf_exec , +.Nm vsxprintf_exec , vxprintf_exec +.Nd execute-only extensible printf execution +.Sh SYNOPSIS +.In printf.h +.Ft int +.Fn asxprintf_exec "char ** restrict ret" "printf_comp_t restrict pc" ... +.Ft int +.Fn dxprintf_exec "int fd" "printf_comp_t restrict pc" ... +.Ft int +.Fn fxprintf_exec "FILE * restrict stream" "printf_comp_t restrict pc" ... +.Ft int +.Fn sxprintf_exec "char * restrict str" "size_t size" "printf_comp_t restrict pc" ... +.Ft int +.Fn xprintf_exec "printf_comp_t restrict pc" ... +.In stdarg.h +.Ft int +.Fn vasxprintf_exec "char ** restrict ret" "printf_comp_t restrict pc" "va_list ap" +.Ft int +.Fn vdxprintf_exec "int fd" "printf_comp_t restrict pc" "va_list ap" +.Ft int +.Fn vfxprintf_exec "FILE * restrict stream" "printf_comp_t restrict pc" "va_list ap" +.Ft int +.Fn vsxprintf_exec "char * restrict str" "size_t size" "printf_comp_t restrict pc" "va_list ap" +.Ft int +.Fn vxprintf_exec "printf_comp_t restrict pc" "va_list ap" +.Sh DESCRIPTION +These functions are execute-only, extensible printf (see +.Xr xprintf 5 ) +variants, taking a +.Ft printf_comp_t +structure created by the format string compilation routine +.Xr new_printf_comp 3 . +All these variants behave like their normal printf counterparts (see +.Xr printf 3 ) +without +.Sq Li x +and +.Dq Li _exec +in the name (except +.Fn sxprintf_exec +and +.Fn vsxprintf_exec +behave like +.Fn snprintf +and +.Fn vsnprintf , +respectively). +.Sh SEE ALSO +.Xr printf 3 , +.Xr xprintf_comp 3 , +.Xr xprintf 5 diff --git a/src/libc/stdio/xprintf_exec.c b/src/libc/stdio/xprintf_exec.c new file mode 100644 index 000000000..9e831c06e --- /dev/null +++ b/src/libc/stdio/xprintf_exec.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2012 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#define __va_list __darwin_va_list + +#include +#include +#include +#include +#include + +int +asxprintf_exec(char ** __restrict ret, + printf_comp_t __restrict pc, ...) +{ + int iret; + va_list ap; + + if (!pc) { + errno = EINVAL; + return -1; + } + + va_start(ap, pc); + iret = _vasprintf(pc, NULL, ret, NULL, NULL, ap); + va_end(ap); + return iret; +} + +int +dxprintf_exec(int fd, printf_comp_t __restrict pc, ...) +{ + int ret; + va_list ap; + + if (!pc) { + errno = EINVAL; + return -1; + } + + va_start(ap, pc); + ret = _vdprintf(pc, NULL, fd, NULL, NULL, ap); + va_end(ap); + return ret; +} + +int +fxprintf_exec(FILE * __restrict stream, + printf_comp_t __restrict pc, ...) +{ + int ret; + va_list ap; + + if (!pc) { + errno = EINVAL; + return -1; + } + + va_start(ap, pc); + ret = __xvprintf(pc, NULL, stream, NULL, NULL, ap); + va_end(ap); + return ret; +} + +int +sxprintf_exec(char * __restrict str, size_t size, + printf_comp_t __restrict pc, ...) +{ + int ret; + va_list ap; + + if (!pc) { + errno = EINVAL; + return -1; + } + + va_start(ap, pc); + ret = _vsnprintf(pc, NULL, str, size, NULL, NULL, ap); + va_end(ap); + return ret; +} + +int +xprintf_exec(printf_comp_t __restrict pc, ...) +{ + int ret; + va_list ap; + + if (!pc) { + errno = EINVAL; + return -1; + } + + va_start(ap, pc); + ret = __xvprintf(pc, NULL, stdout, NULL, NULL, ap); + va_end(ap); + return ret; +} + +int +vasxprintf_exec(char ** __restrict ret, + printf_comp_t __restrict pc, va_list ap) +{ + if (!pc) { + errno = EINVAL; + return -1; + } + + return _vasprintf(pc, NULL, ret, NULL, NULL, ap); +} + +int +vdxprintf_exec(int fd, printf_comp_t __restrict pc, + va_list ap) +{ + if (!pc) { + errno = EINVAL; + return -1; + } + + return _vdprintf(pc, NULL, fd, NULL, NULL, ap); +} + +int +vfxprintf_exec(FILE * __restrict stream, + printf_comp_t __restrict pc, va_list ap) +{ + if (!pc) { + errno = EINVAL; + return -1; + } + + return __xvprintf(pc, NULL, stream, NULL, NULL, ap); +} + +int +vsxprintf_exec(char * __restrict str, size_t size, + printf_comp_t __restrict pc, va_list ap) +{ + if (!pc) { + errno = EINVAL; + return -1; + } + + return _vsnprintf(pc, NULL, str, size, NULL, NULL, ap); +} + +int +vxprintf_exec(printf_comp_t __restrict pc, va_list ap) +{ + if (!pc) { + errno = EINVAL; + return -1; + } + + return __xvprintf(pc, NULL, stdout, NULL, NULL, ap); +} diff --git a/src/libc/stdlib/CMakeLists.txt b/src/libc/stdlib/CMakeLists.txt index d9b6d71e1..1c28f7217 100644 --- a/src/libc/stdlib/CMakeLists.txt +++ b/src/libc/stdlib/CMakeLists.txt @@ -5,6 +5,7 @@ cmake_minimum_required(VERSION 2.4.0) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -D__DYNAMIC__ -D__BLOCKS__ -fblocks -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h") include_directories(${CMAKE_SOURCE_DIR}/src/external/compiler-rt/lib/BlocksRuntime) +include_directories(${CMAKE_SOURCE_DIR}/src/external/libpthread_workqueue-0.8.2/include) set(stdlib_sources a64l.c grantpt.c l64a.c qsort_b-fbsd.c) diff --git a/src/libc/stdlib/FreeBSD/abort.c b/src/libc/stdlib/FreeBSD/abort.c index 0fcbb9e5f..386572c4d 100644 --- a/src/libc/stdlib/FreeBSD/abort.c +++ b/src/libc/stdlib/FreeBSD/abort.c @@ -40,11 +40,12 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/abort.c,v 1.11 2007/01/09 00:28:09 imp E #include #include #include +#include #include "un-namespace.h" #include "libc_private.h" -#include "CrashReporterClient.h" +#include #include "_simple.h" extern void (*__cleanup)(); @@ -77,21 +78,18 @@ abort() /* abort() should call pthread_kill to deliver a signal to the aborting thread * This helps gdb focus on the thread calling abort() */ - if (__is_threaded) { - /* Block all signals on all other threads */ - sigset_t fullmask; - sigfillset(&fullmask); - (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL); - - /* Set the workqueue killable */ - __pthread_workqueue_setkill(1); - - (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL); - (void)pthread_kill(pthread_self(), SIGABRT); - } else { - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); - (void)kill(getpid(), SIGABRT); - } + + /* Block all signals on all other threads */ + sigset_t fullmask; + sigfillset(&fullmask); + (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL); + + /* Set the workqueue killable */ + __pthread_workqueue_setkill(1); + + (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)pthread_kill(pthread_self(), SIGABRT); + usleep(TIMEOUT); /* give time for signal to happen */ /* @@ -117,21 +115,18 @@ __abort() /* abort() should call pthread_kill to deliver a signal to the aborting thread * This helps gdb focus on the thread calling abort() */ - if (__is_threaded) { - /* Block all signals on all other threads */ - sigset_t fullmask; - sigfillset(&fullmask); - (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL); - - /* Set the workqueue killable */ - __pthread_workqueue_setkill(1); - - (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL); - (void)pthread_kill(pthread_self(), SIGABRT); - } else { - (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL); - (void)kill(getpid(), SIGABRT); - } + + /* Block all signals on all other threads */ + sigset_t fullmask; + sigfillset(&fullmask); + (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL); + + /* Set the workqueue killable */ + __pthread_workqueue_setkill(1); + + (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL); + (void)pthread_kill(pthread_self(), SIGABRT); + usleep(TIMEOUT); /* give time for signal to happen */ /* If for some reason SIGABRT was not delivered, we exit using __builtin_trap @@ -145,7 +140,7 @@ __abort() __builtin_trap(); } -__private_extern__ void +void abort_report_np(const char *fmt, ...) { _SIMPLE_STRING s; diff --git a/src/libc/stdlib/FreeBSD/atof.3 b/src/libc/stdlib/FreeBSD/atof.3 index 28f0870db..5454422c9 100644 --- a/src/libc/stdlib/FreeBSD/atof.3 +++ b/src/libc/stdlib/FreeBSD/atof.3 @@ -83,14 +83,14 @@ and functions are thread-safe and async-cancel-safe. .Pp The +.Fn strtod +and +.Fn strtod_l +functions are recommended instead of .Fn atof and .Fn atof_l -functions have been deprecated by -.Fn strtod -and -.Fn strtod_l -and should not be used in new code. +functions, especially in new code. .Sh ERRORS The function .Fn atof diff --git a/src/libc/stdlib/FreeBSD/atoi.3 b/src/libc/stdlib/FreeBSD/atoi.3 index 3dc33e8cd..6e8a79699 100644 --- a/src/libc/stdlib/FreeBSD/atoi.3 +++ b/src/libc/stdlib/FreeBSD/atoi.3 @@ -79,14 +79,14 @@ and functions are thread-safe and async-cancel-safe. .Pp The -.Fn atoi -and -.Fn atoi_l -functions have been deprecated by .Fn strtol and .Fn strtol_l -and should not be used in new code. +functions are recommended instead of +.Fn atoi +and +.Fn atoi_l +functions, especially in new code. .Sh ERRORS The function .Fn atoi diff --git a/src/libc/stdlib/FreeBSD/exit.c b/src/libc/stdlib/FreeBSD/exit.c index aa23703ec..ba66bc664 100644 --- a/src/libc/stdlib/FreeBSD/exit.c +++ b/src/libc/stdlib/FreeBSD/exit.c @@ -41,16 +41,23 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/exit.c,v 1.9 2007/01/09 00:28:09 imp Exp #include "atexit.h" #include "libc_private.h" +#include + void (*__cleanup)(void); -extern void __exit(int); +extern void __exit(int) __attribute__((noreturn)); +#if !TARGET_IPHONE_SIMULATOR && (__i386__ || __x86_64__) +extern void _tlv_exit(); +#endif /* * Exit, flushing stdio buffers if necessary. */ void -exit(status) - int status; +exit(int status) { +#if !TARGET_IPHONE_SIMULATOR && (__i386__ || __x86_64__) + _tlv_exit(); // C++11 requires thread_local objects to be destroyed before global objects +#endif __cxa_finalize(NULL); if (__cleanup) (*__cleanup)(); diff --git a/src/libc/stdlib/FreeBSD/getenv.3 b/src/libc/stdlib/FreeBSD/getenv.3 index 498a365c4..ebe5d2850 100644 --- a/src/libc/stdlib/FreeBSD/getenv.3 +++ b/src/libc/stdlib/FreeBSD/getenv.3 @@ -13,11 +13,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -34,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)getenv.3 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD: src/lib/libc/stdlib/getenv.3,v 1.16 2004/07/07 19:57:13 ru Exp $ +.\" $FreeBSD$ .\" -.Dd December 11, 1993 +.Dd June 20, 2007 .Dt GETENV 3 .Os .Sh NAME @@ -50,41 +46,26 @@ .Sh SYNOPSIS .In stdlib.h .Ft char * -.Fo getenv -.Fa "const char *name" -.Fc +.Fn getenv "const char *name" .Ft int -.Fo putenv -.Fa "char *string" -.Fc +.Fn setenv "const char *name" "const char *value" "int overwrite" .Ft int -.Fo setenv -.Fa "const char *name" -.Fa "const char *value" -.Fa "int overwrite" -.Fc +.Fn putenv "char *string" .Ft int -.Fo unsetenv -.Fa "const char *name" -.Fc +.Fn unsetenv "const char *name" .Sh DESCRIPTION These functions set, unset and fetch environment variables from the host .Em environment list . -For compatibility with differing environment conventions, -the given arguments -.Fa name -and -.Fa value -may be appended and prepended, -respectively, -with an equal sign -.Dq Li \&= . .Pp The .Fn getenv function obtains the current value of the environment variable, .Fa name . +The application should not modify the string pointed +to by the +.Fn getenv +function. .Pp The .Fn setenv @@ -100,8 +81,7 @@ If the variable does exist, the argument .Fa overwrite is tested; if .Fa overwrite -is -zero, the +is zero, the variable is not reset, otherwise it is reset to the given .Fa value . @@ -151,13 +131,33 @@ is returned. .Bl -tag -width Er .It Bq Er EINVAL The function +.Fn getenv , +.Fn setenv +or .Fn unsetenv -failed because +failed because the .Fa name -was not found in the environment list. +is a +.Dv NULL +pointer, points to an empty string, or points to a string containing an +.Dq Li \&= +character. +.Pp +The function +.Fn putenv +failed because +.Fa string +is a +.Dv NULL +pointer or +.Fa string +is without an +.Dq Li \&= +character. .It Bq Er ENOMEM The function -.Fn setenv +.Fn setenv , +.Fn unsetenv or .Fn putenv failed because it was unable to allocate memory for the environment. @@ -206,33 +206,38 @@ The .Fn getenv function conforms to .St -isoC . +The +.Fn setenv , +.Fn putenv +and +.Fn unsetenv +functions conforms to +.St -p1003.1-2001 . +.Sh HISTORY +The functions +.Fn setenv +and +.Fn unsetenv +appeared in +.At v7 . +The +.Fn putenv +function appeared in +.Bx 4.3 Reno . .Sh BUGS Successive calls to .Fn setenv -or -.Fn putenv -assigning a differently sized +that assign a larger-sized .Fa value -to the same +than any previous value to the same .Fa name will result in a memory leak. The .Fx -semantics for these functions +semantics for this function (namely, that the contents of .Fa value are copied and that old values remain accessible indefinitely) make this bug unavoidable. Future versions may eliminate one or both of these semantic guarantees in order to fix the bug. -.Sh HISTORY -The functions -.Fn setenv -and -.Fn unsetenv -appeared in -.At v7 . -The -.Fn putenv -function appeared in -.Bx 4.3 Reno . diff --git a/src/libc/stdlib/FreeBSD/getenv.c b/src/libc/stdlib/FreeBSD/getenv.c index 47b60dfab..bde742115 100644 --- a/src/libc/stdlib/FreeBSD/getenv.c +++ b/src/libc/stdlib/FreeBSD/getenv.c @@ -33,15 +33,18 @@ static char sccsid[] = "@(#)getenv.c 8.1 (Berkeley) 6/4/93"; #include __FBSDID("$FreeBSD: src/lib/libc/stdlib/getenv.c,v 1.8 2007/05/01 16:02:41 ache Exp $"); +#include #include #include #include #include -__private_extern__ char *__findenv(const char *, int *, char **); +__private_extern__ char *__findenv_locked(const char *, int *, char **); +__private_extern__ void __environ_lock(void); +__private_extern__ void __environ_unlock(void); /* - * __findenv -- + * __findenv_locked -- * Returns pointer to value associated with name, if any, else NULL. * Sets offset to be the offset of the name/value combination in the * environmental array, for use by setenv(3) and unsetenv(3). @@ -50,7 +53,7 @@ __private_extern__ char *__findenv(const char *, int *, char **); * This routine *should* be a static; don't use it. */ __private_extern__ char * -__findenv(name, offset, environ) +__findenv_locked(name, offset, environ) const char *name; int *offset; char **environ; @@ -76,6 +79,32 @@ __findenv(name, offset, environ) return (NULL); } +static os_unfair_lock __environ_lock_obj = OS_UNFAIR_LOCK_INIT; +__private_extern__ void +__environ_lock(void) +{ +#if TARGET_OS_IOS && !TARGET_OS_SIMULATOR + os_unfair_lock_lock_with_options_4Libc( + &__environ_lock_obj, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); +#else // TARGET_OS_IOS && !TARGET_OS_SIMULATOR + os_unfair_lock_lock(&__environ_lock_obj); +#endif // TARGET_OS_IOS && !TARGET_OS_SIMULATOR +} +__private_extern__ void +__environ_unlock(void) +{ +#if TARGET_OS_IOS && !TARGET_OS_SIMULATOR + os_unfair_lock_unlock_4Libc(&__environ_lock_obj); +#else // TARGET_OS_IOS && !TARGET_OS_SIMULATOR + os_unfair_lock_unlock(&__environ_lock_obj); +#endif // TARGET_OS_IOS && !TARGET_OS_SIMULATOR +} +__private_extern__ void +__environ_lock_fork_child(void) +{ + __environ_lock_obj = OS_UNFAIR_LOCK_INIT; +} + /* * _getenvp -- SPI using an arbitrary pointer to string array (the array must * have been created with malloc) and an env state, created by _allocenvstate(). @@ -84,9 +113,12 @@ __findenv(name, offset, environ) char * _getenvp(const char *name, char ***envp, void *state __unused) { + // envp is passed as an argument, so the lock is not protecting everything int offset; - - return (__findenv(name, &offset, *envp)); + __environ_lock(); + char *result = (__findenv_locked(name, &offset, *envp)); + __environ_unlock(); + return result; } /* @@ -98,6 +130,8 @@ getenv(name) const char *name; { int offset; - - return (__findenv(name, &offset, *_NSGetEnviron())); + __environ_lock(); + char *result = __findenv_locked(name, &offset, *_NSGetEnviron()); + __environ_unlock(); + return result; } diff --git a/src/libc/stdlib/FreeBSD/getopt_long.3 b/src/libc/stdlib/FreeBSD/getopt_long.3 index fd33cfca7..69047162c 100644 --- a/src/libc/stdlib/FreeBSD/getopt_long.3 +++ b/src/libc/stdlib/FreeBSD/getopt_long.3 @@ -29,9 +29,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)getopt.3 8.5 (Berkeley) 4/27/95 -.\" $FreeBSD: src/lib/libc/stdlib/getopt_long.3,v 1.13 2005/01/20 09:17:04 ru Exp $ +.\" $FreeBSD$ .\" -.Dd April 1, 2000 +.Dd December 25, 2011 .Dt GETOPT_LONG 3 .Os .Sh NAME @@ -130,11 +130,11 @@ field should be one of: .Pp .Bl -tag -width ".Dv optional_argument" -offset indent -compact .It Dv no_argument -no argument to the option is expect +no argument to the option is expected .It Dv required_argument an argument to the option is required .It Dv optional_argument -an argument to the option may be presented. +an argument to the option may be presented .El .Pp If @@ -239,7 +239,7 @@ static struct option longopts[] = { }; bflag = 0; -while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1) +while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1) { switch (ch) { case 'b': bflag = 1; @@ -256,6 +256,7 @@ while ((ch = getopt_long(argc, argv, "bf:", longopts, NULL)) != -1) break; default: usage(); + } } argc -= optind; argv += optind; @@ -469,9 +470,9 @@ The .Fn getopt_long and .Fn getopt_long_only -functions first appeared in +functions first appeared in the .Tn GNU -libiberty. +libiberty library. The first .Bx implementation of diff --git a/src/libc/stdlib/FreeBSD/psort.c b/src/libc/stdlib/FreeBSD/psort.c index a95ce60d7..cb6f707aa 100644 --- a/src/libc/stdlib/FreeBSD/psort.c +++ b/src/libc/stdlib/FreeBSD/psort.c @@ -94,10 +94,8 @@ struct shared { size_t es; size_t turnoff; dispatch_queue_t queue; - pthread_cond_t cond; - pthread_mutex_t mutex; + dispatch_group_t group; OSSpinLock sharedlock; - int count; }; static union args * @@ -321,8 +319,8 @@ nevermind: args->a = a; args->n = r; args->depth_limit = depth_limit; - OSAtomicIncrement32(&shared->count); - dispatch_async_f(shared->queue, args, _psort_parallel); + dispatch_group_async_f(shared->group, shared->queue, args, + _psort_parallel); } else { #ifdef I_AM_PSORT_R _psort(a, r, es, thunk, cmp, depth_limit, NULL); @@ -352,11 +350,6 @@ _psort_parallel(void *x) #endif shared->cmp, args->depth_limit, shared); returnargs(shared, args); - if(OSAtomicDecrement32(&shared->count) <= 0) { - pthread_mutex_lock(&shared->mutex); - pthread_cond_signal(&shared->cond); - pthread_mutex_unlock(&shared->mutex); - } } /* fast, approximate integer square root */ @@ -395,8 +388,7 @@ psort(void *a, size_t n, size_t es, cmp_t *cmp) shared.cmp = cmp; shared.es = es; shared.queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - shared.cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER; - shared.mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + shared.group = dispatch_group_create(); args->a = a; args->n = n; args->depth_limit = DEPTH(n); @@ -415,17 +407,11 @@ psort(void *a, size_t n, size_t es, cmp_t *cmp) * this purpose. */ shared.turnoff = isqrt(n); - OSAtomicIncrement32(&shared.count); _psort_parallel(args); /* wait for queue to drain */ - pthread_mutex_lock(&shared.mutex); - while(shared.count > 0) - pthread_cond_wait(&shared.cond, &shared.mutex); - - pthread_mutex_unlock(&shared.mutex); - pthread_mutex_destroy(&shared.mutex); - pthread_cond_destroy(&shared.cond); + dispatch_group_wait(shared.group, DISPATCH_TIME_FOREVER); + dispatch_release(shared.group); for(p = shared.pagelist; p; p = pp) { pp = p->next; munmap(p, PAGESIZE); diff --git a/src/libc/stdlib/FreeBSD/psort_b.c b/src/libc/stdlib/FreeBSD/psort_b.c deleted file mode 120000 index 9ba0b02aa..000000000 --- a/src/libc/stdlib/FreeBSD/psort_b.c +++ /dev/null @@ -1 +0,0 @@ -psort.c \ No newline at end of file diff --git a/src/libc/stdlib/FreeBSD/psort_b.c b/src/libc/stdlib/FreeBSD/psort_b.c new file mode 100644 index 000000000..cb6f707aa --- /dev/null +++ b/src/libc/stdlib/FreeBSD/psort_b.c @@ -0,0 +1,430 @@ +/****************************************************************************/ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/qsort.c,v 1.15 2008/01/14 09:21:34 das Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#define __APPLE_API_PRIVATE +#include + +#ifdef I_AM_PSORT_R +typedef int cmp_t(void *, const void *, const void *); +#else +typedef int cmp_t(const void *, const void *); +#endif +#ifdef I_AM_PSORT_B +static inline char *med3(char *, char *, char *, cmp_t ^, void *) __attribute__((always_inline)); +#else +static inline char *med3(char *, char *, char *, cmp_t *, void *) __attribute__((always_inline)); +#endif +static inline void swapfunc(char *, char *, int, int) __attribute__((always_inline)); + +#define min(a, b) (a) < (b) ? a : b + +#define NARGS ((PAGESIZE - offsetof(struct page, args)) / sizeof(union args)) +#define PAGESIZE 4096 +#define PARALLEL_MIN_SIZE 2000 /* determine heuristically */ + +struct shared; /* forward reference */ +union args { + union args *next; + struct { + struct shared *shared; + void *a; + size_t n; + int depth_limit; + } /* anonymous */; +}; + +struct page { + struct page *next; + union args args[0]; +}; + +struct shared { + char *who; + union args *freelist; + struct page *pagelist; +#ifdef I_AM_PSORT_R + void *thunk; +#endif +#ifdef I_AM_PSORT_B + cmp_t ^cmp; +#else + cmp_t *cmp; +#endif + size_t es; + size_t turnoff; + dispatch_queue_t queue; + dispatch_group_t group; + OSSpinLock sharedlock; +}; + +static union args * +getargs(struct shared *shared) +{ + union args *args; + + OSSpinLockLock(&shared->sharedlock); + if(!shared->freelist) { + struct page *page; + union args *prev; + int i; + if((page = (struct page *)mmap(NULL, PAGESIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0)) == NULL) + return NULL; + page->next = shared->pagelist; + shared->pagelist = page; + prev = NULL; + for(args = page->args, i = NARGS; i > 0; args++, i--) { + args->next = prev; + prev = args; + } + shared->freelist = prev; + } + args = shared->freelist; + shared->freelist = args->next; + OSSpinLockUnlock(&shared->sharedlock); + return args; +} + +static void +returnargs(struct shared *shared, union args *args) +{ + OSSpinLockLock(&shared->sharedlock); + args->next = shared->freelist; + shared->freelist = args; + OSSpinLockUnlock(&shared->sharedlock); +} + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + TYPE *pi = (TYPE *) (parmi); \ + TYPE *pj = (TYPE *) (parmj); \ + do { \ + TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static inline void +swapfunc(a, b, n, swaptype) + char *a, *b; + int n, swaptype; +{ + if(swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +#ifdef I_AM_PSORT_R +#define CMP(t, x, y) (cmp((t), (x), (y))) +#else +#define CMP(t, x, y) (cmp((x), (y))) +#endif + +static inline char * +med3(char *a, char *b, char *c, +#ifdef I_AM_PSORT_B +cmp_t ^cmp, +#else +cmp_t *cmp, +#endif +void *thunk +#ifndef I_AM_PSORT_R +__unused +#endif +) +{ + return CMP(thunk, a, b) < 0 ? + (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) + :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); +} + +#ifdef __LP64__ +#define DEPTH(x) (2 * (flsl((long)(x)) - 1)) +#else /* !__LP64__ */ +#define DEPTH(x) (2 * (fls((int)(x)) - 1)) +#endif /* __LP64__ */ + +#ifdef I_AM_PSORT_R +int __heapsort_r(void *, size_t, size_t, void *, int (*)(void *, const void *, const void *)); +#endif + +static void _psort_parallel(void *x); + +static void +_psort(void *a, size_t n, size_t es, +#ifdef I_AM_PSORT_R +void *thunk, +#else +#define thunk NULL +#endif +#ifdef I_AM_PSORT_B +cmp_t ^cmp, +#else +cmp_t *cmp, +#endif +int depth_limit, struct shared *shared) +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn; + size_t d, r; + int cmp_result; + int swaptype, swap_cnt; + +loop: + if (depth_limit-- <= 0) { +#ifdef I_AM_PSORT_B + heapsort_b(a, n, es, cmp); +#elif defined(I_AM_PSORT_R) + __heapsort_r(a, n, es, thunk, cmp); +#else + heapsort(a, n, es, cmp); +#endif + return; + } + SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); + pm = med3(pm - d, pm, pm + d, cmp, thunk); + pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); + } + pm = med3(pl, pm, pn, cmp, thunk); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) { + if (cmp_result == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) { + if (cmp_result == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + + pn = (char *)a + n * es; + r = min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = min(pd - pc, pn - pd - es); + vecswap(pb, pn - r, r); + + if (swap_cnt == 0) { /* Switch to insertion sort */ + r = 1 + n / 4; /* n >= 7, so r >= 2 */ + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) { + swap(pl, pl - es); + if (++swap_cnt > r) goto nevermind; + } + return; + } + +nevermind: + if ((r = pb - pa) > es) { + r /= es; + if (shared && r > shared->turnoff) { + union args *args = getargs(shared); + + if (args == NULL) + LIBC_ABORT("%s: getargs: %s", shared->who, strerror(errno)); + args->shared = shared; + args->a = a; + args->n = r; + args->depth_limit = depth_limit; + dispatch_group_async_f(shared->group, shared->queue, args, + _psort_parallel); + } else { +#ifdef I_AM_PSORT_R + _psort(a, r, es, thunk, cmp, depth_limit, NULL); +#else + _psort(a, r, es, cmp, depth_limit, NULL); +#endif + } + } + if ((r = pd - pc) > es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +/* psort(pn - r, r / es, es, cmp);*/ +} + +static void +_psort_parallel(void *x) +{ + union args *args = (union args *)x; + struct shared *shared = args->shared; + + _psort(args->a, args->n, shared->es, +#ifdef I_AM_PSORT_R + shared->thunk, +#endif + shared->cmp, args->depth_limit, shared); + returnargs(shared, args); +} + +/* fast, approximate integer square root */ +static size_t +isqrt(size_t x) +{ + size_t s = 1L << (flsl(x) / 2); + return (s + x / s) / 2; +} + +void +#ifdef I_AM_PSORT_R +psort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) +#elif defined(I_AM_PSORT_B) +psort_b(void *a, size_t n, size_t es, cmp_t ^cmp) +#else +psort(void *a, size_t n, size_t es, cmp_t *cmp) +#endif +{ + if (n >= PARALLEL_MIN_SIZE && _NumCPUs() > 1) { + struct shared shared; + union args *args; + + bzero(&shared, sizeof(shared)); + shared.sharedlock = OS_SPINLOCK_INIT; + if ((args = getargs(&shared)) != NULL) { + struct page *p, *pp; +#ifdef I_AM_PSORT_R + shared.who = "psort_r"; + shared.thunk = thunk; +#elif defined(I_AM_PSORT_B) + shared.who = "psort_b"; +#else + shared.who = "psort"; +#endif + shared.cmp = cmp; + shared.es = es; + shared.queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + shared.group = dispatch_group_create(); + args->a = a; + args->n = n; + args->depth_limit = DEPTH(n); + args->shared = &shared; + /* + * The turnoff value is the size of a partition that, + * below which, we stop doing in parallel, and just do + * in the current thread. The value of sqrt(n) was + * determined heuristically. There is a smaller + * dependence on the slowness of the comparison + * function, and there might be a dependence on the + * number of processors, but the algorithm has not been + * determined. Because the sensitivity to the turnoff + * value is relatively low, we use a fast, approximate + * integer square root routine that is good enough for + * this purpose. + */ + shared.turnoff = isqrt(n); + _psort_parallel(args); + + /* wait for queue to drain */ + dispatch_group_wait(shared.group, DISPATCH_TIME_FOREVER); + dispatch_release(shared.group); + for(p = shared.pagelist; p; p = pp) { + pp = p->next; + munmap(p, PAGESIZE); + } + return; + } + } + /* Just call qsort */ +#ifdef I_AM_PSORT_R + qsort_r(a, n, es, thunk, cmp); +#elif defined(I_AM_PSORT_B) + qsort_b(a, n, es, cmp); +#else + qsort(a, n, es, cmp); +#endif +} diff --git a/src/libc/stdlib/FreeBSD/psort_r.c b/src/libc/stdlib/FreeBSD/psort_r.c deleted file mode 120000 index 9ba0b02aa..000000000 --- a/src/libc/stdlib/FreeBSD/psort_r.c +++ /dev/null @@ -1 +0,0 @@ -psort.c \ No newline at end of file diff --git a/src/libc/stdlib/FreeBSD/psort_r.c b/src/libc/stdlib/FreeBSD/psort_r.c new file mode 100644 index 000000000..cb6f707aa --- /dev/null +++ b/src/libc/stdlib/FreeBSD/psort_r.c @@ -0,0 +1,430 @@ +/****************************************************************************/ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/stdlib/qsort.c,v 1.15 2008/01/14 09:21:34 das Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#define __APPLE_API_PRIVATE +#include + +#ifdef I_AM_PSORT_R +typedef int cmp_t(void *, const void *, const void *); +#else +typedef int cmp_t(const void *, const void *); +#endif +#ifdef I_AM_PSORT_B +static inline char *med3(char *, char *, char *, cmp_t ^, void *) __attribute__((always_inline)); +#else +static inline char *med3(char *, char *, char *, cmp_t *, void *) __attribute__((always_inline)); +#endif +static inline void swapfunc(char *, char *, int, int) __attribute__((always_inline)); + +#define min(a, b) (a) < (b) ? a : b + +#define NARGS ((PAGESIZE - offsetof(struct page, args)) / sizeof(union args)) +#define PAGESIZE 4096 +#define PARALLEL_MIN_SIZE 2000 /* determine heuristically */ + +struct shared; /* forward reference */ +union args { + union args *next; + struct { + struct shared *shared; + void *a; + size_t n; + int depth_limit; + } /* anonymous */; +}; + +struct page { + struct page *next; + union args args[0]; +}; + +struct shared { + char *who; + union args *freelist; + struct page *pagelist; +#ifdef I_AM_PSORT_R + void *thunk; +#endif +#ifdef I_AM_PSORT_B + cmp_t ^cmp; +#else + cmp_t *cmp; +#endif + size_t es; + size_t turnoff; + dispatch_queue_t queue; + dispatch_group_t group; + OSSpinLock sharedlock; +}; + +static union args * +getargs(struct shared *shared) +{ + union args *args; + + OSSpinLockLock(&shared->sharedlock); + if(!shared->freelist) { + struct page *page; + union args *prev; + int i; + if((page = (struct page *)mmap(NULL, PAGESIZE, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0)) == NULL) + return NULL; + page->next = shared->pagelist; + shared->pagelist = page; + prev = NULL; + for(args = page->args, i = NARGS; i > 0; args++, i--) { + args->next = prev; + prev = args; + } + shared->freelist = prev; + } + args = shared->freelist; + shared->freelist = args->next; + OSSpinLockUnlock(&shared->sharedlock); + return args; +} + +static void +returnargs(struct shared *shared, union args *args) +{ + OSSpinLockLock(&shared->sharedlock); + args->next = shared->freelist; + shared->freelist = args; + OSSpinLockUnlock(&shared->sharedlock); +} + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + TYPE *pi = (TYPE *) (parmi); \ + TYPE *pj = (TYPE *) (parmj); \ + do { \ + TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static inline void +swapfunc(a, b, n, swaptype) + char *a, *b; + int n, swaptype; +{ + if(swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +#ifdef I_AM_PSORT_R +#define CMP(t, x, y) (cmp((t), (x), (y))) +#else +#define CMP(t, x, y) (cmp((x), (y))) +#endif + +static inline char * +med3(char *a, char *b, char *c, +#ifdef I_AM_PSORT_B +cmp_t ^cmp, +#else +cmp_t *cmp, +#endif +void *thunk +#ifndef I_AM_PSORT_R +__unused +#endif +) +{ + return CMP(thunk, a, b) < 0 ? + (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) + :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); +} + +#ifdef __LP64__ +#define DEPTH(x) (2 * (flsl((long)(x)) - 1)) +#else /* !__LP64__ */ +#define DEPTH(x) (2 * (fls((int)(x)) - 1)) +#endif /* __LP64__ */ + +#ifdef I_AM_PSORT_R +int __heapsort_r(void *, size_t, size_t, void *, int (*)(void *, const void *, const void *)); +#endif + +static void _psort_parallel(void *x); + +static void +_psort(void *a, size_t n, size_t es, +#ifdef I_AM_PSORT_R +void *thunk, +#else +#define thunk NULL +#endif +#ifdef I_AM_PSORT_B +cmp_t ^cmp, +#else +cmp_t *cmp, +#endif +int depth_limit, struct shared *shared) +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn; + size_t d, r; + int cmp_result; + int swaptype, swap_cnt; + +loop: + if (depth_limit-- <= 0) { +#ifdef I_AM_PSORT_B + heapsort_b(a, n, es, cmp); +#elif defined(I_AM_PSORT_R) + __heapsort_r(a, n, es, thunk, cmp); +#else + heapsort(a, n, es, cmp); +#endif + return; + } + SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); + pm = med3(pm - d, pm, pm + d, cmp, thunk); + pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); + } + pm = med3(pl, pm, pn, cmp, thunk); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) { + if (cmp_result == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) { + if (cmp_result == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + + pn = (char *)a + n * es; + r = min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = min(pd - pc, pn - pd - es); + vecswap(pb, pn - r, r); + + if (swap_cnt == 0) { /* Switch to insertion sort */ + r = 1 + n / 4; /* n >= 7, so r >= 2 */ + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) { + swap(pl, pl - es); + if (++swap_cnt > r) goto nevermind; + } + return; + } + +nevermind: + if ((r = pb - pa) > es) { + r /= es; + if (shared && r > shared->turnoff) { + union args *args = getargs(shared); + + if (args == NULL) + LIBC_ABORT("%s: getargs: %s", shared->who, strerror(errno)); + args->shared = shared; + args->a = a; + args->n = r; + args->depth_limit = depth_limit; + dispatch_group_async_f(shared->group, shared->queue, args, + _psort_parallel); + } else { +#ifdef I_AM_PSORT_R + _psort(a, r, es, thunk, cmp, depth_limit, NULL); +#else + _psort(a, r, es, cmp, depth_limit, NULL); +#endif + } + } + if ((r = pd - pc) > es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +/* psort(pn - r, r / es, es, cmp);*/ +} + +static void +_psort_parallel(void *x) +{ + union args *args = (union args *)x; + struct shared *shared = args->shared; + + _psort(args->a, args->n, shared->es, +#ifdef I_AM_PSORT_R + shared->thunk, +#endif + shared->cmp, args->depth_limit, shared); + returnargs(shared, args); +} + +/* fast, approximate integer square root */ +static size_t +isqrt(size_t x) +{ + size_t s = 1L << (flsl(x) / 2); + return (s + x / s) / 2; +} + +void +#ifdef I_AM_PSORT_R +psort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) +#elif defined(I_AM_PSORT_B) +psort_b(void *a, size_t n, size_t es, cmp_t ^cmp) +#else +psort(void *a, size_t n, size_t es, cmp_t *cmp) +#endif +{ + if (n >= PARALLEL_MIN_SIZE && _NumCPUs() > 1) { + struct shared shared; + union args *args; + + bzero(&shared, sizeof(shared)); + shared.sharedlock = OS_SPINLOCK_INIT; + if ((args = getargs(&shared)) != NULL) { + struct page *p, *pp; +#ifdef I_AM_PSORT_R + shared.who = "psort_r"; + shared.thunk = thunk; +#elif defined(I_AM_PSORT_B) + shared.who = "psort_b"; +#else + shared.who = "psort"; +#endif + shared.cmp = cmp; + shared.es = es; + shared.queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + shared.group = dispatch_group_create(); + args->a = a; + args->n = n; + args->depth_limit = DEPTH(n); + args->shared = &shared; + /* + * The turnoff value is the size of a partition that, + * below which, we stop doing in parallel, and just do + * in the current thread. The value of sqrt(n) was + * determined heuristically. There is a smaller + * dependence on the slowness of the comparison + * function, and there might be a dependence on the + * number of processors, but the algorithm has not been + * determined. Because the sensitivity to the turnoff + * value is relatively low, we use a fast, approximate + * integer square root routine that is good enough for + * this purpose. + */ + shared.turnoff = isqrt(n); + _psort_parallel(args); + + /* wait for queue to drain */ + dispatch_group_wait(shared.group, DISPATCH_TIME_FOREVER); + dispatch_release(shared.group); + for(p = shared.pagelist; p; p = pp) { + pp = p->next; + munmap(p, PAGESIZE); + } + return; + } + } + /* Just call qsort */ +#ifdef I_AM_PSORT_R + qsort_r(a, n, es, thunk, cmp); +#elif defined(I_AM_PSORT_B) + qsort_b(a, n, es, cmp); +#else + qsort(a, n, es, cmp); +#endif +} diff --git a/src/libc/stdlib/FreeBSD/putenv.c b/src/libc/stdlib/FreeBSD/putenv.c index a2c53be35..6458d6306 100644 --- a/src/libc/stdlib/FreeBSD/putenv.c +++ b/src/libc/stdlib/FreeBSD/putenv.c @@ -46,8 +46,10 @@ extern struct owned_ptr *__env_owned; extern char **_saved_environ; #endif /* LEGACY_CRT1_ENVIRON */ -__private_extern__ int __init__env_owned(int); -__private_extern__ int __setenv(const char *, const char *, int, int, char ***, struct owned_ptr *); +__private_extern__ int __init__env_owned_locked(int); +__private_extern__ int __setenv_locked(const char *, const char *, int, int, char ***, struct owned_ptr *); +__private_extern__ void __environ_lock(void); +__private_extern__ void __environ_unlock(void); #ifndef BUILDING_VARIANT /* @@ -58,8 +60,15 @@ __private_extern__ int __setenv(const char *, const char *, int, int, char ***, int _putenvp(char *str, char ***envp, void *state) { - if (__init__env_owned(1)) return (-1); - return (__setenv(str, NULL, 1, 0, envp, (state ? (struct owned_ptr *)state : __env_owned))); + __environ_lock(); + if (__init__env_owned_locked(1)) { + __environ_unlock(); + return (-1); + } + int ret = __setenv_locked(str, NULL, 1, 0, envp, + (state ? (struct owned_ptr *)state : __env_owned)); + __environ_unlock(); + return ret; } #endif /* BUILDING_VARIANT */ @@ -67,9 +76,8 @@ int putenv(str) char *str; { -#ifdef LEGACY_CRT1_ENVIRON int ret; -#endif /* LEGACY_CRT1_ENVIRON */ + int copy; #if __DARWIN_UNIX03 if (str == NULL || *str == 0 || index(str, '=') == NULL) { @@ -80,21 +88,22 @@ putenv(str) if (index(str, '=') == NULL) return (-1); #endif /* __DARWIN_UNIX03 */ - if (__init__env_owned(1)) return (-1); -#ifdef LEGACY_CRT1_ENVIRON - ret = -#else /* !LEGACY_CRT1_ENVIRON */ - return -#endif /* !LEGACY_CRT1_ENVIRON */ - __setenv(str, NULL, 1, + #if __DARWIN_UNIX03 - 0, + copy = 0; #else /* !__DARWIN_UNIX03 */ - -1, + copy = -1; #endif /* __DARWIN_UNIX03 */ - _NSGetEnviron(), __env_owned); + + __environ_lock(); + if (__init__env_owned_locked(1)) { + __environ_unlock(); + return (-1); + } + ret = __setenv_locked(str, NULL, 1, copy, _NSGetEnviron(), __env_owned); #ifdef LEGACY_CRT1_ENVIRON _saved_environ = *_NSGetEnviron(); - return ret; #endif /* LEGACY_CRT1_ENVIRON */ + __environ_unlock(); + return ret; } diff --git a/src/libc/stdlib/FreeBSD/rand.3 b/src/libc/stdlib/FreeBSD/rand.3 index fec6ac633..278a6820d 100644 --- a/src/libc/stdlib/FreeBSD/rand.3 +++ b/src/libc/stdlib/FreeBSD/rand.3 @@ -64,7 +64,7 @@ .Sh DESCRIPTION .Bf -symbolic These interfaces are obsoleted by -.Xr random 3 . +.Xr arc4random 3 . .Ef .Pp The @@ -109,6 +109,7 @@ A pointer to the context value .Fa seed must be supplied by the caller. .Sh SEE ALSO +.Xr arc4random 3 , .Xr random 3 , .Xr random 4 .Sh STANDARDS diff --git a/src/libc/stdlib/FreeBSD/rand.c b/src/libc/stdlib/FreeBSD/rand.c index fd9973f7d..7090acc7d 100644 --- a/src/libc/stdlib/FreeBSD/rand.c +++ b/src/libc/stdlib/FreeBSD/rand.c @@ -33,7 +33,7 @@ static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/rand.c,v 1.17 2007/12/11 20:39:32 ache Exp $"); +__FBSDID("$FreeBSD$"); #include "namespace.h" #include /* for sranddev() */ @@ -116,12 +116,12 @@ u_int seed; * secure random(4) interface. */ void -sranddev() +sranddev(void) { int fd, done; done = 0; - fd = _open("/dev/random", O_RDONLY, 0); + fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0); if (fd >= 0) { if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next)) done = 1; @@ -130,10 +130,9 @@ sranddev() if (!done) { struct timeval tv; - unsigned long junk; gettimeofday(&tv, NULL); - srand((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk); + srand((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec); } } diff --git a/src/libc/stdlib/FreeBSD/random.c b/src/libc/stdlib/FreeBSD/random.c index 15db64023..1ca75ed6b 100644 --- a/src/libc/stdlib/FreeBSD/random.c +++ b/src/libc/stdlib/FreeBSD/random.c @@ -31,16 +31,17 @@ static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.25 2007/01/09 00:28:10 imp Exp $"); +__FBSDID("$FreeBSD$"); -/* - * We always compile with __DARWIN_UNIX03 set to one, relying on the fact that - * (for non-LP64) sizeof(int) == sizeof(long) == sizeof(size_t), so that we - * don't have to have two different versions of the prototypes. For LP64, - * we only support the POSIX-compatible prototypes. - */ +#ifdef __APPLE__ +// Always compile with __DARWIN_UNIX03=1 prototypes. +// Applications using legacy interfaces (i386 only) use types of the same size: +// sizeof(int) == sizeof(long) == sizeof(size_t) #undef __DARWIN_UNIX03 #define __DARWIN_UNIX03 1 +#endif // __APPLE__ + +#include "namespace.h" #include "namespace.h" #include /* for srandomdev() */ #include /* for srandomdev() */ @@ -224,10 +225,8 @@ static int rand_deg = DEG_3; static int rand_sep = SEP_3; static uint32_t *end_ptr = &randtbl[DEG_3 + 1]; -static inline uint32_t good_rand(int32_t) __attribute__((always_inline)); - -static inline uint32_t good_rand (x) - int32_t x; +static inline uint32_t +good_rand(int32_t x) { #ifdef USE_WEAK_SEEDING /* @@ -272,8 +271,11 @@ static inline uint32_t good_rand (x) * for default usage relies on values produced by this routine. */ void -srandom(x) - unsigned x; +#ifdef __APPLE__ +srandom(unsigned int x) +#else +srandom(unsigned long x) +#endif { int i, lim; @@ -303,7 +305,7 @@ srandom(x) * a fixed seed. */ void -srandomdev() +srandomdev(void) { int fd, done; size_t len; @@ -314,7 +316,7 @@ srandomdev() len = rand_deg * sizeof state[0]; done = 0; - fd = _open("/dev/random", O_RDONLY, 0); + fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0); if (fd >= 0) { if (_read(fd, (void *) state, len) == (ssize_t) len) done = 1; @@ -323,10 +325,9 @@ srandomdev() if (!done) { struct timeval tv; - unsigned long junk; gettimeofday(&tv, NULL); - srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk); + srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec); return; } @@ -360,10 +361,11 @@ srandomdev() * complain about mis-alignment, but you should disregard these messages. */ char * -initstate(seed, arg_state, n) - unsigned seed; /* seed for R.N.G. */ - char *arg_state; /* pointer to state array */ - size_t n; /* # bytes of state info */ +#ifdef __APPLE__ +initstate(unsigned int seed, char *arg_state, size_t n) +#else +initstate(unsigned long seed, char *arg_state, long n) +#endif { char *ostate = (char *)(&state[-1]); uint32_t *int_arg_state = (uint32_t *)arg_state; @@ -375,7 +377,7 @@ initstate(seed, arg_state, n) if (n < BREAK_0) { (void)fprintf(stderr, "random: not enough state (%ld bytes); ignored.\n", n); - return(0); + return (0); } if (n < BREAK_1) { rand_type = TYPE_0; @@ -405,7 +407,7 @@ initstate(seed, arg_state, n) int_arg_state[0] = rand_type; else int_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type; - return(ostate); + return (ostate); } /* @@ -428,8 +430,7 @@ initstate(seed, arg_state, n) * complain about mis-alignment, but you should disregard these messages. */ char * -setstate(arg_state) - const char *arg_state; /* pointer to state array */ +setstate(const char *arg_state) { uint32_t *new_state = (uint32_t *)arg_state; uint32_t type = new_state[0] % MAX_TYPES; @@ -460,7 +461,7 @@ setstate(arg_state) fptr = &state[(rear + rand_sep) % rand_deg]; } end_ptr = &state[rand_deg]; /* set end_ptr too */ - return(ostate); + return (ostate); } /* @@ -481,7 +482,7 @@ setstate(arg_state) * Returns a 31-bit random number. */ long -random() +random(void) { uint32_t i; uint32_t *f, *r; @@ -506,5 +507,5 @@ random() fptr = f; rptr = r; } - return((long)i); + return ((long)i); } diff --git a/src/libc/stdlib/FreeBSD/reallocf.c b/src/libc/stdlib/FreeBSD/reallocf.c index d50200622..a85b5a3c0 100644 --- a/src/libc/stdlib/FreeBSD/reallocf.c +++ b/src/libc/stdlib/FreeBSD/reallocf.c @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/lib/libc/stdlib/reallocf.c,v 1.4 2002/03/22 21:53:10 obrien Exp $"); +__FBSDID("$FreeBSD$"); #include @@ -35,7 +35,14 @@ reallocf(void *ptr, size_t size) void *nptr; nptr = realloc(ptr, size); - if (!nptr && ptr) + + /* + * When the System V compatibility option (malloc "V" flag) is + * in effect, realloc(ptr, 0) frees the memory and returns NULL. + * So, to avoid double free, call free() only when size != 0. + * realloc(ptr, 0) can't fail when ptr != NULL. + */ + if (!nptr && ptr && size != 0) free(ptr); return (nptr); } diff --git a/src/libc/stdlib/FreeBSD/realpath.3 b/src/libc/stdlib/FreeBSD/realpath.3 index 3ffdf9c67..bce1dae00 100644 --- a/src/libc/stdlib/FreeBSD/realpath.3 +++ b/src/libc/stdlib/FreeBSD/realpath.3 @@ -99,6 +99,16 @@ If .Fa resolved_name was non-NULL, it will contains the pathname which caused the problem. +.Sh VARIANTS +Defining +.Dv _DARWIN_C_SOURCE +or +.Dv _DARWIN_BETTER_REALPATH +before including stdio.h will cause the provided implementation of +.Fn realpath +to use F_GETPATH from +.Xr fcntl 2 +to discover the path. .Sh ERRORS The function .Fn realpath diff --git a/src/libc/stdlib/FreeBSD/realpath.c b/src/libc/stdlib/FreeBSD/realpath.c index 234bce9a8..13c4e6f1e 100644 --- a/src/libc/stdlib/FreeBSD/realpath.c +++ b/src/libc/stdlib/FreeBSD/realpath.c @@ -55,7 +55,7 @@ struct attrs { }; #ifndef BUILDING_VARIANT -__private_extern__ struct attrlist _rp_alist = { +__private_extern__ const struct attrlist _rp_alist = { ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID, @@ -65,7 +65,7 @@ __private_extern__ struct attrlist _rp_alist = { 0, }; #else /* BUILDING_VARIANT */ -__private_extern__ struct attrlist _rp_alist; +__private_extern__ const struct attrlist _rp_alist; #endif /* BUILDING_VARIANT */ extern char * __private_getcwd(char *, size_t, int); @@ -224,7 +224,7 @@ error_return: errno = ENAMETOOLONG; goto error_return; } - if (getattrlist(resolved, &_rp_alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) { + if (getattrlist(resolved, (void *)&_rp_alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) { useattrs = 1; islink = (attrs.type == VLNK); dev = attrs.dev; @@ -327,7 +327,7 @@ error_return: symlink[slen] = '/'; symlink[slen + 1] = 0; } - left_len = strlcat(symlink, left, sizeof(left)); + left_len = strlcat(symlink, left, sizeof(symlink)); if (left_len >= sizeof(left)) { errno = ENAMETOOLONG; goto error_return; diff --git a/src/libc/stdlib/FreeBSD/setenv.c b/src/libc/stdlib/FreeBSD/setenv.c index 7a12cea3e..75a5a0db9 100644 --- a/src/libc/stdlib/FreeBSD/setenv.c +++ b/src/libc/stdlib/FreeBSD/setenv.c @@ -42,12 +42,15 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/setenv.c,v 1.14 2007/05/01 16:02:41 ache #include struct owned_ptr; -__private_extern__ char *__findenv(const char *, int *, char **); -__private_extern__ int __setenv(const char *, const char *, int, int, char ***, struct owned_ptr *); -__private_extern__ void __unsetenv(const char *, char **, struct owned_ptr *); +__private_extern__ char *__findenv_locked(const char *, int *, char **); +__private_extern__ int __setenv_locked(const char *, const char *, int, int, char ***, struct owned_ptr *); +__private_extern__ void __unsetenv_locked(const char *, char **, struct owned_ptr *); + +__private_extern__ void __environ_lock(void); +__private_extern__ void __environ_unlock(void); __private_extern__ struct owned_ptr *__env_owned; -__private_extern__ int __init__env_owned(int); +__private_extern__ int __init__env_owned_locked(int); /* * _cthread_init_routine used to be called from crt1.o to initialize threads. @@ -205,7 +208,7 @@ _owned_ptr_search(struct owned_ptr * __restrict owned, const void * __restrict p * Initialize the process's __env_owned structure */ __private_extern__ int -__init__env_owned(int should_set_errno) +__init__env_owned_locked(int should_set_errno) { int save; @@ -229,7 +232,7 @@ __init__env_owned(int should_set_errno) * -1 - like 0, except we copy of the name=value string in name */ __private_extern__ int -__setenv(name, value, rewrite, copy, environp, owned) +__setenv_locked(name, value, rewrite, copy, environp, owned) const char *name; const char *value; int rewrite, copy; @@ -240,7 +243,7 @@ __setenv(name, value, rewrite, copy, environp, owned) int offset; int oindex; - if ((c = __findenv(name, &offset, *environp))) { /* find if already exists */ + if ((c = __findenv_locked(name, &offset, *environp))) { /* find if already exists */ char *e; if (!rewrite) return (0); @@ -326,13 +329,13 @@ __setenv(name, value, rewrite, copy, environp, owned) } __private_extern__ void -__unsetenv(const char *name, char **environ, struct owned_ptr *owned) +__unsetenv_locked(const char *name, char **environ, struct owned_ptr *owned) { char **p; int offset; int oindex; - while (__findenv(name, &offset, environ)) { /* if set multiple times */ + while (__findenv_locked(name, &offset, environ)) { /* if set multiple times */ /* if we malloc-ed it, free it first */ if (_owned_ptr_search(owned, environ[offset], &oindex) == 0) { _owned_ptr_delete(owned, oindex); @@ -358,7 +361,7 @@ _allocenvstate(void) * _copyenv -- SPI that copies a NULL-tereminated char * array in a newly * allocated buffer, compatible with the other SPI env routines. If env * is NULL, a char * array composed of a single NULL is returned. NULL - * is returned on error. (This isn't needed anymore, as __setenv will + * is returned on error. (This isn't needed anymore, as __setenv_locked will * automatically make a copy.) */ char ** @@ -407,8 +410,15 @@ _deallocenvstate(void *state) int _setenvp(const char *name, const char *value, int rewrite, char ***envp, void *state) { - if (__init__env_owned(1)) return (-1); - return (__setenv(name, value, rewrite, 1, envp, (state ? (struct owned_ptr *)state : __env_owned))); + __environ_lock(); + if (__init__env_owned_locked(1)) { + __environ_unlock(); + return (-1); + } + int ret = __setenv_locked(name, value, rewrite, 1, envp, + (state ? (struct owned_ptr *)state : __env_owned)); + __environ_unlock(); + return ret; } /* @@ -420,8 +430,13 @@ _setenvp(const char *name, const char *value, int rewrite, char ***envp, void *s int _unsetenvp(const char *name, char ***envp, void *state) { - if (__init__env_owned(1)) return (-1); - __unsetenv(name, *envp, (state ? (struct owned_ptr *)state : __env_owned)); + __environ_lock(); + if (__init__env_owned_locked(1)) { + __environ_unlock(); + return (-1); + } + __unsetenv_locked(name, *envp, (state ? (struct owned_ptr *)state : __env_owned)); + __environ_unlock(); return 0; } @@ -438,9 +453,7 @@ setenv(name, value, rewrite) const char *value; int rewrite; { -#ifdef LEGACY_CRT1_ENVIRON int ret; -#endif /* LEGACY_CRT1_ENVIRON */ /* no null ptr or empty str */ if(name == NULL || *name == 0) { @@ -456,16 +469,31 @@ setenv(name, value, rewrite) } #endif /* __DARWIN_UNIX03 */ - if (*value == '=') /* no `=' in value */ - ++value; - if (__init__env_owned(1)) return (-1); + __environ_lock(); + if (__init__env_owned_locked(1)) { + __environ_unlock(); + return (-1); + } + ret = __setenv_locked(name, value, rewrite, 1, _NSGetEnviron(), __env_owned); #ifdef LEGACY_CRT1_ENVIRON - ret = __setenv(name, value, rewrite, 1, _NSGetEnviron(), __env_owned); _saved_environ = *_NSGetEnviron(); - return ret; -#else /* !LEGACY_CRT1_ENVIRON */ - return (__setenv(name, value, rewrite, 1, _NSGetEnviron(), __env_owned)); #endif /* !LEGACY_CRT1_ENVIRON */ + __environ_unlock(); + + return ret; +} + +static inline __attribute__((always_inline)) int +_unsetenv(const char *name, int should_set_errno) +{ + __environ_lock(); + if (__init__env_owned_locked(should_set_errno)) { + __environ_unlock(); + return (-1); + } + __unsetenv_locked(name, *_NSGetEnviron(), __env_owned); + __environ_unlock(); + return 0; } /* @@ -474,13 +502,8 @@ setenv(name, value, rewrite) */ #if __DARWIN_UNIX03 int -#else /* !__DARWIN_UNIX03 */ -void -#endif /* __DARWIN_UNIX03 */ -unsetenv(name) - const char *name; +unsetenv(const char *name) { -#if __DARWIN_UNIX03 /* no null ptr or empty str */ if(name == NULL || *name == 0) { errno = EINVAL; @@ -492,15 +515,15 @@ unsetenv(name) errno = EINVAL; return (-1); } - if (__init__env_owned(1)) return (-1); + return _unsetenv(name, 1); +} #else /* !__DARWIN_UNIX03 */ +void +unsetenv(const char *name) +{ /* no null ptr or empty str */ if(name == NULL || *name == 0) return; - if (__init__env_owned(0)) return; -#endif /* __DARWIN_UNIX03 */ - __unsetenv(name, *_NSGetEnviron(), __env_owned); -#if __DARWIN_UNIX03 - return 0; -#endif /* __DARWIN_UNIX03 */ + _unsetenv(name, 0); } +#endif /* __DARWIN_UNIX03 */ diff --git a/src/libc/stdlib/FreeBSD/system.c b/src/libc/stdlib/FreeBSD/system.c index c2a56c7c5..61ef03cbf 100644 --- a/src/libc/stdlib/FreeBSD/system.c +++ b/src/libc/stdlib/FreeBSD/system.c @@ -49,20 +49,23 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/system.c,v 1.11 2007/01/09 00:28:10 imp #include #define environ (*_NSGetEnviron()) +#include + #if __DARWIN_UNIX03 #include static pthread_mutex_t __systemfn_mutex = PTHREAD_MUTEX_INITIALIZER; extern int __unix_conforming; -#ifdef VARIANT_CANCELABLE -extern void _pthread_testcancel(pthread_t thread, int isconforming); -#endif /* VARIANT_CANCELABLE */ #endif /* __DARWIN_UNIX03 */ int __system(command) const char *command; { +#if TARGET_OS_IPHONE && (TARGET_OS_SIMULATOR || !TARGET_OS_IOS) + // Don't abort() on iOS for now + LIBC_ABORT("system() is not supported on this platform."); +#else pid_t pid, savedpid; int pstat, err; struct sigaction ign, intact, quitact; @@ -75,15 +78,19 @@ __system(command) if (__unix_conforming == 0) __unix_conforming = 1; #ifdef VARIANT_CANCELABLE - _pthread_testcancel(pthread_self(), 1); + pthread_testcancel(); #endif /* VARIANT_CANCELABLE */ #endif /* __DARWIN_UNIX03 */ if (!command) { /* just checking... */ +#if TARGET_OS_IPHONE + return(0); +#else if (access(_PATH_BSHELL, F_OK) == -1) /* if no sh or no access */ return(0); else return(1); +#endif } if ((err = posix_spawnattr_init(&attr)) != 0) { @@ -142,6 +149,7 @@ __system(command) pthread_mutex_unlock(&__systemfn_mutex); #endif /* __DARWIN_UNIX03 */ return(pstat); +#endif /* TARGET_OS_IPHONE && (TARGET_OS_SIMULATOR || !TARGET_OS_IOS) */ } __weak_reference(__system, system); diff --git a/src/libc/stdlib/NetBSD/strfmon.c b/src/libc/stdlib/NetBSD/strfmon.c index 2afa83568..8ee41da4c 100644 --- a/src/libc/stdlib/NetBSD/strfmon.c +++ b/src/libc/stdlib/NetBSD/strfmon.c @@ -483,7 +483,7 @@ __calc_left_pad(int flags, char *cur_symb, struct lconv *lc) { } static int -get_groups(int size, char *grouping) { +get_groups(int size, const char *grouping) { int chars = 0; @@ -522,7 +522,7 @@ __format_grouped_double(double value, int *flags, int padded; - char *grouping; + const char *grouping; char decimal_point; char thousands_sep; diff --git a/src/libc/stdlib/grantpt.c b/src/libc/stdlib/grantpt.c index d0411baa5..c8653ec96 100644 --- a/src/libc/stdlib/grantpt.c +++ b/src/libc/stdlib/grantpt.c @@ -62,11 +62,15 @@ grantpt(int fd) char * ptsname(int fd) { - static char ptsnamebuf[ 128]; /* ioctl knows length */ + static char *ptsnamebuf = NULL; int error; char *retval = NULL; struct stat sbuf; + if (ptsnamebuf == NULL) { + ptsnamebuf = malloc(128); // defined by TIOCPTYGNAME + } + error = ioctl(fd, TIOCPTYGNAME, ptsnamebuf); if (!error) { /* @@ -75,8 +79,9 @@ ptsname(int fd) * POSIX: Handle device rename test case, which is expected * to fail if the pty has been renamed. */ - if (stat(ptsnamebuf, &sbuf) == 0) + if (stat(ptsnamebuf, &sbuf) == 0) { retval = ptsnamebuf; + } } return (retval); diff --git a/src/libc/stdtime/FreeBSD/ctime.3 b/src/libc/stdtime/FreeBSD/ctime.3 index 7bcc80b98..1cd4fcd86 100644 --- a/src/libc/stdtime/FreeBSD/ctime.3 +++ b/src/libc/stdtime/FreeBSD/ctime.3 @@ -84,6 +84,11 @@ the Epoch (00:00:00 .Tn UTC , January 1, 1970; see .Xr time 3 ) . +When encountering an error, these functions return +.Dv NULL +and set +.Dv errno +to an appropriate value. .Pp The function .Fn localtime diff --git a/src/libc/stdtime/FreeBSD/localtime.c b/src/libc/stdtime/FreeBSD/localtime.c index 7e3cd2a02..c814a30fb 100644 --- a/src/libc/stdtime/FreeBSD/localtime.c +++ b/src/libc/stdtime/FreeBSD/localtime.c @@ -97,7 +97,7 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime/localtime.c,v 1.43 2008/04/01 06:56:11 #define WILDABBR " " #endif /* !defined WILDABBR */ -static char wildabbr[] = "WILDABBR"; +static const char wildabbr[] = "WILDABBR"; /* * In June 2004 it was decided UTC was a more appropriate default time @@ -167,7 +167,6 @@ struct rule { #ifdef NOTIFY_TZ typedef struct { int token; - int notify_was_off; int is_set; } notify_tz_t; @@ -210,7 +209,11 @@ static const char * getnum(const char * strp, int * nump, int min, static const char * getsecs(const char * strp, long * secsp); static const char * getoffset(const char * strp, long * offsetp); static const char * getrule(const char * strp, struct rule * rulep); +#ifdef NOTIFY_TZ +static void gmtload(struct state * sp, char *path); +#else /* ! NOTIFY_TZ */ static void gmtload(struct state * sp); +#endif /* NOTIFY_TZ */ #ifdef __LP64__ static struct tm * gmtsub(const time_t * timep, long offset, struct tm * tmp); @@ -256,7 +259,11 @@ static int tmcomp(const struct tm * atmp, const struct tm * btmp); static time_t transtime(time_t janfirst, int year, const struct rule * rulep, long offset); +#ifdef NOTIFY_TZ +static int tzload(const char * name, struct state * sp, char *path); +#else /* ! NOTIFY_TZ */ static int tzload(const char * name, struct state * sp); +#endif /* NOTIFY_TZ */ static int tzparse(const char * name, struct state * sp, int lastditch); @@ -288,8 +295,8 @@ __private_extern__ pthread_rwlock_t lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER; static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; char * tzname[2] = { - wildabbr, - wildabbr + (char *)wildabbr, + (char *)wildabbr }; /* @@ -339,23 +346,10 @@ __private_extern__ long __darwin_altzone = 0; } \ } #endif /* NOTIFY_TZ_LOG */ -/*-------------------------------------------------------------------- - * __notify_78945668_info__ is a global variable (defined in Libnotify) - * that can be used to disable the notify mechanism. Set to a negative - * value to disable. It can then be set back to zero to re-enable. - *-------------------------------------------------------------------- */ -extern int __notify_78945668_info__; - -/*-------------------------------------------------------------------- - * fullname is used to pass the actual path of the timezone file to the - * notify routines. If it is a nil string, that means no timezone file - * is being used. - *-------------------------------------------------------------------- */ -static char * fullname = NULL; - -static notify_tz_t gmt_notify = {-1, 0, 0}; -static notify_tz_t lcl_notify = {-1, 0, 0}; -static char notify_tz_name[] = NOTIFY_TZ_NAME; + +static notify_tz_t gmt_notify = {-1, 0}; +static notify_tz_t lcl_notify = {-1, 0}; +static const char notify_tz_name[] = NOTIFY_TZ_NAME; #endif /* NOTIFY_TZ */ static long @@ -382,8 +376,8 @@ settzname(void) #define NEED_DAYLIGHT 4 #define NEED_ALL (NEED_STD | NEED_DST | NEED_DAYLIGHT) - tzname[0] = wildabbr; - tzname[1] = wildabbr; + tzname[0] = (char *)wildabbr; + tzname[1] = (char *)wildabbr; #ifdef USG_COMPAT daylight = 0; _st_set_timezone(0); @@ -467,22 +461,6 @@ notify_check_tz(notify_tz_t *p) unsigned int nstat; int ncheck; - if (__notify_78945668_info__ < 0) { -#ifdef NOTIFY_TZ_DEBUG - if(!p->notify_was_off) NOTIFY_TZ_PRINTF("notify_check_tz: setting %s_notify->notify_was_off\n", (p == &lcl_notify ? "lcl" : "gmt")); -#endif /* NOTIFY_TZ_DEBUG */ - p->notify_was_off = 1; - return; - } - /* force rereading the timezone file if notify was off */ - if (p->notify_was_off) { -#ifdef NOTIFY_TZ_DEBUG - NOTIFY_TZ_PRINTF("notify_check_tz: saw %s_notify->notify_was_off\n", (p == &lcl_notify ? "lcl" : "gmt")); -#endif /* NOTIFY_TZ_DEBUG */ - p->is_set = 0; - p->notify_was_off = 0; - return; - } if (p->token < 0) return; nstat = notify_check(p->token, &ncheck); @@ -506,8 +484,6 @@ notify_register_tz(char *file, notify_tz_t *p) unsigned int nstat; int ncheck; - if (__notify_78945668_info__ < 0) - return; /*---------------------------------------------------------------- * Since we don't record the last time zone filename, just cancel * (which should remove the file monitor) and setup from scratch @@ -524,7 +500,7 @@ notify_register_tz(char *file, notify_tz_t *p) * Otherwise use com.apple.system.timezone. *----------------------------------------------------------------*/ if (TZDEFAULT && strcmp(file, TZDEFAULT) == 0) - name = notify_tz_name; + name = (char *)notify_tz_name; else { name = alloca(sizeof(notify_tz_name) + strlen(file) + 1); if (name == NULL) { @@ -574,9 +550,16 @@ notify_register_tz(char *file, notify_tz_t *p) #endif /* NOTIFY_TZ */ static int +#ifdef NOTIFY_TZ +tzload(name, sp, path) +#else /* ! NOTIFY_TZ */ tzload(name, sp) +#endif /* NOTIFY_TZ */ const char * name; struct state * const sp; +#ifdef NOTIFY_TZ +char * path; /* copy full path if non-NULL */ +#endif /* NOTIFY_TZ */ { const char * p; int i; @@ -590,6 +573,10 @@ struct state * const sp; if ((name[0] == ':' && name[1] == '/') || name[0] == '/' || strchr(name, '.')) name = NULL; +#ifdef NOTIFY_TZ + if (path) + *path = 0; /* default to empty string on error */ +#endif /* NOTIFY_TZ */ if (name == NULL && (name = TZDEFAULT) == NULL) return -1; { @@ -602,15 +589,7 @@ struct state * const sp; ** to hold the longest file name string that the implementation ** guarantees can be opened." */ -#ifdef NOTIFY_TZ - if (!fullname) { - fullname = malloc(FILENAME_MAX + 1); - if (!fullname) - return -1; - } -#else /* ! NOTIFY_TZ */ char fullname[FILENAME_MAX + 1]; -#endif /* NOTIFY_TZ */ if (name[0] == ':') ++name; @@ -618,11 +597,7 @@ struct state * const sp; if (!doaccess) { if ((p = TZDIR) == NULL) return -1; -#ifdef NOTIFY_TZ - if ((strlen(p) + 1 + strlen(name) + 1) >= (FILENAME_MAX + 1)) -#else /* ! NOTIFY_TZ */ if ((strlen(p) + 1 + strlen(name) + 1) >= sizeof fullname) -#endif /* NOTIFY_TZ */ return -1; (void) strcpy(fullname, p); (void) strcat(fullname, "/"); @@ -635,8 +610,11 @@ struct state * const sp; name = fullname; } #ifdef NOTIFY_TZ - else - strcpy(fullname, name); + if (path) { + if (strlen(name) > FILENAME_MAX) + return -1; + strcpy(path, name); + } #endif /* NOTIFY_TZ */ if (doaccess && access(name, R_OK) != 0) return -1; @@ -1081,9 +1059,10 @@ const int lastditch; return -1; } } - load_result = tzload(TZDEFRULES, sp); #ifdef NOTIFY_TZ - *fullname = 0; /* mark fullname as invalid */ + load_result = tzload(TZDEFRULES, sp, NULL); +#else /* !NOTIFY_TZ */ + load_result = tzload(TZDEFRULES, sp); #endif /* NOTIFY_TZ */ if (load_result != 0) sp->leapcnt = 0; /* so, we're off a little */ @@ -1261,10 +1240,21 @@ const int lastditch; } static void +#ifdef NOTIFY_TZ +gmtload(sp, path) +#else /* ! NOTIFY_TZ */ gmtload(sp) +#endif /* NOTIFY_TZ */ struct state * const sp; +#ifdef NOTIFY_TZ +char *path; +#endif /* NOTIFY_TZ */ { +#ifdef NOTIFY_TZ + if (tzload(gmt, sp, path) != 0) +#else /* ! NOTIFY_TZ */ if (tzload(gmt, sp) != 0) +#endif /* NOTIFY_TZ */ (void) tzparse(gmt, sp, TRUE); } @@ -1319,10 +1309,20 @@ tzsetwall_basic(int rdlocked) } } #endif /* defined ALL_STATE */ +#ifdef NOTIFY_TZ + { + char fullname[FILENAME_MAX + 1]; + if (tzload((char *) NULL, lclptr, fullname) != 0) + /* + * If fullname is empty (an error occurred) then + * default to the UTC path + */ + gmtload(lclptr, *fullname ? NULL : fullname); + notify_register_tz(fullname, &lcl_notify); + } +#else /* ! NOTIFY_TZ */ if (tzload((char *) NULL, lclptr) != 0) gmtload(lclptr); -#ifdef NOTIFY_TZ - notify_register_tz(fullname, &lcl_notify); #endif /* NOTIFY_TZ */ settzname(); _RWLOCK_UNLOCK(&lcl_rwlock); @@ -1395,14 +1395,32 @@ tzset_basic(int rdlocked) lclptr->ttis[0].tt_abbrind = 0; (void) strcpy(lclptr->chars, gmt); #ifdef NOTIFY_TZ - if (fullname) - *fullname = 0; + notify_register_tz(NULL, &lcl_notify); #endif /* NOTIFY_TZ */ - } else if (tzload(name, lclptr) != 0) + } else +#ifdef NOTIFY_TZ + { + char fullname[FILENAME_MAX + 1]; + /* + * parsedOK indicates whether tzparse() was called and + * succeeded. This means that TZ is a time conversion + * specification, so we don't need to register for + * notifications. + */ + int parsedOK = FALSE; + if (tzload(name, lclptr, fullname) != 0) + if (name[0] == ':' || !(parsedOK = tzparse(name, lclptr, FALSE) == 0)) + /* + * If fullname is empty (an error occurred) then + * default to the UTC path + */ + (void) gmtload(lclptr, *fullname ? NULL : fullname); + notify_register_tz(parsedOK ? NULL : fullname, &lcl_notify); + } +#else /* ! NOTIFY_TZ */ + if (tzload(name, lclptr) != 0) if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) (void) gmtload(lclptr); -#ifdef NOTIFY_TZ - notify_register_tz(fullname, &lcl_notify); #endif /* NOTIFY_TZ */ settzname(); _RWLOCK_UNLOCK(&lcl_rwlock); @@ -1589,16 +1607,15 @@ struct tm * const tmp; #endif /* NOTIFY_TZ */ gmtptr = (struct state *) malloc(sizeof *gmtptr); if (gmtptr != NULL) -#ifdef NOTIFY_TZ - { -#endif /* NOTIFY_TZ */ #endif /* defined ALL_STATE */ - gmtload(gmtptr); #ifdef NOTIFY_TZ + { + char fullname[FILENAME_MAX + 1]; + gmtload(gmtptr, fullname); notify_register_tz(fullname, &gmt_notify); -#ifdef ALL_STATE } -#endif +#else /* ! NOTIFY_TZ */ + gmtload(gmtptr); #endif /* NOTIFY_TZ */ gmt_is_set = TRUE; } diff --git a/src/libc/stdtime/FreeBSD/private.h b/src/libc/stdtime/FreeBSD/private.h index 5f7f59507..d1d821eb3 100644 --- a/src/libc/stdtime/FreeBSD/private.h +++ b/src/libc/stdtime/FreeBSD/private.h @@ -19,7 +19,7 @@ #define HAVE_STRERROR 1 #define HAVE_UNISTD_H 1 #define LOCALE_HOME _PATH_LOCALE -#define TZDIR "/usr/share/zoneinfo" +/* #define TZDIR "/usr/share/zoneinfo" */ #endif /* ndef TM_GMTOFF */ /* diff --git a/src/libc/stdtime/FreeBSD/strftime.c b/src/libc/stdtime/FreeBSD/strftime.c index 0f0e524fd..8acb0a415 100644 --- a/src/libc/stdtime/FreeBSD/strftime.c +++ b/src/libc/stdtime/FreeBSD/strftime.c @@ -72,7 +72,7 @@ __private_extern__ long _st_get_timezone(void); #define PAD_ZERO 3 #ifndef BUILDING_VARIANT -static const char* fmt_padding[][4] = { +static const char * const fmt_padding[][4] = { /* DEFAULT, LESS, SPACE, ZERO */ #define PAD_FMT_MONTHDAY 0 #define PAD_FMT_HMS 0 diff --git a/src/libc/stdtime/FreeBSD/strptime.3 b/src/libc/stdtime/FreeBSD/strptime.3 index a9c25f98d..eb8c16c17 100644 --- a/src/libc/stdtime/FreeBSD/strptime.3 +++ b/src/libc/stdtime/FreeBSD/strptime.3 @@ -23,9 +23,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD: src/lib/libc/stdtime/strptime.3,v 1.24 2005/01/20 09:17:04 ru Exp $ +.\" $FreeBSD$ .\" " -.Dd January 4, 2003 +.Dd October 2, 2014 .Dt STRPTIME 3 .Os .Sh NAME @@ -38,31 +38,31 @@ .In time.h .Ft char * .Fo strptime -.Fa "const char *restrict buf" -.Fa "const char *restrict format" -.Fa "struct tm *restrict tm" +.Fa "const char * restrict buf" +.Fa "const char * restrict format" +.Fa "struct tm * restrict timeptr" .Fc .In time.h .In xlocale.h .Ft char * -.Fo strptime_l -.Fa "const char *restrict buf" -.Fa "const char *restrict format" -.Fa "struct tm *restrict tm" -.Fa "locale_t loc" -.Fc +.Fn strptime_l "const char * restrict buf" "const char * restrict format" "struct tm * restrict timeptr" "locale_t loc" .Sh DESCRIPTION The .Fn strptime function parses the string in the buffer -.Fa buf , +.Fa buf according to the string pointed to by .Fa format , and fills in the elements of the structure pointed to by -.Fa tm . +.Fa timeptr . The resulting values will be relative to the local time zone. Thus, it can be considered the reverse operation of .Xr strftime 3 . +The +.Fn strptime_l +function does the same as +.Fn strptime , +but takes an explicit locale rather than using the current locale. .Pp The .Fa format @@ -81,6 +81,11 @@ and are now interpreted as beginning at 1969 per POSIX requirements. Years 69-00 are interpreted in the 20th century (1969-2000), years 01-68 in the 21st century (2001-2068). +The +.Fa \&%U +and +.Fa %W +format specifiers accept any value within the range 00 to 53. .Pp If the .Fa format @@ -88,7 +93,7 @@ string does not contain enough conversion specifications to completely specify the resulting .Vt struct tm , the unspecified members of -.Va tm +.Va timeptr are left untouched. For example, if .Fa format @@ -101,17 +106,9 @@ and .Va tm_min will be modified. If time relative to today is desired, initialize the -.Fa tm +.Fa timeptr structure with today's date before passing it to .Fn strptime . -.Pp -While the -.Fn strptime -function uses the current locale, the -.Fn strptime_l -function may be passed a locale directly. See -.Xr xlocale 3 -for more information. .Sh RETURN VALUES Upon successful completion, .Fn strptime @@ -122,6 +119,9 @@ that has not been required to satisfy the specified conversions in It returns .Dv NULL if one of the conversions failed. +.Fn strptime_l +returns the same values as +.Fn strptime . .Sh LEGACY DESCRIPTION In legacy mode, the .Fa %Y @@ -173,14 +173,6 @@ and 12PM is taken as noon. .Pp The -.Fa %U -and -.Fa %W -format specifiers accept any value within the range 00 to 53 -without validating against other values supplied (like month -or day of the year, for example). -.Pp -The .Fa %Z format specifier only accepts time zone abbreviations of the local time zone, or the value "GMT". diff --git a/src/libc/stdtime/FreeBSD/strptime.c b/src/libc/stdtime/FreeBSD/strptime.c index 963410b0e..2220c5dac 100644 --- a/src/libc/stdtime/FreeBSD/strptime.c +++ b/src/libc/stdtime/FreeBSD/strptime.c @@ -1,27 +1,13 @@ -/* - * Powerdog Industries kindly requests feedback from anyone modifying - * this function: - * - * Date: Thu, 05 Jun 1997 23:17:17 -0400 - * From: Kevin Ruddy - * To: James FitzGibbon - * Subject: Re: Use of your strptime(3) code (fwd) - * - * The reason for the "no mod" clause was so that modifications would - * come back and we could integrate them and reissue so that a wider - * audience could use it (thereby spreading the wealth). This has - * made it possible to get strptime to work on many operating systems. - * I'm not sure why that's "plain unacceptable" to the FreeBSD team. - * - * Anyway, you can change it to "with or without modification" as - * you see fit. Enjoy. - * - * Kevin Ruddy - * Powerdog Industries, Inc. - */ -/* +/*- + * Copyright (c) 2014 Gary Mills + * Copyright 2011, Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1994 Powerdog Industries. All rights reserved. * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -31,12 +17,6 @@ * notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgement: - * This product includes software developed by Powerdog Industries. - * 4. The name of Powerdog Industries may not be used to endorse or - * promote products derived from this software without specific prior - * written permission. * * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -49,6 +29,10 @@ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of Powerdog Industries. */ #include @@ -59,7 +43,7 @@ static char copyright[] __unused = static char sccsid[] __unused = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; #endif /* !defined NOID */ #endif /* not lint */ -__FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.37 2009/09/02 04:56:30 ache Exp $"); +__FBSDID("$FreeBSD$"); #include "xlocale_private.h" @@ -71,48 +55,69 @@ __FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.37 2009/09/02 04:56:30 a #include #include #include -#include -#include #include "un-namespace.h" #include "libc_private.h" #include "timelocal.h" +#include "tzfile.h" time_t _mktime(struct tm *, const char *); -#define asizeof(a) (sizeof (a) / sizeof ((a)[0])) +#define asizeof(a) (sizeof(a) / sizeof((a)[0])) enum {CONVERT_NONE, CONVERT_GMT, CONVERT_ZONE}; +enum week_kind { WEEK_U = 'U', WEEK_V = 'V', WEEK_W = 'W'}; + +#define _strptime(b,f,t,c,l) _strptime0(b,f,t,c,l,FLAG_NONE,0,WEEK_U) + +#define FLAG_NONE 0x01 +#define FLAG_YEAR 0x02 +#define FLAG_MONTH 0x04 +#define FLAG_YDAY 0x08 +#define FLAG_MDAY 0x10 +#define FLAG_WDAY 0x20 +#define FLAG_WEEK 0x40 +#define FLAG_CENTURY 0x100 +#define FLAG_YEAR_IN_CENTURY 0x200 + +/* + * Calculate the week day of the first day of a year. Valid for + * the Gregorian calendar, which began Sept 14, 1752 in the UK + * and its colonies. Ref: + * http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week + */ -#define _strptime(b,f,t,c,l) _strptime0(b,f,t,c,l,-1,0,-1) +static int +first_wday_of(int year) +{ + return (((2 * (3 - (year / 100) % 4)) + (year % 100) + + ((year % 100) / 4) + (isleap(year) ? 6 : 0) + 1) % 7); +} static char * -_strptime0(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t loc, int year, int yday, int wday) +_strptime0(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t locale, int flags, int week_number, enum week_kind week_kind) { char c; const char *ptr; - int i, - len; + int wday_offset; + int i, len; int Ealternative, Oalternative; - struct lc_time_T *tptr = __get_current_time_locale(loc); + const struct lc_time_T *tptr = __get_current_time_locale(locale); + static int start_of_month[2][13] = { + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, + {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} + }; ptr = fmt; while (*ptr != 0) { - if (*buf == 0) { - fmt = ptr; - while (isspace_l((unsigned char)*ptr, loc)) { - ptr++; - } - return ((*ptr)==0) ? (char *)fmt : 0; /* trailing whitespace is ok */ - } - c = *ptr++; if (c != '%') { - if (isspace_l((unsigned char)c, loc)) - while (*buf != 0 && isspace_l((unsigned char)*buf, loc)) + if (isspace_l((unsigned char)c, locale)) + while (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) buf++; else if (c != *buf++) - return 0; + return (NULL); continue; } @@ -121,133 +126,145 @@ _strptime0(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t label: c = *ptr++; switch (c) { - case 0: case '%': if (*buf++ != '%') - return 0; + return (NULL); break; case '+': - buf = _strptime(buf, tptr->date_fmt, tm, convp, loc); - if (buf == 0) - return 0; + buf = _strptime(buf, tptr->date_fmt, tm, convp, locale); + if (buf == NULL) + return (NULL); + flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; break; case 'C': - if (!isdigit_l((unsigned char)*buf, loc)) - return 0; + if (!isdigit_l((unsigned char)*buf, locale)) + return (NULL); /* XXX This will break for 3-digit centuries. */ len = 2; - for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (i < 19) - return 0; + return (NULL); + + if (flags & FLAG_YEAR_IN_CENTURY) { + tm->tm_year = i * 100 + (tm->tm_year % 100) - TM_YEAR_BASE; + flags &= ~FLAG_YEAR_IN_CENTURY; + } else { + tm->tm_year = i * 100 - TM_YEAR_BASE; + flags |= FLAG_YEAR; + flags |= FLAG_CENTURY; + } - if (year != -1) - tm->tm_year = (year % 100) + i * 100 - 1900; - else - tm->tm_year = i * 100 - 1900; - year = tm->tm_year; break; case 'c': - buf = _strptime(buf, tptr->c_fmt, tm, convp, loc); - if (buf == 0) - return 0; + buf = _strptime(buf, tptr->c_fmt, tm, convp, locale); + if (buf == NULL) + return (NULL); + flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + flags &= ~(FLAG_CENTURY | FLAG_YEAR_IN_CENTURY); break; case 'D': - buf = _strptime(buf, "%m/%d/%y", tm, convp, loc); - if (buf == 0) - return 0; + buf = _strptime(buf, "%m/%d/%y", tm, convp, locale); + if (buf == NULL) + return (NULL); + flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + flags &= ~(FLAG_CENTURY | FLAG_YEAR_IN_CENTURY); break; case 'E': if (Ealternative || Oalternative) break; Ealternative++; + if (*ptr == '%') return (NULL); goto label; case 'O': if (Ealternative || Oalternative) break; Oalternative++; + if (*ptr == '%') return (NULL); goto label; case 'F': - buf = _strptime(buf, "%Y-%m-%d", tm, convp, loc); - if (buf == 0) - return 0; + buf = _strptime(buf, "%Y-%m-%d", tm, convp, locale); + if (buf == NULL) + return (NULL); + flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + flags &= ~(FLAG_CENTURY | FLAG_YEAR_IN_CENTURY); break; case 'R': - buf = _strptime(buf, "%H:%M", tm, convp, loc); - if (buf == 0) - return 0; + buf = _strptime(buf, "%H:%M", tm, convp, locale); + if (buf == NULL) + return (NULL); break; case 'r': - buf = _strptime(buf, tptr->ampm_fmt, tm, convp, loc); - if (buf == 0) - return 0; - break; - - case 'n': - case 't': - if (!isspace((unsigned char)*buf)) - return 0; - while (isspace((unsigned char)*buf)) - buf++; + buf = _strptime(buf, tptr->ampm_fmt, tm, convp, locale); + if (buf == NULL) + return (NULL); break; case 'T': - buf = _strptime(buf, "%H:%M:%S", tm, convp, loc); - if (buf == 0) - return 0; + buf = _strptime(buf, "%H:%M:%S", tm, convp, locale); + if (buf == NULL) + return (NULL); break; case 'X': - buf = _strptime(buf, tptr->X_fmt, tm, convp, loc); - if (buf == 0) - return 0; + buf = _strptime(buf, tptr->X_fmt, tm, convp, locale); + if (buf == NULL) + return (NULL); break; case 'x': - buf = _strptime(buf, tptr->x_fmt, tm, convp, loc); - if (buf == 0) - return 0; + buf = _strptime(buf, tptr->x_fmt, tm, convp, locale); + if (buf == NULL) + return (NULL); + flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + flags &= ~(FLAG_CENTURY | FLAG_YEAR_IN_CENTURY); break; case 'j': - if (!isdigit_l((unsigned char)*buf, loc)) - return 0; + if (!isdigit_l((unsigned char)*buf, locale)) + return (NULL); len = 3; - for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++){ i *= 10; i += *buf - '0'; len--; } if (i < 1 || i > 366) - return 0; + return (NULL); + + tm->tm_yday = i - 1; + flags |= FLAG_YDAY; - tm->tm_yday = yday = i - 1; break; case 'M': case 'S': - if (*buf == 0 || isspace_l((unsigned char)*buf, loc)) + if (*buf == 0 || + isspace_l((unsigned char)*buf, locale)) break; - if (!isdigit_l((unsigned char)*buf, loc)) - return 0; + if (!isdigit_l((unsigned char)*buf, locale)) + return (NULL); len = 2; - for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++){ i *= 10; i += *buf - '0'; len--; @@ -255,17 +272,14 @@ label: if (c == 'M') { if (i > 59) - return 0; + return (NULL); tm->tm_min = i; } else { if (i > 60) - return 0; + return (NULL); tm->tm_sec = i; } - if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) - while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') - ptr++; break; case 'H': @@ -280,26 +294,24 @@ label: * XXX The %l specifier may gobble one too many * digits if used incorrectly. */ - if (!isdigit_l((unsigned char)*buf, loc)) - return 0; + if (!isdigit_l((unsigned char)*buf, locale)) + return (NULL); len = 2; - for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (c == 'H' || c == 'k') { if (i > 23) - return 0; + return (NULL); } else if (i > 12) - return 0; + return (NULL); tm->tm_hour = i; - if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) - while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') - ptr++; break; case 'p': @@ -308,9 +320,9 @@ label: * specifiers. */ len = strlen(tptr->am); - if (strncasecmp_l(buf, tptr->am, len, loc) == 0) { + if (strncasecmp_l(buf, tptr->am, len, locale) == 0) { if (tm->tm_hour > 12) - return 0; + return (NULL); if (tm->tm_hour == 12) tm->tm_hour = 0; buf += len; @@ -318,98 +330,92 @@ label: } len = strlen(tptr->pm); - if (strncasecmp_l(buf, tptr->pm, len, loc) == 0) { + if (strncasecmp_l(buf, tptr->pm, len, locale) == 0) { if (tm->tm_hour > 12) - return 0; + return (NULL); if (tm->tm_hour != 12) tm->tm_hour += 12; buf += len; break; } - return 0; + return (NULL); case 'A': case 'a': for (i = 0; i < asizeof(tptr->weekday); i++) { len = strlen(tptr->weekday[i]); if (strncasecmp_l(buf, tptr->weekday[i], - len, loc) == 0) + len, locale) == 0) break; len = strlen(tptr->wday[i]); if (strncasecmp_l(buf, tptr->wday[i], - len, loc) == 0) + len, locale) == 0) break; } if (i == asizeof(tptr->weekday)) - return 0; + return (NULL); - tm->tm_wday = wday = i; buf += len; + tm->tm_wday = i; + flags |= FLAG_WDAY; break; - case 'U': /* Sunday week */ - case 'W': /* Monday week */ - if (!isdigit_l((unsigned char)*buf, loc)) - return 0; + case 'U': /* Sunday week */ + case 'V': /* ISO 8601 week */ + case 'W': /* Monday week */ + if (!isdigit_l((unsigned char)*buf, locale)) + return (NULL); len = 2; - for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (i > 53) - return 0; + return (NULL); + if (c == WEEK_V && i < 1) + return (NULL); + + week_number = i; + week_kind = c; + flags |= FLAG_WEEK; - /* Calculate yday if we have enough data */ - if ((year != -1) && (wday != -1)) { - struct tm mktm; - mktm.tm_year = year; - mktm.tm_mon = 0; - mktm.tm_mday = 1; - mktm.tm_sec = 1; - mktm.tm_min = mktm.tm_hour = 0; - mktm.tm_isdst = 0; - mktm.tm_gmtoff = 0; - if (mktime(&mktm) != -1) { - /* yday0 == Jan 1 == mktm.tm_wday */ - int delta = wday - mktm.tm_wday; - if (!wday && c =='W') - i++; /* Sunday is part of the following week */ - yday = 7 * i + delta; - if (yday < 0) - yday += 7; - tm->tm_yday = yday; - } - } - if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) - while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') - ptr++; break; - case 'u': /* [1,7] */ - case 'w': /* [0,6] */ - if (!isdigit_l((unsigned char)*buf, loc)) - return 0; + case 'u': /* [1,7] */ + case 'w': /* [0,6] */ + if (!isdigit_l((unsigned char)*buf, locale)) + return (NULL); i = *buf - '0'; if (i > 6 + (c == 'u')) - return 0; + return (NULL); if (i == 7) i = 0; - tm->tm_wday = wday = i; + + tm->tm_wday = i; + flags |= FLAG_WDAY; buf++; - if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) - while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') - ptr++; + break; - case 'd': case 'e': /* - * The %e specifier is explicitly documented as not - * being zero-padded but there is no harm in allowing + * With %e format, our strftime(3) adds a blank space + * before single digits. + */ + if (*buf != 0 && + isspace_l((unsigned char)*buf, locale)) + buf++; + /* FALLTHROUGH */ + case 'd': + /* + * The %e specifier was once explicitly documented as + * not being zero-padded but was later changed to + * equivalent to %d. There is no harm in allowing * such padding. * * XXX The %e specifier may gobble one too many @@ -417,28 +423,27 @@ label: */ /* Leading space is ok if date is single digit */ len = 2; - if (isspace_l((unsigned char)buf[0], loc) && - isdigit_l((unsigned char)buf[1], loc) && - !isdigit_l((unsigned char)buf[2], loc)) { + if (isspace_l((unsigned char)buf[0], locale) && + isdigit_l((unsigned char)buf[1], locale) && + !isdigit_l((unsigned char)buf[2], locale)) { len = 1; buf++; } - if (!isdigit_l((unsigned char)*buf, loc)) - return 0; + if (!isdigit_l((unsigned char)*buf, locale)) + return (NULL); - for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (i > 31) - return 0; + return (NULL); tm->tm_mday = i; + flags |= FLAG_MDAY; - if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) - while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') - ptr++; break; case 'B': @@ -450,45 +455,54 @@ label: len = strlen(tptr->alt_month[i]); if (strncasecmp_l(buf, tptr->alt_month[i], - len, loc) == 0) + len, locale) == 0) break; } } else { len = strlen(tptr->month[i]); if (strncasecmp_l(buf, tptr->month[i], - len, loc) == 0) + len, locale) == 0) break; + } + } + /* + * Try the abbreviated month name if the full name + * wasn't found and Oalternative was not requested. + */ + if (i == asizeof(tptr->month) && !Oalternative) { + for (i = 0; i < asizeof(tptr->month); i++) { len = strlen(tptr->mon[i]); if (strncasecmp_l(buf, tptr->mon[i], - len, loc) == 0) + len, locale) == 0) break; } } if (i == asizeof(tptr->month)) - return 0; + return (NULL); tm->tm_mon = i; buf += len; + flags |= FLAG_MONTH; + break; case 'm': - if (!isdigit_l((unsigned char)*buf, loc)) - return 0; + if (!isdigit_l((unsigned char)*buf, locale)) + return (NULL); len = 2; - for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { i *= 10; i += *buf - '0'; len--; } if (i < 1 || i > 12) - return 0; + return (NULL); tm->tm_mon = i - 1; + flags |= FLAG_MONTH; - if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) - while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') - ptr++; break; case 's': @@ -500,25 +514,30 @@ label: sverrno = errno; errno = 0; - n = strtol_l(buf, &cp, 10, loc); + n = strtol_l(buf, &cp, 10, locale); if (errno == ERANGE || (long)(t = n) != n) { errno = sverrno; - return 0; + return (NULL); } errno = sverrno; buf = cp; - gmtime_r(&t, tm); + if (gmtime_r(&t, tm) == NULL) + return (NULL); *convp = CONVERT_GMT; + flags |= FLAG_YDAY | FLAG_WDAY | FLAG_MONTH | + FLAG_MDAY | FLAG_YEAR; + flags &= ~(FLAG_CENTURY | FLAG_YEAR_IN_CENTURY); } break; case 'Y': case 'y': - if (*buf == 0 || isspace_l((unsigned char)*buf, loc)) + if (*buf == 0 || + isspace_l((unsigned char)*buf, locale)) break; - if (!isdigit_l((unsigned char)*buf, loc)) - return 0; + if (!isdigit_l((unsigned char)*buf, locale)) + return (NULL); #if __DARWIN_UNIX03 if (c == 'Y') { @@ -527,7 +546,7 @@ label: int64_t i64 = 0; int overflow = 0; - for (len = 0; *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { + for (len = 0; *buf != 0 && isdigit_l((unsigned char)*buf, locale); buf++) { i64 *= 10; i64 += *buf - '0'; if (++len <= 4) { @@ -559,10 +578,10 @@ label: tm->tm_year = i64 - 1900; - if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) - while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') + if (*buf != 0 && isspace_l((unsigned char)*buf, locale)) + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, locale) && *ptr != '%') ptr++; - ret = _strptime0(buf, ptr, tm, convp, loc, tm->tm_year, yday, wday); + ret = _strptime0(buf, ptr, tm, convp, locale, flags, week_number, week_kind); if (ret) return ret; /* Failed, so try 4-digit year */ *tm = savetm; @@ -574,94 +593,186 @@ label: } else { len = 2; #else /* !__DARWIN_UNIX03 */ - len = (c == 'Y') ? 4 : 2; + len = (c == 'Y') ? 4 : 2; #endif /* __DARWIN_UNIX03 */ - for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } + + for (i = 0; len && *buf != 0 && + isdigit_l((unsigned char)*buf, locale); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } #if __DARWIN_UNIX03 } #endif /* __DARWIN_UNIX03 */ - if (c == 'Y') - i -= 1900; - if (c == 'y' && i < 69) - i += 100; + if (i < 0) - return 0; + return (NULL); + + if (c == 'Y'){ + i -= TM_YEAR_BASE; + } else if (c == 'y' && flags & FLAG_CENTURY) { + i = tm->tm_year + (i % 100); + flags &= ~FLAG_CENTURY; + } else if (c == 'y'){ + if (i < 69) i += 100; + flags |= FLAG_YEAR_IN_CENTURY; + } - tm->tm_year = year = i; + tm->tm_year = i; + flags |= FLAG_YEAR; + if (c == 'Y'){ + flags &= ~(FLAG_CENTURY | FLAG_YEAR_IN_CENTURY); + } - if (*buf != 0 && isspace_l((unsigned char)*buf, loc)) - while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%') - ptr++; break; case 'Z': { - const char *cp; - size_t tzlen, len; + const char *cp; + size_t tzlen, len; - for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/} - len = cp - buf; - if (len == 3 && strncmp(buf, "GMT", 3) == 0) { - *convp = CONVERT_GMT; - buf += len; - break; - } - tzset(); - tzlen = strlen(tzname[0]); - if (len == tzlen && strncmp(buf, tzname[0], tzlen) == 0) { - tm->tm_isdst = 0; - buf += len; - break; - } - tzlen = strlen(tzname[1]); - if (len == tzlen && strncmp(buf, tzname[1], tzlen) == 0) { - tm->tm_isdst = 1; - buf += len; - break; - } - return 0; + for (cp = buf; *cp && + isupper_l((unsigned char)*cp, locale); ++cp) { + /*empty*/ + } + len = cp - buf; + if (len == 3 && strncmp(buf, "GMT", 3) == 0) { + *convp = CONVERT_GMT; + buf += len; + break; + } + + tzset(); + tzlen = strlen(tzname[0]); + if (len == tzlen && strncmp(buf, tzname[0], tzlen) == 0) { + tm->tm_isdst = 0; + buf += len; + break; + } + tzlen = strlen(tzname[1]); + if (len == tzlen && strncmp(buf, tzname[1], tzlen) == 0) { + tm->tm_isdst = 1; + buf += len; + break; + } + return (NULL); } case 'z': { - int sign = 1; - - if (*buf != '+') { - if (*buf == '-') - sign = -1; - else + char sign; + int hr, min; + if ((buf[0] != '+' && buf[0] != '-') + || !isdigit_l((unsigned char)buf[1], locale) + || !isdigit_l((unsigned char)buf[2], locale) + || !isdigit_l((unsigned char)buf[3], locale) + || !isdigit_l((unsigned char)buf[4], locale)) return 0; + sscanf(buf, "%c%2d%2d", &sign, &hr, &min); + *convp = CONVERT_ZONE; + tm->tm_gmtoff = 60 * (60 * hr + min); + if (sign == '-') + tm->tm_gmtoff = -tm->tm_gmtoff; + buf += 5; } + break; - buf++; - i = 0; - for (len = 4; len > 0; len--) { - if (isdigit_l((unsigned char)*buf, loc)) { - i *= 10; - i += *buf - '0'; - buf++; - } else - return 0; + case 'n': + case 't': + if (!isspace((unsigned char)*buf)) + return 0; + while (isspace_l((unsigned char)*buf, locale)) + buf++; + break; + + default: + return (NULL); + } + } + + if (!(flags & FLAG_YDAY) && (flags & FLAG_YEAR)) { + if ((flags & (FLAG_MONTH | FLAG_MDAY)) == + (FLAG_MONTH | FLAG_MDAY)) { + tm->tm_yday = start_of_month[isleap(tm->tm_year + + TM_YEAR_BASE)][tm->tm_mon] + (tm->tm_mday - 1); + flags |= FLAG_YDAY; + } else if (flags & FLAG_WEEK){ + if (!(flags & FLAG_WDAY)) { + tm->tm_wday = week_kind == WEEK_U ? TM_SUNDAY : TM_MONDAY; + flags |= FLAG_WDAY; } - tm->tm_hour -= sign * (i / 100); - tm->tm_min -= sign * (i % 100); - *convp = CONVERT_GMT; + struct tm t = {0}; + t.tm_mday = week_kind == WEEK_V ? 4 : 1; + t.tm_hour = 12; /* avoid any DST effects */ + t.tm_year = tm->tm_year; + if (timegm(&t) == (time_t)-1) return 0; + + int off = t.tm_wday; + int wday = tm->tm_wday; + + if (week_kind != WEEK_U) { + off = (off + 6) % 7; + wday = (wday + 6) % 7; } - break; + + if (week_kind == WEEK_V) { + t.tm_mday = 7 * week_number + wday - off - 3; + } else { + if(off == 0) off = 7; + t.tm_mday = 7 * week_number + wday - off + 1; + } + if (timegm(&t) == (time_t)-1) return 0; + + tm->tm_yday = t.tm_yday; + + flags |= FLAG_YDAY; } } - return (char *)buf; + + if ((flags & (FLAG_YEAR | FLAG_YDAY)) == (FLAG_YEAR | FLAG_YDAY)) { + if (!(flags & FLAG_MONTH)) { + i = 0; + while (tm->tm_yday >= + start_of_month[isleap(tm->tm_year + + TM_YEAR_BASE)][i]) + i++; + if (i > 12) { + i = 1; + tm->tm_yday -= + start_of_month[isleap(tm->tm_year + + TM_YEAR_BASE)][12]; + tm->tm_year++; + } + tm->tm_mon = i - 1; + flags |= FLAG_MONTH; + } + if (!(flags & FLAG_MDAY)) { + tm->tm_mday = tm->tm_yday - + start_of_month[isleap(tm->tm_year + TM_YEAR_BASE)] + [tm->tm_mon] + 1; + flags |= FLAG_MDAY; + } + if (!(flags & FLAG_WDAY)) { + i = 0; + wday_offset = first_wday_of(tm->tm_year); + while (i++ <= tm->tm_yday) { + if (wday_offset++ >= 6) + wday_offset = 0; + } + tm->tm_wday = wday_offset; + flags |= FLAG_WDAY; + } + } + + return ((char *)buf); } char * strptime(const char * __restrict buf, const char * __restrict fmt, - struct tm * __restrict tm) + struct tm * __restrict tm) { return strptime_l(buf, fmt, tm, __current_locale()); } diff --git a/src/libc/stdtime/FreeBSD/tzfile.h b/src/libc/stdtime/FreeBSD/tzfile.h index efa8416e9..aff38e7fd 100644 --- a/src/libc/stdtime/FreeBSD/tzfile.h +++ b/src/libc/stdtime/FreeBSD/tzfile.h @@ -34,7 +34,11 @@ static char tzfilehid[] = "@(#)tzfile.h 7.14"; */ #ifndef TZDIR +#ifdef UNIFDEF_TZDIR_SYMLINK +#define TZDIR "/var/db/timezone/zoneinfo" /* Time zone object file directory */ +#else /* !UNIFDEF_TZDIR_SYMLINK */ #define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */ +#endif /* UNIFDEF_TZDIR_SYMLINK */ #endif /* !defined TZDIR */ #ifndef TZDEFAULT diff --git a/src/libc/stdtime/getdate.c b/src/libc/stdtime/getdate.c index 7e3bc79ff..e8e1ff571 100644 --- a/src/libc/stdtime/getdate.c +++ b/src/libc/stdtime/getdate.c @@ -242,14 +242,17 @@ getdate(const char *str) getdate_err = INVALID_DATE; break; } - if(wday_set != UNDEFINED) { + if(wday_set != UNDEFINED && + (dateset != (TM_YEAR_SET | TM_MON_SET | TM_MDAY_SET))) { + /* + * We got back a week day, but not enough information to resolve it + * to a specific day, so we need to push forward the time to the + * correct wday. + */ int delta = wday_set - tm.tm_wday; - if(delta && (dateset & TM_MDAY_SET)) { - getdate_err = INVALID_DATE; - break; - } - if(delta < 0) + if(delta < 0) { delta += 7; + } tm.tm_mday += delta; if(mktime(&tm) == (time_t)-1) { getdate_err = INVALID_DATE; diff --git a/src/libc/string/CMakeLists.txt b/src/libc/string/CMakeLists.txt index a727407ba..f64c42922 100644 --- a/src/libc/string/CMakeLists.txt +++ b/src/libc/string/CMakeLists.txt @@ -5,64 +5,55 @@ cmake_minimum_required(VERSION 2.4.0) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -D_SECURE__STRING_H_") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h") +add_definitions(-D__STDC_WANT_LIB_EXT1__=1) + set(string_sources - # memset_pattern.c # in assembly + bcopy.c stpcpy.c stpncpy.c strcat.c - # strcpy.c # in assembly - # strlcat.c # in assembly - # strlcpy.c # in assembly + #strcpy.c + #strlcat.c + #strlcpy.c strncat.c - # strncpy.c # in assembly + #strncpy.c ) set(string_sources ${string_sources} - # FreeBSD/bcmp.c # in assembly - FreeBSD/bcopy.c - FreeBSD/bzero.c FreeBSD/index.c - FreeBSD/memccpy.c - FreeBSD/memchr.c - # FreeBSD/memcmp.c # in assembly - FreeBSD/memcpy.c FreeBSD/memmem.c - FreeBSD/memmove.c - # FreeBSD/memset.c # in assembly FreeBSD/rindex.c FreeBSD/strcasecmp.c FreeBSD/strcasestr.c - FreeBSD/strchr.c - FreeBSD/strcmp.c FreeBSD/strcoll.c FreeBSD/strcspn.c FreeBSD/strdup.c FreeBSD/strerror.c - # FreeBSD/strlen.c # in assembly + #FreeBSD/strlen.c FreeBSD/strmode.c - # FreeBSD/strncmp.c # in assembly - FreeBSD/strndup.c - FreeBSD/strnlen.c - FreeBSD/strnstr.c - FreeBSD/strpbrk.c - FreeBSD/strrchr.c - FreeBSD/strsep.c + FreeBSD/strndup.c + #FreeBSD/strnlen.c + FreeBSD/strnstr.c + FreeBSD/strpbrk.c + FreeBSD/strrchr.c + FreeBSD/strsep.c FreeBSD/strsignal.c FreeBSD/strspn.c FreeBSD/strstr.c FreeBSD/strtok.c FreeBSD/strxfrm.c FreeBSD/swab.c + FreeBSD/timingsafe_bcmp.c FreeBSD/wcpcpy.c FreeBSD/wcpncpy.c FreeBSD/wcscasecmp.c FreeBSD/wcscat.c - FreeBSD/wcschr.c FreeBSD/wcscmp.c FreeBSD/wcscoll.c FreeBSD/wcscpy.c FreeBSD/wcscspn.c FreeBSD/wcsdup.c + FreeBSD/wcschr.c FreeBSD/wcslcat.c FreeBSD/wcslcpy.c FreeBSD/wcslen.c @@ -78,11 +69,12 @@ set(string_sources ${string_sources} FreeBSD/wcstok.c FreeBSD/wcswidth.c FreeBSD/wcsxfrm.c - FreeBSD/wmemchr.c FreeBSD/wmemcmp.c FreeBSD/wmemcpy.c + FreeBSD/wmemchr.c FreeBSD/wmemmove.c FreeBSD/wmemset.c + NetBSD/memset_s.c ) SET_SOURCE_FILES_PROPERTIES(FreeBSD/strerror.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_STRERROR") @@ -96,7 +88,7 @@ add_library(libc-string_legacy OBJECT ${string-legacy_sources}) SET_TARGET_PROPERTIES(libc-string_legacy PROPERTIES COMPILE_DEFINITIONS "BUILDING_VARIANT;VARIANT_LEGACY") # DYLD variant -add_library(libc-string_dyld OBJECT strcat.c FreeBSD/strchr.c strcpy.c FreeBSD/strdup.c strlcat.c strlcpy.c FreeBSD/strncmp.c FreeBSD/strnlen.c FreeBSD/strrchr.c FreeBSD/strstr.c FreeBSD/strtok.c - FreeBSD/memchr.c FreeBSD/memcmp.c FreeBSD/memcpy.c FreeBSD/wcscpy.c FreeBSD/wcslen.c FreeBSD/wcsncmp.c FreeBSD/wcsncpy.c FreeBSD/strerror.c) +add_library(libc-string_dyld OBJECT strcat.c strcpy.c FreeBSD/strdup.c strlcat.c strlcpy.c FreeBSD/strnlen.c FreeBSD/strrchr.c FreeBSD/strstr.c FreeBSD/strtok.c + FreeBSD/wcscpy.c FreeBSD/wcslen.c FreeBSD/wcsncmp.c FreeBSD/wcsncpy.c FreeBSD/strerror.c) SET_TARGET_PROPERTIES(libc-string_dyld PROPERTIES COMPILE_FLAGS "-UBUILDING_VARIANT -DVARIANT_DYLD -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN") diff --git a/src/libc/string/FreeBSD/bcmp.3 b/src/libc/string/FreeBSD/bcmp.3 index 67f456b08..e2d4063a1 100644 --- a/src/libc/string/FreeBSD/bcmp.3 +++ b/src/libc/string/FreeBSD/bcmp.3 @@ -11,7 +11,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -28,9 +28,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)bcmp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/bcmp.3,v 1.11 2007/01/09 00:28:11 imp Exp $ +.\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd August 15, 2016 .Dt BCMP 3 .Os .Sh NAME @@ -41,18 +41,18 @@ .Sh SYNOPSIS .In strings.h .Ft int -.Fn bcmp "const void *s1" "const void *s2" "size_t n" +.Fn bcmp "const void *b1" "const void *b2" "size_t len" .Sh DESCRIPTION The .Fn bcmp function compares byte string -.Fa s1 +.Fa b1 against byte string -.Fa s2 , +.Fa b2 , returning zero if they are identical, non-zero otherwise. Both strings are assumed to be -.Fa n +.Fa len bytes long. Zero-length strings are always identical. .Pp @@ -62,7 +62,8 @@ The strings may overlap. .Xr strcasecmp 3 , .Xr strcmp 3 , .Xr strcoll 3 , -.Xr strxfrm 3 +.Xr strxfrm 3 , +.Xr timingsafe_bcmp 3 .Sh HISTORY A .Fn bcmp diff --git a/src/libc/string/FreeBSD/bcmp.c b/src/libc/string/FreeBSD/bcmp.c deleted file mode 100644 index 4c518ee8c..000000000 --- a/src/libc/string/FreeBSD/bcmp.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1987, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bcmp.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/bcmp.c,v 1.6 2007/01/09 00:28:11 imp Exp $"); - -#include - -/* - * bcmp -- vax cmpc3 instruction - */ -int -bcmp(const void *b1, const void *b2, size_t length) -{ - char *p1, *p2; - - if (length == 0) - return (0); - p1 = (char *)b1; - p2 = (char *)b2; - do - if (*p1++ != *p2++) - break; - while (--length); - return (length); -} diff --git a/src/libc/string/FreeBSD/bcopy.3 b/src/libc/string/FreeBSD/bcopy.3 index e0371a4d1..3cfa002b6 100644 --- a/src/libc/string/FreeBSD/bcopy.3 +++ b/src/libc/string/FreeBSD/bcopy.3 @@ -42,20 +42,20 @@ .Sh SYNOPSIS .In strings.h .Ft void -.Fn bcopy "const void *s1" "void *s2" "size_t n" +.Fn bcopy "const void *src" "void *dst" "size_t len" .Sh DESCRIPTION The .Fn bcopy function copies -.Fa n +.Fa len bytes from string -.Fa s1 +.Fa src to string -.Fa s2 . +.Fa dst . The two strings may overlap. If -.Fa n +.Fa len is zero, no bytes are copied. .Sh SEE ALSO .Xr memccpy 3 , @@ -75,3 +75,9 @@ before it was moved to for .St -p1003.1-2001 compliance. +.Pp +.Fn bcopy +was deprecated in +.St -p1003.1-2001 +and removed in +.St -p1003.1-2008 . diff --git a/src/libc/string/FreeBSD/bcopy.c b/src/libc/string/FreeBSD/bcopy.c deleted file mode 100644 index f1cb0b511..000000000 --- a/src/libc/string/FreeBSD/bcopy.c +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - diff --git a/src/libc/string/FreeBSD/bzero.3 b/src/libc/string/FreeBSD/bzero.3 index 642b2f1b3..04c82de9d 100644 --- a/src/libc/string/FreeBSD/bzero.3 +++ b/src/libc/string/FreeBSD/bzero.3 @@ -72,3 +72,9 @@ before it was moved to for .St -p1003.1-2001 compliance. +.Pp +.Fn bzero +was deprecated in +.St -p1003.1-2001 +and removed in +.St -p1003.1-2008 . diff --git a/src/libc/string/FreeBSD/bzero.c b/src/libc/string/FreeBSD/bzero.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/libc/string/FreeBSD/memccpy.3 b/src/libc/string/FreeBSD/memccpy.3 index 02cfa37ea..80db44fe4 100644 --- a/src/libc/string/FreeBSD/memccpy.3 +++ b/src/libc/string/FreeBSD/memccpy.3 @@ -40,8 +40,8 @@ .In string.h .Ft void * .Fo memccpy -.Fa "void *restrict s1" -.Fa "const void *restrict s2" +.Fa "void *restrict dst" +.Fa "const void *restrict src" .Fa "int c" .Fa "size_t n" .Fc @@ -50,17 +50,17 @@ The .Fn memccpy function copies bytes from string -.Fa s2 +.Fa src to string -.Fa s1 . +.Fa dst . If the character .Fa c (as converted to an unsigned char) occurs in the string -.Fa s2 , +.Fa src , the copy stops and a pointer to the byte after the copy of .Fa c in the string -.Fa s1 +.Fa dst is returned. Otherwise, .Fa n diff --git a/src/libc/string/FreeBSD/memccpy.c b/src/libc/string/FreeBSD/memccpy.c deleted file mode 100644 index 4c5f421dc..000000000 --- a/src/libc/string/FreeBSD/memccpy.c +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/memccpy.c,v 1.7 2009/02/03 17:58:20 danger Exp $"); - -#include - -void * -memccpy(void *t, const void *f, int c, size_t n) -{ - - if (n) { - unsigned char *tp = t; - const unsigned char *fp = f; - unsigned char uc = c; - do { - if ((*tp++ = *fp++) == uc) - return (tp); - } while (--n != 0); - } - return (0); -} diff --git a/src/libc/string/FreeBSD/memcmp.3 b/src/libc/string/FreeBSD/memcmp.3 index f48f5d4c6..892efbe50 100644 --- a/src/libc/string/FreeBSD/memcmp.3 +++ b/src/libc/string/FreeBSD/memcmp.3 @@ -13,7 +13,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memcmp.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memcmp.3,v 1.10 2009/04/07 13:42:53 trasz Exp $ +.\" $FreeBSD$ .\" .Dd June 4, 1993 .Dt MEMCMP 3 @@ -65,12 +65,16 @@ The function returns zero if the two strings are identical, otherwise returns the difference between the first two differing bytes -(treated as unsigned char values, so that +(treated as +.Vt "unsigned char" +values, so that .Sq Li \e200 is greater than .Sq Li \&\e0 , for example). Zero-length strings are always identical. +This behavior is not required by C and portable code should only depend on the +sign of the returned value. .Sh SEE ALSO .Xr bcmp 3 , .Xr strcasecmp 3 , diff --git a/src/libc/string/FreeBSD/memcpy.3 b/src/libc/string/FreeBSD/memcpy.3 index 77bd719e7..a58e8daa4 100644 --- a/src/libc/string/FreeBSD/memcpy.3 +++ b/src/libc/string/FreeBSD/memcpy.3 @@ -44,8 +44,8 @@ .In string.h .Ft void * .Fo memcpy -.Fa "void *restrict s1" -.Fa "const void *restrict s2" +.Fa "void *restrict dst" +.Fa "const void *restrict src" .Fa "size_t n" .Fc .Sh DESCRIPTION @@ -55,18 +55,18 @@ function copies .Fa n bytes from memory area -.Fa s2 +.Fa src to memory area -.Fa s1 . +.Fa dst . If -.Fa s1 +.Fa dst and -.Fa s2 +.Fa src overlap, behavior is undefined. Applications in which -.Fa s1 +.Fa dst and -.Fa s2 +.Fa src might overlap should use .Xr memmove 3 instead. @@ -75,7 +75,7 @@ The .Fn memcpy function returns the original value of -.Fa s1 . +.Fa dst . .Sh SEE ALSO .Xr bcopy 3 , .Xr memccpy 3 , diff --git a/src/libc/string/FreeBSD/memcpy.c b/src/libc/string/FreeBSD/memcpy.c deleted file mode 100644 index ed03856e5..000000000 --- a/src/libc/string/FreeBSD/memcpy.c +++ /dev/null @@ -1,5 +0,0 @@ -#include -__FBSDID("$FreeBSD$"); - -#define MEMCOPY -#include "bcopy.c" diff --git a/src/libc/string/FreeBSD/memmove.3 b/src/libc/string/FreeBSD/memmove.3 index 64871c892..6cac60464 100644 --- a/src/libc/string/FreeBSD/memmove.3 +++ b/src/libc/string/FreeBSD/memmove.3 @@ -43,28 +43,24 @@ .Sh SYNOPSIS .In string.h .Ft void * -.Fo memmove -.Fa "void *s1" -.Fa "const void *s2" -.Fa "size_t n" -.Fc +.Fn memmove "void *dst" "const void *src" "size_t len" .Sh DESCRIPTION The .Fn memmove function copies -.Fa n +.Fa len bytes from string -.Fa s2 +.Fa src to string -.Fa s1 . +.Fa dst . The two strings may overlap; the copy is always done in a non-destructive manner. .Sh RETURN VALUES The .Fn memmove function returns the original value of -.Fa s1 . +.Fa dst . .Sh SEE ALSO .Xr bcopy 3 , .Xr memccpy 3 , diff --git a/src/libc/string/FreeBSD/memmove.c b/src/libc/string/FreeBSD/memmove.c deleted file mode 100644 index 05cf75a2c..000000000 --- a/src/libc/string/FreeBSD/memmove.c +++ /dev/null @@ -1,5 +0,0 @@ -#include -__FBSDID("$FreeBSD$"); - -#define MEMMOVE -#include "bcopy.c" diff --git a/src/libc/string/FreeBSD/memset.3 b/src/libc/string/FreeBSD/memset.3 index 701d7392e..2c96f5083 100644 --- a/src/libc/string/FreeBSD/memset.3 +++ b/src/libc/string/FreeBSD/memset.3 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)memset.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/memset.3,v 1.9 2009/04/07 13:42:53 trasz Exp $ +.\" $FreeBSD: src/lib/libc/string/memset.3,v 1.10 2010/02/04 11:23:28 ru Exp $ .\" .Dd June 4, 1993 .Dt MEMSET 3 @@ -52,7 +52,9 @@ writes .Fa len bytes of value .Fa c -(converted to an unsigned char) to the byte string +(converted to an +.Vt "unsigned char" ) +to the string .Fa b . .Sh RETURN VALUES The @@ -61,6 +63,7 @@ function returns its first argument. .Sh SEE ALSO .Xr bzero 3 , .Xr memset_pattern 3 , +.Xr memset_s.3 , .Xr swab 3 , .Xr wmemset 3 .Sh STANDARDS diff --git a/src/libc/string/FreeBSD/memset.c b/src/libc/string/FreeBSD/memset.c deleted file mode 100644 index 2b3a2268e..000000000 --- a/src/libc/string/FreeBSD/memset.c +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Hibler and Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)memset.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/memset.c,v 1.9 2007/01/09 00:28:12 imp Exp $"); - -#include - -#include - -#define wsize sizeof(u_int) -#define wmask (wsize - 1) - -#ifdef BZERO -#include - -#define RETURN return -#define VAL 0 -#define WIDEVAL 0 - -void -bzero(void *dst0, size_t length) -#else -#include - -#define RETURN return (dst0) -#define VAL c0 -#define WIDEVAL c - -void * -memset(void *dst0, int c0, size_t length) -#endif -{ - size_t t; -#ifndef BZERO - u_int c; -#endif - u_char *dst; - - dst = dst0; - /* - * If not enough words, just fill bytes. A length >= 2 words - * guarantees that at least one of them is `complete' after - * any necessary alignment. For instance: - * - * |-----------|-----------|-----------| - * |00|01|02|03|04|05|06|07|08|09|0A|00| - * ^---------------------^ - * dst dst+length-1 - * - * but we use a minimum of 3 here since the overhead of the code - * to do word writes is substantial. - */ - if (length < 3 * wsize) { - while (length != 0) { - *dst++ = VAL; - --length; - } - RETURN; - } - -#ifndef BZERO - if ((c = (u_char)c0) != 0) { /* Fill the word. */ - c = (c << 8) | c; /* u_int is 16 bits. */ -#if UINT_MAX > 0xffff - c = (c << 16) | c; /* u_int is 32 bits. */ -#endif -#if UINT_MAX > 0xffffffff - c = (c << 32) | c; /* u_int is 64 bits. */ -#endif - } -#endif - /* Align destination by filling in bytes. */ - if ((t = (long)dst & wmask) != 0) { - t = wsize - t; - length -= t; - do { - *dst++ = VAL; - } while (--t != 0); - } - - /* Fill words. Length was >= 2*words so we know t >= 1 here. */ - t = length / wsize; - do { - *(u_int *)dst = WIDEVAL; - dst += wsize; - } while (--t != 0); - - /* Mop up trailing bytes, if any. */ - t = length & wmask; - if (t != 0) - do { - *dst++ = VAL; - } while (--t != 0); - RETURN; -} diff --git a/src/libc/string/FreeBSD/strchr.c b/src/libc/string/FreeBSD/strchr.c deleted file mode 100644 index 2fb911409..000000000 --- a/src/libc/string/FreeBSD/strchr.c +++ /dev/null @@ -1,5 +0,0 @@ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/strchr.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); - -#define STRCHR -#include "index.c" diff --git a/src/libc/string/FreeBSD/strcpy.3 b/src/libc/string/FreeBSD/strcpy.3 index e1fbdc1bb..fda6eb44b 100644 --- a/src/libc/string/FreeBSD/strcpy.3 +++ b/src/libc/string/FreeBSD/strcpy.3 @@ -13,7 +13,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcpy.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcpy.3,v 1.28 2009/04/07 13:42:53 trasz Exp $ +.\" $FreeBSD$ .\" .Dd February 28, 2009 .Dt STRCPY 3 @@ -43,27 +43,13 @@ .Sh SYNOPSIS .In string.h .Ft char * -.Fo stpcpy -.Fa "char *s1" -.Fa "const char *s2" -.Fc +.Fn stpcpy "char * dst" "const char * src" .Ft char * -.Fo stpncpy -.Fa "char *restrict s1" -.Fa "const char *restrict s2" -.Fa "size_t n" -.Fc +.Fn stpncpy "char * dst" "const char * src" "size_t len" .Ft char * -.Fo strcpy -.Fa "char *restrict s1" -.Fa "const char *restrict s2" -.Fc +.Fn strcpy "char * dst" "const char * src" .Ft char * -.Fo strncpy -.Fa "char *restrict s1" -.Fa "const char *restrict s2" -.Fa "size_t n" -.Fc +.Fn strncpy "char * dst" "const char * src" "size_t len" .Sh DESCRIPTION The .Fn stpcpy @@ -71,35 +57,35 @@ and .Fn strcpy functions copy the string -.Fa s2 +.Fa src to -.Fa s1 +.Fa dst (including the terminating .Ql \e0 -character). +character.) .Pp The .Fn stpncpy and .Fn strncpy functions copy at most -.Fa n +.Fa len characters from -.Fa s2 +.Fa src into -.Fa s1 . +.Fa dst . If -.Fa s2 +.Fa src is less than -.Fa n +.Fa len characters long, the remainder of -.Fa s1 +.Fa dst is filled with .Ql \e0 characters. Otherwise, -.Fa s1 +.Fa dst is .Em not terminated. @@ -113,7 +99,7 @@ and .Fn strncpy functions return -.Fa s1 . +.Fa dst . The .Fn stpcpy and @@ -121,15 +107,15 @@ and functions return a pointer to the terminating .Ql \e0 character of -.Fa s1 . +.Fa dst . If .Fn stpncpy does not terminate -.Fa s1 +.Fa dst with a .Dv NUL character, it instead returns a pointer to -.Li s1[n] +.Li dst[n] (which does not necessarily refer to a valid memory location.) .Sh EXAMPLES The following sets @@ -156,7 +142,7 @@ Note that it does .Em not .Tn NUL terminate -.Va chararray , +.Va chararray because the length of the source string is greater than or equal to the length argument. .Pp @@ -186,26 +172,11 @@ This could be better achieved using as shown in the following example: .Pp .Dl "(void)strlcpy(buf, input, sizeof(buf));" -.Sh SECURITY CONSIDERATIONS -The -.Fn strcpy , -.Fn strncpy , -.Fn stpcpy , -and -.Fn stpncpy -functions are easily misused in a manner which enables malicious users -to arbitrarily change a running program's functionality through a -buffer overflow attack. -(See -the FSA -and -.Sx EXAMPLES . ) .Pp -It is recommended that -.Xr strlcpy 3 -be used instead as a way to avoid such problems. +Note that because .Xr strlcpy 3 -is not defined in any standards, but it has been adopted by most major libc implementations. +is not defined in any standards, it should +only be used when portability is not a concern. .Sh SEE ALSO .Xr bcopy 3 , .Xr memccpy 3 , @@ -236,3 +207,9 @@ and .Fn stpncpy was added in .Fx 8.0 . +.Sh SECURITY CONSIDERATIONS +The +.Fn strcpy +function is easily misused in a manner which enables malicious users +to arbitrarily change a running program's functionality through a +buffer overflow attack. diff --git a/src/libc/string/FreeBSD/strcspn.3 b/src/libc/string/FreeBSD/strcspn.3 deleted file mode 100644 index 938f80b41..000000000 --- a/src/libc/string/FreeBSD/strcspn.3 +++ /dev/null @@ -1,91 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Chris Torek and the American National Standards Committee X3, -.\" on Information Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)strcspn.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcspn.3,v 1.9 2007/01/09 00:28:12 imp Exp $ -.\" -.Dd June 4, 1993 -.Dt STRCSPN 3 -.Os -.Sh NAME -.Nm strcspn -.Nd span the complement of a string -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In string.h -.Ft size_t -.Fo strcspn -.Fa "const char *s1" -.Fa "const char *s2" -.Fc -.Sh DESCRIPTION -The -.Fn strcspn -function -spans the initial part of the null-terminated string -.Fa s1 , -as long as the characters from -.Fa s1 -do not occur in string -.Fa s2 -(it -spans the -.Em complement -of -.Fa s2 ) . -In other words, it computes the string array index in -.Fa s1 -of the first character of -.Fa s1 -which is also in -.Fa s2 , -else the index of the first null character. -.Sh RETURN VALUES -The -.Fn strcspn -function -returns the number of characters spanned. -.Sh SEE ALSO -.Xr memchr 3 , -.Xr strchr 3 , -.Xr strpbrk 3 , -.Xr strrchr 3 , -.Xr strsep 3 , -.Xr strspn 3 , -.Xr strstr 3 , -.Xr strtok 3 -.Sh STANDARDS -The -.Fn strcspn -function -conforms to -.St -isoC . diff --git a/src/libc/string/FreeBSD/strerror.c b/src/libc/string/FreeBSD/strerror.c index 63e810199..46144e36b 100644 --- a/src/libc/string/FreeBSD/strerror.c +++ b/src/libc/string/FreeBSD/strerror.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.16 2007/01/09 00:28:12 im #include #include #include +#include #define UPREFIX "Unknown error" @@ -115,20 +116,32 @@ strerror_r(int errnum, char *strerrbuf, size_t buflen) return (retval); } + +__private_extern__ char *__strerror_ebuf = NULL; #else /* BUILDING_VARIANT */ __private_extern__ void __errstr(int, char *, size_t); + +extern char *__strerror_ebuf; #endif /* !BUILDING_VARIANT */ char * strerror(int num) { - static char ebuf[NL_TEXTMAX]; + // Dynamically allocate a big buffer to receive the text then shrink it + // down to the actual size needed. + size_t ebufsiz = NL_TEXTMAX; + if (__strerror_ebuf == NULL) { + __strerror_ebuf = calloc(1, ebufsiz); + if (__strerror_ebuf == NULL) { + return NULL; + } + } + + if (strerror_r(num, __strerror_ebuf, ebufsiz) != 0) { #if !__DARWIN_UNIX03 - if (strerror_r(num, ebuf, sizeof(ebuf)) != 0) - errno = EINVAL; -#else - (void)strerror_r(num, ebuf, sizeof(ebuf)); + errno = EINVAL; #endif - return (ebuf); + } + return __strerror_ebuf; } diff --git a/src/libc/string/FreeBSD/strpbrk.3 b/src/libc/string/FreeBSD/strpbrk.3 index 30db8c21d..bfa50990a 100644 --- a/src/libc/string/FreeBSD/strpbrk.3 +++ b/src/libc/string/FreeBSD/strpbrk.3 @@ -13,7 +13,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strpbrk.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strpbrk.3,v 1.9 2009/04/07 13:42:53 trasz Exp $ +.\" $FreeBSD$ .\" .Dd June 4, 1993 .Dt STRPBRK 3 @@ -43,23 +43,20 @@ .Sh SYNOPSIS .In string.h .Ft char * -.Fo strpbrk -.Fa "const char *s1" -.Fa "const char *s2" -.Fc +.Fn strpbrk "const char *s" "const char *charset" .Sh DESCRIPTION The .Fn strpbrk function locates in the null-terminated string -.Fa s1 +.Fa s the first occurrence of any character in the string -.Fa s2 , -returning a pointer to this character. +.Fa charset +and returns a pointer to this character. If no characters from -.Fa s2 +.Fa charset occur anywhere in -.Fa s1 , +.Fa s .Fn strpbrk returns NULL. .Sh SEE ALSO diff --git a/src/libc/string/FreeBSD/strspn.3 b/src/libc/string/FreeBSD/strspn.3 index fcd199c1f..4a8e3f40c 100644 --- a/src/libc/string/FreeBSD/strspn.3 +++ b/src/libc/string/FreeBSD/strspn.3 @@ -13,7 +13,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -30,49 +30,71 @@ .\" SUCH DAMAGE. .\" .\" @(#)strspn.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strspn.3,v 1.11 2009/04/07 13:42:53 trasz Exp $ +.\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd May 24, 2014 .Dt STRSPN 3 .Os .Sh NAME -.Nm strspn +.Nm strspn , +.Nm strcspn .Nd span a string .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In string.h .Ft size_t -.Fo strspn -.Fa "const char *s1" -.Fa "const char *s2" -.Fc +.Fn strspn "const char *s" "const char *charset" +.Ft size_t +.Fn strcspn "const char *s" "const char *charset" .Sh DESCRIPTION The .Fn strspn function spans the initial part of the null-terminated string -.Fa s1 , +.Fa s as long as the characters from -.Fa s1 +.Fa s occur in the null-terminated string -.Fa s2 . -In other words, it computes the string array index in -.Fa s1 +.Fa charset . +In other words, it computes the string array index of the first character of -.Fa s1 +.Fa s which is not in -.Fa s2 , +.Fa charset , +else the index of the first null character. +.Pp +The +.Fn strcspn +function +spans the initial part of the null-terminated string +.Fa s +as long as the characters from +.Fa s +.Sy do not +occur in the null-terminated string +.Fa charset +.Po it spans the +.Sy complement +of +.Fa charset +.Pc . +In other words, it computes the string array index +of the first character of +.Fa s +which is also in +.Fa charset , else the index of the first null character. .Sh RETURN VALUES The .Fn strspn -function -returns the number of characters spanned. +and +.Fn strcspn +functions +return the number of characters spanned. .Sh SEE ALSO .Xr memchr 3 , .Xr strchr 3 , -.Xr strcspn 3 , .Xr strpbrk 3 , .Xr strrchr 3 , .Xr strsep 3 , @@ -82,6 +104,8 @@ returns the number of characters spanned. .Sh STANDARDS The .Fn strspn -function -conforms to +and +.Fn strcspn +functions +conform to .St -isoC . diff --git a/src/libc/string/FreeBSD/strstr.3 b/src/libc/string/FreeBSD/strstr.3 index 70fbda4db..a87044f39 100644 --- a/src/libc/string/FreeBSD/strstr.3 +++ b/src/libc/string/FreeBSD/strstr.3 @@ -14,7 +14,7 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 4. Neither the name of the University nor the names of its contributors +.\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" @@ -31,53 +31,36 @@ .\" SUCH DAMAGE. .\" .\" @(#)strstr.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strstr.3,v 1.15 2009/04/07 13:42:53 trasz Exp $ +.\" $FreeBSD$ .\" .Dd October 11, 2001 .Dt STRSTR 3 .Os .Sh NAME -.Nm strcasestr , -.Nm strcasestr_l , -.Nm strnstr , -.Nm strstr +.Nm strstr , strcasestr , strnstr .Nd locate a substring in a string .Sh LIBRARY .Lb libc .Sh SYNOPSIS .In string.h .Ft char * -.Fo strcasestr -.Fa "const char *s1" -.Fa "const char *s2" -.Fc +.Fn strstr "const char *haystack" "const char *needle" .Ft char * -.Fo strnstr -.Fa "const char *s1" -.Fa "const char *s2" -.Fa "size_t n" -.Fc +.Fn strcasestr "const char *haystack" "const char *needle" .Ft char * -.Fo strstr -.Fa "const char *s1" -.Fa "const char *s2" -.Fc +.Fn strnstr "const char *haystack" "const char *needle" "size_t len" .In string.h .In xlocale.h .Ft char * -.Fo strcasestr_l -.Fa "const char *s1" -.Fa "const char *s2" -.Fa "locale_t loc" -.Fc +.Fn strcasestr_l "const char *haystack" "const char *needle" "locale_t loc" .Sh DESCRIPTION The .Fn strstr function locates the first occurrence of the null-terminated string -.Fa s2 +.Fa needle in the null-terminated string -.Fa s1 . +.Fa haystack . .Pp The .Fn strcasestr @@ -89,11 +72,11 @@ The .Fn strnstr function locates the first occurrence of the null-terminated string -.Fa s2 +.Fa needle in the string -.Fa s1 , +.Fa haystack , where not more than -.Fa n +.Fa len characters are searched. Characters that appear after a .Ql \e0 @@ -113,18 +96,18 @@ function may be passed a locale directly. See for more information. .Sh RETURN VALUES If -.Fa s2 +.Fa needle is an empty string, -.Fa s1 +.Fa haystack is returned; if -.Fa s2 +.Fa needle occurs nowhere in -.Fa s1 , +.Fa haystack , .Dv NULL is returned; otherwise a pointer to the first character of the first occurrence of -.Fa s2 +.Fa needle is returned. .Sh EXAMPLES The following sets the pointer @@ -157,6 +140,7 @@ ptr = strnstr(largestring, smallstring, 4); .Ed .Sh SEE ALSO .Xr memchr 3 , +.Xr memmem 3 , .Xr strchr 3 , .Xr strcspn 3 , .Xr strpbrk 3 , diff --git a/src/libc/string/FreeBSD/timingsafe_bcmp.3 b/src/libc/string/FreeBSD/timingsafe_bcmp.3 new file mode 100644 index 000000000..22a396199 --- /dev/null +++ b/src/libc/string/FreeBSD/timingsafe_bcmp.3 @@ -0,0 +1,65 @@ +.\" $OpenBSD: timingsafe_bcmp.3,v 1.2 2014/06/21 20:22:15 tedu Exp $ +.\" +.\" Copyright (c) 2014 Google Inc. +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" $FreeBSD$ +.Dd August 15, 2016 +.Dt TIMINGSAFE_BCMP 3 +.Os +.Sh NAME +.Nm timingsafe_bcmp +.Nd timing-safe byte sequence comparisons +.Sh SYNOPSIS +.In string.h +.Ft int +.Fn timingsafe_bcmp "const void *b1" "const void *b2" "size_t len" +.Sh DESCRIPTION +The +.Fn timingsafe_bcmp +function compares the first +.Fa len +bytes pointed to by +.Fa b1 +and +.Fa b2 . +.Pp +Additionally, the running time is independent of the byte sequences compared, +making it safe to use for comparing secret values such as cryptographic MACs. +In contrast, +.Xr bcmp 3 +and +.Xr memcmp 3 +may short-circuit after finding the first differing byte. +.Sh RETURN VALUES +The +.Fn timingsafe_bcmp +function returns 0 or not zero if the byte sequence pointed to by +.Fa b1 +compares equal to or not equal to (respectively) +the byte sequence pointed to by +.Fa b2 . +.Sh SEE ALSO +.Xr bcmp 3 +.Sh STANDARDS +The +.Fn timingsafe_bcmp +function is a non-standard extension. +.Sh HISTORY +The +.Fn timingsafe_bcmp +function first appeared in +.Ox 4.9 , +.Fx 12.0 , +and macOS 10.12.1. diff --git a/src/libc/string/FreeBSD/timingsafe_bcmp.c b/src/libc/string/FreeBSD/timingsafe_bcmp.c new file mode 100644 index 000000000..838c3c61f --- /dev/null +++ b/src/libc/string/FreeBSD/timingsafe_bcmp.c @@ -0,0 +1,32 @@ +/* $OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ */ +/* + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +int +timingsafe_bcmp(const void *b1, const void *b2, size_t n) +{ + const unsigned char *p1 = b1, *p2 = b2; + int ret = 0; + + for (; n > 0; n--) + ret |= *p1++ ^ *p2++; + return ret; +} diff --git a/src/libc/string/FreeBSD/wcscoll.c b/src/libc/string/FreeBSD/wcscoll.c index ce09e41fd..68d902984 100644 --- a/src/libc/string/FreeBSD/wcscoll.c +++ b/src/libc/string/FreeBSD/wcscoll.c @@ -45,7 +45,6 @@ wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t loc) const wchar_t *t, *t2; wchar_t *tt = NULL, *tt2 = NULL; wchar_t *tr = NULL, *tr2 = NULL; - wchar_t w, w2; struct __collate_st_info *info; NORMALIZE_LOCALE(loc); diff --git a/src/libc/string/NetBSD/memset_s.3 b/src/libc/string/NetBSD/memset_s.3 new file mode 100644 index 000000000..9b1f662c7 --- /dev/null +++ b/src/libc/string/NetBSD/memset_s.3 @@ -0,0 +1,147 @@ +.\" +.\" Copyright (c) 2012 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Alan Barrett +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $NetBSD$ +.\" +.Dd February 21, 2012 +.Dt MEMSET_S 3 +.Os +.Sh NAME +.Nm memset_s +.Nd copy a value to all bytes of a memory buffer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Fd "#define __STDC_WANT_LIB_EXT1__ 1 +.In string.h +.Ft errno_t +.Fn memset_s "void *s" "rsize_t smax" "int c" "rsize_t n" +.Sh DESCRIPTION +The +.Fn memset_s +function copies the value +.Fa c +(converted to an unsigned char) +into each of the first +.Fa n +bytes of the memory buffer whose starting address is given by +.Fa s . +.Pp +It is a runtime-consrtaints violation if +.Fa s +is a null pointer, +or if either of +.Fa smax +or +.Fa n +is larger than +.Dv RSIZE_MAX , +or if +.Fa smax +is smaller than +.Fa n . +If there is a runtime-constraints violation, and if +.Fa s +is not a null pointer, +and if +.Fa smax +is not larger than +.Dv RSIZE_MAX , +then, before reporting the runtime-constraints violation, +.Fn memset_s +copies +.Fa smax +bytes to the destination. +.Pp +In contrast to the +.Xr memset 3 +function, +calls to +.Fn memset_s +will never be +.Dq optimised away +by a compiler. +This property is required by the following sentences in +section K.3.7.4.1 of +.St -isoC-2011 : +.Bd -filled -offset indent +Unlike +.Fn memset , +any call to the +.Fn memset_s +function shall be evaluated strictly according to the rules of +the abstract machine as described in (5.1.2.3). +That is, any call to the +.Fn memset_s +function shall assume that the memory indicated by +.Fa s +and +.Fa n +may be accessible in the future and thus must contain +the values indicated by +.Fa c . +.Ed +.Sh RETURN VALUES +The +.Fn memset_s +function returns zero for success, or a non-zero error code +if there was a runtime-constraints violation. +.Sh ERRORS +.Fn memset_s +returns the following error codes. +It does not store the error code in the global +.Va errno +variable: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa s +argument was a null pointer. +.It Bq Er E2BIG +One or both of +.Fa smax +or +.Fa n +was larger than +.Dv RSIZE_MAX . +.It Bq Er EOVERFLOW +.Fa n +was larger than +.Fa smax . +.El +. +.Sh SEE ALSO +.Xr memset 3 . +.Sh STANDARDS +The +.Fn memset_s +function conforms to +.St -isoC-2011 , +except that the +.Fn set_constraint_handler_s +interface is not supported. diff --git a/src/libc/string/NetBSD/memset_s.c b/src/libc/string/NetBSD/memset_s.c new file mode 100644 index 000000000..f010ca7f8 --- /dev/null +++ b/src/libc/string/NetBSD/memset_s.c @@ -0,0 +1,71 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Alan Barrett + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * ISO/IEC 9899:2011 section K.3.7.4.1 The memset_s function + */ + +#include + +__RCSID("$NetBSD$"); + +#define __STDC_WANT_LIB_EXT1__ 1 +#include +#include +#include + +#undef memset_s /* in case it was defined as a macro */ +#undef memset /* in case it was defined as a macro */ + +errno_t +memset_s(void *s, rsize_t smax, int c, rsize_t n) +{ + errno_t err = 0; + + if (s == NULL) + return EINVAL; + if (smax > RSIZE_MAX) + return E2BIG; + + if (n > RSIZE_MAX) { + err = E2BIG; + n = smax; + } + + if (n > smax) { + err = EOVERFLOW; + n = smax; + } + + memset(s, c, n); + + return err; +} diff --git a/src/libc/string/bcopy.c b/src/libc/string/bcopy.c new file mode 100644 index 000000000..fce9703f9 --- /dev/null +++ b/src/libc/string/bcopy.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013 Apple, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +void bcopy(const void *src, void *dst, size_t n) { + _platform_memmove(dst, src, n); +} diff --git a/src/libc/string/memset_pattern.c b/src/libc/string/memset_pattern.c deleted file mode 100644 index ebeb780b6..000000000 --- a/src/libc/string/memset_pattern.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -#include - -void -bcopy(const void *src0, void *dst0, size_t length); - -void -memset_pattern4(void *b, const void *pattern4, size_t len) -{ - char * start = (char *)b; - char * p = (char *)b; - while ((start + len) - p >= 4) { - bcopy(pattern4, p, 4); - p += 4; - } - if ((start + len) - p != 0) { - bcopy(pattern4, p, (start + len) - p); - } -} - -void -memset_pattern8(void *b, const void *pattern8, size_t len) -{ - char * start = (char *)b; - char * p = (char *)b; - while ((start + len) - p >= 8) { - bcopy(pattern8, p, 8); - p += 8; - } - if ((start + len) - p != 0) { - bcopy(pattern8, p, (start + len) - p); - } - -} - -void -memset_pattern16(void *b, const void *pattern16, size_t len) -{ - char * start = (char *)b; - char * p = (char *)b; - while ((start + len) - p >= 16) { - bcopy(pattern16, p, 16); - p += 16; - } - if ((start + len) - p != 0) { - bcopy(pattern16, p, (start + len) - p); - } -} diff --git a/src/libc/string/strlcat.c b/src/libc/string/strlcat.c index ac4416359..4a79281d3 100644 --- a/src/libc/string/strlcat.c +++ b/src/libc/string/strlcat.c @@ -31,8 +31,8 @@ strlcat(char * restrict dst, const char * restrict src, size_t maxlen) { if (srclen < maxlen-dstlen) { memcpy(dst+dstlen, src, srclen+1); } else { - memcpy(dst+dstlen, src, maxlen-1); - dst[dstlen+maxlen-1] = '\0'; + memcpy(dst+dstlen, src, maxlen-dstlen-1); + dst[maxlen-1] = '\0'; } return dstlen + srclen; } diff --git a/src/libc/sys/CLIB-LIST b/src/libc/sys/CLIB-LIST deleted file mode 100644 index 7b30a40f1..000000000 --- a/src/libc/sys/CLIB-LIST +++ /dev/null @@ -1,679 +0,0 @@ -CIRCLEQ_ENTRY M -CIRCLEQ_HEAD M -CIRCLEQ_INIT M -CIRCLEQ_INSERT_AFTER M -CIRCLEQ_INSERT_BEFORE M -CIRCLEQ_INSERT_HEAD M -CIRCLEQ_INSERT_TAIL M -CIRCLEQ_REMOVE M -LIST_ENTRY M -LIST_HEAD M -LIST_INIT M -LIST_INSERT_AFTER M -LIST_REMOVE M -TAILQ_ENTRY M -TAILQ_HEAD M -TAILQ_INIT M -TAILQ_INSERT_AFTER M -TAILQ_INSERT_HEAD M -TAILQ_INSERT_TAIL M -TAILQ_REMOVE M -_longjmp -_setjmp -abort -abs -acl_add -acl_canocicalize_principal -acl_check -acl_delete -acl_exact_match -acl_initialize -acos -acosh -addch -addstr -alarm -alloca -alphasort -arc -asctime -asin -asinh -assert -atan -atan2 -atanh -atexit -atof -atoi -atol -bcmp -bcopy -bit_alloc M -bit_clear M -bit_decl M -bit_ffc M -bit_ffs M -bit_nclear M -bit_nset M -bit_test M -bitstr_size M -box -bsearch -bypot -bzero -cabs -calloc -cbreak -cbrt -ceil -cfgetispeed -cfgetospeed -cfmakeraw -cfsetispeed -cfsetospeed -cfsetspeed -cgetcap -cgetclose -cgetent -cgetfirst -cgetmatch -cgetnext -cgetnum -cgetset -cgetstr -cgetustr -circle -clear -clearerr -clearok -clock -closedir -closelog -closepl -clrtobot -clrtoeol -confstr -cont -copysign -cos -cosh -crypt -ctermid -ctime -daemon -dbopen -delch -delwin -des_cbc_cksum -des_cbc_encrypt -des_cipher -des_ecb_encrypt -des_pcbc_encrypt -des_quad_cksum -des_random_key -des_read_password -des_set_key -des_setkey -des_string_to_key -devanme -diffti8me -dirfd -div -dleteln -dn_comp -dn_expand -drem -echo -ectv -edata -encrypt -end -endfsent -endgrent -endhostent -endnetent -endnetgrent -endprotoent -endpwent -endservent -endttyent -endusershell -endwin -er -erase -erf -erfc -err -errx -etext -etfc -execl -execle -execlp -exect -execv -execvp -exit -exp -expm1 -fabs -fclose -fctv -fdopen -feof -ferror -fflush -ffs -fgetc -fgetline -fgetln -fgetpos -fgets -fileno -finite -floor -flusok -fmin MP -fmod -fmount MP -fnmatch -fopen -fprintf -fpurge -fputc -fputs -fread -free -freopen -frexp -fropen -fscanf -fseek -fsetpos -ftell -ftime -fts_children -fts_close -fts_open -fts_read -fts_set -funopen -fwopen -fwrite -gamma -gcd MP -gctv -getbsize -getc -getcap -getch -getchar -getcwd -getdiskbyname -getenv -getfsent -getfsfile -getfsspec -getgrent -getgrgid -getgrnam -getgrouplist -gethostbyaddr -gethostbyname -gethostent -gethostid -gethostname -getloadavg -getmntinfo -getmntopts -getmode -getnetbyaddr -getnetbyname -getnetent -getnetgrent -getopt -getpagesize -getpass -getprotobyname -getprotobynumber -getprotoent -getpw -getpwent -getpwnam -getpwuid -gets -getservbyname -getservbyport -getservent -getstr -getsubopt -gettmode -getttyent -getttynam -getusershell -getw -getwd -getyx -glob -globfree -gmtime -group_from_gid -gtty -heapsort -herror -htonl -htons -hypot -inch -index -inet_addr -inet_aton -inet_lnaof -inet_makeaddr -inet_netof -inet_network -inet_ntoa -infnan -initgroups -initscr -initstate -innetgr -insch -insetln -insque -invert MP -isalnum -isalpha -isascii -isatty -isblank -iscntrl -isdigit -isgraph -isinf -islower -isnan -iso_addr -iso_ntoa -isprint -ispunct -isspace -isupper -isxdigit -itom MP -j0 -j1 -jn -krb_err_txt -krb_get_admhst -krb_get_cred -krb_get_krbhst -krb_get_lrealm -krb_get_phost -krb_kntoln -krb_mk_err -krb_mk_priv -krb_mk_req -krb_mk_safe -krb_net_read -krb_net_write -krb_rd_err -krb_rd_priv -krb_rd_req -krb_rd_safe -krb_realmofhost -krb_recvauth -krb_sendauth -krb_set_key -krb_set_tkt_string -kuserok -kvm_close -kvm_getargv -kvm_getenvv -kvm_geterr -kvm_getfiles -kvm_getloadavg -kvm_getprocs -kvm_nlist -kvm_open -kvm_openfiles -kvm_read -kvm_write -label -labs -ldexp -ldiv -leaveok -lfind -lgamma -line -linemod -link_addr -link_ntoa -localeconv -localtime -log -log10 -log1p -logb -longjmp -longjmperror -longname -lsearch -m_in MP -m_out MP -madd MP -malloc -mamcpy -mblen -mbmb -mbrrune -mbrune -mbstowcs -mbtowc -mcmp MP -mdiv MP -memccpy -memchr -memcmp -memcpy -memmove -memset -mergesort -min MP -mkstemp -mktemp -mktime -modf -moncontrol -monstartup -mount MP -move -move MP -mpool_close -mpool_filter -mpool_get -mpool_new -mpool_open -mpool_put -mpool_sync -msqrt MP -msub MP -mult MP -mvcur -newein -nice -nl -nlist -nocbreak -noecho -nonl -noraw -ns_addr -ns_ntoa -ntohl -ntohs -omin MP -omount MP -opendir -openlog -openpl -optarg -opterr -optind -optopt -optreset -overlay -overwrite -pause -pclose -perror -point -popen -pow -pow MP -printf -printw -psignal -putc -putchar -putenv -puts -putw -qsort -radixsort -raise -rand -random -raw -rcmd -re_comp -re_exec -readdir -realloc -realpath -refresh -regcomp -regerror -regexec -regfree -regsub -remove -remque -res_init -res_mkquery -res_query -res_send -res_serach -resetty -rewind -rewinddir -rexec -rindex -rint -rpow MP -rresvport -ruserok -savetty -scalb -scandir -scanf -scanw -scroll -scrollok -sdiv MP -seekdir -setbuf -setbuffer -setenv -setfsent -setgrent -setgroupent -sethostent -sethostid -sethostname -setinvalidrunt -setjmp -setkey -setlinebuf -setlocale -setlogmask -setmode -setnetent -setnetgrent -setpassent -setprotoent -setpwent -setrgid -setruid -setrunelocale -setservent -setstate -setterm -setttyent -setusershell -setvbuf -sgetrune -sigaddset -sigdelset -sigemptyset -sigfillset -siginterrupt -sigismember -siglongjmp -signal -signgam -sigsetjmp -sin -sinh -sleep -snprintf -space -sprintf -sputrune -sqrt -sradixsort -srand -sreandom -sscanf -standend -standout -stderr -stdin -stdout -strcasecmp -strcat -strchr -strcmp -strcoll -strcpy -strcspn -strdup -strerror -strftime -strlen -strmode -strncasecmp -strncat -strncmp -strncpy -strpbrk -strrchr -strsep -strspc -strspn -strstr -strtod -strtok -strtol -strtoq -strtoul -strtouq -strunvis -strvis -strvisx -strxfrm -stty -subwin -swab -sys_errlist -sys_nerr -sys_siglist -sys_signame -sysconf -sysctl -syslog -system -tan -tanh -tcdrain -tcflow -tcflush -tcgetattr -tcgetpgrp -tcsendbreak -tcsetattr -tcsetpgrp -telldir -tempnam -tf_close -tf_get_cred -tf_get_pinst -tf_get_pname -tf_init -tgetent -tgetflag -tgetnum -tgetstr -tgoto -time -times -timezone -tmpfile -tmpnam -toascii -tolower -touchline -touchoverlap -touchwin -toupper -tputs -ttynam -ttyslot -tzset -tzsetwall -ualarm -uname -unctrl -ungetc -unsetenv -unvis -user_from_uid -usleep -utime -va_arg M -va_end M -va_start M -valloc -verr -verrx -vfprintf -vfscanf -vis -vlimit -vprintf -vscanf -vsnprintf -vsprintf -vsscanf -vsyslog -vtimes -vwarn -vwarnx -waddch -waddstr -warn -warnx -wclear -wclreol -wclrtobot -wcstombs -wctomb -wdelch -wdeleteln -werase -wgetch -wgetstr -winch -winsch -winsertln -wmove -wprintw -wrefreash -wscanw -wstandend -wstandout -y0 -y1 -yn diff --git a/src/libc/sys/CMakeLists.txt b/src/libc/sys/CMakeLists.txt index a23840f82..91b16c805 100644 --- a/src/libc/sys/CMakeLists.txt +++ b/src/libc/sys/CMakeLists.txt @@ -3,29 +3,28 @@ project(libc-sys) cmake_minimum_required(VERSION 2.4.0) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") -include_directories(${DARLING_TOP_DIRECTORY}/src/libnotify) +include_directories(${CMAKE_SOURCE_DIR}/src/libnotify) +include_directories(${CMAKE_SOURCE_DIR}/src/kernel/libsyscall/wrappers/spawn) +include_directories(${CMAKE_SOURCE_DIR}/src/external/syslog/libsystem_asl.tproj/include) +include_directories(${CMAKE_SOURCE_DIR}/src/kernel/libsyscall/wrappers/libproc) -set(sys_sources chmodx_np.c +set(sys_sources crt_externs.c - #errno.c # Moved by Apple into libsystem_kernel fork.c getgroups.c - #getiopolicy_np.c gettimeofday.c + chmodx_np.c _libc_fork_child.c - __libc_init.c - #msgctl.c + _libc_init.c + msgctl.c openx_np.c - #OSMemoryNotification.c - #OSThermalNotification.c + OSMemoryNotification.c + OSThermalNotification.c posix_spawn.c semctl.c settimeofday.c shmctl.c sigaction.c - sigcatch.c - sigtramp.c - slot_name.c statx_np.c umaskx_np.c OpenBSD/stack_protector.c @@ -35,6 +34,7 @@ set(sys_sources chmodx_np.c # set(sys_sources ${sys_sources} context-stubs.c) #endif() +SET_SOURCE_FILES_PROPERTIES(msgctl.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DKERNEL -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0") SET_SOURCE_FILES_PROPERTIES(semctl.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_SEMCTL -DKERNEL -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0") SET_SOURCE_FILES_PROPERTIES(shmctl.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_SEMCTL -DKERNEL -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0") SET_SOURCE_FILES_PROPERTIES(sigtramp.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE") diff --git a/src/libc/sys/MISSING-MANPAGE b/src/libc/sys/MISSING-MANPAGE deleted file mode 100644 index 6aa16bded..000000000 --- a/src/libc/sys/MISSING-MANPAGE +++ /dev/null @@ -1,9 +0,0 @@ -creat (obsoleted by open) -killpg -ptarce -setregid -setreuid -sigblock (obsoleted by sigprocmask) -sigpause (obsoleted by sigsuspend) -sigsetmask (obsoleted by sigprocmask) -sigvec (obsoleted by sigaction) diff --git a/src/libc/sys/MISSING_SYSCALLS b/src/libc/sys/MISSING_SYSCALLS deleted file mode 100644 index 2cb324652..000000000 --- a/src/libc/sys/MISSING_SYSCALLS +++ /dev/null @@ -1,8 +0,0 @@ -madvise UNIX -mincore UNIX -mlock UNIX -mprotect UNIX -msync UNIX -munlock UNIX -sigpending POSIX -sigstack compat[sigaltstack] diff --git a/src/libc/sys/OSMemoryNotification.c b/src/libc/sys/OSMemoryNotification.c index 897b9ac33..9e94e4ee7 100644 --- a/src/libc/sys/OSMemoryNotification.c +++ b/src/libc/sys/OSMemoryNotification.c @@ -21,115 +21,11 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include -#include -#include -#include -#include -#include -#include -#include +// Legacy symbols preserved for binary compatibility. const char *kOSMemoryNotificationName = "com.apple.system.memorystatus"; -struct _OSMemoryNotification { - int token; - mach_port_t port; -}; - -int -OSMemoryNotificationCreate(OSMemoryNotificationRef *note) -{ - OSMemoryNotificationRef ref = malloc(sizeof(struct _OSMemoryNotification)); - - if (NULL == ref) { - return ENOMEM; - } - - if (NOTIFY_STATUS_OK != notify_register_mach_port(kOSMemoryNotificationName, &ref->port, 0, &ref->token)) - return ENOMEM; - - *note = ref; - - return 0; -} - -int -OSMemoryNotificationDestroy(OSMemoryNotificationRef note) -{ - if (NOTIFY_STATUS_OK != notify_cancel(note->token)) - return EINVAL; - - if (KERN_SUCCESS != mach_port_deallocate(mach_task_self(), note->port)) - return EINVAL; - - free(note); - - return 0; -} - -int -OSMemoryNotificationWait(OSMemoryNotificationRef note, OSMemoryNotificationLevel *level) -{ - return OSMemoryNotificationTimedWait(note, level, NULL); -} - -static mach_msg_timeout_t -abs_to_timeout(const struct timeval *abstime) -{ - struct timeval rel, now; - - gettimeofday(&now, NULL); - - rel.tv_usec = abstime->tv_usec - now.tv_usec; - rel.tv_sec = abstime->tv_sec - now.tv_sec; - if (rel.tv_usec < 0) { - rel.tv_usec += 1000000; - rel.tv_sec--; - } - if (((int)rel.tv_sec < 0) || ((rel.tv_sec == 0) && (rel.tv_usec == 0))) { - return 0; - } - return rel.tv_sec * 1000 + rel.tv_usec / 1000; -} - -int -OSMemoryNotificationTimedWait(OSMemoryNotificationRef note, OSMemoryNotificationLevel *level, const struct timeval *abstime) -{ - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - dispatch_retain(sema); - - dispatch_source_t memoryNotificationSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_VM, 0, DISPATCH_VM_PRESSURE, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); - dispatch_source_set_event_handler(memoryNotificationSource, ^{ - dispatch_semaphore_signal(sema); - dispatch_release(sema); - }); - - dispatch_resume(memoryNotificationSource); - - dispatch_time_t waitTime = DISPATCH_TIME_FOREVER; - if (abstime) { - mach_msg_timeout_t timeout = abs_to_timeout(abstime); - waitTime = dispatch_time(DISPATCH_TIME_NOW, timeout * 1e6); - } - - long ret = dispatch_semaphore_wait(sema, waitTime); - - dispatch_release(sema); - dispatch_release(memoryNotificationSource); - - if (ret != 0) { - return ETIMEDOUT; - } - - if (level) { - *level = OSMemoryNotificationLevelUrgent; - } - - return 0; -} - -OSMemoryNotificationLevel OSMemoryNotificationCurrentLevel(void) +int OSMemoryNotificationCurrentLevel(void) { - return OSMemoryNotificationLevelNormal; + return 0; // OSMemoryNotificationLevelNormal } diff --git a/src/libc/sys/OSThermalNotification.c b/src/libc/sys/OSThermalNotification.c index 772490f41..ef884f634 100644 --- a/src/libc/sys/OSThermalNotification.c +++ b/src/libc/sys/OSThermalNotification.c @@ -25,9 +25,19 @@ #include #include +#include + +#define OSThermalPressureLevelName "com.apple.system.thermalpressurelevel" +const char * const kOSThermalNotificationPressureLevelName = OSThermalPressureLevelName; + +#if TARGET_OS_IPHONE +#define OSThermalAlert "com.apple.system.thermalalert" +#define OSThermalDecision "com.apple.system.thermaldecision" #define OSThermalStatusName "com.apple.system.thermalstatus" -const char * const kOSThermalNotificationName = OSThermalStatusName; +const char * const kOSThermalNotificationAlert = OSThermalAlert; +const char * const kOSThermalNotificationDecision = OSThermalDecision; +const char * const kOSThermalNotificationName = OSThermalStatusName; static const char * const kOSThermalMitigationNames[kOSThermalMitigationCount] = { OSThermalStatusName, @@ -108,3 +118,5 @@ OSThermalNotificationLevel OSThermalNotificationCurrentLevel(void) // Not ready returns -1, which should not be equal or greater than any other thermal state. return OSThermalNotificationLevelAny; } + +#endif // TARGET_OS_IPHONE diff --git a/src/libc/sys/OpenBSD/stack_protector.c b/src/libc/sys/OpenBSD/stack_protector.c index 74976f631..988d8edc1 100644 --- a/src/libc/sys/OpenBSD/stack_protector.c +++ b/src/libc/sys/OpenBSD/stack_protector.c @@ -35,7 +35,7 @@ #include #include #include -#include "CrashReporterClient.h" +#include #include "libproc.h" #include "_simple.h" @@ -88,8 +88,10 @@ __guard_setup(const char *apple[]) for (p = apple; p && *p; p++) { if (strstr(*p, "stack_guard") == *p) { __guard_from_kernel(*p); - if (__stack_chk_guard[0] != 0) + bzero((void*)*p, strlen(*p)); + if (__stack_chk_guard[0] != 0) { return; + } } } diff --git a/src/libc/sys/REQUIRED-MACROS b/src/libc/sys/REQUIRED-MACROS deleted file mode 100644 index 4482b7a0b..000000000 --- a/src/libc/sys/REQUIRED-MACROS +++ /dev/null @@ -1,3 +0,0 @@ -sigmask -WCOREDUMP - diff --git a/src/libc/sys/SYSCALL-LIST b/src/libc/sys/SYSCALL-LIST deleted file mode 100644 index edaf3fcff..000000000 --- a/src/libc/sys/SYSCALL-LIST +++ /dev/null @@ -1,148 +0,0 @@ -accept -access -acct -adjtime -bind -brk -sbrk -chdir -fchdir -chflags -creat -fchflags -chmod -fchmod -chown -fchown -lchown -chroot -close -connect -dup -dup2 -execve -_exit -fcntl -fhopen -flock -fork -fsync -getdirentries -getdtablesize -getfh -getfsstat -getgid -getegid -getgroups -getitimer -setitimer -getlogin -setlogin -getpeername -getpgrp -getpid -getppid -getpriority -setpriority -getrlimit -setrlimit -getrusage -getsockname -getsockopt -setsockopt -gettimeofday -settimeofday -getuid -geteuid -ioctl -kill -killpg -link -listen -lseek -madvise -mincore -mkdir -mkfifo -mknod -mlock -munlock -mmap -mount -unmount -mprotect -msync -munmap -nfsclnt -nfssvc -open -pathconf -fpathconf -pipe -profil -pthread_kill -pthread_sigmask -ptrace -quotactl -read -readv -readlink -reboot -recv -recvfrom -recvmsg -rename -revoke -rmdir -select -send -sendto -sendmsg -setgroups -setpgid -setpgrp -setregid -setreuid -setsid -setuid -seteuid -setgid -setegid -shutdown -sigaction -sigaltstack -sigblock -sigpause -sigpending -sigprocmask -sigreturn -sigsetmask -sigstack -sigsuspend -sigvec -sigwait -socket -socketpair -stat -lstat -fstat -statfs -fstatfs -swapon -symlink -sync -syscall -__syscall -truncate -ftruncate -umask -unlink -utimes -vfork -wait -waitpid -wait3 -wait4 -waitid -write -writev diff --git a/src/libc/sys/__libc_init.c b/src/libc/sys/__libc_init.c deleted file mode 100644 index 1549563fe..000000000 --- a/src/libc/sys/__libc_init.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2005-2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * __libc_init() is called from libSystem_initializer() - */ - -#include -#include -#include -#include - -struct ProgramVars; /* forward reference */ - -extern void _program_vars_init(const struct ProgramVars *vars); -extern void _libc_fork_init(void (*prepare)(void), void (*parent)(void), void (*child)(void)); -extern void _init_clock_port(); -//extern pthread_lock_t _malloc_lock; -extern void __xlocale_init(void); -extern void __pthread_pfz_setup(const char *apple[]); -extern void __guard_setup(const char *apple[]); -extern void __malloc_entropy_setup(const char *apple[]); -extern void __atexit_init(void); -extern int usenew_impl; - -__private_extern__ uintptr_t commpage_pfz_base; - -#ifdef PR_5243343 -/* 5243343 - temporary hack to detect if we are running the conformance test */ -#include -__private_extern__ int PR_5243343_flag = 0; -#endif /* PR_5243343 */ -__private_extern__ int __pthread_lock_debug = 0; -__private_extern__ int __pthread_lock_old = 0; - - -void -__libc_init(const struct ProgramVars *vars, void (*atfork_prepare)(void), void (*atfork_parent)(void), void (*atfork_child)(void), const char *apple[]) -{ - _program_vars_init(vars); - _libc_fork_init(atfork_prepare, atfork_parent, atfork_child); -// LOCK_INIT(_malloc_lock); - __atexit_init(); - _init_clock_port(); - __xlocale_init(); - __guard_setup(apple); - __pthread_pfz_setup(apple); - __malloc_entropy_setup(apple); - - -#ifdef PR_5243343 - /* 5243343 - temporary hack to detect if we are running the conformance test */ - if(getenv("TET_EXECUTE")) - PR_5243343_flag = 1; -#endif /* PR_5243343 */ -#if defined(__i386__) || defined(__x86_64__) - if(getenv("__PTHREAD_LOCK_DEBUG__")) - __pthread_lock_debug = 1; - if(getenv("__PTHREAD_LOCK_OLD__")) { - __pthread_lock_old = 1; - usenew_impl = 0; - } -#endif - -} diff --git a/src/libc/sys/_libc_fork_child.c b/src/libc/sys/_libc_fork_child.c index fe665cf5b..9311b0d9b 100644 --- a/src/libc/sys/_libc_fork_child.c +++ b/src/libc/sys/_libc_fork_child.c @@ -23,17 +23,20 @@ /* * _libc_fork_child() is called from Libsystem's libSystem_atfork_child() */ +#include +#include -extern void _asl_fork_child(); extern void _arc4_fork_child(); -extern void _init_clock_port(); -extern void _dirhelper_fork_child(); +extern void _init_clock_port(void); +extern void __environ_lock_fork_child(); +void _libc_fork_child(void); // todo: private_extern? void _libc_fork_child(void) { - _asl_fork_child(); + CRSetCrashLogMessage("crashed on child side of fork pre-exec"); + _arc4_fork_child(); _init_clock_port(); - _dirhelper_fork_child(); + __environ_lock_fork_child(); } diff --git a/src/libc/sys/_libc_init.c b/src/libc/sys/_libc_init.c new file mode 100644 index 000000000..3f95640c5 --- /dev/null +++ b/src/libc/sys/_libc_init.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2005-2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * _libc_initializer() is called from libSystem_initializer() + */ + +#include +#include +#include +#include +#include +#include +#include +#include <_simple.h> + +#include "libc_private.h" + +extern void _program_vars_init(const struct ProgramVars *vars); +extern void _libc_fork_init(const struct _libc_functions *funcs); +extern void _arc4_init(void); +extern void __atexit_init(void); +extern void __confstr_init(const struct _libc_functions *funcs); +extern void _init_clock_port(void); +extern void __chk_init(void); +extern void __xlocale_init(void); +extern void __guard_setup(const char *apple[]); + +void +_libc_initializer(const struct _libc_functions *funcs, + const char *envp[], + const char *apple[], + const struct ProgramVars *vars) +{ + _program_vars_init(vars); + _libc_fork_init(funcs); + __confstr_init(funcs); + __atexit_init(); + _init_clock_port(); + __chk_init(); + __xlocale_init(); + __guard_setup(apple); +} + + +void +__libc_init(const struct ProgramVars *vars, + void (*atfork_prepare)(void), + void (*atfork_parent)(void), + void (*atfork_child)(void), + const char *apple[]) +{ + const struct _libc_functions funcs = { + .version = 1, + .atfork_prepare = atfork_prepare, + .atfork_parent = atfork_parent, + .atfork_child = atfork_child, + .dirhelper = NULL, + }; + + return _libc_initializer(&funcs, NULL, apple, vars); +} diff --git a/src/libc/sys/atomic.3 b/src/libc/sys/atomic.3 deleted file mode 100644 index acd0d2ba3..000000000 --- a/src/libc/sys/atomic.3 +++ /dev/null @@ -1,246 +0,0 @@ -.Dd May 26, 2004 -.Dt ATOMIC 3 -.Os Darwin -.Sh NAME -.Nm OSAtomicAdd32 , -.Nm OSAtomicAdd32Barrier , -.Nm OSAtomicIncrement32 , -.Nm OSAtomicIncrement32Barrier , -.Nm OSAtomicDecrement32 , -.Nm OSAtomicDecrement32Barrier , -.Nm OSAtomicOr32 , -.Nm OSAtomicOr32Barrier , -.Nm OSAtomicOr32Orig , -.Nm OSAtomicOr32OrigBarrier , -.Nm OSAtomicAnd32 , -.Nm OSAtomicAnd32Barrier , -.Nm OSAtomicAnd32Orig , -.Nm OSAtomicAnd32OrigBarrier , -.Nm OSAtomicXor32 , -.Nm OSAtomicXor32Barrier , -.Nm OSAtomicXor32Orig , -.Nm OSAtomicXor32OrigBarrier , -.Nm OSAtomicAdd64 , -.Nm OSAtomicAdd64Barrier , -.Nm OSAtomicIncrement64 , -.Nm OSAtomicIncrement64Barrier , -.Nm OSAtomicDecrement64 , -.Nm OSAtomicDecrement64Barrier , -.Nm OSAtomicCompareAndSwapInt , -.Nm OSAtomicCompareAndSwapIntBarrier , -.Nm OSAtomicCompareAndSwapLong , -.Nm OSAtomicCompareAndSwapLongBarrier , -.Nm OSAtomicCompareAndSwapPtr , -.Nm OSAtomicCompareAndSwapPtrBarrier , -.Nm OSAtomicCompareAndSwap32 , -.Nm OSAtomicCompareAndSwap32Barrier , -.Nm OSAtomicCompareAndSwap64 , -.Nm OSAtomicCompareAndSwap64Barrier , -.Nm OSAtomicTestAndSet , -.Nm OSAtomicTestAndSetBarrier , -.Nm OSAtomicTestAndClear , -.Nm OSAtomicTestAndClearBarrier , -.Nm OSSpinLockTry , -.Nm OSSpinLockLock , -.Nm OSSpinLockUnlock , -.Nm OSAtomicEnqueue , -.Nm OSAtomicDequeue -.Nd atomic add, increment, decrement, or, and, xor, compare and swap, test and set, test and clear, spinlocks, and lockless queues -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In libkern/OSAtomic.h -.Ft int32_t -.Fn OSAtomicAdd32 "int32_t theAmount" "volatile int32_t *theValue" -.Ft int32_t -.Fn OSAtomicAdd32Barrier "int32_t theAmount" "volatile int32_t *theValue" -.Ft int32_t -.Fn OSAtomicIncrement32 "volatile int32_t *theValue" -.Ft int32_t -.Fn OSAtomicIncrement32Barrier "volatile int32_t *theValue" -.Ft int32_t -.Fn OSAtomicDecrement32 "volatile int32_t *theValue" -.Ft int32_t -.Fn OSAtomicDecrement32Barrier "volatile int32_t *theValue" -.Ft int32_t -.Fn OSAtomicOr32 "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicOr32Barrier "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicAnd32 "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicAnd32Barrier "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicXor32 "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicXor32Barrier "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicOr32Orig "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicOr32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicAnd32Orig "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicAnd32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicXor32Orig "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int32_t -.Fn OSAtomicXor32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue" -.Ft int64_t -.Fn OSAtomicAdd64 "int64_t theAmount" "volatile int64_t *theValue" -.Ft int64_t -.Fn OSAtomicAdd64Barrier "int64_t theAmount" "volatile int64_t *theValue" -.Ft int64_t -.Fn OSAtomicIncrement64 "volatile int64_t *theValue" -.Ft int64_t -.Fn OSAtomicIncrement64Barrier "volatile int64_t *theValue" -.Ft int64_t -.Fn OSAtomicDecrement64 "volatile int64_t *theValue" -.Ft int64_t -.Fn OSAtomicDecrement64Barrier "volatile int64_t *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwapInt "int oldValue" "int newValue" "volatile int *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwapIntBarrier "int oldValue" "int newValue" "volatile int *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwapLong "long oldValue" "long newValue" "volatile long *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwapLongBarrier "long oldValue" "long newValue" "volatile long *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwapPtr "void* oldValue" "void* newValue" "void* volatile *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwapPtrBarrier "void* oldValue" "void* newValue" "void* volatile *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "volatile int64_t *theValue" -.Ft bool -.Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "volatile int64_t *theValue" -.Ft bool -.Fn OSAtomicTestAndSet "uint32_t n" "volatile void *theAddress" -.Ft bool -.Fn OSAtomicTestAndSetBarrier "uint32_t n" "volatile void *theAddress" -.Ft bool -.Fn OSAtomicTestAndClear "uint32_t n" "volatile void *theAddress" -.Ft bool -.Fn OSAtomicTestAndClearBarrier "uint32_t n" "volatile void *theAddress" -.Ft bool -.Fn OSSpinLockTry "OSSpinLock *lock" -.Ft void -.Fn OSSpinLockLock "OSSpinLock *lock" -.Ft void -.Fn OSSpinLockUnlock "OSSpinLock *lock" -.Ft void -.Fn OSAtomicEnqueue "OSQueueHead *list" "void *new" "size_t offset" -.Ft void* -.Fn OSAtomicDequeue "OSQueueHead *list" "size_t offset" -.Sh DESCRIPTION -These functions are thread and multiprocessor safe. For each function, there -is a version that does and another that does not incorporate a memory barrier. -Barriers strictly order memory access on a weakly-ordered -architecture such as PPC. All loads and stores executed in sequential program -order before the barrier will complete before any load or store executed after -the barrier. On a uniprocessor, the barrier operation is typically a nop. -On a multiprocessor, the barrier can be quite expensive. -.Pp -Most code will want to use the barrier functions to ensure that memory shared -between threads is properly synchronized. For example, if you want to initialize -a shared data structure and then atomically increment a variable to indicate -that the initialization is complete, then you must use OSAtomicIncrement32Barrier() -to ensure that the stores to your data structure complete before the atomic add. -Likewise, the consumer of that data structure must use OSAtomicDecrement32Barrier(), -in order to ensure that their loads of the structure are not executed before -the atomic decrement. On the other hand, -if you are simply incrementing a global counter, then it is safe and potentially much -faster to use OSAtomicIncrement32(). If you are unsure which version to use, prefer -the barrier variants as they are safer. -.Pp -The logical (and, or, xor) and bit test operations are layered on top of the -.Fn OSAtomicCompareAndSwap -primitives. There are four versions of each logical operation, depending on whether -or not there is a barrier, and whether the return value is the result of the -operation (eg, -.Fn OSAtomicOr32 -) or the original value before the operation (eg, -.Fn OSAtomicOr32Orig -). -.Pp -The memory address -.Fa theValue -must be naturally aligned, ie 32-bit aligned for 32-bit operations and 64-bit -aligned for 64-bit operations. -.Pp -The 64-bit operations are not implemented for 32-bit processes on PPC platforms. -.Pp -The -.Fn OSAtomicCompareAndSwap -operations compare -.Fa oldValue -to -.Fa *theValue , -and set -.Fa *theValue -to -.Fa newValue -if the comparison is equal. The comparison and assignment -occur as one atomic operation. -.Pp -.Fn OSAtomicTestAndSet -and -.Fn OSAtomicTestAndClear -operate on bit (0x80 >> ( -.Fa n -& 7)) of byte ((char*) -.Fa theAddress -+ ( -.Fa n ->> 3)). They set the named bit to either 1 or 0, respectively. -.Fa theAddress -need not be aligned. -.Pp -The routines -.Fn OSAtomicEnqueue -and -.Fn OSAtomicDequeue -operate on singly linked LIFO queues. Ie, a dequeue operation will return the -most recently enqueued element, or NULL if the list is empty. The operations -are lockless, and barriers are used as necessary to permit thread-safe access to -the queue element. -.Fa offset -is the offset in bytes to the link field in the queue element. For example: -.Bd -literal -offset indent - typedef struct elem { - long data1; - struct elem *link; - int data2; - } elem_t; - - elem_t fred, mary, *p; - - OSQueueHead q = OS_ATOMIC_QUEUE_INIT; - - OSAtomicEnqueue( &q, &fred, offsetof(elem_t,link) ); - OSAtomicEnqueue( &q, &mary, offsetof(elem_t,link) ); - - p = OSAtomicDequeue( &q, offsetof(elem_t,link) ); - -.Ed -In this example, the call of -.Fn OSAtomicDequeue -will return a ptr to mary. -.Sh RETURN VALUES -The arithmetic operations return the new value, after the operation has been performed. -The boolean operations come in two styles, one of which returns the new value, and one -of which (the "Orig" versions) returns the old. -The compare-and-swap operations return true if the comparison was equal, ie if the swap occured. -The bit test and set/clear operations return the original value of the bit. -The dequeue operation returns the most recently enqueued element, or NULL if the list in empty. -.Sh SEE ALSO -.Xr spinlock 3 , -.Xr barrier 3 -.Sh HISTORY -Most of these functions first appeared in Mac OS 10.4 (Tiger). The "Orig" forms of the -boolean operations, the "int", "long" and "ptr" forms of compare-and-swap, and lockless -enqueue/dequeue first appeared in Mac OS 10.5 (Leopard). diff --git a/src/libc/sys/barrier.3 b/src/libc/sys/barrier.3 deleted file mode 100644 index de5fed84f..000000000 --- a/src/libc/sys/barrier.3 +++ /dev/null @@ -1,24 +0,0 @@ -.Dd May 26, 2004 -.Dt BARRIER 3 -.Os Darwin -.Sh NAME -.Nm OSMemoryBarrier -.Nd memory barrier to order loads and stores -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In libkern/OSAtomic.h -.Ft void -.Fn OSMemoryBarrier "void" -.Sh DESCRIPTION -.Fn OSMemoryBarrier -strictly orders memory accesses in a weakly ordered memory model such as with PowerPC, -by creating a barrier. All loads and stores executed in sequential program order before -the barrier will complete with respect to the memory coherence mechanism, before any -load or store executed after the barrier. Used with an atomic operation, the barrier -can be used to create custom synchronization protocols as an alternative to the -spinlock or queue/dequeue operations. Note that this barrier does not order uncached loads -and stores. On a uniprocessor, the barrier operation is typically optimized into a nop. -.Sh SEE ALSO -.Xr atomic 3 , -.Xr spinlock 3 diff --git a/src/libc/sys/context-stubs.c b/src/libc/sys/context-stubs.c deleted file mode 100644 index 39f3dcc0b..000000000 --- a/src/libc/sys/context-stubs.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -/* stubs for ppc64 and i386, until real support is available */ -int getcontext(ucontext_t *u) { errno = ENOTSUP; return -1; } -void makecontext(ucontext_t *u, void (*f)(void), int a, ...) {} -int setcontext(const ucontext_t *u) { errno = ENOTSUP; return -1; } -int swapcontext(ucontext_t * __restrict u1, const ucontext_t * __restrict u2) { errno = ENOTSUP; return -1; } diff --git a/src/libc/sys/crt_externs.c b/src/libc/sys/crt_externs.c index 03ea7d3cc..a78524ff1 100644 --- a/src/libc/sys/crt_externs.c +++ b/src/libc/sys/crt_externs.c @@ -1,4 +1,3 @@ -/* Modified by Lubos Dolezel for Darling */ /* * Copyright (c) 1999-2007 Apple Inc. All rights reserved. * @@ -68,14 +67,6 @@ struct mach_header *_NSGetMachExecuteHeader(void) { return(USE_VAR(_mh_execute_header)); } -void __darling_set_libc_vars(int* argc, char*** argv, char*** env) -{ - NXArgc_pointer = argc; - NXArgv_pointer = argv; - environ_pointer = env; - __progname_pointer = &(*argv)[0]; -} - #if __DYNAMIC__ struct ProgramVars { @@ -91,8 +82,9 @@ struct ProgramVars /* - * dyld calls libSystem_initializer() and passes it a ProgramVars struct containing pointers to the - * main executable's NXArg* global variables. libSystem_initializer() calls __libc_init() which calls + * dyld calls libSystem_initializer() and passes it a ProgramVars struct + * containing pointers to the main executable's NXArg* global variables. + * libSystem_initializer() calls _libc_initializer() which calls * _program_vars_init() passing the ProgramVars parameter. */ void __attribute__((visibility("hidden"))) diff --git a/src/libc/sys/errno.c b/src/libc/sys/errno.c deleted file mode 100644 index 7c20fa537..000000000 --- a/src/libc/sys/errno.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -/* - * The world-renowned global variable - */ -#include - -#undef errno - -__asm__(".symver errno, errno@DARWIN"); -extern int errno; -int *__error(void) { - pthread_t self = pthread_self(); - /* If we're not a detached pthread, just return the global errno */ - if ((self == (pthread_t)0) || (self->sig != _PTHREAD_SIG)) { - return &errno; - } - return &self->err_no; -} - -int cthread_errno(void) { - return *__error(); -} - diff --git a/src/libc/sys/fork.c b/src/libc/sys/fork.c index b026e0626..6a83b53df 100644 --- a/src/libc/sys/fork.c +++ b/src/libc/sys/fork.c @@ -23,21 +23,22 @@ #include #include #include +#include + +#include "libc_private.h" extern pid_t __fork(void); -extern void _cthread_fork_prepare(); -extern void _cthread_fork_parent(); -extern void _cthread_fork_child(); static void (*_libSystem_atfork_prepare)(void) = 0; static void (*_libSystem_atfork_parent)(void) = 0; static void (*_libSystem_atfork_child)(void) = 0; -__private_extern__ void _libc_fork_init(void (*prepare)(void), void (*parent)(void), void (*child)(void)) +__private_extern__ +void _libc_fork_init(const struct _libc_functions *funcs) { - _libSystem_atfork_prepare = prepare; - _libSystem_atfork_parent = parent; - _libSystem_atfork_child = child; + _libSystem_atfork_prepare = funcs->atfork_prepare; + _libSystem_atfork_parent = funcs->atfork_parent; + _libSystem_atfork_child = funcs->atfork_child; } /* diff --git a/src/libc/sys/getiopolicy_np.3 b/src/libc/sys/getiopolicy_np.3 deleted file mode 100644 index fd801a886..000000000 --- a/src/libc/sys/getiopolicy_np.3 +++ /dev/null @@ -1,188 +0,0 @@ -.Dd July 18, 2006 -.Dt getiopolicy_np 3 -.Os -.Sh NAME -.Nm getiopolicy_np, setiopolicy_np -.Nd manipulate the I/O policy of a process or thread -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In sys/resource.h -.Ft int -.Fn getiopolicy_np "int iotype" "int scope" -.Ft int -.Fn setiopolicy_np "int iotype" "int scope" "int policy" -.Sh DESCRIPTION -The -.Fn getiopolicy_np -and -.Fn setiopolicy_np -functions are provided to get or set the I/O policy of the current process -or the current thread. The policy of the I/O of the given type -.Fa iotype -can be get or set for the given -.Fa scope . -.Pp -The I/O type is specified in the argument -.Fa iotype . -The currently supported I/O type is -.Dv IOPOL_TYPE_DISK , -which means the I/O policy for I/Os to local disks can be get or set. I/Os to -local disks are I/Os sent to the media without going through a network, -including I/Os to internal and external hard drives, optical media in internal -and external drives, flash drives, floppy disks, ram disks, and mounted disk -images which reside on these media, but not including remote volumes mounted -through networks (AFP, SMB, NFS, etc) or disk images residing on remote volumes. -.Pp -The scope that the I/O policy takes effect is specified in the argument -.Fa scope -as follows: -.Bl -tag -width IOPOL_SCOPE_PROCESS -.It IOPOL_SCOPE_PROCESS -The I/O policy of all I/Os issued by the current process is get or set. -.It IOPOL_SCOPE_THREAD -The I/O policy of all I/Os issued by the current thread is get or set. -.El -.Pp -In -.Fn getiopolicy_np , -the I/O policy of the given I/O type and scope is returned. In -.Fn setiopolicy_np , -the argument -.Fa policy -is an integer which contains the new I/O policy to be set for the given I/O -type and scope. The I/O policy can have the following values: -.Bl -tag -width IOPOL_PASSIVEXX -.It IOPOL_DEFAULT -This is the default I/O policy for the first process and every new created thread. -.It IOPOL_NORMAL -I/Os with NORMAL policy are called NORMAL I/Os. They are handled by the -system using best-effort. -.It IOPOL_THROTTLE -I/Os with THROTTLE policy are called THROTTLE I/Os. If a THROTTLE I/O request -occurs within a small time window (usually a fraction of a second) of another -NORMAL I/O request, the thread that issues the THROTTLE I/O is forced to sleep -for a certain interval. This slows down the thread that issues the THROTTLE I/O -so that NORMAL I/Os can utilize most of the disk I/O bandwidth. -Furthermore, a NORMAL I/O request may bypass a previously issued THROTTLE I/O -request in kernel or driver queues and be sent to the device first. -In some circumstances, very large THROTTLE I/O requests will be broken -into smaller requests which are then issued serially. -.It IOPOL_PASSIVE -The PASSIVE I/Os are a special type of NORMAL I/O that are processed the same as -NORMAL I/Os but are ignored by the THROTTLE I/Os so that the threads issuing -THROTTLE I/Os are not slowed down by PASSIVE I/Os. The PASSIVE I/O policy is -useful for server type applications. The I/Os generated by these applications -are called passive I/Os because these I/Os are caused directly or indirectly by -the I/O requests they receive from client applications. For example, when an -image file is mounted by DiskImages, DiskImages generate passive I/Os. -DiskImages should mark these I/Os using the PASSIVE I/O policy so that when -client applications that issue THROTTLE I/Os access the volume managed by -DiskImages, these client applications will not be slowed down by the I/Os -generated by DiskImages. -.El -.Pp -The I/O policy of a new created process is inherited from its parent -process. The I/O policy of an I/O request depends on the I/O policy of -both the current thread and the current process. If the I/O policy of the -current thread is IOPOL_DEFAULT, the I/O policy of the current process is -used; if the I/O policy of the current thread is not IOPOL_DEFAULT, the -I/O policy of the current thread overrides the I/O policy of the current -process; if the I/O policy of the current process is IOPOL_DEFAULT, the -policy of I/Os issued by this process is NORMAL. For example, given the -following thread and process I/O policy in the first two columns, the I/O -policy of all I/Os issued by the thread is given in the third column: -.Bl -column "Process I/O ScopeXXX" "Thread I/O ScopeXXX" "I/O Policy" -offset indent -.It Sy "Process I/O Policy Thread I/O Policy I/O Policy" -.It "DEFAULT DEFAULT NORMAL" -.It "DEFAULT PASSIVE PASSIVE" -.It "THROTTLE DEFAULT THROTTLE" -.It "THROTTLE PASSIVE PASSIVE" -.It "PASSIVE NORMAL NORMAL" -.El -.Pp -The thread or process with THROTTLE I/O policy enabled may be slowed down when -it issues reads, but will not be slowed down when it issues writes. -If it issues far more writes than reads (e.g., an application -downloading large amounts of data through the network), these writes compete with the -normal I/Os of other processes and may have an adverse effect on the I/O -throughput or latency of those processes. -.Pp -.Sh RETURN VALUES -The -.Fn getiopolicy_np -call returns the I/O policy of the given I/O type and scope. If error -happens, -1 is returned. The -.Fn setiopolicy_np -call returns 0 if there is no error, or -1 if there is an error. When error -happens, the error code is stored in the external variable -.Fa errno . -.Sh ERRORS -.Fn Getiopolicy_np -and -.Fn setiopolicy_np -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Io_type or scope is not one of the values defined in this manual. -.El -.Pp -In addition to the errors indicated above, -.Fn setiopolicy_np -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -Policy is not one of the values defined in this manual. -.El -.Sh NOTES -The thread or process with THROTTLE I/O policy enabled will be generally -prevented from having an adverse effect on the throughput or latency of -the normal I/Os of other processes. -However, there are a few considerations that users of the THROTTLE I/O policy should keep in mind: -.Pp -Consider using the -.Dv F_NOCACHE -.Xr fcntl 2 -command to prevent caching when using the THROTTLE I/O policy. -This will reduce contention for available caches with NORMAL I/O. -.Pp -Large read requests will automatically be broken up into smaller requests -to avoid stalling NORMAL I/O requests. -However, due to the consistency guarantees provided to contiguous writes, -this can not be done automatically for large writes. -If a thread or process with THROTTLE I/O policy enabled will be issuing -large writes, consider the use of the -.Dv F_SINGLE_WRITER -.Xr fcntl 2 -command. -This will indicate to the system that there is only one thread writing to -the file and allow automatic division of large writes. -.Pp -Write-heavy THROTTLE I/O workloads may fill a drive’s track (write) cache. -Subsequent NORMAL I/O writes must then wait for enough of the track cache -to be flushed before they can continue. -If the writes issued as THROTTLE I/O are small and not contiguous, many -seeks may be incurred before space is available for a subsequent NORMAL -I/O write. -Issuers of THROTTLE I/O should attempt to issue their writes sequentially -or to locations in a single small area of the drive (i.e. different -positions in the same file) to ensure good spacial locality. -.Pp -The -.Dv F_FULLFSYNC -.Xr fcntl 2 -command can cause very long system-wide IO stalls. -Users of THROTTLE I/O should issue this command only if absolutely necessary. -.Sh SEE ALSO -.Xr nice 3 , -.Xr getpriority 2 , -.Xr setpriority 2 , -.Xr fcntl 2 , -.Xr open 2 , -.Xr renice 8 -.Sh HISTORY -The -.Fn getiopolicy_np -and -.Fn setiopolicy_np -function call first appeared in Mac OS X 10.5 (Leopard) . diff --git a/src/libc/sys/getiopolicy_np.c b/src/libc/sys/getiopolicy_np.c deleted file mode 100644 index 146fdac6d..000000000 --- a/src/libc/sys/getiopolicy_np.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include -#include - -extern int __iopolicysys(int, struct _iopol_param_t *); - -int -getiopolicy_np(int iotype, int scope) -{ - int policy, error; - struct _iopol_param_t iop_param; - - if (iotype != IOPOL_TYPE_DISK || - (scope != IOPOL_SCOPE_PROCESS && scope != IOPOL_SCOPE_THREAD)) { - errno = EINVAL; - policy = -1; - goto exit; - } - - iop_param.iop_scope = scope; - iop_param.iop_iotype = iotype; - error = __iopolicysys(IOPOL_CMD_GET, &iop_param); - if (error != 0) { - errno = error; - policy = -1; - goto exit; - } - - policy = iop_param.iop_policy; - - exit: - return policy; -} - -int -setiopolicy_np(int iotype, int scope, int policy) -{ - /* kernel validates the indiv values, no need to repeat it */ - struct _iopol_param_t iop_param; - - iop_param.iop_scope = scope; - iop_param.iop_iotype = iotype; - iop_param.iop_policy = policy; - - return( __iopolicysys(IOPOL_CMD_SET, &iop_param)); -} diff --git a/src/libc/sys/gettimeofday.c b/src/libc/sys/gettimeofday.c index 75830eabf..56d931267 100644 --- a/src/libc/sys/gettimeofday.c +++ b/src/libc/sys/gettimeofday.c @@ -1,4 +1,3 @@ -// Modified by Lubos Dolezel for Darling /* * Copyright (c) 2003-2005 Apple Computer, Inc. All rights reserved. * @@ -53,11 +52,11 @@ int gettimeofday (struct timeval *tp, void *vtzp) tp = &atv; } - //if (__commpage_gettimeofday(tp)) { /* first try commpage */ + if (__commpage_gettimeofday(tp)) { /* first try commpage */ if (__gettimeofday(tp, NULL) < 0) { /* if it fails, use syscall */ return (-1); } - //} + } if (tzp) { if (validtz == 0) { diff --git a/src/libc/sys/posix_spawn.c b/src/libc/sys/posix_spawn.c index ef1bfa94f..97efabf9a 100644 --- a/src/libc/sys/posix_spawn.c +++ b/src/libc/sys/posix_spawn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2008 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2006-2012 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -25,1304 +25,15 @@ * [SPN] Support for _POSIX_SPAWN */ -#include /* for user_size_t */ #include #include #include #include #include #include /* for OPEN_MAX, PATH_MAX */ -#include /* for offsetof() */ #include /* for strlcpy() */ #include /* for _PATH_DEFPATH */ #include /* for struct stat */ -#include -#include - -#if TARGET_OS_EMBEDDED -#include -#endif - -/* - * posix_spawnattr_init - * - * Description: Initialize a spawn attributes object attr with default values - * - * Parameters: attr The spawn attributes object to be - * initialized - * - * Returns: 0 Success - * ENOMEM Insufficient memory exists to - * initialize the spawn attributes object. - * - * Note: As an implementation detail, the externally visibily type - * posix_spawnattr_t is defined to be a void *, and initialization - * involves allocation of a memory object. Subsequent changes to - * the spawn attributes may result in reallocation under the - * covers. - * - * Reinitialization of an already initialized spawn attributes - * object will result in memory being leaked. Because spawn - * attributes are not required to be used in conjunction with a - * static initializer, there is no way to distinguish a spawn - * attribute with stack garbage from one that's been initialized. - * This is arguably an API design error. - */ -int -posix_spawnattr_init(posix_spawnattr_t *attr) -{ - _posix_spawnattr_t *psattrp = (_posix_spawnattr_t *)attr; - int err = 0; - - if ((*psattrp = (_posix_spawnattr_t)malloc(sizeof(struct _posix_spawnattr))) == NULL) { - err = ENOMEM; - } else { - - /* - * The default value of this attribute shall be as if no - * flags were set - */ - (*psattrp)->psa_flags = 0; - - /* - * The default value of this attribute shall be an empty - * signal set - */ - (*psattrp)->psa_sigdefault = 0; - - /* The default value of this attribute is unspecified */ - (*psattrp)->psa_sigmask = 0; - - /* The default value of this attribute shall be zero */ - (*psattrp)->psa_pgroup = 0; /* doesn't matter */ - - /* Default is no binary preferences, i.e. use normal grading */ - memset((*psattrp)->psa_binprefs, 0, - sizeof((*psattrp)->psa_binprefs)); - - /* Default is no port actions to take */ - (*psattrp)->psa_ports = NULL; - - /* - * The default value of this attribute shall be an no - * process control on resource starvation - */ - (*psattrp)->psa_pcontrol = 0; - - /* - * The default value of this attribute shall be an no - * process control on resource starvation - */ - (*psattrp)->psa_apptype = 0; - -#if TARGET_OS_EMBEDDED - /* Jetsam related */ - (*psattrp)->psa_jetsam_flags = 0; - (*psattrp)->psa_priority = DEFAULT_JETSAM_PRIORITY; - (*psattrp)->psa_high_water_mark = -1; -#endif - - /* Default is no CPU usage monitor active. */ - (*psattrp)->psa_cpumonitor_percent = 0; - (*psattrp)->psa_cpumonitor_interval = 0; - } - - return (err); -} - - -/* - * posix_spawnattr_destroy - * - * Description: Destroy a spawn attributes object that was previously - * initialized via posix_spawnattr_init() by freeing any - * memory associated with it and setting it to an invalid value. - * - * Parameters: attr The spawn attributes object to be - * destroyed. - * - * Returns: 0 Success - * - * Notes: The destroyed spawn attribute results in the void * pointer - * being set to NULL; subsequent use without reinitialization - * will result in explicit program failure (rather than merely - * "undefined behaviour"). - * - * NOTIMP: Allowed failures (checking NOT required): - * EINVAL The value specified by attr is invalid. - */ -static int posix_spawn_destroyportactions_np(posix_spawnattr_t *); - -int -posix_spawnattr_destroy(posix_spawnattr_t *attr) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - posix_spawn_destroyportactions_np(attr); - - free(psattr); - *attr = NULL; - - return (0); -} - - -/* - * posix_spawnattr_setflags - * - * Description: Set the spawn flags attribute for the spawn attribute object - * referred to by 'attr'. - * - * Parameters: attr The spawn attributes object whose flags - * are to be set - * flags The flags value to set - * - * Returns: 0 Success - * - * NOTIMP: Allowed failures (checking NOT required): - * EINVAL The value specified by attr is invalid. - * EINVAL The value of the attribute being set is not valid. - */ -int -posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - psattr->psa_flags = flags; - - return (0); -} - - -/* - * posix_spawnattr_getflags - * - * Description: Retrieve the spawn attributes flag for the spawn attributes - * object referenced by 'attr' and place them in the memory - * location referenced by 'flagsp' - * - * Parameters: attr The spawn attributes object whose flags - * are to be retrieved - * flagsp A pointer to a short value to receive - * the flags - * - * Returns: 0 Success - * - * Implicit Returns: - * *flagps (modified) The flags value from the spawn - * attributes object - * - * NOTIMP: Allowed failures (checking NOT required): - * EINVAL The value specified by attr is invalid. - * EINVAL The value of the attribute being set is not valid. - */ -int -posix_spawnattr_getflags(const posix_spawnattr_t * __restrict attr, - short * __restrict flagsp) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - *flagsp = psattr->psa_flags; - - return (0); -} - - -/* - * posix_spawnattr_getsigdefault - * - * Description: Retrieve the set of signals to be set to default according to - * the spawn attribute value referenced by 'attr' and place the - * result into the memory containing the sigset_t referenced by - * 'sigdefault' - * - * Parameters: attr The spawn attributes object whose - * signal set for default signals is to - * be retrieved - * sigdefault A pointer to the sigset_t to receive - * the signal set - * - * Returns: 0 Success - * - * Implicit Returns: - * *sigdefault (modified) The signal set of signals to default - * from the spawn attributes object - */ -int -posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict attr, - sigset_t * __restrict sigdefault) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - *sigdefault = psattr->psa_sigdefault; - - return (0); -} - - -/* - * posix_spawnattr_getpgroup - * - * Description: Obtain the value of the spawn process group attribute from the - * spawn attributes object referenced by 'attr' and place the - * results in the memory location referenced by 'pgroup' - * - * Parameters: attr The spawn attributes object whose - * process group information is to be - * retrieved - * pgroup A pointer to the pid_t to receive the - * process group - * - * Returns: 0 Success - * - * Implicit Returns: - * *pgroup (modified) The process group information from the - * spawn attributes object - */ -int -posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict attr, - pid_t * __restrict pgroup) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - *pgroup = psattr->psa_pgroup; - - return (0); -} - - -/* - * posix_spawnattr_getsigmask - * - * Description: Obtain the value of the spawn signal mask attribute from the - * spawn attributes object referenced by 'attr' and place the - * result into the memory containing the sigset_t referenced by - * 'sigmask' - * - * Parameters: attr The spawn attributes object whose - * signal set for masked signals is to - * be retrieved - * sigmask A pointer to the sigset_t to receive - * the signal set - * - * Returns: 0 Success - * - * Implicit Returns: - * *sigmask (modified) The signal set of signals to mask - * from the spawn attributes object - */ -int -posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict attr, - sigset_t * __restrict sigmask) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - *sigmask = psattr->psa_sigmask; - - return (0); -} - -/* - * posix_spawnattr_getbinpref_np - * - * Description: Obtain the value of the spawn binary preferences attribute from - * the spawn attributes object referenced by 'attr' and place the - * result into the memory referenced by 'pref'. - * - * Parameters: attr The spawn attributes object whose - * binary preferences are to be retrieved - * count The size of the cpu_type_t array - * pref An array of cpu types - * ocount The actual number copied - * - * Returns: 0 No binary preferences found - * > 0 The number of cpu types (less than - * count) copied over from 'attr'. - * - * Implicit Returns: - * *pref (modified) The binary preferences array - * from the spawn attributes object - */ -int -posix_spawnattr_getbinpref_np(const posix_spawnattr_t * __restrict attr, - size_t count, cpu_type_t *pref, size_t * __restrict ocount) -{ - _posix_spawnattr_t psattr; - int i = 0; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - for (i = 0; i < count && i < 4; i++) { - pref[i] = psattr->psa_binprefs[i]; - } - - if (ocount) - *ocount = i; - return 0; -} - - -/* - * posix_spawnattr_getpcontrol_np - * - * Description: Retrieve the process control property set default according to - * the spawn attribute value referenced by 'attr' and place the - * result into the memory containing the control referenced by - * 'pcontrol' - * - * Parameters: attr The spawn attributes object whose - * signal set for default signals is to - * be retrieved - * pcontrol A pointer to an int to receive - * the process control info - * - * Returns: 0 Success - * - * Implicit Returns: - * *pcontrol (modified) The signal set of signals to default - * from the spawn attributes object - */ -int -posix_spawnattr_getpcontrol_np(const posix_spawnattr_t * __restrict attr, - int * __restrict pcontrol) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - *pcontrol = psattr->psa_pcontrol; - - return (0); -} - -/* - * posix_spawnattr_getapptype_np - * - * Description: Retrieve the process specific behaviors and app launch typea - * spawn attribute value referenced by 'attr' and place the - * result into the memory containing the control referenced by - * 'apptype' - * - * Parameters: attr The spawn attributes object whose - * signal set for default signals is to - * be retrieved - * apptype A pointer to an int to receive - * the process control info - * - * Returns: 0 Success - * - * Implicit Returns: - * *pcontrol (modified) The signal set of signals to default - * from the spawn attributes object - */ -int -posix_spawnattr_getapptype_np(const posix_spawnattr_t * __restrict attr, - int * __restrict apptype) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - *apptype = psattr->psa_apptype; - - return (0); -} - -/* - * posix_spawnattr_setsigdefault - * - * Description: Set the set of signals to be set to default for the spawn - * attribute value referenced by 'attr' from the memory - * containing the sigset_t referenced by 'sigdefault' - * - * Parameters: attr The spawn attributes object whose - * signal set for default signals is to - * be set - * sigdefault A pointer to the sigset_t from which to - * obtain the signal set - * - * Returns: 0 Success - */ -int -posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict attr, - const sigset_t * __restrict sigdefault) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - psattr->psa_sigdefault = *sigdefault; - - return (0); -} - - -/* - * posix_spawnattr_setpgroup - * - * Description: Set the value of the spawn process group attribute for the - * spawn attributes object referenced by 'attr' from the value - * of 'pgroup' - * - * Parameters: attr The spawn attributes object for which - * the process group information is to be - * set - * pgroup The process group to set - * - * Returns: 0 Success - */ -int -posix_spawnattr_setpgroup(posix_spawnattr_t * attr, pid_t pgroup) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - psattr->psa_pgroup = pgroup; - - return (0); -} - - -/* - * posix_spawnattr_setsigmask - * - * Description: Set the set of signals to be masked for the spawn attribute - * value referenced by 'attr' from the memory containing the - * sigset_t referenced by 'sigmask' - * - * Parameters: attr The spawn attributes object whose - * signal set for masked signals is to - * be set - * sigmask A pointer to the sigset_t from which to - * obtain the signal set - * - * Returns: 0 Success - */ -int -posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict attr, - const sigset_t * __restrict sigmask) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - psattr->psa_sigmask = *sigmask; - - return (0); -} - - -/* - * posix_spawnattr_setbinpref_np - * - * Description: Set the universal binary preferences for the spawn attribute - * value referenced by 'attr' from the memory containing the - * cpu_type_t array referenced by 'pref', size of 'count' - * - * Parameters: attr The spawn attributes object whose - * binary preferences are to be set - * count Size of the array pointed to by 'pref' - * pref cpu_type_t array of binary preferences - * ocount The actual number copied - * - * Returns: 0 No preferences copied - * > 0 Number of preferences copied - * - * Note: The posix_spawnattr_t currently only holds four cpu_type_t's. - * If the caller provides more preferences than this limit, they - * will be ignored, as reflected in the return value. - */ -int -posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict attr, - size_t count, cpu_type_t *pref, size_t * __restrict ocount) -{ - _posix_spawnattr_t psattr; - int i = 0; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - for (i = 0; i < count && i < 4; i++) { - psattr->psa_binprefs[i] = pref[i]; - } - - /* return number of binprefs copied over */ - if (ocount) - *ocount = i; - return 0; -} - - -/* - * posix_spawnattr_setpcontrol_np - * - * Description: Set the process control property according to - * attribute value referenced by 'attr' from the memory - * containing the int value 'pcontrol' - * - * Parameters: attr The spawn attributes object whose - * signal set for default signals is to - * be set - * pcontrol An int value of the process control info - * - * Returns: 0 Success - */ -int -posix_spawnattr_setpcontrol_np(posix_spawnattr_t * __restrict attr, - const int pcontrol) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - psattr->psa_pcontrol = pcontrol; - - return (0); -} - - -/* - * posix_spawnattr_setapptype_np - * - * Description: Set the process specific behaviors and app launch type - * attribute value referenced by 'attr' from the memory - * containing the int value 'apptype' - * - * Parameters: attr The spawn attributes object whose - * signal set for default signals is to - * be set - * apptype An int value of the apptype info - * - * Returns: 0 Success - */ -int -posix_spawnattr_setapptype_np(posix_spawnattr_t * __restrict attr, - const int apptype) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - psattr->psa_apptype = apptype; - - return (0); -} - -/* - * posix_spawn_createportactions_np - * Description: create a new posix_spawn_port_actions struct and link - * it into the posix_spawnattr. - */ -static int -posix_spawn_createportactions_np(posix_spawnattr_t *attr) -{ - _posix_spawnattr_t psattr; - _posix_spawn_port_actions_t acts; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - acts = (_posix_spawn_port_actions_t)malloc(PS_PORT_ACTIONS_SIZE(2)); - if (acts == NULL) - return ENOMEM; - - acts->pspa_alloc = 2; - acts->pspa_count = 0; - - psattr->psa_ports = acts; - return 0; -} - -/* - * posix_spawn_growportactions_np - * Description: Enlarge the size of portactions if necessary - */ -static int -posix_spawn_growportactions_np(posix_spawnattr_t *attr) -{ - _posix_spawnattr_t psattr; - _posix_spawn_port_actions_t acts; - int newnum; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - acts = psattr->psa_ports; - if (acts == NULL) - return EINVAL; - - /* Double number of port actions allocated for */ - newnum = 2 * acts->pspa_alloc; - acts = realloc(acts, PS_PORT_ACTIONS_SIZE(newnum)); - if (acts == NULL) - return ENOMEM; - - acts->pspa_alloc = newnum; - return 0; -} - -/* - * posix_spawn_destroyportactions_np - * Description: clean up portactions struct in posix_spawnattr_t attr - */ -static int -posix_spawn_destroyportactions_np(posix_spawnattr_t *attr) -{ - _posix_spawnattr_t psattr; - _posix_spawn_port_actions_t acts; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - acts = psattr->psa_ports; - if (acts == NULL) - return EINVAL; - - free(acts); - return 0; -} - - -/* - * posix_spawnattr_setspecialport_np - * - * Description: Set a new value for a mach special port in the spawned task. - * - * Parameters: attr The spawn attributes object for the - * new process - * new_port The new value for the special port - * which The particular port to be set - * (see task_set_special_port for details) - * - * Returns: 0 Success - * ENOMEM Couldn't allocate memory - */ -int -posix_spawnattr_setspecialport_np( - posix_spawnattr_t *attr, - mach_port_t new_port, - int which) -{ - _posix_spawnattr_t psattr; - int err = 0; - _ps_port_action_t *action; - _posix_spawn_port_actions_t ports; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - ports = psattr->psa_ports; - /* Have any port actions been created yet? */ - if (ports == NULL) { - err = posix_spawn_createportactions_np(attr); - if (err) - return err; - ports = psattr->psa_ports; - } - - /* Is there enough room? */ - if (ports->pspa_alloc == ports->pspa_count) { - err = posix_spawn_growportactions_np(attr); - if (err) - return err; - } - - /* Add this action to next spot in array */ - action = &ports->pspa_actions[ports->pspa_count]; - action->port_type = PSPA_SPECIAL; - action->new_port = new_port; - action->which = which; - - ports->pspa_count++; - return err; -} - -/* - * posix_spawnattr_setexceptionports_np - * - * Description: Set a new port for a set of exception ports in the spawned task. - * - * Parameters: attr The spawn attributes object for the - * new process - * mask A bitfield indicating which exceptions - * to associate the port with - * new_port The new value for the exception port - * behavior The default behavior for the port - * flavor The default flavor for the port - * (see task_set_exception_ports) - * - * Returns: 0 Success - */ -int -posix_spawnattr_setexceptionports_np( - posix_spawnattr_t *attr, - exception_mask_t mask, - mach_port_t new_port, - exception_behavior_t behavior, - thread_state_flavor_t flavor) -{ - _posix_spawnattr_t psattr; - int err = 0; - _ps_port_action_t *action; - _posix_spawn_port_actions_t ports; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - ports = psattr->psa_ports; - /* Have any port actions been created yet? */ - if (ports == NULL) { - err = posix_spawn_createportactions_np(attr); - if (err) - return err; - ports = psattr->psa_ports; - } - - /* Is there enough room? */ - if (ports->pspa_alloc == ports->pspa_count) { - err = posix_spawn_growportactions_np(attr); - if (err) - return err; - } - - /* Add this action to next spot in array */ - action = &ports->pspa_actions[ports->pspa_count]; - action->port_type = PSPA_EXCEPTION; - action->mask = mask; - action->new_port = new_port; - action->behavior = behavior; - action->flavor = flavor; - - ports->pspa_count++; - return err; -} - -/* - * posix_spawnattr_setauditsessionport_np - * - * Description: Set the audit session port rights attribute in the spawned task. - * This is used to securely set the audit session information for - * the new task. - * - * Parameters: attr The spawn attributes object for the - * new process - * au_sessionport The audit session send port right - * - * Returns: 0 Success - */ -int -posix_spawnattr_setauditsessionport_np( - posix_spawnattr_t *attr, - mach_port_t au_sessionport) -{ - _posix_spawnattr_t psattr; - int err = 0; - _ps_port_action_t *action; - _posix_spawn_port_actions_t ports; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - ports = psattr->psa_ports; - /* Have any port actions been created yet? */ - if (ports == NULL) { - err = posix_spawn_createportactions_np(attr); - if (err) - return err; - ports = psattr->psa_ports; - } - - /* Is there enough room? */ - if (ports->pspa_alloc == ports->pspa_count) { - err = posix_spawn_growportactions_np(attr); - if (err) - return err; - } - - /* Add this action to next spot in array */ - action = &ports->pspa_actions[ports->pspa_count]; - action->port_type = PSPA_AU_SESSION; - action->new_port = au_sessionport; - - ports->pspa_count++; - return err; -} - - -/* - * posix_spawn_file_actions_init - * - * Description: Initialize a spawn file actions object attr with default values - * - * Parameters: file_actions The spawn file actions object to be - * initialized - * - * Returns: 0 Success - * ENOMEM Insufficient memory exists to - * initialize the spawn file actions - * object. - * - * Note: As an implementation detail, the externally visibily type - * posix_spawn_file_actions_t is defined to be a void *, and - * initialization involves allocation of a memory object. - * Subsequent changes to the spawn file actions may result in - * reallocation under the covers. - * - * Reinitialization of an already initialized spawn file actions - * object will result in memory being leaked. Because spawn - * file actions are not required to be used in conjunction with a - * static initializer, there is no way to distinguish a spawn - * file actions with stack garbage from one that's been - * initialized. This is arguably an API design error. - */ -int -posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions) -{ - _posix_spawn_file_actions_t *psactsp = (_posix_spawn_file_actions_t *)file_actions; - int err = 0; - - if ((*psactsp = (_posix_spawn_file_actions_t)malloc(PSF_ACTIONS_SIZE(PSF_ACTIONS_INIT_COUNT))) == NULL) { - err = ENOMEM; - } else { - (*psactsp)->psfa_act_alloc = PSF_ACTIONS_INIT_COUNT; - (*psactsp)->psfa_act_count = 0; - } - - return (err); -} - - -/* - * posix_spawn_file_actions_destroy - * - * Description: Destroy a spawn file actions object that was previously - * initialized via posix_spawn_file_actions_init() by freeing any - * memory associated with it and setting it to an invalid value. - * - * Parameters: attr The spawn file actions object to be - * destroyed. - * - * Returns: 0 Success - * - * Notes: The destroyed spawn file actions results in the void * pointer - * being set to NULL; subsequent use without reinitialization - * will result in explicit program failure (rather than merely - * "undefined behaviour"). - * - * NOTIMP: Allowed failures (checking NOT required): - * EINVAL The value specified by file_actions is invalid. - */ -int -posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions) -{ - _posix_spawn_file_actions_t psacts; - - if (file_actions == NULL || *file_actions == NULL) - return EINVAL; - - psacts = *(_posix_spawn_file_actions_t *)file_actions; - free(psacts); - *file_actions = NULL; - - return (0); -} - - -/* - * _posix_spawn_file_actions_grow - * - * Description: Grow the available list of file actions associated with the - * pointer to the structure provided; replace the contents of the - * pointer as a side effect. - * - * Parameters: psactsp Pointer to _posix_spawn_file_actions_t - * to grow - * - * Returns: 0 Success - * ENOMEM Insufficient memory for operation - * - * Notes: This code is common to all posix_spawn_file_actions_*() - * functions, since we use a naieve data structure implementation - * at present. Future optimization will likely change this. - */ -static int -_posix_spawn_file_actions_grow(_posix_spawn_file_actions_t *psactsp) -{ - int new_alloc = (*psactsp)->psfa_act_alloc * 2; - _posix_spawn_file_actions_t new_psacts; - - /* - * XXX may want to impose an administrative limit here; POSIX does - * XXX not provide for an administrative error return in this case, - * XXX so it's probably acceptable to just fail catastrophically - * XXX instead of implementing one. - */ - if ((new_psacts = (_posix_spawn_file_actions_t)realloc((*psactsp), PSF_ACTIONS_SIZE(new_alloc))) == NULL) { - return (ENOMEM); - } - new_psacts->psfa_act_alloc = new_alloc; - *psactsp = new_psacts; - - return (0); -} - - -/* - * posix_spawn_file_actions_addopen - * - * Description: Add an open action to the object referenced by 'file_actions' - * that will cause the file named by 'path' to be attempted to be - * opened with flags 'oflag' and mode 'mode', and, if successful, - * return as descriptor 'filedes' to the spawned process. - * - * Parameters: file_actions File action object to augment - * filedes fd that open is to use - * path path to file to open - * oflag open file flags - * mode open file mode - * - * Returns: 0 Success - * EBADF The value specified by fildes is - * negative or greater than or equal to - * {OPEN_MAX}. - * ENOMEM Insufficient memory exists to add to - * the spawn file actions object. - * - * NOTIMP: Allowed failures (checking NOT required): - * EINVAL The value specified by file_actions is invalid. - */ -int -posix_spawn_file_actions_addopen( - posix_spawn_file_actions_t * __restrict file_actions, - int filedes, const char * __restrict path, int oflag, - mode_t mode) -{ - _posix_spawn_file_actions_t *psactsp; - _psfa_action_t *psfileact; - - if (file_actions == NULL || *file_actions == NULL) - return EINVAL; - - psactsp = (_posix_spawn_file_actions_t *)file_actions; - /* Range check; required by POSIX */ - if (filedes < 0 || filedes >= OPEN_MAX) - return (EBADF); - - /* If we do not have enough slots, grow the structure */ - if ((*psactsp)->psfa_act_count == (*psactsp)->psfa_act_alloc) { - /* need to grow file actions structure */ - if (_posix_spawn_file_actions_grow(psactsp)) - return (ENOMEM); - } - - /* - * Allocate next available slot and fill it out - */ - psfileact = &(*psactsp)->psfa_act_acts[(*psactsp)->psfa_act_count++]; - - psfileact->psfaa_type = PSFA_OPEN; - psfileact->psfaa_filedes = filedes; - psfileact->psfaa_openargs.psfao_oflag = oflag; - psfileact->psfaa_openargs.psfao_mode = mode; - strlcpy(psfileact->psfaa_openargs.psfao_path, path, PATH_MAX); - - return (0); -} - - -/* - * posix_spawn_file_actions_addclose - * - * Description: Add a close action to the object referenced by 'file_actions' - * that will cause the file referenced by 'filedes' to be - * attempted to be closed in the spawned process. - * - * Parameters: file_actions File action object to augment - * filedes fd to close - * - * Returns: 0 Success - * EBADF The value specified by fildes is - * negative or greater than or equal to - * {OPEN_MAX}. - * ENOMEM Insufficient memory exists to add to - * the spawn file actions object. - * - * NOTIMP: Allowed failures (checking NOT required): - * EINVAL The value specified by file_actions is invalid. - */ -int -posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *file_actions, - int filedes) -{ - _posix_spawn_file_actions_t *psactsp; - _psfa_action_t *psfileact; - - if (file_actions == NULL || *file_actions == NULL) - return EINVAL; - - psactsp = (_posix_spawn_file_actions_t *)file_actions; - /* Range check; required by POSIX */ - if (filedes < 0 || filedes >= OPEN_MAX) - return (EBADF); - - /* If we do not have enough slots, grow the structure */ - if ((*psactsp)->psfa_act_count == (*psactsp)->psfa_act_alloc) { - /* need to grow file actions structure */ - if (_posix_spawn_file_actions_grow(psactsp)) - return (ENOMEM); - } - - /* - * Allocate next available slot and fill it out - */ - psfileact = &(*psactsp)->psfa_act_acts[(*psactsp)->psfa_act_count++]; - - psfileact->psfaa_type = PSFA_CLOSE; - psfileact->psfaa_filedes = filedes; - - return (0); -} - - -/* - * posix_spawn_file_actions_adddup2 - * - * Description: Add a dup2 action to the object referenced by 'file_actions' - * that will cause the file referenced by 'filedes' to be - * attempted to be dup2'ed to the descriptor 'newfiledes' in the - * spawned process. - * - * Parameters: file_actions File action object to augment - * filedes fd to dup2 - * newfiledes fd to dup2 it to - * - * Returns: 0 Success - * EBADF The value specified by either fildes - * or by newfiledes is negative or greater - * than or equal to {OPEN_MAX}. - * ENOMEM Insufficient memory exists to add to - * the spawn file actions object. - * - * NOTIMP: Allowed failures (checking NOT required): - * EINVAL The value specified by file_actions is invalid. - */ -int -posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions, - int filedes, int newfiledes) -{ - _posix_spawn_file_actions_t *psactsp; - _psfa_action_t *psfileact; - - if (file_actions == NULL || *file_actions == NULL) - return EINVAL; - - psactsp = (_posix_spawn_file_actions_t *)file_actions; - /* Range check; required by POSIX */ - if (filedes < 0 || filedes >= OPEN_MAX || - newfiledes < 0 || newfiledes >= OPEN_MAX) - return (EBADF); - - /* If we do not have enough slots, grow the structure */ - if ((*psactsp)->psfa_act_count == (*psactsp)->psfa_act_alloc) { - /* need to grow file actions structure */ - if (_posix_spawn_file_actions_grow(psactsp)) - return (ENOMEM); - } - - /* - * Allocate next available slot and fill it out - */ - psfileact = &(*psactsp)->psfa_act_acts[(*psactsp)->psfa_act_count++]; - - psfileact->psfaa_type = PSFA_DUP2; - psfileact->psfaa_filedes = filedes; - psfileact->psfaa_openargs.psfao_oflag = newfiledes; - - return (0); -} - -/* - * posix_spawn_file_actions_addinherit_np - * - * Description: Add the "inherit" action to the object referenced by - * 'file_actions' that will cause the file referenced by - * 'filedes' to continue to be available in the spawned - * process via the same descriptor. - * - * Inheritance is the normal default behaviour for - * file descriptors across exec and spawn; but if the - * POSIX_SPAWN_CLOEXEC_DEFAULT flag is set, the usual - * default is reversed for the purposes of the spawn - * invocation. Any pre-existing descriptors that - * need to be made available to the spawned process can - * be marked explicitly as 'inherit' via this interface. - * Otherwise they will be automatically closed. - * - * Note that any descriptors created via the other file - * actions interfaces are automatically marked as 'inherit'. - * - * Parameters: file_actions File action object to augment - * filedes fd to inherit. - * - * Returns: 0 Success - * EBADF The value specified by fildes is - * negative or greater than or equal to - * {OPEN_MAX}. - * ENOMEM Insufficient memory exists to add to - * the spawn file actions object. - * - * NOTIMP: Allowed failures (checking NOT required): - * EINVAL The value specified by file_actions is invalid. - */ -int -posix_spawn_file_actions_addinherit_np(posix_spawn_file_actions_t *file_actions, - int filedes) -{ - _posix_spawn_file_actions_t *psactsp; - _psfa_action_t *psfileact; - - if (file_actions == NULL || *file_actions == NULL) - return (EINVAL); - - psactsp = (_posix_spawn_file_actions_t *)file_actions; - /* Range check; required by POSIX */ - if (filedes < 0 || filedes >= OPEN_MAX) - return (EBADF); - -#if defined(POSIX_SPAWN_CLOEXEC_DEFAULT) // TODO: delete this check - /* If we do not have enough slots, grow the structure */ - if ((*psactsp)->psfa_act_count == (*psactsp)->psfa_act_alloc) { - /* need to grow file actions structure */ - if (_posix_spawn_file_actions_grow(psactsp)) - return (ENOMEM); - } - - /* - * Allocate next available slot and fill it out - */ - psfileact = &(*psactsp)->psfa_act_acts[(*psactsp)->psfa_act_count++]; - - psfileact->psfaa_type = PSFA_INHERIT; - psfileact->psfaa_filedes = filedes; -#endif - return (0); -} - -int -posix_spawnattr_setcpumonitor(posix_spawnattr_t * __restrict attr, - uint64_t percent, uint64_t interval) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL || percent == 0 || percent > 100) - return (EINVAL); - - psattr = *(_posix_spawnattr_t *)attr; - - psattr->psa_cpumonitor_percent = percent; - psattr->psa_cpumonitor_interval = interval; - - return (0); -} - -int -posix_spawnattr_getcpumonitor(posix_spawnattr_t * __restrict attr, - uint64_t *percent, uint64_t *interval) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return (EINVAL); - - psattr = *(_posix_spawnattr_t *)attr; - - *percent = psattr->psa_cpumonitor_percent; - *interval = psattr->psa_cpumonitor_interval; - - return (0); -} - -#if TARGET_OS_EMBEDDED -/* - * posix_spawnattr_setjetsam - * - * Description: Set jetsam attributes for the spawn attribute object - * referred to by 'attr'. - * - * Parameters: flags The flags value to set - * priority Relative jetsam priority - * high_water_mark Value in pages; resident page - * counts above this level can - * result in termination - * - * Returns: 0 Success - */ -int -posix_spawnattr_setjetsam(posix_spawnattr_t * __restrict attr, - short flags, int priority, int high_water_mark) -{ - _posix_spawnattr_t psattr; - - if (attr == NULL || *attr == NULL) - return EINVAL; - - psattr = *(_posix_spawnattr_t *)attr; - - psattr->psa_jetsam_flags = flags; - psattr->psa_priority = priority; - psattr->psa_high_water_mark = high_water_mark; - - return (0); -} -#endif /* * posix_spawnp @@ -1467,94 +178,3 @@ retry: err = posix_spawn(pid, bp, file_actions, attrp, argv, envp); done: return (err); } - - -/* - * posix_spawn - * - * Description: Create a new process from the process image corresponding to - * the supplied 'path' argument. - * - * Parameters: pid Pointer to pid_t to receive the - * PID of the spawned process, if - * successful and 'pid' != NULL - * path Path of image file to spawn - * file_actions spawn file actions object which - * describes file actions to be - * performed during the spawn - * attrp spawn attributes object which - * describes attributes to be - * applied during the spawn - * argv argument vector array; NULL - * terminated - * envp environment vector array; NULL - * terminated - * - * Returns: 0 Success - * !0 An errno value indicating the - * cause of the failure to spawn - * - * Notes: Unlike other system calls, the return value of this system - * call is expected to either be a 0 or an errno, rather than a - * 0 or a -1, with the 'errno' variable being set. - */ -extern int __posix_spawn(pid_t * __restrict, const char * __restrict, - struct _posix_spawn_args_desc *, - char *const argv[ __restrict], char *const envp[ __restrict]); - -int -posix_spawn(pid_t * __restrict pid, const char * __restrict path, - const posix_spawn_file_actions_t *file_actions, - const posix_spawnattr_t * __restrict attrp, - char *const argv[ __restrict], char *const envp[ __restrict]) -{ - int saveerrno = errno; - int ret; - /* - * Only do extra work if we have file actions or attributes to push - * down. We use a descriptor to push this information down, since we - * want to have size information, which will let us (1) preallocate a - * single chunk of memory for the copyin(), and (2) allow us to do a - * single copyin() per attributes or file actions as a monlithic block. - * - * Note: A future implementation may attempt to do the same - * thing for the argv/envp data, which could potentially - * result in a performance improvement due to increased - * kernel efficiency, even though it would mean copying - * the data in user space. - */ - if ((file_actions != NULL && (*file_actions != NULL) && (*(_posix_spawn_file_actions_t *)file_actions)->psfa_act_count > 0) || attrp != NULL) { - struct _posix_spawn_args_desc ad; - - memset(&ad, 0, sizeof(ad)); - if (attrp != NULL && *attrp != NULL) { - _posix_spawnattr_t psattr = *(_posix_spawnattr_t *)attrp; - ad.attr_size = sizeof(struct _posix_spawnattr); - ad.attrp = psattr; - - if (psattr->psa_ports != NULL) { - ad.port_actions = psattr->psa_ports; - ad.port_actions_size = PS_PORT_ACTIONS_SIZE( - ad.port_actions->pspa_count); - } - } - if (file_actions != NULL && *file_actions != NULL) { - _posix_spawn_file_actions_t psactsp = - *(_posix_spawn_file_actions_t *)file_actions; - - if (psactsp->psfa_act_count > 0) { - ad.file_actions_size = PSF_ACTIONS_SIZE(psactsp->psfa_act_count); - ad.file_actions = psactsp; - } - } - - ret = __posix_spawn(pid, path, &ad, argv, envp); - } else - ret = __posix_spawn(pid, path, NULL, argv, envp); - - if (ret < 0) - ret = errno; - errno = saveerrno; - return ret; -} - diff --git a/src/libc/sys/pthread_kill.2 b/src/libc/sys/pthread_kill.2 deleted file mode 100644 index 8c83b99b9..000000000 --- a/src/libc/sys/pthread_kill.2 +++ /dev/null @@ -1,81 +0,0 @@ -.\" Darwin -.\" -.\" Copyright (C) 2000 Jason Evans . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice(s), this list of conditions and the following disclaimer as -.\" the first lines of this file unmodified other than the possible -.\" addition of one or more copyright notices. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice(s), this list of conditions and the following disclaimer in -.\" the documentation and/or other materials provided with the -.\" distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY -.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE -.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_kill.3,v 1.8 2001/10/01 16:09:09 ru Exp $ -.Dd Feb 05, 2002 -.Dt PTHREAD_KILL 2 -.Os -.Sh NAME -.Nm pthread_kill -.Nd send a signal to a specified thread -.Sh SYNOPSIS -.In signal.h -.Ft int -.Fn pthread_kill "pthread_t thread" "int sig" -.Sh DESCRIPTION -The -.Fn pthread_kill -function sends a signal, specified by -.Fa sig , -to a thread, specified by -.Fa thread . -If -.Fa sig -is 0, error checking is performed, but no signal is actually sent. -.Sh RETURN VALUES -If successful, -.Fn pthread_kill -returns 0. -Otherwise, an error number is returned. -.Sh ERRORS -.Fn pthread_kill -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -.Fa sig -is an invalid or unsupported signal number. -.It Bq Er ESRCH -.Fa thread -is an invalid thread ID. -.El -.Sh LEGACY SYNOPSIS -.Fd #include -.Fd #include -.Pp -The include file -.In pthread.h -is necessary. -.Sh SEE ALSO -.Xr kill 2 , -.Xr pthread_self 3 , -.Xr raise 3 , -.Xr compat 5 -.Sh STANDARDS -.Fn pthread_kill -conforms to ISO/IEC 9945-1:1996 (``POSIX.1'') diff --git a/src/libc/sys/pthread_sigmask.2 b/src/libc/sys/pthread_sigmask.2 deleted file mode 100644 index 5680dd25a..000000000 --- a/src/libc/sys/pthread_sigmask.2 +++ /dev/null @@ -1,104 +0,0 @@ -.\" Copyright (C) 2000 Jason Evans . -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice(s), this list of conditions and the following disclaimer as -.\" the first lines of this file unmodified other than the possible -.\" addition of one or more copyright notices. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice(s), this list of conditions and the following disclaimer in -.\" the documentation and/or other materials provided with the -.\" distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY -.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE -.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD: src/lib/libc_r/man/pthread_sigmask.3,v 1.9 2001/10/01 16:09:09 ru Exp $ -.Dd April 27, 2000 -.Dt PTHREAD_SIGMASK 2 -.Os -.Sh NAME -.Nm pthread_sigmask -.Nd examine and/or change a thread's signal mask -.Sh SYNOPSIS -.In signal.h -.Ft int -.Fo pthread_sigmask -.Fa "int how" -.Fa "const sigset_t *restrict set" -.Fa "sigset_t *restrict oset" -.Fc -.Sh DESCRIPTION -The -.Fn pthread_sigmask -function examines and/or changes the calling thread's signal mask. -.Pp -If -.Fa set -is not -.Dv NULL , -it specifies a set of signals to be modified, and -.Fa how -specifies what to set the signal mask to: -.Bl -tag -width SIG_UNBLOCK -.It Dv SIG_BLOCK -Union of the current mask and -.Fa set . -.It Dv SIG_UNBLOCK -Intersection of the current mask and the complement of -.Fa set . -.It Dv SIG_SETMASK -.Fa set . -.El -.Pp -If -.Fa oset -is not NULL, the previous signal mask is stored in the location pointed to by -.Fa oset . -.Pp -.Dv SIGKILL -and -.Dv SIGSTOP -cannot be blocked, and will be silently ignored if included in the signal mask. -.Sh RETURN VALUES -If successful, -.Fn pthread_sigmask -returns 0. -Otherwise, an error is returned. -.Sh ERRORS -.Fn pthread_sigmask -will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -.Fa how -is not one of the defined values. -.El -.Sh LEGACY SYNOPSIS -.Fd #include -.Fd #include -.Pp -The include file -.In pthread.h -is necessary. -.Sh SEE ALSO -.Xr sigaction 2 , -.Xr sigpending 2 , -.Xr sigprocmask 2 , -.Xr sigsuspend 2 , -.Xr sigsetops 3 , -.Xr compat 5 -.Sh STANDARDS -.Fn pthread_sigmask -conforms to ISO/IEC 9945-1:1996 (``POSIX.1'') diff --git a/src/libc/sys/sigaction.c b/src/libc/sys/sigaction.c index 2e9652cdf..72d181151 100644 --- a/src/libc/sys/sigaction.c +++ b/src/libc/sys/sigaction.c @@ -26,6 +26,9 @@ * @(#)sigaction.c 1.0 */ +#include +#include +#include #include #include #include @@ -44,6 +47,7 @@ sigaction (int sig, const struct sigaction * __restrict nsv, struct sigaction * extern void _sigtramp(); struct __sigaction sa; struct __sigaction *sap; + int ret; if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) { errno = EINVAL; @@ -57,7 +61,17 @@ sigaction (int sig, const struct sigaction * __restrict nsv, struct sigaction * sa.sa_flags = nsv->sa_flags; sap = &sa; } - return __sigaction(sig, sap, osv); + ret = __sigaction(sig, sap, osv); +#ifdef FEATURE_SIGNAL_RESTRICTION + // Note: The "sig != 0" here is to force the compiler to maintain that "sig" + // is live, and in a register, after __sigaction so it is visible in the + // crashing register state. + if (ret == -1 && errno == ENOTSUP && sig != 0) { + CRSetCrashLogMessage("sigaction on fatal signals is not supported"); + __builtin_trap(); + } +#endif + return ret; } // XXX diff --git a/src/libc/sys/sigcatch.c b/src/libc/sys/sigcatch.c deleted file mode 100644 index e4ce2bce0..000000000 --- a/src/libc/sys/sigcatch.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 1999, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * This file contains global data and the size of the global data can NOT - * change or otherwise it would make the shared library incompatable. This - * data has been padded so new signals can be added. Also see gen/siglist.c - */ - -#include "sigcatch.h" - -/* - * Actually declare the global data. - */ -sigcatch_t sigcatch[PADDING] = { (sigcatch_t)0 }; - - diff --git a/src/libc/sys/sigcatch.h b/src/libc/sys/sigcatch.h deleted file mode 100644 index 86f1e60b5..000000000 --- a/src/libc/sys/sigcatch.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. - * - * File: libc/m98k/sigcatch.h - * - * Header file for sigtramp data structures. - */ - -#include - -/* - * Constants - */ -#define PADDING 50 - -/* - * Type definitions. - */ -typedef void (*sigcatch_t)(int, int, struct sigcontext *); - -/* - * Global data. - */ -extern sigcatch_t sigcatch[PADDING]; diff --git a/src/libc/sys/sigtramp.c b/src/libc/sys/sigtramp.c deleted file mode 100644 index 74f49633b..000000000 --- a/src/libc/sys/sigtramp.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 1999, 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -#import "sigcatch.h" -#import -#import -#import -#import -#import -#import - -extern int __sigreturn(ucontext_t *, int); - -/* - * sigvec registers _sigtramp as the handler for any signal requiring - * user-mode intervention. All _sigtramp does is find the real handler, - * calls it, then sigreturn's. - * - * Note that the kernel saves/restores all of our register state. - */ - -/* On i386, i386/sys/_sigtramp.s defines this. */ -#if defined(__DYNAMIC__) && ! defined(__i386__) -int __in_sigtramp = 0; -#endif - -/* These defn should match the kernel one */ -#define UC_TRAD 1 -#define UC_FLAVOR 30 -#if defined(__ppc__) || defined(__ppc64__) -#define UC_TRAD64 20 -#define UC_TRAD64_VEC 25 -#define UC_FLAVOR_VEC 35 -#define UC_FLAVOR64 40 -#define UC_FLAVOR64_VEC 45 -#define UC_DUAL 50 -#define UC_DUAL_VEC 55 - - /* The following are valid mcontext sizes */ -#define UC_FLAVOR_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int)) - -#define UC_FLAVOR_VEC_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int)) - -#define UC_FLAVOR64_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int)) - -#define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int)) -#endif - -#define UC_SET_ALT_STACK 0x40000000 -#define UC_RESET_ALT_STACK 0x80000000 - -#if defined(__ppc__) -/* This routine will be replaced by an assembly soon */ -static int -restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) -{ - if (mctx->ss.srr0 != (unsigned int)mctx64->ss.srr0) - return(0); - if (mctx->ss.srr1 != (unsigned int)mctx64->ss.srr1) - return(0); - if (mctx->ss.r0 != (unsigned int)mctx64->ss.r0) - return(0); - if (mctx->ss.r1 != (unsigned int)mctx64->ss.r1) - return(0); - if (mctx->ss.r2 != (unsigned int)mctx64->ss.r2) - return(0); - if (mctx->ss.r3 != (unsigned int)mctx64->ss.r3) - return(0); - if (mctx->ss.r4 != (unsigned int)mctx64->ss.r4) - return(0); - if (mctx->ss.r5 != (unsigned int)mctx64->ss.r5) - return(0); - if (mctx->ss.r6 != (unsigned int)mctx64->ss.r6) - return(0); - if (mctx->ss.r7 != (unsigned int)mctx64->ss.r7) - return(0); - if (mctx->ss.r8 != (unsigned int)mctx64->ss.r8) - return(0); - if (mctx->ss.r9 != (unsigned int)mctx64->ss.r9) - return(0); - if (mctx->ss.r10 != (unsigned int)mctx64->ss.r10) - return(0); - if (mctx->ss.r11 != (unsigned int)mctx64->ss.r11) - return(0); - if (mctx->ss.r12 != (unsigned int)mctx64->ss.r12) - return(0); - if (mctx->ss.r13 != (unsigned int)mctx64->ss.r13) - return(0); - if (mctx->ss.r14 != (unsigned int)mctx64->ss.r14) - return(0); - if (mctx->ss.r15 != (unsigned int)mctx64->ss.r15) - return(0); - if (mctx->ss.r16 != (unsigned int)mctx64->ss.r16) - return(0); - if (mctx->ss.r17 != (unsigned int)mctx64->ss.r17) - return(0); - if (mctx->ss.r18 != (unsigned int)mctx64->ss.r18) - return(0); - if (mctx->ss.r19 != (unsigned int)mctx64->ss.r19) - return(0); - if (mctx->ss.r20 != (unsigned int)mctx64->ss.r20) - return(0); - if (mctx->ss.r21 != (unsigned int)mctx64->ss.r21) - return(0); - if (mctx->ss.r22 != (unsigned int)mctx64->ss.r22) - return(0); - if (mctx->ss.r23 != (unsigned int)mctx64->ss.r23) - return(0); - if (mctx->ss.r24 != (unsigned int)mctx64->ss.r24) - return(0); - if (mctx->ss.r25 != (unsigned int)mctx64->ss.r25) - return(0); - if (mctx->ss.r26 != (unsigned int)mctx64->ss.r26) - return(0); - if (mctx->ss.r27 != (unsigned int)mctx64->ss.r27) - return(0); - if (mctx->ss.r28 != (unsigned int)mctx64->ss.r28) - return(0); - if (mctx->ss.r29 != (unsigned int)mctx64->ss.r29) - return(0); - if (mctx->ss.r30 != (unsigned int)mctx64->ss.r30) - return(0); - if (mctx->ss.r31 != (unsigned int)mctx64->ss.r31) - return(0); - - if (mctx->ss.cr != mctx64->ss.cr) - return(0); - if (mctx->ss.xer != (unsigned int)mctx64->ss.xer) - return(0); - if (mctx->ss.lr != (unsigned int)mctx64->ss.lr) - return(0); - if (mctx->ss.ctr != (unsigned int)mctx64->ss.ctr) - return(0); - - if (bcmp(&mctx->fs, &mctx64->fs, (PPC_FLOAT_STATE_COUNT * sizeof(int)))) - return(0); - if ((sigstyle == UC_DUAL_VEC) && bcmp(&mctx->vs, &mctx64->vs, (PPC_VECTOR_STATE_COUNT * sizeof(int)))) - return(0); - - return(1); - -} - -/* This routine is called from ppc/sys/_sigtramp.s on return from - sa_handler. */ - -void -__finish_sigtramp( - ucontext_t *uctx, - int sigstyle -) { - int ctxstyle = UC_FLAVOR; - mcontext_t mctx; - mcontext64_t mctx64; - - if ((sigstyle == UC_DUAL) || (sigstyle == UC_DUAL_VEC)) { - mctx = uctx->uc_mcontext; - mctx64 = (mcontext64_t)((char *)(uctx->uc_mcontext) + sizeof(struct mcontext)); - /* restore 64bit state ? */ - if (restore64_state(mctx, mctx64, sigstyle)) { - uctx->uc_mcontext = (void *)mctx64; - if (sigstyle == UC_DUAL) { - uctx->uc_mcsize = UC_FLAVOR64_SIZE; - ctxstyle = UC_FLAVOR64; - } else { - uctx->uc_mcsize = UC_FLAVOR64_VEC_SIZE; - ctxstyle = UC_FLAVOR64_VEC; - } - } else { - if (sigstyle == UC_DUAL) - ctxstyle = UC_FLAVOR; - else - ctxstyle = UC_FLAVOR_VEC; - } - } else - ctxstyle = sigstyle; - -#if defined(__DYNAMIC__) - __in_sigtramp--; -#endif - - __sigreturn (uctx, ctxstyle); -} - -#endif /* ppc */ - -/* - * Reset the kernel's idea of the use of an alternate stack; this is used by - * both longjmp() and siglongjmp(). Nothing other than this reset is needed, - * since restoring the registers and other operations that would normally be - * done by sigreturn() are handled in user space, so we do not pass a user - * context (in PPC, a user context is not the same as a jmpbuf mcontext, due - * to having more than one set of registers, etc., for the various 32/64 etc. - * contexts).. - */ -void -_sigunaltstack(int set) -{ - /* sigreturn(uctx, ctxstyle); */ - /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */ - __sigreturn (NULL, (set == SS_ONSTACK) ? UC_SET_ALT_STACK : UC_RESET_ALT_STACK); -} - -/* On these architectures, _sigtramp is implemented in assembly to - ensure it matches its DWARF unwind information. */ -#if ! defined (__ppc__) && ! defined (__ppc64__) && ! defined (__i386__) \ - && ! defined (__x86_64__) - -void -_sigtramp( - union __sigaction_u __sigaction_u, - int sigstyle, - int sig, - siginfo_t *sinfo, - ucontext_t *uctx -) { - int ctxstyle = UC_FLAVOR; - -#if defined(__DYNAMIC__) - __in_sigtramp++; -#endif - - if (sigstyle == UC_TRAD) - sa_handler(sig); - else { - sa_sigaction(sig, sinfo, uctx); - } - -#if defined(__DYNAMIC__) - __in_sigtramp--; -#endif - /* sigreturn(uctx, ctxstyle); */ - /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */ - __sigreturn (uctx, ctxstyle); -} - -#endif /* not ppc nor ppc64 nor i386 nor x86_64 */ diff --git a/src/libc/sys/slot_name.c b/src/libc/sys/slot_name.c deleted file mode 100644 index a7804306b..000000000 --- a/src/libc/sys/slot_name.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* - * File: slot_name.c - * Author: Avadis Tevanian, Jr. - * - * Copyright (C) 1987, Avadis Tevanian, Jr. - * - * Convert machine slot values to human readable strings. - * - * HISTORY - * 26-Jan-88 Mary Thompson (mrt) at Carnegie Mellon - * added case for CUP_SUBTYPE_RT_APC - * - * 28-Feb-87 Avadis Tevanian (avie) at Carnegie-Mellon University - * Created. - * - */ - -#include -#include - -/* - * Convert the specified cpu_type/cpu_subtype pair to their - * human readable form. - */ -void slot_name(cpu_type, cpu_subtype, cpu_name, cpu_subname) - cpu_type_t cpu_type; - cpu_subtype_t cpu_subtype; - char **cpu_name, **cpu_subname; -{ - register char *name = "Unknown CPU"; - register char *subname = ""; - const NXArchInfo *ai = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype); - if (ai != NULL) { - name = (char *)ai->name; - subname = (char *)ai->description; - } - *cpu_name = name; - *cpu_subname = subname; -} diff --git a/src/libc/sys/spinlock.3 b/src/libc/sys/spinlock.3 deleted file mode 100644 index 18ba5a335..000000000 --- a/src/libc/sys/spinlock.3 +++ /dev/null @@ -1,45 +0,0 @@ -.Dd May 26, 2004 -.Dt SPINLOCK 3 -.Os Darwin -.Sh NAME -.Nm OSSpinLockTry , -.Nm OSSpinLockLock , -.Nm OSSpinLockUnlock -.Nd atomic spin lock synchronization primitives -.Sh LIBRARY -.Lb libc -.Sh SYNOPSIS -.In libkern/OSAtomic.h -.Ft bool -.Fn OSSpinLockTry "OSSpinLock *lock" -.Ft void -.Fn OSSpinLockLock "OSSpinLock *lock" -.Ft void -.Fn OSSpinLockUnlock "OSSpinLock *lock" -.Sh DESCRIPTION -Spin locks are a simple, fast, thread-safe synchronization primitive that is -suitable in situations where contention is expected to be low. The spinlock -operations use memory barriers to synchronize access to shared memory protected -by the lock. Preemption is possible while the lock is held. -.Pp -.Ft OSSpinLock -is an integer type. The convention is that unlocked is zero, and locked is nonzero. -Locks must be naturally aligned and cannot be in cache-inhibited memory. -.Pp -.Fn OSSpinLockLock -will spin if the lock is already held, but employs various strategies to back off, -making it immune to most priority-inversion livelocks. But because it can spin, it -may be inefficient in some situations. -.Pp -.Fn OSSpinLockTry -immediately returns false if the lock was held, true if it took the lock. -It does not spin. -.Pp -.Fn OSSpinLockUnlock -unconditionally unlocks the lock by zeroing it. -.Sh RETURN VALUES -.Fn OSSpinLockTry -returns true if it took the lock, false if the lock was already held. -.Sh SEE ALSO -.Xr atomic 3 , -.Xr barrier 3 diff --git a/src/libc/threads/CMakeLists.txt b/src/libc/threads/CMakeLists.txt deleted file mode 100644 index cea697077..000000000 --- a/src/libc/threads/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -project(libc-threads) - -cmake_minimum_required(VERSION 2.4.0) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -include ${CMAKE_CURRENT_SOURCE_DIR}/../fbsdcompat/_fbsd_compat_.h") - -set(threads_sources - cprocs.c - cthreads.c - mig_support.c -) - -add_library(libc-threads OBJECT ${threads_sources}) - -add_library(libc-threads_dyld OBJECT mig_support.c) -SET_TARGET_PROPERTIES(libc-threads_dyld PROPERTIES COMPILE_FLAGS "-UBUILDING_VARIANT -DVARIANT_DYLD -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN") - diff --git a/src/libc/threads/cprocs.c b/src/libc/threads/cprocs.c deleted file mode 100644 index ffcad5873..000000000 --- a/src/libc/threads/cprocs.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 1999, 2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Mach Operating System - * Copyright (c) 1989 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ - -/* - * HISTORY - * 22-July-93 Blaine Garst - * fixed kernel cache set up of cproc info - * - * 05-April-90 Morris Meyer (mmeyer) at NeXT - * Fixed bug in cproc_fork_child() where the first cproc would - * try doing a msg_rpc() with an invalid reply port. - * - */ - -/* - * cprocs.c - by Eric Cooper - * - * Implementation of cprocs (lightweight processes) - * and primitive synchronization operations. - */ -#include "pthread_internals.h" -#include -#include "cthreads.h" -#include "cthread_internals.h" -#include - -/* - * C Threads imports: - */ -extern void stack_init(); -extern void alloc_stack(), _dealloc_stack(); - -/* - * Mach imports: - */ -extern mach_port_t mach_thread_self(); -extern boolean_t swtch_pri(); - -#ifdef CTHREADS_DEBUG -private void -print_cproc(p) - cproc_t p; -{ - char *s; - - switch (p->state) { - case CPROC_RUNNING: - s = ""; - break; - case CPROC_SPINNING: - s = "+"; - break; - case CPROC_BLOCKED: - s = "*"; - break; - default: - ASSERT(SHOULDNT_HAPPEN); - } - printf(" %x(%s)%s", - p->id, - cthread_name(p->incarnation), s); -} - -private void -print_cproc_queue(name, queue) - const char * name; - cthread_queue_t queue; -{ - printf("[%s] %s:", cthread_name(cthread_self()), name); - cthread_queue_map(queue, cproc_t, print_cproc); - printf("\n"); -} -#endif /* CTHREADS_DEBUG */ - -#ifdef CTHREADS_DEBUG -private cproc_t cprocs = NO_CPROC; /* linked list of cprocs */ - -private void -print_all_cprocs() -{ - cproc_t p; - - printf("[%s] cprocs:", cthread_name(cthread_self())); - for (p = cprocs; p != NO_CPROC; p = p->link) - print_cproc(p); - printf("\n"); -} -#endif /* CTHREADS_DEBUG */ - -/* - * Routines for supporting fork() of multi-threaded programs. - */ - -void -_cproc_fork_child() -/* - * Called in the child after a fork(). Resets cproc data structures to - * coincide with the reality that we now have a single cproc and cthread. - */ -{ - pthread_t pself; - - pself = pthread_self(); - pself->reply_port = MACH_PORT_NULL; -} - -/* - * Support for a per-thread UNIX errno. - */ - -#undef errno -extern int errno; -extern int *__error(void); -extern int __pthread_canceled(int); - -void -cthread_set_errno_self(int error, int nocancel) -{ - int *ep = __error(); - extern int __unix_conforming; - pthread_t self = NULL; - int check_cancel = __unix_conforming && !nocancel; - - if (check_cancel && ((error & 0xff) == EINTR) && (__pthread_canceled(0) == 0)) { - self = pthread_self(); - if (self != NULL) - self->cancel_error = error; - pthread_exit(PTHREAD_CANCELED); - } - - if (ep != &errno) { - *ep = error; - } - - errno = error; -} - diff --git a/src/libc/threads/cthread_internals.h b/src/libc/threads/cthread_internals.h deleted file mode 100644 index 7bc550a5c..000000000 --- a/src/libc/threads/cthread_internals.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Mach Operating System - * Copyright (c) 1989 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ - -/* - * HISTORY - * 08-Mar-90 Avadis Tevanian, Jr. (avie) at NeXT - * Added errno field to cproc structure. - * - */ - -/* - * cthread_internals.h - by Eric Cooper - * - * Private definitions for the C Threads implementation. - * - * The cproc structure is used for different implementations - * of the basic schedulable units that execute cthreads. - * - * MTHREAD MACH threads; single address space, - * kernel-mode preemptive scheduling - */ -#include -#include -#include - -/* - * Low-level thread implementation. - * This structure must agree with struct ur_cthread in cthreads.h - */ -typedef struct cproc { - struct cproc *next; /* for lock, condition, and ready queues */ - struct cproc *incarnation; /* for cthread_self() */ - int state; - mach_port_t reply_port; /* for mig_get_reply_port() */ - - mach_port_t wait_port; - - int id; - struct cproc *link; /* so all cprocs can be found - after a fork() */ - int flags; - - unsigned int stack_base; - unsigned int stack_size; - int error; - -} *cproc_t; - -#define NO_CPROC ((cproc_t) 0) -#define cproc_self() ((cproc_t) ur_cthread_self()) -extern void cthread_set_self(cproc_t p); - -/* - * Possible cproc states. - */ -#define CPROC_RUNNING 0 -#define CPROC_SPINNING 1 -#define CPROC_BLOCKED 2 - -/* - * The cproc flag bits. - */ -#define CPROC_INITIAL_STACK 0x1 -#define CPROC_NOCACHE_THREAD /* Don't try to cache this cthread on exit */ - -/* - * C Threads imports: - */ -#ifdef __STRICT_BSD__ -extern char *malloc(); -#endif /* __STRICT_BSD__ */ - -/* - * Mach imports: - */ -extern void mach_error(); - -/* - * C library imports: - */ -#ifdef __STRICT_BSD__ -extern exit(); -#else -#include -#endif /* __STRICT_BSD__ */ - -/* - * Macro for MACH kernel calls. - */ -#ifndef MACH_CALL -#define MACH_CALL(expr, ret) { \ - if (((ret) = (expr)) != KERN_SUCCESS) { \ - mach_error(#expr, (ret)); \ - assert(0); \ - } \ -} -#endif - -/* - * Debugging support. - */ -#ifdef CTHREADS_DEBUG - -#define private -#define TRACE(x) if (cthread_debug) x ; else -extern int cthread_debug; - -/* - * C library imports: - */ -#include -#include -#else /* CTHREADS_DEBUG */ - -#define private static -#define TRACE(x) - -#endif /* DEBUG */ diff --git a/src/libc/threads/cthreads.c b/src/libc/threads/cthreads.c deleted file mode 100644 index 2b301ab0c..000000000 --- a/src/libc/threads/cthreads.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * cthreads.c - by Eric Cooper - * - * Implementation of cthread_fork, cthread_join, cthread_exit, etc. - * HISTORY - * 22-July-93 Blaine Garst - * fixed association of read_thread info - * fixed kernel cache set up of cproc info - * - */ -#include "pthread_internals.h" -#include -#include -#include "cthreads.h" -#include "cthread_internals.h" -/* - * C Threads imports: - */ -extern void cproc_init(); -extern thread_port_t cproc_create(); -extern void mig_init(); -extern void _pthread_set_self(pthread_t); - -extern void pthread_workqueue_atfork_prepare(void); -extern void pthread_workqueue_atfork_parent(void); -extern void pthread_workqueue_atfork_child(void); -/* - * Mach imports: - */ -extern void mig_fork_child(); - -/* - * C library imports: - */ -extern int _setjmp(jmp_buf env); -extern void _longjmp(jmp_buf env, int val); - -/* - * Thread status bits. - */ -#define T_MAIN 0x1 -#define T_RETURNED 0x2 -#define T_DETACHED 0x4 - -#ifdef CTHREADS_DEBUG -int cthread_debug = FALSE; -#endif /* CTHREADS_DEBUG */ - -/* - * Routines for supporting fork() of multi-threaded programs. - */ - - -extern void _malloc_fork_prepare(), _malloc_fork_parent(); -extern void _malloc_fork_child(); -extern void fork_mach_init(); -extern void _cproc_fork_child(), _stack_fork_child(); -extern void _asl_fork_child(void); -extern void _pthread_fork_child(pthread_t); -extern void _pthread_fork_child_postinit(); -extern void _notify_fork_child(void); - -static pthread_t psaved_self = 0; -static pthread_lock_t psaved_self_global_lock = LOCK_INITIALIZER; -static pthread_lock_t pthread_atfork_lock = LOCK_INITIALIZER; -struct pthread_atfork_entry { - TAILQ_ENTRY(pthread_atfork_entry) qentry; - void (*prepare)(void); - void (*parent)(void); - void (*child)(void); -}; -static TAILQ_HEAD(pthread_atfork_queue_head, pthread_atfork_entry) pthread_atfork_queue = TAILQ_HEAD_INITIALIZER(pthread_atfork_queue); - -int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)) -{ - struct pthread_atfork_entry *e; - - e = malloc(sizeof(struct pthread_atfork_entry)); - if (e == NULL) - return (ENOMEM); - - e->prepare = prepare; - e->parent = parent; - e->child = child; - - _spin_lock(&pthread_atfork_lock); - TAILQ_INSERT_TAIL(&pthread_atfork_queue, e, qentry); - _spin_unlock(&pthread_atfork_lock); - - return 0; -} - -void _cthread_fork_prepare() -/* - * Prepare cthreads library to fork() a multi-threaded program. All cthread - * library critical section locks are acquired before a fork() and released - * afterwards to insure no cthread data structure is left in an inconsistent - * state in the child, which comes up with only the forking thread running. - */ -{ - struct pthread_atfork_entry *e; - - _spin_lock(&pthread_atfork_lock); -#ifdef TAILQ_FOREACH_REVERSE_LEGACY_ORDER - TAILQ_FOREACH_REVERSE(e, &pthread_atfork_queue, qentry, pthread_atfork_queue_head) -#else /* !TAILQ_FOREACH_REVERSE_LEGACY_ORDER */ - TAILQ_FOREACH_REVERSE(e, &pthread_atfork_queue, pthread_atfork_queue_head, qentry) -#endif /* TAILQ_FOREACH_REVERSE_LEGACY_ORDER */ - { - if (e->prepare != NULL) - e->prepare(); - } - - _spin_lock(&psaved_self_global_lock); - psaved_self = pthread_self(); - _spin_lock(&psaved_self->lock); - _malloc_fork_prepare(); - - pthread_workqueue_atfork_prepare(); -} - -void _cthread_fork_parent() -/* - * Called in the parent process after a fork syscall. - * Releases locks acquired by cthread_fork_prepare(). - */ -{ - struct pthread_atfork_entry *e; - - _malloc_fork_parent(); - _spin_unlock(&psaved_self->lock); - _spin_unlock(&psaved_self_global_lock); - - TAILQ_FOREACH(e, &pthread_atfork_queue, qentry) { - if (e->parent != NULL) - e->parent(); - } - _spin_unlock(&pthread_atfork_lock); - - pthread_workqueue_atfork_parent(); -} - -void _cthread_fork_child() -/* - * Called in the child process after a fork syscall. Releases locks acquired - * by cthread_fork_prepare(). Deallocates cthread data structures which - * described other threads in our parent. Makes this thread the main thread. - */ -{ - pthread_t p = psaved_self; - - _pthread_set_self(p); - _spin_unlock(&psaved_self_global_lock); - mig_fork_child(); - _malloc_fork_child(); - p->kernel_thread = mach_thread_self(); - p->reply_port = mach_reply_port(); - p->__cleanup_stack = NULL; - p->death = MACH_PORT_NULL; - p->joiner = NULL; - p->detached |= _PTHREAD_CREATE_PARENT; - _spin_unlock(&p->lock); - - _pthread_fork_child(p); -} - -void _cthread_fork_child_postinit() -{ - struct pthread_atfork_entry *e; - - __is_threaded = 0; - - _pthread_fork_child_postinit(); - mig_init(1); /* enable multi-threaded mig interfaces */ - - pthread_workqueue_atfork_child(); - - TAILQ_FOREACH(e, &pthread_atfork_queue, qentry) { - if (e->child != NULL) - e->child(); - } - LOCK_INIT(pthread_atfork_lock); -} diff --git a/src/libc/threads/cthreads.h b/src/libc/threads/cthreads.h deleted file mode 100644 index c4fa284da..000000000 --- a/src/libc/threads/cthreads.h +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Cthreads. - */ - -#ifndef _CTHREADS_ -#define _CTHREADS_ 1 - -#if defined(__cplusplus) -#define __DECLBEGIN extern "C" { -#define __DECLEND } -#else -#define __DECLBEGIN -#define __DECLEND -#endif - -typedef void *any_t; - -/* - * Spin locks. - */ -__DECLBEGIN -extern void spin_unlock(int *p); -extern void spin_lock(int *p); -__DECLEND - -#include -#include - -#ifndef MACRO_BEGIN - -#define NEVER FALSE - -#define MACRO_BEGIN do { -#define MACRO_END } while (NEVER) - -#endif /* MACRO_BEGIN */ - -/* - * C Threads package initialization. - */ -__DECLBEGIN -extern void cthread_init(); -__DECLEND - -#include - -/* - * Queues. - */ -typedef struct cthread_queue { - struct cthread_queue_item *head; - struct cthread_queue_item *tail; -} *cthread_queue_t; - -typedef struct cthread_queue_item { - struct cthread_queue_item *next; -} *cthread_queue_item_t; - -#define NO_QUEUE_ITEM ((cthread_queue_item_t) 0) - -#define QUEUE_INITIALIZER { NO_QUEUE_ITEM, NO_QUEUE_ITEM } - -#define cthread_queue_alloc() ((cthread_queue_t) calloc(1, sizeof(struct cthread_queue))) -#define cthread_queue_init(q) ((q)->head = (q)->tail = 0) -#define cthread_queue_free(q) free((any_t) (q)) - -#define cthread_queue_enq(q, x) \ - MACRO_BEGIN \ - (x)->next = 0; \ - if ((q)->tail == 0) \ - (q)->head = (cthread_queue_item_t) (x); \ - else \ - (q)->tail->next = (cthread_queue_item_t) (x); \ - (q)->tail = (cthread_queue_item_t) (x); \ - MACRO_END - -#define cthread_queue_preq(q, x) \ - MACRO_BEGIN \ - if ((q)->tail == 0) \ - (q)->tail = (cthread_queue_item_t) (x); \ - ((cthread_queue_item_t) (x))->next = (q)->head; \ - (q)->head = (cthread_queue_item_t) (x); \ - MACRO_END - -#define cthread_queue_head(q, t) ((t) ((q)->head)) - -#define cthread_queue_deq(q, t, x) \ - MACRO_BEGIN \ - if (((x) = (t) ((q)->head)) != 0 && \ - ((q)->head = (cthread_queue_item_t) ((x)->next)) == 0) \ - (q)->tail = 0; \ - MACRO_END - -#define cthread_queue_map(q, t, f) \ - MACRO_BEGIN \ - register cthread_queue_item_t x, next; \ - for (x = (cthread_queue_item_t) ((q)->head); x != 0; x = next) { \ - next = x->next; \ - (*(f))((t) x); \ - } \ - MACRO_END - - -/* - * Mutex objects. - */ -typedef struct mutex { - int lock; - char *name; -} *mutex_t; - -#define MUTEX_INITIALIZER { 0, 0 } - -#define mutex_alloc() ((mutex_t) calloc(1, sizeof(struct mutex))) -#define mutex_init(m) ((m)->lock = 0) -#define mutex_set_name(m, x) ((m)->name = (x)) -#define mutex_name(m) ((m)->name != 0 ? (m)->name : "?") -#define mutex_clear(m) /* nop */ -#define mutex_free(m) free((any_t) (m)) - -#define mutex_lock(m) \ - MACRO_BEGIN \ - if (! mutex_try_lock(m)) mutex_wait_lock(m); \ - MACRO_END - -__DECLBEGIN -extern int mutex_try_lock(mutex_t m); /* nonblocking */ -extern void mutex_wait_lock(mutex_t m); /* blocking */ -extern void mutex_unlock(mutex_t m); -__DECLEND - -/* - * Condition variables. - */ -typedef struct condition { - int lock; - struct cthread_queue queue; - char *name; -} *condition_t; - -#define CONDITION_INITIALIZER { 0, QUEUE_INITIALIZER, 0 } - -#define condition_alloc() ((condition_t) calloc(1, sizeof(struct condition))) -#define condition_init(c) MACRO_BEGIN (c)->lock = 0; cthread_queue_init(&(c)->queue); MACRO_END -#define condition_set_name(c, x) ((c)->name = (x)) -#define condition_name(c) ((c)->name != 0 ? (c)->name : "?") -#define condition_clear(c) MACRO_BEGIN condition_broadcast(c); spin_lock(&(c)->lock); MACRO_END -#define condition_free(c) MACRO_BEGIN condition_clear(c); free((any_t) (c)); MACRO_END - -#define condition_signal(c) \ - MACRO_BEGIN \ - if ((c)->queue.head) cond_signal(c); \ - MACRO_END - -#define condition_broadcast(c) \ - MACRO_BEGIN \ - if ((c)->queue.head) cond_broadcast(c); \ - MACRO_END - -__DECLBEGIN -extern void cond_signal(condition_t c); -extern void cond_broadcast(condition_t c); -extern void condition_wait(condition_t c, mutex_t m); -__DECLEND - -/* - * Threads. - */ - -typedef any_t (*cthread_fn_t)(any_t arg); - -#import - -typedef struct cthread { - struct cthread *next; - thread_port_t real_thread; - struct mutex lock; - struct condition done; - int state; -#if defined(__cplusplus) - jmp_buf catchBuf; -#else - jmp_buf catch; -#endif - cthread_fn_t func; - any_t arg; - any_t result; - const char *name; - any_t data; -} *cthread_t; - -#define NO_CTHREAD ((cthread_t) 0) - -__DECLBEGIN -extern cthread_t cthread_fork(cthread_fn_t func, any_t arg); -extern void cthread_detach(cthread_t t); -extern any_t cthread_join(cthread_t t); -extern void cthread_yield(void); -extern void cthread_exit(any_t result); -extern kern_return_t cthread_priority( - cthread_t t, - int priority, - boolean_t set_max); -extern kern_return_t cthread_max_priority( - cthread_t t, - mach_port_t pset, - int max_priority); -extern kern_return_t cthread_abort(cthread_t t); -__DECLEND - -/* - * This structure must agree with struct cproc in cthread_internals.h - */ -typedef struct ur_cthread { - struct ur_cthread *next; - cthread_t incarnation; -} *ur_cthread_t; - -__DECLBEGIN -extern int cthread_sp(void); - -extern int cthread_stack_mask; - -extern ur_cthread_t ur_cthread_self(void); -#define cthread_thread(c) (c->real_thread) -extern void cthread_set_errno_self(int e, int nocancel); -extern int cthread_errno(void); -#define cthread_assoc(id, t) (((ur_cthread_t) (id))->incarnation = (t)) -#define cthread_self() (ur_cthread_self()->incarnation) - -extern void cthread_set_name(cthread_t t, const char *name); -extern const char *cthread_name(cthread_t t); -extern int cthread_count(void); -extern void cthread_set_limit(int n); -extern int cthread_limit(void); -__DECLEND - -#define cthread_set_data(t, x) ((t)->data = (x)) -#define cthread_data(t) ((t)->data) - -/* - * Spin locks. - */ -#define spin_unlock(p) (*(p) = 0) - -/* - * Mutex locks. - */ -#define mutex_unlock(m) ((m)->lock = 0) - - -/* - * Debugging support. - */ -#ifdef CTHREADS_DEBUG - -#ifndef ASSERT -/* - * Assertion macro, similar to - */ -#import -#define ASSERT(p) \ - MACRO_BEGIN \ - if (!(p)) { \ - fprintf(stderr, \ - "File %s, line %d: assertion p failed.\n", \ - __FILE__, __LINE__); \ - abort(); \ - } \ - MACRO_END - -#endif /* ASSERT */ - -#define SHOULDNT_HAPPEN 0 - -extern int cthread_debug; - -#else /* CTHREADS_DEBUG */ - -#ifndef ASSERT -#define ASSERT(p) -#endif /* ASSERT */ - -#endif /* CTHREADS_DEBUG */ - -#endif /* _CTHREADS_ */ diff --git a/src/libc/threads/mig_support.c b/src/libc/threads/mig_support.c deleted file mode 100644 index 30cb7bebd..000000000 --- a/src/libc/threads/mig_support.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Mach Operating System - * Copyright (c) 1989 Carnegie-Mellon University - * All rights reserved. The CMU software License Agreement specifies - * the terms and conditions for use and redistribution. - */ -/* - * mig_support.c - by Mary Thompson - * - * Routines to set and deallocate the mig reply port for the current thread. - * Called from mig-generated interfaces. - */ -#include -#include -#include - -#include "cthreads.h" -#include "cthread_internals.h" - -pthread_lock_t reply_port_lock; -extern mach_port_t _pthread_reply_port(pthread_t); -static mach_port_t _task_reply_port = MACH_PORT_NULL; - -/* - * called in new child... - * clear lock to cover case where the parent had - * a thread holding this lock while another thread - * did the fork() - */ -void mig_fork_child() -{ - UNLOCK(reply_port_lock); -} - -/* - * Called by mach_init with 0 before cthread_init is - * called and again with 1 at the end of cthread_init. - */ -void -mig_init(init_done) - int init_done; -{ - if (init_done == 0) { - LOCK_INIT(reply_port_lock); - _task_reply_port = mach_reply_port(); - } -} - -/* - * Called by mig interface code whenever a reply port is needed. - * Tracing is masked during this call; otherwise, a call to printf() - * can result in a call to malloc() which eventually reenters - * mig_get_reply_port() and deadlocks. - */ -mach_port_t _mig_get_reply_port() -{ - pthread_t pself; - - pself = pthread_self(); - if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) { - return pself->reply_port; - } - return MACH_PORT_NULL; -} - -void _mig_set_reply_port(mach_port_t port) -{ - pthread_t pself; - pself = pthread_self(); - - if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) { - pself->reply_port = port; - } -} diff --git a/src/libc/util/logout.c b/src/libc/util/logout.c index 245201499..665fec991 100644 --- a/src/libc/util/logout.c +++ b/src/libc/util/logout.c @@ -77,16 +77,18 @@ logout(char *line) int which; #endif /* UTMP_COMPAT */ + struct _utmpx *def_utx = __default_utx(); + bzero(&utx, sizeof(utx)); strncpy(utx.ut_line, line, sizeof(utx.ut_line)); utx.ut_type = UTMPX_AUTOFILL_MASK | UTMPX_DEAD_IF_CORRESPONDING_MASK | DEAD_PROCESS; (void)gettimeofday(&utx.ut_tv, NULL); - UTMPX_LOCK(&__utx__); - __setutxent(&__utx__); - ux = __pututxline(&__utx__, &utx); - __endutxent(&__utx__); + UTMPX_LOCK(def_utx); + __setutxent(def_utx); + ux = __pututxline(def_utx, &utx); + __endutxent(def_utx); if (!ux) { - UTMPX_UNLOCK(&__utx__); + UTMPX_UNLOCK(def_utx); return 0; } #ifdef UTMP_COMPAT @@ -98,6 +100,6 @@ logout(char *line) _write_utmp(&u, 1); } #endif /* UTMP_COMPAT */ - UTMPX_UNLOCK(&__utx__); + UTMPX_UNLOCK(def_utx); return 1; } diff --git a/src/libc/util/mkpath_np.c b/src/libc/util/mkpath_np.c index 453219a79..b830b3f63 100644 --- a/src/libc/util/mkpath_np.c +++ b/src/libc/util/mkpath_np.c @@ -26,21 +26,12 @@ #include #include #include +#include -/* This extended version of mkpath_np is provided to help NSFileManager - * maintain binary compatibility. If firstdir is not NULL, *firstdir will be - * set to the path of the first created directory, and it is the caller's - * responsibility to free the returned string. This SPI is subject to removal - * once NSFileManager no longer has a need for it, and use in new code is - * highly discouraged. - * - * See: - */ - -int -_mkpath_np(const char *path, mode_t omode, const char ** firstdir) +static int +_mkpath(int dfd, const char *path, mode_t omode, const char ** firstdir) { - char *apath = NULL; + char *apath = NULL, *opath = NULL, *s, *sn, *sl; unsigned int depth = 0; mode_t chmod_mode = 0; int retval = 0; @@ -48,7 +39,7 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) struct stat sbuf; /* Try the trivial case first. */ - if (0 == mkdir(path, omode)) { + if (0 == mkdirat(dfd, path, omode)) { if (firstdir) { *firstdir = strdup(path); } @@ -63,9 +54,14 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) case ENOENT: break; case EEXIST: - if (stat(path, &sbuf) == 0 && - !S_ISDIR(sbuf.st_mode)) { - retval = ENOTDIR; + if (fstatat(dfd, path, &sbuf, 0) == 0) { + if (S_ISDIR(sbuf.st_mode)) { + retval = EEXIST; + } else { + retval = ENOTDIR; + } + } else { + retval = EIO; } goto mkpath_exit; case EISDIR: /* */ @@ -82,9 +78,36 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) goto mkpath_exit; } + sl = s = apath + strlen(apath) - 1; + do { + sn = s; + /* Strip off trailing /., see */ + if (s - 1 > apath && *s == '.' && *(s - 1) == '/') + s -= 2; + /* Strip off trailing /, see */ + if (s > apath && *s == '/') + s--; + } while (s < sn); + if (s < sl) { + s[1] = '\0'; + path = opath = strdup(apath); + if (opath == NULL) { + retval = ENOMEM; + goto mkpath_exit; + } + } + + /* Retry the trivial case after having stripped of trailing /. */ + if (0 == mkdirat(dfd, path, omode)) { + if (firstdir) { + *firstdir = strdup(path); + } + goto mkpath_exit; + } + while (1) { /* Increase our depth and try making that directory */ - char *s = strrchr(apath, '/'); + s = strrchr(apath, '/'); if (!s) { /* We should never hit this under normal circumstances, * but it can occur due to really unfortunate timing @@ -95,7 +118,7 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) *s = '\0'; depth++; - if (0 == mkdir(apath, S_IRWXU | S_IRWXG | S_IRWXO)) { + if (0 == mkdirat(dfd, apath, S_IRWXU | S_IRWXG | S_IRWXO)) { /* Found our starting point */ /* POSIX 1003.2: @@ -108,7 +131,7 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) */ struct stat dirstat; - if (-1 == stat(apath, &dirstat)) { + if (-1 == fstatat(dfd, apath, &dirstat, 0)) { /* Really unfortunate timing ... */ retval = ENOENT; goto mkpath_exit; @@ -116,7 +139,7 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) if ((dirstat.st_mode & (S_IWUSR | S_IXUSR)) != (S_IWUSR | S_IXUSR)) { chmod_mode = dirstat.st_mode | S_IWUSR | S_IXUSR; - if (-1 == chmod(apath, chmod_mode)) { + if (-1 == fchmodat(dfd, apath, chmod_mode, 0)) { /* Really unfortunate timing ... */ retval = ENOENT; goto mkpath_exit; @@ -132,7 +155,7 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) * before we did. We will use this as our starting point. * See: */ - if (stat(apath, &sbuf) == 0 && + if (fstatat(dfd, apath, &sbuf, 0) == 0 && S_ISDIR(sbuf.st_mode)) { if (firstdir) { @@ -151,11 +174,11 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) while (depth > 1) { /* Decrease our depth and make that directory */ - char *s = strrchr(apath, '\0'); + s = strrchr(apath, '\0'); *s = '/'; depth--; - if (-1 == mkdir(apath, S_IRWXU | S_IRWXG | S_IRWXO)) { + if (-1 == mkdirat(dfd, apath, S_IRWXU | S_IRWXG | S_IRWXO)) { /* This handles "." and ".." added to the new section of path */ if (errno == EEXIST) continue; @@ -164,7 +187,7 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) } if (chmod_mode) { - if (-1 == chmod(apath, chmod_mode)) { + if (-1 == fchmodat(dfd, apath, chmod_mode, 0)) { /* Really unfortunate timing ... */ retval = ENOENT; goto mkpath_exit; @@ -172,10 +195,10 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) } } - if (-1 == mkdir(path, omode)) { + if (-1 == mkdirat(dfd, path, omode)) { retval = errno; if (errno == EEXIST && - stat(path, &sbuf) == 0 && + fstatat(dfd, path, &sbuf, 0) == 0 && !S_ISDIR(sbuf.st_mode)) { retval = ENOTDIR; } @@ -183,11 +206,31 @@ _mkpath_np(const char *path, mode_t omode, const char ** firstdir) mkpath_exit: free(apath); + free(opath); errno = old_errno; return retval; } +/* This extended version of mkpath_np is provided to help NSFileManager + * maintain binary compatibility. If firstdir is not NULL, *firstdir will be + * set to the path of the first created directory, and it is the caller's + * responsibility to free the returned string. This SPI is subject to removal + * once NSFileManager no longer has a need for it, and use in new code is + * highly discouraged. + * + * See: + */ + +int +_mkpath_np(const char *path, mode_t omode, const char ** firstdir) { + return _mkpath(AT_FDCWD, path, omode, firstdir); +} + int mkpath_np(const char *path, mode_t omode) { - return _mkpath_np(path, omode, NULL); + return _mkpath(AT_FDCWD, path, omode, NULL); +} + +int mkpathat_np(int dfd, const char *path, mode_t omode) { + return _mkpath(dfd, path, omode, NULL); } diff --git a/src/libc/uuid/uuidsrc/gen_uuid.c b/src/libc/uuid/uuidsrc/gen_uuid.c index cad4eb70d..c56c8c9aa 100644 --- a/src/libc/uuid/uuidsrc/gen_uuid.c +++ b/src/libc/uuid/uuidsrc/gen_uuid.c @@ -146,7 +146,11 @@ static int get_node_id(unsigned char *node_id) #endif /* AF_LINK */ #endif /* SIOCGENADDR */ #endif /* SIOCGIFHWADDR */ - if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) + /* + * Skip interfaces that return either 00:00:00:00:00:00 or + * 02:00:00:00:00:00. + */ + if ((!a[0] || a[0] == 0x02) && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) continue; if (node_id) { memcpy(node_id, a, 6); diff --git a/src/libc/x86_64/CMakeLists.txt b/src/libc/x86_64/CMakeLists.txt index a6e6e31f2..e82950596 100644 --- a/src/libc/x86_64/CMakeLists.txt +++ b/src/libc/x86_64/CMakeLists.txt @@ -3,120 +3,28 @@ project(libc-x86_64) cmake_minimum_required(VERSION 2.8.0) enable_language(C ASM) -#add_definitions(-D_getcontext=getcontext) -#add_definitions(-D_moncount=moncount) -#add_definitions(-D__setcontext=_setcontext) -#add_definitions(-D_getmcontext=getmcontext) -#add_definitions(-D__ctx_done=_ctx_done) -#add_definitions(-D__ctx_start=_ctx_start) -#add_definitions(-D_cpu_number=cpu_number) -#add_definitions(-D_sys_icache_invalidate=sys_icache_invalidate) -#add_definitions(-D_sys_dcache_flush=sys_dcache_flush) add_definitions(-DPRIVATE) #set(CMAKE_C_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_C_FLAGS} -include ${CMAKE_CURRENT_SOURCE_DIR}/../../duct/include/commpage.h -include ${DARLING_TOP_DIRECTORY}/platform-include/sys/time.h") set(x86_64_sources - gen/getmcontext.c - gen/makecontext.c - gen/setcontext.c - gen/setjmperr.c - gen/swapcontext.c - gen/cpu_number.S - gen/icacheinval.S gen/mcount.S - gen/_ctx_start.S - gen/getcontext.S - gen/_setcontext.S - ../i386/pthreads/init_cpu_capabilities.c -) - -#add_definitions(-D_preempt=preempt) -#add_definitions(-D_backoff=backoff) -#add_definitions(-D_pthread_getspecific=pthread_getspecific) -#add_definitions(-D__commpage_pthread_mutex_lock=_commpage_pthread_mutex_lock) -#add_definitions(-D_pthread_self=pthread_self) -#add_definitions(-D___pthread_set_self=__pthread_set_self) -#add_definitions(-D_start_wqthread=start_wqthread) -#add_definitions(-D_thread_start=thread_start) -#add_definitions(-D__pthread_start=_pthread_start) -#add_definitions(-D__pthread_wqthread=_pthread_wqthread) - -set(x86_64_sources ${x86_64_sources} - pthreads/preempt.S - pthreads/pthread_getspecific.S - pthreads/pthread_mutex_lock.S - pthreads/pthread_self.S - #pthreads/pthread_set_self.S - pthreads/start_wqthread.S - pthreads/thread_start.S -) - -set(x86_64_sources ${x86_64_sources} - string/bcopy.c - string/bcopy_sse3x.S - string/bcopy_sse42.S - string/bzero.c - string/__bzero.S - string/bzero_sse2.S - string/bzero_sse42.S - string/ffs.S - string/longcopy_sse3x.S - string/memcmp.S - string/memcpy.c - string/memmove.c - string/memset.S - string/strcmp.S string/strcpy.S - string/strlcat.S - string/strlcpy.S string/strlen.S - string/strncmp.S string/strncpy.S -) - -add_definitions(-DkUP=0x8000) -set(x86_64_sources ${x86_64_sources} - sys/atomic.c - sys/i386_gettimeofday_asm.S - #sys/nanotime.S # Fully dependent on commpage! TODO: reimplement in system_kernel - sys/OSAtomic.S - sys/_setjmp.S - sys/setjmp.S - sys/_sigtramp.S - sys/spinlocks_asm.S - sys/spinlocks.c # aliases in other complation units don't work, work done in spinlocks_asm.S + string/strnlen.S ) -add_library(libc-hwplat OBJECT ${x86_64_sources}) +add_library(libc-x86_64 OBJECT ${x86_64_sources}) add_library(libc-hwplat_dyld OBJECT - #pthreads/pthread_set_self.S # in system_kernel - pthreads/pthread_self.S - pthreads/pthread_getspecific.S - pthreads/preempt.S - pthreads/thread_start.S - pthreads/start_wqthread.S - string/__bzero.S - string/bcopy_sse3x.S - string/bcopy_sse42.S - string/bcopy.c - string/bzero_sse2.S - string/bzero_sse42.S - string/bzero.c - string/ffs.S - string/longcopy_sse3x.S - string/strcmp.S + gen/mcount.S + string/strcpy.S string/strlen.S string/strncpy.S - string/memmove.c - string/memcpy.c - sys/OSAtomic.S - sys/atomic.c - sys/spinlocks.c - sys/i386_gettimeofday_asm.S - sys/spinlocks_asm.S) + string/strnlen.S +) set_target_properties(libc-hwplat_dyld PROPERTIES COMPILE_FLAGS "-DVARIANT_DYLD") diff --git a/src/libc/x86_64/gen/_ctx_start.S b/src/libc/x86_64/gen/_ctx_start.S deleted file mode 100644 index dfca3e9c8..000000000 --- a/src/libc/x86_64/gen/_ctx_start.S +++ /dev/null @@ -1,90 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Copyright (c) 2001 Daniel Eischen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(__x86_64__) - -#include - -/* - * _ctx_start((void *func)(int arg1, ..., argn), - * int arg1, ..., argn, ucontext_t *ucp) - * - * %rdi - func - * %rsi - arg1 - * %rdx - arg2 - * %rcx - arg3 - * %r8 - arg4 - * %r9 - arg5 - * WRONG! - * (8*(n-6))(%rsp) - argn - * (8*(n + 1))(%rsp) - ucp, %rbp setup to point here (base of stack) - */ -TEXT -LABEL(__ctx_start) - popq %rax /* accounted for in makecontext() */ - /* makecontext will simulate 6 parameters at least */ - /* Or it could just set these in the mcontext... */ - popq %rdi - popq %rsi - popq %rdx - popq %rcx - popq %r8 - popq %r9 - - callq *%rax /* call start function */ - movq %r12, %rsp /* - * setup stack for completion routine; - * ucp is now at top of stack - */ - movq (%rsp), %rdi - CALL_EXTERN(__ctx_done) /* should never return */ - int $5 /* trap */ - -#endif /* __x86_64__ */ diff --git a/src/libc/x86_64/gen/_setcontext.S b/src/libc/x86_64/gen/_setcontext.S deleted file mode 100644 index 004a6a104..000000000 --- a/src/libc/x86_64/gen/_setcontext.S +++ /dev/null @@ -1,71 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007,2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined(__x86_64__) - -#include - -#define MCONTEXT_SS_RAX 16 -#define MCONTEXT_SS_RBX 24 -#define MCONTEXT_SS_RCX 32 -#define MCONTEXT_SS_RDX 40 -#define MCONTEXT_SS_RDI 48 -#define MCONTEXT_SS_RSI 56 -#define MCONTEXT_SS_RBP 64 -#define MCONTEXT_SS_RSP 72 -#define MCONTEXT_SS_R8 80 -#define MCONTEXT_SS_RIP 144 -#define MCONTEXT_SS_RFLAGS 152 - -TEXT -LABEL(__setcontext) - /* struct mcontext_t * %rdi */ -#if DEBUG - movq MCONTEXT_SS_RSI(%rdi), %rsi - movq MCONTEXT_SS_RCX(%rdi), %rcx - movq MCONTEXT_SS_R8+0(%rdi), %r8 - movq MCONTEXT_SS_R8+8(%rdi), %r9 - movq MCONTEXT_SS_R8+16(%rdi), %r10 - movq MCONTEXT_SS_R8+24(%rdi), %r11 -#endif - movq MCONTEXT_SS_RBX(%rdi), %rbx - movq MCONTEXT_SS_R8+32(%rdi), %r12 - movq MCONTEXT_SS_R8+40(%rdi), %r13 - movq MCONTEXT_SS_R8+48(%rdi), %r14 - movq MCONTEXT_SS_R8+56(%rdi), %r15 - - movq MCONTEXT_SS_RSP(%rdi), %rsp - movq MCONTEXT_SS_RBP(%rdi), %rbp - - xorl %eax, %eax /* force x=getcontext(); ... setcontext(); to keep x==0 */ - -#if DEBUG - movq MCONTEXT_SS_RIP(%rdi), %rdx - movq MCONTEXT_SS_RDI(%rdi), %rdi - jmp *%rdx -#else - jmp *MCONTEXT_SS_RIP(%rdi) -#endif - -#endif /* __x86_64__ */ diff --git a/src/libc/x86_64/gen/cpu_number.S b/src/libc/x86_64/gen/cpu_number.S deleted file mode 100644 index cc08534cc..000000000 --- a/src/libc/x86_64/gen/cpu_number.S +++ /dev/null @@ -1,54 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2008 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -/* - * This routine provides fast access to the logical cpu number - * of the calling processor assuming no pre-emption occurs. This number - * is encoded in the bottom 12-bits of the limit field of the IDTR (the - * Interrupt Descriptor Table Register). The SIDT instruction is used in - * userspace to read this register and thus to gain access to the cpu number. - * The IDTR is loaded by the kernel for each processor at startup - see - * osfmk/i386/mp_desc.c. - */ - -/* return logical cpu number in %rax */ - - .globl _cpu_number -_cpu_number: - push %rbp - mov %rsp,%rbp - sub $16,%rsp // space to read IDTR - - sidt (%rsp) // store limit:base on stack - movw (%rsp), %ax // get limit - and $0xfff, %rax // mask off lower 12 bits to return - - mov %rbp,%rsp - pop %rbp - ret diff --git a/src/libc/x86_64/gen/getcontext.S b/src/libc/x86_64/gen/getcontext.S deleted file mode 100644 index b36f963c2..000000000 --- a/src/libc/x86_64/gen/getcontext.S +++ /dev/null @@ -1,76 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007,2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined(__x86_64__) - -#include - -#define MCONTEXT_SS_RAX 16 -#define MCONTEXT_SS_RBX 24 -#define MCONTEXT_SS_RCX 32 -#define MCONTEXT_SS_RDX 40 -#define MCONTEXT_SS_RDI 48 -#define MCONTEXT_SS_RSI 56 -#define MCONTEXT_SS_RBP 64 -#define MCONTEXT_SS_RSP 72 -#define MCONTEXT_SS_R8 80 -#define MCONTEXT_SS_RIP 144 -#define MCONTEXT_SS_RFLAGS 152 - -TEXT -LABEL(_getcontext) - /* struct ucontext_t * $rdi */ - push %rbp - movq %rsp, %rbp - movq %rsp, %rsi - CALL_EXTERN(_getmcontext) /* getmcontext(uctx, sp) */ - pop %rbp - -#if DEBUG - movq $0, MCONTEXT_SS_RAX(%rax) - movq $0, MCONTEXT_SS_RDX(%rax) - movq $0, MCONTEXT_SS_RCX(%rax) - movq $0, MCONTEXT_SS_RDI(%rax) - movq $0, MCONTEXT_SS_RSI(%rax) - movq $0, MCONTEXT_SS_R8(%rax) - movq $0, MCONTEXT_SS_R8+8(%rax) - movq $0, MCONTEXT_SS_R8+16(%rax) - movq $0, MCONTEXT_SS_R8+24(%rax) - movq $0, MCONTEXT_SS_RFLAGS(%rax) -#endif - - movq %rbp, MCONTEXT_SS_RBP(%rax) - movq %rbx, MCONTEXT_SS_RBX(%rax) - movq %r12, MCONTEXT_SS_R8+32(%rax) - movq %r13, MCONTEXT_SS_R8+40(%rax) - movq %r14, MCONTEXT_SS_R8+48(%rax) - movq %r15, MCONTEXT_SS_R8+56(%rax) - movq (%rsp), %rcx /* return address */ - movq %rcx, MCONTEXT_SS_RIP(%rax) - leaq 8(%rsp), %rcx - movq %rcx, MCONTEXT_SS_RSP(%rax) - xorl %eax, %eax - ret - -#endif /* __x86_64__ */ diff --git a/src/libc/x86_64/gen/getmcontext.c b/src/libc/x86_64/gen/getmcontext.c deleted file mode 100644 index b8a2ea6e8..000000000 --- a/src/libc/x86_64/gen/getmcontext.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined(__x86_64__) - -#define _XOPEN_SOURCE 600L - -#include -#include -#include -#include -#include -#include - -extern size_t pthread_get_stacksize_np(pthread_t); -extern void *pthread_get_stackaddr_np(pthread_t); -#ifdef __DYNAMIC__ -extern int __in_sigtramp; -#endif /* __DYNAMIC_ */ - -__private_extern__ mcontext_t -getmcontext(ucontext_t *uctx, void *sp) -{ - pthread_t self = pthread_self(); - mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; - size_t stacksize = pthread_get_stacksize_np(self); - stack_t stack; - - uctx->uc_stack.ss_sp = sp; - uctx->uc_stack.ss_flags = 0; - - if (0 == sigaltstack(NULL, &stack)) { - if (stack.ss_flags & SS_ONSTACK) { - uctx->uc_stack = stack; - stacksize = stack.ss_size; - } - } - - if (stacksize == 0) { /* main thread doesn't have pthread stack size */ - struct rlimit rlim; - if (0 == getrlimit(RLIMIT_STACK, &rlim)) - stacksize = rlim.rlim_cur; - } - - uctx->uc_stack.ss_size = stacksize; - - if (uctx->uc_mcontext != mctx) { - uctx->uc_mcontext = mctx; - -#ifdef __DYNAMIC__ - uctx->uc_link = (ucontext_t*)(uintptr_t)__in_sigtramp; /* non-zero if in signal handler */ -#else /* !__DYNAMIC__ */ - uctx->uc_link = 0; -#endif /* __DYNAMIC__ */ - - } - - sigprocmask(0, NULL, &uctx->uc_sigmask); - return mctx; -} - -#endif /* __x86_64__ */ diff --git a/src/libc/x86_64/gen/icacheinval.S b/src/libc/x86_64/gen/icacheinval.S deleted file mode 100644 index 9990c734b..000000000 --- a/src/libc/x86_64/gen/icacheinval.S +++ /dev/null @@ -1,56 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - - #include - - .text - .align 4, 0x00 - -/* void sys_icache_invalidate(addr_t start, int length) */ - - .globl _sys_icache_invalidate -_sys_icache_invalidate: - // This is a NOP on intel processors, since the intent of the API - // is to make data executable, and Intel L1Is are coherent with L1D. - ret - - -/* void sys_dcache_flush(addr_t start, int length) */ - - .globl _sys_dcache_flush -_sys_dcache_flush: - testq %rsi,%rsi // length 0? - jz 2f // yes - mfence // ensure previous stores make it to memory - clflush -1(%rdi,%rsi) // make sure last line is flushed -1: - clflush (%rdi) // flush a line - addq $64,%rdi - subq $64,%rsi - ja 1b - mfence // make sure memory is updated before we return -2: - ret diff --git a/src/libc/x86_64/gen/makecontext.c b/src/libc/x86_64/gen/makecontext.c deleted file mode 100644 index 56df69c07..000000000 --- a/src/libc/x86_64/gen/makecontext.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2007, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Copyright (c) 2001 Daniel M. Eischen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(__x86_64__) - -#define _XOPEN_SOURCE -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -/* Prototypes */ -extern void _ctx_start(ucontext_t *, int argc, ...); - -void -_ctx_done (ucontext_t *ucp) -{ - if (ucp->uc_link == NULL) - exit(0); - else { - /* - * Since this context has finished, don't allow it - * to be restarted without being reinitialized (via - * setcontext or swapcontext). - */ - ucp->uc_mcsize = 0; - - /* Set context to next one in link */ - /* XXX - what to do for error, abort? */ - setcontext((const ucontext_t *)ucp->uc_link); - LIBC_ABORT("setcontext failed"); /* should never get here */ - } -} - -void -makecontext(ucontext_t *ucp, void (*start)(), int argc, ...) -{ - va_list ap; - char *stack_top; - intptr_t *argp; - int i; - - if (ucp == NULL) - return; - else if ((ucp->uc_stack.ss_sp == NULL) || - (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { - /* - * This should really return -1 with errno set to ENOMEM - * or something, but the spec says that makecontext is - * a void function. At least make sure that the context - * isn't valid so it can't be used without an error. - */ - ucp->uc_mcsize = 0; - } - /* XXX - Do we want to sanity check argc? */ - else if ((argc < 0) || (argc > NCARGS)) { - ucp->uc_mcsize = 0; - } - /* Make sure the context is valid. */ - else { - /* - * Arrange the stack as follows: - * - * _ctx_start() - context start wrapper - * start() - user start routine - * arg1 - first argument, aligned(16) - * ... - * argn - * ucp - this context, %rbp points here - * - * When the context is started, control will return to - * the context start wrapper which will pop the user - * start routine from the top of the stack. After that, - * the top of the stack will be setup with all arguments - * necessary for calling the start routine. When the - * start routine returns, the context wrapper then sets - * the stack pointer to %rbp which was setup to point to - * the base of the stack (and where ucp is stored). It - * will then call _ctx_done() to swap in the next context - * (uc_link != 0) or exit the program (uc_link == 0). - */ - mcontext_t mc; - - stack_top = (char *)(ucp->uc_stack.ss_sp + - ucp->uc_stack.ss_size - sizeof(intptr_t)); - - - /* Give 6 stack slots to _ctx_start */ - int minargc = 6; - if (argc > minargc) - minargc = argc; - - /* - * Adjust top of stack to allow for 3 pointers (return - * address, _ctx_start, and ucp) and argc arguments. - * We allow the arguments to be pointers also. The first - * argument to the user function must be properly aligned. - */ - - stack_top = stack_top - (sizeof(intptr_t) * (1 + minargc)); - stack_top = (char *)((intptr_t)stack_top & ~15); - stack_top = stack_top - (2 * sizeof(intptr_t)); - argp = (intptr_t *)stack_top; - - /* - * Setup the top of the stack with the user start routine - * followed by all of its aguments and the pointer to the - * ucontext. We need to leave a spare spot at the top of - * the stack because setcontext will move rip to the top - * of the stack before returning. - */ - *argp = (intptr_t)_ctx_start; /* overwritten with same value */ - argp++; - *argp = (intptr_t)start; - argp++; - - /* Add all the arguments: */ - va_start(ap, argc); - for (i = 0; i < argc; i++) { - *argp = va_arg(ap, intptr_t); - argp++; - } - va_end(ap); - - /* Always provide space for ctx_start to pop the parameter registers */ - for (;argc < minargc; argc++) { - *argp++ = 0; - } - - /* Keep stack aligned */ - if (argc & 1) { - *argp++ = 0; - } - - /* The ucontext is placed at the bottom of the stack. */ - *argp = (intptr_t)ucp; - - /* - * Set the machine context to point to the top of the - * stack and the program counter to the context start - * wrapper. Note that setcontext() pushes the return - * address onto the top of the stack, so allow for this - * by adjusting the stack downward 1 slot. Also set - * %r12 to point to the base of the stack where ucp - * is stored. - */ - mc = ucp->uc_mcontext; - /* Use callee-save and match _ctx_start implementation */ - mc->__ss.__r12 = (intptr_t)argp; - mc->__ss.__rbp = 0; - mc->__ss.__rsp = (intptr_t)stack_top + sizeof(caddr_t); - mc->__ss.__rip = (intptr_t)_ctx_start; - } -} - -#endif /* __x86_64__ */ diff --git a/src/libc/x86_64/gen/mcount.S b/src/libc/x86_64/gen/mcount.S index 062519d91..345686204 100644 --- a/src/libc/x86_64/gen/mcount.S +++ b/src/libc/x86_64/gen/mcount.S @@ -23,8 +23,8 @@ #import .text - .globl _mcount -_mcount: + .globl mcount +mcount: pushq %rbp // setup mcount's frame movq %rsp, %rbp subq $64, %rsp // allocate space for storage and alignment diff --git a/src/libc/x86_64/gen/setcontext.c b/src/libc/x86_64/gen/setcontext.c deleted file mode 100644 index c89b4f49e..000000000 --- a/src/libc/x86_64/gen/setcontext.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2007, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if defined(__x86_64__) - -#define _XOPEN_SOURCE 600L -#include -#undef _XOPEN_SOURCE -#undef _POSIX_C_SOURCE /* sigsetmask() */ -#include - -extern int _setcontext(const mcontext_t); - -int -setcontext(const ucontext_t *uctx) -{ - mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data; - ucontext_t *_uctx = (ucontext_t *)uctx; - if (mctx != _uctx->uc_mcontext) - _uctx->uc_mcontext = mctx; - sigsetmask(uctx->uc_sigmask); - return _setcontext(mctx); -} - -#endif /* __x86_64__ */ diff --git a/src/libc/x86_64/gen/setjmperr.c b/src/libc/x86_64/gen/setjmperr.c deleted file mode 100644 index bf065952f..000000000 --- a/src/libc/x86_64/gen/setjmperr.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1980 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)setjmperr.c 5.4 (Berkeley) 6/27/88"; -#endif /* LIBC_SCCS and not lint */ - -#include - -/* - * This routine is called from longjmp() when an error occurs. - * Programs that wish to exit gracefully from this error may - * write their own versions. - * If this routine returns, the program is aborted. - */ - -void -longjmperror() -{ -#define ERRMSG "longjmp botch\n" - write(2, ERRMSG, sizeof(ERRMSG) - 1); -} diff --git a/src/libc/x86_64/gen/swapcontext.c b/src/libc/x86_64/gen/swapcontext.c deleted file mode 100644 index 8b7513c2e..000000000 --- a/src/libc/x86_64/gen/swapcontext.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2007, 2009 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Copyright (c) 2001 Daniel M. Eischen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of the author nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(__x86_64__) - -#include -#include -#include -#include - -#include -#include - -#define uc_flags uc_onstack -#define UCF_SWAPPED 0x80000000 - -int -swapcontext(ucontext_t *oucp, const ucontext_t *ucp) -{ - int ret; - - if ((oucp == NULL) || (ucp == NULL)) { - errno = EINVAL; - return (-1); - } - oucp->uc_flags &= ~UCF_SWAPPED; - ret = getcontext(oucp); - if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) { - oucp->uc_flags |= UCF_SWAPPED; - ret = setcontext(ucp); - } - return (ret); -} - -#endif /* __x86_64__ */ diff --git a/src/libc/x86_64/pthreads/preempt.S b/src/libc/x86_64/pthreads/preempt.S deleted file mode 100644 index d287c07e5..000000000 --- a/src/libc/x86_64/pthreads/preempt.S +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -/* Subroutine to make a preempt syscall. Called when we notice %ebx is - * nonzero after returning from a PFZ subroutine. Not in PFZ. - * - * All registers preserved (but does clear the %ebx preemption flag). - */ - .align 2 - .globl _preempt -_preempt: -#ifndef DARLING /* Modified by Lubos Dolezel, DARLING-TODO */ - pushq %rax - pushq %rcx - pushq %r11 - movl $(SYSCALL_CONSTRUCT_MACH(58)),%eax /* 58 = pfz_exit */ - xorl %ebx,%ebx - syscall - popq %r11 - popq %rcx - popq %rax -#endif - ret - -/* Subroutine to back off if we cannot get the spinlock. Called - * after a few attempts inline in the PFZ subroutines. This code is - * not in the PFZ. - * %rdi = ptr to queue head structure - * %ebx = preemption flag (nonzero if preemption pending) - * Uses: %rax. - */ - .align 2 - .globl _backoff -_backoff: - testl %ebx,%ebx // does kernel want to preempt us? - jz 1f // no - call _preempt -1: - pause // SMT-friendly backoff - cmpl $0,16(%rdi) // sniff the lockword - jnz 1b // loop if still taken - ret // lockword is free, so reenter PFZ diff --git a/src/libc/x86_64/pthreads/pthread_getspecific.S b/src/libc/x86_64/pthreads/pthread_getspecific.S deleted file mode 100644 index 50d6371c4..000000000 --- a/src/libc/x86_64/pthreads/pthread_getspecific.S +++ /dev/null @@ -1,32 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "pthread_machdep.h" - -.text -.align (2<<2), 0x90 -.globl _pthread_getspecific -_pthread_getspecific: - movq %gs:(,%rdi,8),%rax - ret diff --git a/src/libc/x86_64/pthreads/pthread_mutex_lock.S b/src/libc/x86_64/pthreads/pthread_mutex_lock.S deleted file mode 100644 index 209362b0a..000000000 --- a/src/libc/x86_64/pthreads/pthread_mutex_lock.S +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include - -#define PTHRW_LVAL 0 -#define PTHRW_UVAL 4 - - .text - .align (2<<2) - .globl __commpage_pthread_mutex_lock -__commpage_pthread_mutex_lock: -#ifndef DARLING /* DARLING-TODO, Modified by Lubos Dolezel */ - pushq %rbp // set up frame for backtrace - movq %rsp,%rbp - pushq %rbx - xorl %ebx,%ebx // clear "preemption pending" flag - movl $(_COMM_PAGE_SPIN_COUNT), %eax -1: - testl PTHRW_LVAL(%rdi),%ecx // is mutex available? - jz 2f // yes, it is available - pause - decl %eax // decrement max spin count - jnz 1b // keep spinning -2: - movq _commpage_pfz_base(%rip),%rcx - addq $(_COMM_TEXT_PFZ_MUTEX_LOCK_OFFSET), %rcx - call *%rcx - testl %ebx,%ebx // pending preemption? - jz 1f // no - call _preempt -1: - popq %rbx - popq %rbp -#endif - ret diff --git a/src/libc/x86_64/pthreads/pthread_self.S b/src/libc/x86_64/pthreads/pthread_self.S deleted file mode 100644 index 1ff6e122e..000000000 --- a/src/libc/x86_64/pthreads/pthread_self.S +++ /dev/null @@ -1,32 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "pthread_machdep.h" - -.text -.align (2<<2), 0x90 -.globl _pthread_self -_pthread_self: - movq %gs:0,%rax - ret diff --git a/src/libc/x86_64/pthreads/pthread_set_self.S b/src/libc/x86_64/pthreads/pthread_set_self.S deleted file mode 100644 index 322531ed4..000000000 --- a/src/libc/x86_64/pthreads/pthread_set_self.S +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -.text -.align (2<<2), 0x90 -.globl ___pthread_set_self -___pthread_set_self: -#ifndef DARLING /* DARLING-TODO, Modified by Lubos Dolezel */ - movl $0, %esi // 0 as the second argument - movl $ SYSCALL_CONSTRUCT_MDEP(3), %eax // Machine-dependent syscall number 3 - MACHDEP_SYSCALL_TRAP -#endif - ret diff --git a/src/libc/x86_64/pthreads/start_wqthread.S b/src/libc/x86_64/pthreads/start_wqthread.S deleted file mode 100644 index 2087838e9..000000000 --- a/src/libc/x86_64/pthreads/start_wqthread.S +++ /dev/null @@ -1,39 +0,0 @@ -/* Modified by Lubos Dolezel for Linux support */ -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "pthread_machdep.h" -#include - -.text -.align (2<<2), 0x90 -.globl _start_wqthread -_start_wqthread: -// This routine is never called directly by user code, jumped from kernel - push %rbp - mov %rsp,%rbp - sub $24,%rsp // align the stack - CALL_EXTERN(__pthread_wqthread) - leave - ret - diff --git a/src/libc/x86_64/pthreads/thread_start.S b/src/libc/x86_64/pthreads/thread_start.S deleted file mode 100644 index ab5a7b279..000000000 --- a/src/libc/x86_64/pthreads/thread_start.S +++ /dev/null @@ -1,39 +0,0 @@ -/* Modified by Lubos Dolezel for Linux support */ -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "pthread_machdep.h" -#include - -.text -.align (2<<2), 0x90 -.globl _thread_start -_thread_start: -// This routine is never called directly by user code, jumped from kernel - push %rbp - mov %rsp,%rbp - sub $24,%rsp // align the stack - CALL_EXTERN(__pthread_start) - leave - ret - diff --git a/src/libc/x86_64/string/__bzero.S b/src/libc/x86_64/string/__bzero.S deleted file mode 100644 index c16f31ac9..000000000 --- a/src/libc/x86_64/string/__bzero.S +++ /dev/null @@ -1,3 +0,0 @@ - .globl ___bzero -___bzero: - jmp _bzero diff --git a/src/libc/x86_64/string/bcopy.c b/src/libc/x86_64/string/bcopy.c deleted file mode 100644 index 3187decbf..000000000 --- a/src/libc/x86_64/string/bcopy.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse42) -PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse3x) - -static const platfunc_descriptor *bcopy_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse42), - PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse3x), - 0 -}; - -void *bcopy_chooser() __asm__("_bcopy"); -void *bcopy_chooser() { - __asm__(".desc _bcopy, 0x100"); - return find_platform_function((const platfunc_descriptor **) bcopy_platfunc_descriptors); -} diff --git a/src/libc/x86_64/string/bcopy_sse3x.S b/src/libc/x86_64/string/bcopy_sse3x.S deleted file mode 100644 index 0881b1400..000000000 --- a/src/libc/x86_64/string/bcopy_sse3x.S +++ /dev/null @@ -1,806 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -/* - * The bcopy/memcpy loops, tuned for 64-bit Pentium-M class processors with - * Supplemental SSE3 and 64-byte cache lines. This is the 64-bit version. - * - * The following #defines are tightly coupled to the u-architecture: - */ - -#define kShort 80 // too short to bother with SSE (must be >=80) -#define kVeryLong (500*1024) // large enough for non-temporal stores (>=8192 and <2GB) -#define kFastUCode ((16*1024)-15) // cutoff for microcode fastpath for "rep/movsl" - -// void bcopy(const void *src, void *dst, size_t len); - -PLATFUNC_FUNCTION_START_GENERIC(bcopy, sse3x, 64, 5) -LZero: - pushq %rbp // set up a frame for backtraces - movq %rsp,%rbp - movq %rsi,%rax // copy dest ptr - movq %rdi,%rsi // xchange source and dest ptrs - movq %rax,%rdi - subq %rsi,%rax // (dest - source) - cmpq %rdx,%rax // must move in reverse if (dest - source) < length - jb LReverseIsland - cmpq $(kShort),%rdx // long enough to bother with SSE? - jbe LShort // no - jmp LNotShort - -// -// void *memcpy(void *dst, const void *src, size_t len); -// void *memmove(void *dst, const void *src, size_t len); -// - -PLATFUNC_FUNCTION_START_GENERIC(memcpy, sse3x, 64, 0) // void *memcpy(void *dst, const void *src, size_t len) -PLATFUNC_FUNCTION_START_GENERIC(memmove, sse3x, 64, 0) // void *memmove(void *dst, const void *src, size_t len) - pushq %rbp // set up a frame for backtraces - movq %rsp,%rbp - movq %rdi,%r11 // save return value here - movq %rdi,%rax - subq %rsi,%rax // (dest - source) - cmpq %rdx,%rax // must move in reverse if (dest - source) < length - jb LReverseIsland - cmpq $(kShort),%rdx // long enough to bother with SSE? - ja LNotShort // yes - -// Handle short forward copies. As the most common case, this is the fall-through path. -// rdx = length (<= kShort) -// rsi = source ptr -// rdi = dest ptr - -LShort: - movl %edx,%ecx // copy length using 32-bit operation - shrl $2,%ecx // get #doublewords - jz LLeftovers -2: // loop copying doublewords - movl (%rsi),%eax - addq $4,%rsi - movl %eax,(%rdi) - addq $4,%rdi - decl %ecx - jnz 2b -LLeftovers: // handle leftover bytes (0..3) in last word - andl $3,%edx // any leftover bytes? - jz 5f -4: // loop copying bytes - movb (%rsi),%al - incq %rsi - movb %al,(%rdi) - incq %rdi - decl %edx - jnz 4b -5: - movq %r11,%rax // get return value (dst ptr) for memcpy/memmove - popq %rbp - ret - - -LReverseIsland: // keep the "jb" above a short branch... - jmp LReverse // ...because reverse moves are uncommon - - -// Handle forward moves that are long enough to justify use of SSE. -// First, 16-byte align the destination. -// rdx = length (> kShort) -// rsi = source ptr -// rdi = dest ptr - -LNotShort: - cmpq $(kVeryLong),%rdx // long enough to justify heavyweight loops? - jae LVeryLong // use very-long-operand path - movl %edi,%ecx // copy low half of destination ptr - negl %ecx - andl $15,%ecx // get #bytes to align destination - jz LDestAligned // already aligned - subl %ecx,%edx // decrement length - rep // align destination - movsb - - -// Destination is now aligned. Dispatch to one of sixteen loops over 64-byte chunks, -// based on the alignment of the source. All vector loads and stores are aligned. -// Even though this means we have to shift and repack vectors, doing so is much faster -// than unaligned loads. Since kShort>=80 and we've moved at most 15 bytes already, -// there is at least one chunk. When we enter the copy loops, the following registers -// are set up: -// rdx = residual length (0..63) -// rcx = -(length to move), a multiple of 64 less than 2GB -// rsi = ptr to 1st source byte not to move (unaligned) -// rdi = ptr to 1st dest byte not to move (aligned) - -LDestAligned: - movq %rdx,%rcx // copy length - movl %esi,%eax // copy low half of source address - andl $63,%edx // get remaining bytes for LShort - andl $15,%eax // mask to low 4 bits of source address - andq $-64,%rcx // get number of bytes we will copy in inner loop - leaq LTable(%rip), %r8 - addq %rcx,%rsi // point to 1st byte not copied - addq %rcx,%rdi - movl (%r8,%rax,4),%eax // get offset of routine - negq %rcx // now generate offset to 1st byte to be copied - addq %r8,%rax // generate address of copy loop - jmp *%rax // enter copy loop, selected by source alignment - - .align 2 -LTable: // table of copy loop addresses -// force generation of assembly-time constants. Otherwise assembler -// creates subtractor relocations relative to first external symbol, -// and this file has none - .set LMod0Offset, LMod0 - LTable - .set LMod1Offset, LMod1 - LTable - .set LMod2Offset, LMod2 - LTable - .set LMod3Offset, LMod3 - LTable - .set LMod4Offset, LMod4 - LTable - .set LMod5Offset, LMod5 - LTable - .set LMod6Offset, LMod6 - LTable - .set LMod7Offset, LMod7 - LTable - .set LMod8Offset, LMod8 - LTable - .set LMod9Offset, LMod9 - LTable - .set LMod10Offset, LMod10 - LTable - .set LMod11Offset, LMod11 - LTable - .set LMod12Offset, LMod12 - LTable - .set LMod13Offset, LMod13 - LTable - .set LMod14Offset, LMod14 - LTable - .set LMod15Offset, LMod15 - LTable - .long LMod0Offset - .long LMod1Offset - .long LMod2Offset - .long LMod3Offset - .long LMod4Offset - .long LMod5Offset - .long LMod6Offset - .long LMod7Offset - .long LMod8Offset - .long LMod9Offset - .long LMod10Offset - .long LMod11Offset - .long LMod12Offset - .long LMod13Offset - .long LMod14Offset - .long LMod15Offset - - -// Very long forward moves. These are at least several pages. They are special cased -// and aggressively optimized, not so much because they are common or useful, but -// because they are subject to benchmark. There isn't enough room for them in the -// area reserved on the platfunc for bcopy, so we put them elsewhere. We call -// the longcopy routine using the normal ABI: -// rdi = dest -// rsi = source -// rdx = length (>= kVeryLong bytes) - -LVeryLong: - pushq %r11 // save return value - call _longcopy // call very long operand routine - popq %rax // pop return value - popq %rbp - ret - - -// On Pentium-M, the microcode for "rep/movsl" is faster than SSE for 16-byte -// aligned operands from about 32KB up to kVeryLong for the hot cache case, and from -// about 256 bytes up to kVeryLong for cold caches. This is because the microcode -// avoids having to read destination cache lines that will be completely overwritten. -// The cutoff we use (ie, kFastUCode) must somehow balance the two cases, since -// we do not know if the destination is in cache or not. - -Lfastpath: - addq %rcx,%rsi // restore ptrs to 1st byte of source and dest - addq %rcx,%rdi - negl %ecx // make length positive (known to be < 2GB) - orl %edx,%ecx // restore total #bytes remaining to move - cld // we'll move forward - shrl $2,%ecx // compute #words to move - rep // the u-code will optimize this - movsl - jmp LLeftovers // handle 0..3 leftover bytes - - -// Forward loop for medium length operands in which low four bits of %rsi == 0000 - -LMod0: - cmpl $(-kFastUCode),%ecx // %rcx == -length, where (length < kVeryLong) - jle Lfastpath // long enough for fastpath in microcode - jmp 1f - .align 4,0x90 // 16-byte align inner loops -1: // loop over 64-byte chunks - movdqa (%rsi,%rcx),%xmm0 - movdqa 16(%rsi,%rcx),%xmm1 - movdqa 32(%rsi,%rcx),%xmm2 - movdqa 48(%rsi,%rcx),%xmm3 - - movdqa %xmm0,(%rdi,%rcx) - movdqa %xmm1,16(%rdi,%rcx) - movdqa %xmm2,32(%rdi,%rcx) - movdqa %xmm3,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 0001 - -LMod1: - movdqa -1(%rsi,%rcx),%xmm0 // prime the loop by loading 1st quadword -1: // loop over 64-byte chunks - movdqa 15(%rsi,%rcx),%xmm1 - movdqa 31(%rsi,%rcx),%xmm2 - movdqa 47(%rsi,%rcx),%xmm3 - movdqa 63(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $1,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $1,%xmm2,%xmm3 - palignr $1,%xmm1,%xmm2 - palignr $1,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 0010 - -LMod2: - movdqa -2(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 14(%rsi,%rcx),%xmm1 - movdqa 30(%rsi,%rcx),%xmm2 - movdqa 46(%rsi,%rcx),%xmm3 - movdqa 62(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $2,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $2,%xmm2,%xmm3 - palignr $2,%xmm1,%xmm2 - palignr $2,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 0011 - -LMod3: - movdqa -3(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 13(%rsi,%rcx),%xmm1 - movdqa 29(%rsi,%rcx),%xmm2 - movdqa 45(%rsi,%rcx),%xmm3 - movdqa 61(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $3,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $3,%xmm2,%xmm3 - palignr $3,%xmm1,%xmm2 - palignr $3,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 0100 -// We use the float single data type in order to use "movss" to merge vectors. - -LMod4: - movaps -4(%rsi,%rcx),%xmm0 // 4-byte aligned: prime the loop - jmp 1f - .align 4,0x90 -1: // loop over 64-byte chunks - movaps 12(%rsi,%rcx),%xmm1 - movaps 28(%rsi,%rcx),%xmm2 - movss %xmm1,%xmm0 // copy low 4 bytes of source into destination - pshufd $(0x39),%xmm0,%xmm0 // rotate right 4 bytes (mask -- 00 11 10 01) - movaps 44(%rsi,%rcx),%xmm3 - movss %xmm2,%xmm1 - pshufd $(0x39),%xmm1,%xmm1 - movaps 60(%rsi,%rcx),%xmm4 - movss %xmm3,%xmm2 - pshufd $(0x39),%xmm2,%xmm2 - - movaps %xmm0,(%rdi,%rcx) - movss %xmm4,%xmm3 - pshufd $(0x39),%xmm3,%xmm3 - movaps %xmm1,16(%rdi,%rcx) - movaps %xmm2,32(%rdi,%rcx) - movaps %xmm4,%xmm0 - movaps %xmm3,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 0101 - -LMod5: - movdqa -5(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 11(%rsi,%rcx),%xmm1 - movdqa 27(%rsi,%rcx),%xmm2 - movdqa 43(%rsi,%rcx),%xmm3 - movdqa 59(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $5,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $5,%xmm2,%xmm3 - palignr $5,%xmm1,%xmm2 - palignr $5,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 0110 - -LMod6: - movdqa -6(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 10(%rsi,%rcx),%xmm1 - movdqa 26(%rsi,%rcx),%xmm2 - movdqa 42(%rsi,%rcx),%xmm3 - movdqa 58(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $6,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $6,%xmm2,%xmm3 - palignr $6,%xmm1,%xmm2 - palignr $6,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 0111 - -LMod7: - movdqa -7(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 9(%rsi,%rcx),%xmm1 - movdqa 25(%rsi,%rcx),%xmm2 - movdqa 41(%rsi,%rcx),%xmm3 - movdqa 57(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $7,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $7,%xmm2,%xmm3 - palignr $7,%xmm1,%xmm2 - palignr $7,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 1000 -// We use the float double data type in order to use "shufpd" to shift by 8 bytes. - -LMod8: - cmpl $(-kFastUCode),%ecx // %rcx == -length, where (length < kVeryLong) - jle Lfastpath // long enough for fastpath in microcode - movapd -8(%rsi,%rcx),%xmm0 // 8-byte aligned: prime the loop - jmp 1f - .align 4,0x90 -1: // loop over 64-byte chunks - movapd 8(%rsi,%rcx),%xmm1 - movapd 24(%rsi,%rcx),%xmm2 - shufpd $01,%xmm1,%xmm0 // %xmm0 <- shr( %xmm0 || %xmm1, 8 bytes) - movapd 40(%rsi,%rcx),%xmm3 - shufpd $01,%xmm2,%xmm1 - movapd 56(%rsi,%rcx),%xmm4 - shufpd $01,%xmm3,%xmm2 - - movapd %xmm0,(%rdi,%rcx) - shufpd $01,%xmm4,%xmm3 - movapd %xmm1,16(%rdi,%rcx) - movapd %xmm2,32(%rdi,%rcx) - movapd %xmm4,%xmm0 - movapd %xmm3,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 1001 - -LMod9: - movdqa -9(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 7(%rsi,%rcx),%xmm1 - movdqa 23(%rsi,%rcx),%xmm2 - movdqa 39(%rsi,%rcx),%xmm3 - movdqa 55(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $9,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $9,%xmm2,%xmm3 - palignr $9,%xmm1,%xmm2 - palignr $9,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 1010 - -LMod10: - movdqa -10(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 6(%rsi,%rcx),%xmm1 - movdqa 22(%rsi,%rcx),%xmm2 - movdqa 38(%rsi,%rcx),%xmm3 - movdqa 54(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $10,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $10,%xmm2,%xmm3 - palignr $10,%xmm1,%xmm2 - palignr $10,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 1011 - -LMod11: - movdqa -11(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 5(%rsi,%rcx),%xmm1 - movdqa 21(%rsi,%rcx),%xmm2 - movdqa 37(%rsi,%rcx),%xmm3 - movdqa 53(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $11,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $11,%xmm2,%xmm3 - palignr $11,%xmm1,%xmm2 - palignr $11,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 1100 -// We use the float single data type in order to use "movss" to merge vectors. - -LMod12: - movss (%rsi,%rcx),%xmm0 // prefetch 1st four bytes of source, right justified - jmp 1f - .align 4,0x90 -1: // loop over 64-byte chunks - pshufd $(0x93),4(%rsi,%rcx),%xmm1 // load and rotate right 12 bytes (mask -- 10 01 00 11) - pshufd $(0x93),20(%rsi,%rcx),%xmm2 - pshufd $(0x93),36(%rsi,%rcx),%xmm3 - pshufd $(0x93),52(%rsi,%rcx),%xmm4 - - movaps %xmm4,%xmm5 - movss %xmm3,%xmm4 // copy low 4 bytes of source into destination - movss %xmm2,%xmm3 - movss %xmm1,%xmm2 - movss %xmm0,%xmm1 - - movaps %xmm1,(%rdi,%rcx) - movaps %xmm2,16(%rdi,%rcx) - movaps %xmm5,%xmm0 - movaps %xmm3,32(%rdi,%rcx) - movaps %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 1101 - -LMod13: - movdqa -13(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 3(%rsi,%rcx),%xmm1 - movdqa 19(%rsi,%rcx),%xmm2 - movdqa 35(%rsi,%rcx),%xmm3 - movdqa 51(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $13,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $13,%xmm2,%xmm3 - palignr $13,%xmm1,%xmm2 - palignr $13,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 1110 - -LMod14: - movdqa -14(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 2(%rsi,%rcx),%xmm1 - movdqa 18(%rsi,%rcx),%xmm2 - movdqa 34(%rsi,%rcx),%xmm3 - movdqa 50(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $14,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $14,%xmm2,%xmm3 - palignr $14,%xmm1,%xmm2 - palignr $14,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for medium length operands in which low four bits of %rsi == 1111 - -LMod15: - movdqa -15(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq -1: // loop over 64-byte chunks - movdqa 1(%rsi,%rcx),%xmm1 - movdqa 17(%rsi,%rcx),%xmm2 - movdqa 33(%rsi,%rcx),%xmm3 - movdqa 49(%rsi,%rcx),%xmm4 - - movdqa %xmm0,%xmm5 - movdqa %xmm4,%xmm0 - - palignr $15,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 ) - palignr $15,%xmm2,%xmm3 - palignr $15,%xmm1,%xmm2 - palignr $15,%xmm5,%xmm1 - - movdqa %xmm1,(%rdi,%rcx) - movdqa %xmm2,16(%rdi,%rcx) - movdqa %xmm3,32(%rdi,%rcx) - movdqa %xmm4,48(%rdi,%rcx) - - addq $64,%rcx - jnz 1b - - jmp LShort // copy remaining 0..63 bytes and done - - -// Reverse moves. These are not optimized as aggressively as their forward -// counterparts, as they are only used with destructive overlap. -// rdx = length -// rsi = source ptr -// rdi = dest ptr - -LReverse: - addq %rdx,%rsi // point to end of strings - addq %rdx,%rdi - cmpq $(kShort),%rdx // long enough to bother with SSE? - ja LReverseNotShort // yes - -// Handle reverse short copies. -// edx = length (<= kShort) -// rsi = one byte past end of source -// rdi = one byte past end of dest - -LReverseShort: - movl %edx,%ecx // copy length - shrl $3,%ecx // #quadwords - jz 3f -1: - subq $8,%rsi - movq (%rsi),%rax - subq $8,%rdi - movq %rax,(%rdi) - decl %ecx - jnz 1b -3: - andl $7,%edx // bytes? - jz 5f -4: - decq %rsi - movb (%rsi),%al - decq %rdi - movb %al,(%rdi) - decl %edx - jnz 4b -5: - movq %r11,%rax // get return value (dst ptr) for memcpy/memmove - popq %rbp - ret - -// Handle a reverse move long enough to justify using SSE. -// rdx = length (> kShort) -// rsi = one byte past end of source -// rdi = one byte past end of dest - -LReverseNotShort: - movl %edi,%ecx // copy destination - andl $15,%ecx // get #bytes to align destination - je LReverseDestAligned // already aligned - subq %rcx,%rdx // adjust length -1: // loop copying 1..15 bytes - decq %rsi - movb (%rsi),%al - decq %rdi - movb %al,(%rdi) - decl %ecx - jnz 1b - -// Destination is now aligned. Prepare for reverse loops. - -LReverseDestAligned: - movq %rdx,%rcx // copy length - andl $63,%edx // get remaining bytes for LReverseShort - andq $-64,%rcx // get number of bytes we will copy in inner loop - subq %rcx,%rsi // point to endpoint of copy - subq %rcx,%rdi - testl $15,%esi // is source aligned too? - jnz LReverseUnalignedLoop // no - -LReverseAlignedLoop: // loop over 64-byte chunks - movdqa -16(%rsi,%rcx),%xmm0 - movdqa -32(%rsi,%rcx),%xmm1 - movdqa -48(%rsi,%rcx),%xmm2 - movdqa -64(%rsi,%rcx),%xmm3 - - movdqa %xmm0,-16(%rdi,%rcx) - movdqa %xmm1,-32(%rdi,%rcx) - movdqa %xmm2,-48(%rdi,%rcx) - movdqa %xmm3,-64(%rdi,%rcx) - - subq $64,%rcx - jne LReverseAlignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - - -// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. - -LReverseUnalignedLoop: // loop over 64-byte chunks - movdqu -16(%rsi,%rcx),%xmm0 - movdqu -32(%rsi,%rcx),%xmm1 - movdqu -48(%rsi,%rcx),%xmm2 - movdqu -64(%rsi,%rcx),%xmm3 - - movdqa %xmm0,-16(%rdi,%rcx) - movdqa %xmm1,-32(%rdi,%rcx) - movdqa %xmm2,-48(%rdi,%rcx) - movdqa %xmm3,-64(%rdi,%rcx) - - subq $64,%rcx - jne LReverseUnalignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - -PLATFUNC_DESCRIPTOR(bcopy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) -PLATFUNC_DESCRIPTOR(memcpy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) -PLATFUNC_DESCRIPTOR(memmove,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2) diff --git a/src/libc/x86_64/string/bcopy_sse42.S b/src/libc/x86_64/string/bcopy_sse42.S deleted file mode 100644 index 236e45494..000000000 --- a/src/libc/x86_64/string/bcopy_sse42.S +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -/* - * The bcopy/memcpy loops, tuned for Nehalem. This is the 64-bit version. - * - * The following #defines are tightly coupled to the u-architecture: - */ - -#define kShort 80 // too short to bother with SSE (must be >=80) - - -// void bcopy(const void *src, void *dst, size_t len); - -PLATFUNC_FUNCTION_START(bcopy, sse42, 64, 5) - pushq %rbp // set up a frame for backtraces - movq %rsp,%rbp - movq %rsi,%rax // copy dest ptr - movq %rdi,%rsi // xchange source and dest ptrs - movq %rax,%rdi - subq %rsi,%rax // (dest - source) - cmpq %rdx,%rax // must move in reverse if (dest - source) < length - jb LReverseIsland - cmpq $(kShort),%rdx // long enough to bother with SSE? - jbe LShort // no - jmp LNotShort - -// -// void *memcpy(void *dst, const void *src, size_t len); -// void *memmove(void *dst, const void *src, size_t len); -// - -PLATFUNC_FUNCTION_START(memcpy, sse42, 64, 0) // void *memcpy(void *dst, const void *src, size_t len) -PLATFUNC_FUNCTION_START(memmove, sse42, 64, 0) // void *memmove(void *dst, const void *src, size_t len) - pushq %rbp // set up a frame for backtraces - movq %rsp,%rbp - movq %rdi,%r11 // save return value here - movq %rdi,%rax - subq %rsi,%rax // (dest - source) - cmpq %rdx,%rax // must move in reverse if (dest - source) < length - jb LReverseIsland - cmpq $(kShort),%rdx // long enough to bother with SSE? - ja LNotShort // yes - -// Handle short forward copies. As the most common case, this is the fall-through path. -// rdx = length (<= kShort) -// rsi = source ptr -// rdi = dest ptr - -LShort: - movl %edx,%ecx // copy length using 32-bit operation - shrl $2,%ecx // get #doublewords - jz 3f -2: // loop copying doublewords - movl (%rsi),%eax - addq $4,%rsi - movl %eax,(%rdi) - addq $4,%rdi - decl %ecx - jnz 2b -3: // handle leftover bytes (0..3) in last word - andl $3,%edx // any leftover bytes? - jz 5f -4: // loop copying bytes - movb (%rsi),%al - incq %rsi - movb %al,(%rdi) - incq %rdi - decl %edx - jnz 4b -5: - movq %r11,%rax // get return value (dst ptr) for memcpy/memmove - popq %rbp - ret - - -LReverseIsland: // keep the "jb" above a short branch... - jmp LReverse // ...because reverse moves are uncommon - - -// Handle forward moves that are long enough to justify use of SSE. -// First, 16-byte align the destination. -// rdx = length (> kShort) -// rsi = source ptr -// rdi = dest ptr - -LNotShort: - movl %edi,%ecx // copy low half of destination ptr - negl %ecx - andl $15,%ecx // get #bytes to align destination - jz LDestAligned // already aligned - subl %ecx,%edx // decrement length -1: // loop copying 1..15 bytes - movb (%rsi),%al - inc %rsi - movb %al,(%rdi) - inc %rdi - dec %ecx - jnz 1b - - -// Destination is now aligned. Nehalem does a great job with unaligned SSE loads, -// so we use MOVDQU rather than aligned loads and shifts. Since kShort>=80, we -// know there is at least one 64-byte chunk to move. -// When we enter the copy loops, the following registers are set up: -// rdx = residual length (0..63) -// rcx = -(length to move), a multiple of 64 less than 2GB -// rsi = ptr to 1st source byte not to move (unaligned) -// rdi = ptr to 1st dest byte not to move (aligned) - -LDestAligned: - movq %rdx,%rcx // copy length - andl $63,%edx // get remaining bytes for LShort - andq $-64,%rcx // get number of bytes we will copy in inner loop - addq %rcx,%rsi // point to 1st byte not copied - addq %rcx,%rdi - negq %rcx // now generate offset to 1st byte to be copied - testl $15,%esi // source also aligned? - jnz LUnalignedLoop - jmp LAlignedLoop - - -// Forward loop for aligned operands. - - .align 4,0x90 // 16-byte align inner loops -LAlignedLoop: // loop over 64-byte chunks - movdqa (%rsi,%rcx),%xmm0 - movdqa 16(%rsi,%rcx),%xmm1 - movdqa 32(%rsi,%rcx),%xmm2 - movdqa 48(%rsi,%rcx),%xmm3 - - movdqa %xmm0,(%rdi,%rcx) - movdqa %xmm1,16(%rdi,%rcx) - movdqa %xmm2,32(%rdi,%rcx) - movdqa %xmm3,48(%rdi,%rcx) - - addq $64,%rcx - jnz LAlignedLoop - - jmp LShort // copy remaining 0..63 bytes and done - - -// Forward loop for unaligned operands. - - .align 4,0x90 // 16-byte align inner loops -LUnalignedLoop: // loop over 64-byte chunks - movdqu (%rsi,%rcx),%xmm0 - movdqu 16(%rsi,%rcx),%xmm1 - movdqu 32(%rsi,%rcx),%xmm2 - movdqu 48(%rsi,%rcx),%xmm3 - - movdqa %xmm0,(%rdi,%rcx) - movdqa %xmm1,16(%rdi,%rcx) - movdqa %xmm2,32(%rdi,%rcx) - movdqa %xmm3,48(%rdi,%rcx) - - addq $64,%rcx - jnz LUnalignedLoop - - jmp LShort // copy remaining 0..63 bytes and done - - -// Reverse moves. These are only used with destructive overlap. -// rdx = length -// rsi = source ptr -// rdi = dest ptr - -LReverse: - addq %rdx,%rsi // point to end of strings - addq %rdx,%rdi - cmpq $(kShort),%rdx // long enough to bother with SSE? - ja LReverseNotShort // yes - -// Handle reverse short copies. -// edx = length (<= kShort) -// rsi = one byte past end of source -// rdi = one byte past end of dest - -LReverseShort: - movl %edx,%ecx // copy length - shrl $3,%ecx // #quadwords - jz 3f -1: - subq $8,%rsi - movq (%rsi),%rax - subq $8,%rdi - movq %rax,(%rdi) - decl %ecx - jnz 1b -3: - andl $7,%edx // bytes? - jz 5f -4: - decq %rsi - movb (%rsi),%al - decq %rdi - movb %al,(%rdi) - decl %edx - jnz 4b -5: - movq %r11,%rax // get return value (dst ptr) for memcpy/memmove - popq %rbp - ret - -// Handle a reverse move long enough to justify using SSE. -// rdx = length (> kShort) -// rsi = one byte past end of source -// rdi = one byte past end of dest - -LReverseNotShort: - movl %edi,%ecx // copy destination - andl $15,%ecx // get #bytes to align destination - jz LReverseDestAligned // already aligned - subq %rcx,%rdx // adjust length -1: // loop copying 1..15 bytes - decq %rsi - movb (%rsi),%al - decq %rdi - movb %al,(%rdi) - decl %ecx - jnz 1b - -// Destination is now aligned. Prepare for reverse loops. - -LReverseDestAligned: - movq %rdx,%rcx // copy length - andl $63,%edx // get remaining bytes for LReverseShort - andq $-64,%rcx // get number of bytes we will copy in inner loop - subq %rcx,%rsi // point to endpoint of copy - subq %rcx,%rdi - testl $15,%esi // is source aligned too? - jnz LReverseUnalignedLoop // no - -LReverseAlignedLoop: // loop over 64-byte chunks - movdqa -16(%rsi,%rcx),%xmm0 - movdqa -32(%rsi,%rcx),%xmm1 - movdqa -48(%rsi,%rcx),%xmm2 - movdqa -64(%rsi,%rcx),%xmm3 - - movdqa %xmm0,-16(%rdi,%rcx) - movdqa %xmm1,-32(%rdi,%rcx) - movdqa %xmm2,-48(%rdi,%rcx) - movdqa %xmm3,-64(%rdi,%rcx) - - subq $64,%rcx - jne LReverseAlignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - - -// Reverse, unaligned loop. LDDQU==MOVDQU on these machines. - -LReverseUnalignedLoop: // loop over 64-byte chunks - movdqu -16(%rsi,%rcx),%xmm0 - movdqu -32(%rsi,%rcx),%xmm1 - movdqu -48(%rsi,%rcx),%xmm2 - movdqu -64(%rsi,%rcx),%xmm3 - - movdqa %xmm0,-16(%rdi,%rcx) - movdqa %xmm1,-32(%rdi,%rcx) - movdqa %xmm2,-48(%rdi,%rcx) - movdqa %xmm3,-64(%rdi,%rcx) - - subq $64,%rcx - jne LReverseUnalignedLoop - - jmp LReverseShort // copy remaining 0..63 bytes and done - - -PLATFUNC_DESCRIPTOR(bcopy,sse42,kHasSSE4_2,0) -PLATFUNC_DESCRIPTOR(memcpy,sse42,kHasSSE4_2,0) -PLATFUNC_DESCRIPTOR(memmove,sse42,kHasSSE4_2,0) diff --git a/src/libc/x86_64/string/bzero.c b/src/libc/x86_64/string/bzero.c deleted file mode 100644 index d5feed575..000000000 --- a/src/libc/x86_64/string/bzero.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse42) -PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse2) - -static const platfunc_descriptor *bzero_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse42), - PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse2), - 0 -}; - -void *bzero_chooser() __asm__("_bzero"); -void *bzero_chooser() { - __asm__(".desc _bzero, 0x100"); - return find_platform_function((const platfunc_descriptor **) bzero_platfunc_descriptors); -} diff --git a/src/libc/x86_64/string/bzero_sse2.S b/src/libc/x86_64/string/bzero_sse2.S deleted file mode 100644 index 3d7d596c9..000000000 --- a/src/libc/x86_64/string/bzero_sse2.S +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -/* - * Bzero, tuned for Pentium-M class processors with SSE2 - * and 64-byte cache lines. This is the 64-bit version. - * - * This routine is also used for memset(p,0,n), which is a common case - * since gcc sometimes silently maps bzero() into memset(). As a result, - * we always load the original ptr into %eax before returning. - */ - -#define kShort 80 // too short to bother with SSE (must be >=80) -#define kVeryLong (1024*1024) - -// void bzero(void *b, size_t len); - -PLATFUNC_FUNCTION_START_GENERIC(bzero, sse2, 64, 5) - pushq %rbp // set up a frame for backtraces - movq %rsp,%rbp - xorl %eax,%eax // set fill data to 0 - movq %rdi,%r11 // save original ptr as return value - cmpq $(kShort),%rsi // long enough for SSE? - jg LNotShort // yes - -// Here for short operands or the end of long ones. -// %esi = length (<= kShort) -// %rdi = ptr -// %eax = zero - -Lshort: - cmpl $16,%esi // long enough to word align? - jge 3f // yes - test %esi,%esi // length==0? - jz 6f -1: - movb %al,(%rdi) // zero a byte - incq %rdi - decl %esi - jnz 1b - jmp 6f -2: - movb %al,(%rdi) // zero a byte - incq %rdi - decl %esi -3: - testl $3,%edi // is ptr doubleword aligned? - jnz 2b // no - movl %esi,%ecx // copy length - shrl $2,%esi // #doublewords to store -4: - movl %eax,(%rdi) // zero an aligned doubleword - addq $4,%rdi - decl %esi - jnz 4b - andl $3,%ecx // mask down to #bytes at end (0..3) - jz 6f // none -5: - movb %al,(%rdi) // zero a byte - incq %rdi - decl %ecx - jnz 5b -6: - movq %r11,%rax // set return value in case this was a call of memset() - popq %rbp - ret - - -// We will be using SSE, so align ptr. -// %rsi = length (> kShort) -// %rdi = ptr -// %eax = zero - -LNotShort: - movl %edi,%ecx // get #bytes to 16-byte align ptr - negl %ecx - andl $15,%ecx - jz LDestAligned // already aligned - subq %rcx,%rsi // decrement length -0: // loop storing bytes to align the ptr - movb %al,(%rdi) // pack in a byte - incq %rdi - decl %ecx - jnz 0b - -// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks. -// %rsi = length (> (kShort-15)) -// %rdi = ptr (aligned) -// %eax = zero - -LDestAligned: - movq %rsi,%rcx - andl $63,%esi // mask down to residual length (0..63) - andq $-64,%rcx // get #bytes we will zero in this loop - pxor %xmm0,%xmm0 // zero an SSE register - addq %rcx,%rdi // increment ptr by length to move - cmpq $(kVeryLong),%rcx // long enough to justify non-temporal stores? - jae LVeryLong // yes - negq %rcx // negate length to move - jmp 1f - -// Loop over 64-byte chunks, storing into cache. - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movdqa %xmm0,(%rdi,%rcx) - movdqa %xmm0,16(%rdi,%rcx) - movdqa %xmm0,32(%rdi,%rcx) - movdqa %xmm0,48(%rdi,%rcx) - addq $64,%rcx - jne 1b - - jmp Lshort - -// Very long operands: use non-temporal stores to bypass cache. - -LVeryLong: - negq %rcx // negate length to move - jmp 1f - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movntdq %xmm0,(%rdi,%rcx) - movntdq %xmm0,16(%rdi,%rcx) - movntdq %xmm0,32(%rdi,%rcx) - movntdq %xmm0,48(%rdi,%rcx) - addq $64,%rcx - jne 1b - - sfence // required by non-temporal stores - jmp Lshort - -PLATFUNC_DESCRIPTOR(bzero,sse2,kHasSSE2,kHasSSE4_2) diff --git a/src/libc/x86_64/string/bzero_sse42.S b/src/libc/x86_64/string/bzero_sse42.S deleted file mode 100644 index 415d8d473..000000000 --- a/src/libc/x86_64/string/bzero_sse42.S +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -/* - * Bzero, tuned for processors with SSE4.2 and 64-byte cache lines, ie Nehalem. - * We don't actually use SSE4.2, but rather use it to identify Nehalem. - * This is the 64-bit version. - * - * We do not use nontemporal operations, but use MOVDQA in preference to REP/STOS. - * - * This routine is also used for memset(p,0,n), which is a common case - * since gcc sometimes silently maps bzero() into memset(). As a result, - * we always load the original ptr into %eax before returning. - */ - -#define kShort 80 // too short to bother with SSE (must be >=80) - - -// void bzero(void *b, size_t len); - -PLATFUNC_FUNCTION_START(bzero, sse42, 64, 5) - pushq %rbp // set up a frame for backtraces - movq %rsp,%rbp - xorl %eax,%eax // set fill data to 0 - movq %rdi,%r11 // save original ptr as return value - cmpq $(kShort),%rsi // long enough for SSE? - jg LNotShort // yes - -// Here for short operands or the end of long ones. -// %esi = length (<= kShort) -// %rdi = ptr -// %eax = zero - -Lshort: - cmpl $12,%esi // long enough to word align? - jge 3f // yes - test %esi,%esi // length==0? - jz 6f -1: - movb %al,(%rdi) // zero a byte - incq %rdi - decl %esi - jnz 1b - jmp 6f -2: - movb %al,(%rdi) // zero a byte - incq %rdi - decl %esi -3: - testl $3,%edi // is ptr doubleword aligned? - jnz 2b // no - movl %esi,%ecx // copy length - shrl $2,%esi // #doublewords to store -4: - movl %eax,(%rdi) // zero an aligned doubleword - addq $4,%rdi - decl %esi - jnz 4b - andl $3,%ecx // mask down to #bytes at end (0..3) - jz 6f // none -5: - movb %al,(%rdi) // zero a byte - incq %rdi - decl %ecx - jnz 5b -6: - movq %r11,%rax // set return value in case this was a call of memset() - popq %rbp - ret - - -// We will be using SSE, so align ptr. -// %rsi = length (> kShort) -// %rdi = ptr -// %eax = zero - -LNotShort: - testl $3,%edi // 4-byte aligned? - jz 2f // yes - movb %al,(%rdi) // zero another byte - incq %rdi - decq %rsi - jmp LNotShort -1: // zero doublewords until 16-byte aligned - movl %eax,(%rdi) - addq $4,%rdi - subq $4,%rsi -2: - testl $15,%edi // 16-byte aligned? - jnz 1b // no - -// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks. -// %rsi = length (> (kShort-15)) -// %rdi = ptr (aligned) -// %eax = zero - -LDestAligned: - movq %rsi,%rcx - andl $63,%esi // mask down to residual length (0..63) - andq $-64,%rcx // get #bytes we will zero in this loop - pxor %xmm0,%xmm0 // zero an SSE register - addq %rcx,%rdi // increment ptr by length to move - negq %rcx // negate length to move - jmp 1f - -// Loop over 64-byte chunks, storing into cache. - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movdqa %xmm0,(%rdi,%rcx) - movdqa %xmm0,16(%rdi,%rcx) - movdqa %xmm0,32(%rdi,%rcx) - movdqa %xmm0,48(%rdi,%rcx) - addq $64,%rcx - jne 1b - - jmp Lshort - - -PLATFUNC_DESCRIPTOR(bzero,sse42,kHasSSE4_2,0) diff --git a/src/libc/x86_64/string/ffs.S b/src/libc/x86_64/string/ffs.S deleted file mode 100644 index 8a4eb8302..000000000 --- a/src/libc/x86_64/string/ffs.S +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - .text - - .align 2 - .globl _ffs -_ffs: - movl $(-1), %edx - bsfl %edi, %eax - cmovel %edx, %eax - incl %eax - ret - - - .align 2 - .globl _ffsl -_ffsl: - movl $(-1), %edx - bsfq %rdi, %rax - cmovel %edx, %eax - incl %eax - ret - - - .align 2 - .globl _fls -_fls: - movl $(-1), %edx - bsrl %edi, %eax - cmovel %edx, %eax - incl %eax - ret - - - .align 2 - .globl _flsl -_flsl: - movl $(-1), %edx - bsrq %rdi, %rax - cmovel %edx, %eax - incl %eax - ret diff --git a/src/libc/x86_64/string/longcopy_sse3x.S b/src/libc/x86_64/string/longcopy_sse3x.S deleted file mode 100644 index 86dad2925..000000000 --- a/src/libc/x86_64/string/longcopy_sse3x.S +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include - -/* - * The bcopy/memcpy loops for very long operands, tuned for 64-bit - * Pentium-M class processors with Supplemental SSE3 and 64-byte cache lines. - * This is the 64-bit version. - * - * The following #defines are tightly coupled to the u-architecture: - */ - -#define kBigChunk (256*1024) // outer loop chunk size for kVeryLong sized operands - - -// Very long forward moves. These are at least several pages, so we loop over big -// chunks of memory (kBigChunk in size.) We first prefetch the chunk, and then copy -// it using non-temporal stores. Hopefully all the reads occur in the prefetch loop, -// so the copy loop reads from L2 and writes directly to memory (with write combining.) -// This minimizes bus turnaround and maintains good DRAM page locality. -// Note that for this scheme to work, kVeryLong must be a large fraction of L2 cache -// size. Otherwise, it is counter-productive to bypass L2 on the stores. -// -// We are called from the platfunc bcopy loops when they encounter very long -// operands, with the standard ABI: -// rdi = dest ptr -// rsi = source ptr -// rdx = length (>= 8kb, probably much bigger) - -// void longcopy(const void *dest, void *sou, size_t len) - - .private_extern _longcopy -_longcopy: - pushq %rbp // set up a frame for backtraces - movq %rsp,%rbp - movl %edi,%eax // copy dest ptr - negl %eax - andl $63,%eax // get #bytes to cache line align destination - jz LBigChunkLoop // already aligned - - // Cache line align destination, so temporal stores in copy loops work right. - // The recursive call returns with the source and dest ptrs properly updated. - - subq %rax,%rdx // get length remaining after dest is aligned - pushq %rdx // save length remaining - movl %eax,%edx // #bytes to copy to align destination - call _memcpy - popq %rdx // recover adjusted length - -// Loop over big chunks. -// rdx = length remaining (>= 4096) -// rdi = dest (64-byte aligned) -// rsi = source (may be unaligned) - -LBigChunkLoop: - movl $(kBigChunk),%r8d // assume we can do a full chunk - cmpq %r8,%rdx // do we have a full chunk left to do? - cmovbl %edx,%r8d // if not, only move what we have left - andl $-4096,%r8d // we work in page multiples - xorl %eax,%eax // initialize chunk offset - jmp LTouchLoop - -// Touch in the next chunk. We try to keep the prefetch unit in "kick-start" mode, -// by touching two adjacent cache lines every 8 lines of each page, in four slices. -// Because the source may be unaligned, we use byte loads to touch. -// rdx = length remaining (including this chunk) -// rdi = ptr to start of dest chunk -// rsi = ptr to start of source chunk -// r8d = chunk length (multiples of pages, less than 2**32) -// ecx = scratch reg used to read a byte of each cache line -// eax = chunk offset - - .align 4,0x90 // 16-byte align inner loops -LTouchLoop: - movzb (%rsi,%rax),%ecx // touch line 0, 2, 4, or 6 of page - movzb 1*64(%rsi,%rax),%ecx // touch line 1, 3, 5, or 7 - movzb 8*64(%rsi,%rax),%ecx // touch line 8, 10, 12, or 14 - movzb 9*64(%rsi,%rax),%ecx // etc - - movzb 16*64(%rsi,%rax),%ecx - movzb 17*64(%rsi,%rax),%ecx - movzb 24*64(%rsi,%rax),%ecx - movzb 25*64(%rsi,%rax),%ecx - - movzb 32*64(%rsi,%rax),%ecx - movzb 33*64(%rsi,%rax),%ecx - movzb 40*64(%rsi,%rax),%ecx - movzb 41*64(%rsi,%rax),%ecx - - movzb 48*64(%rsi,%rax),%ecx - movzb 49*64(%rsi,%rax),%ecx - movzb 56*64(%rsi,%rax),%ecx - movzb 57*64(%rsi,%rax),%ecx - - subl $-128,%eax // next slice of page (adding 128 w 8-bit immediate) - testl $512,%eax // done with this page? - jz LTouchLoop // no, next of four slices - addl $(4096-512),%eax // move on to next page - cmpl %eax,%r8d // done with this chunk? - jnz LTouchLoop // no, do next page - - // The chunk has been pre-fetched, now copy it using non-temporal stores. - // There are two copy loops, depending on whether the source is 16-byte aligned - // or not. - - movl %r8d,%ecx // copy chunk size to a reg that doesn't use REX prefix - addq %rcx,%rsi // increment ptrs by chunk length - addq %rcx,%rdi - subq %rcx,%rdx // adjust remaining length - negq %rcx // prepare loop index (counts up to 0) - testl $15,%esi // is source 16-byte aligned? - jnz LVeryLongUnaligned // no - jmp LVeryLongAligned - - .align 4,0x90 // 16-byte align inner loops -LVeryLongAligned: // aligned loop over 128-bytes - movdqa (%rsi,%rcx),%xmm0 - movdqa 16(%rsi,%rcx),%xmm1 - movdqa 32(%rsi,%rcx),%xmm2 - movdqa 48(%rsi,%rcx),%xmm3 - movdqa 64(%rsi,%rcx),%xmm4 - movdqa 80(%rsi,%rcx),%xmm5 - movdqa 96(%rsi,%rcx),%xmm6 - movdqa 112(%rsi,%rcx),%xmm7 - - movntdq %xmm0,(%rdi,%rcx) - movntdq %xmm1,16(%rdi,%rcx) - movntdq %xmm2,32(%rdi,%rcx) - movntdq %xmm3,48(%rdi,%rcx) - movntdq %xmm4,64(%rdi,%rcx) - movntdq %xmm5,80(%rdi,%rcx) - movntdq %xmm6,96(%rdi,%rcx) - movntdq %xmm7,112(%rdi,%rcx) - - subq $-128,%rcx // add 128 with an 8-bit immediate - jnz LVeryLongAligned - jmp LVeryLongChunkEnd - - .align 4,0x90 // 16-byte align inner loops -LVeryLongUnaligned: // unaligned loop over 128-bytes - movdqu (%rsi,%rcx),%xmm0 - movdqu 16(%rsi,%rcx),%xmm1 - movdqu 32(%rsi,%rcx),%xmm2 - movdqu 48(%rsi,%rcx),%xmm3 - movdqu 64(%rsi,%rcx),%xmm4 - movdqu 80(%rsi,%rcx),%xmm5 - movdqu 96(%rsi,%rcx),%xmm6 - movdqu 112(%rsi,%rcx),%xmm7 - - movntdq %xmm0,(%rdi,%rcx) - movntdq %xmm1,16(%rdi,%rcx) - movntdq %xmm2,32(%rdi,%rcx) - movntdq %xmm3,48(%rdi,%rcx) - movntdq %xmm4,64(%rdi,%rcx) - movntdq %xmm5,80(%rdi,%rcx) - movntdq %xmm6,96(%rdi,%rcx) - movntdq %xmm7,112(%rdi,%rcx) - - subq $-128,%rcx // add 128 with an 8-bit immediate - jnz LVeryLongUnaligned - -LVeryLongChunkEnd: - cmpq $4096,%rdx // at least another page to go? - jae LBigChunkLoop // yes - - // Done. Call memcpy() again to handle the 0-4095 bytes at the end. - // We still have the args in the right registers: - // rdi = destination ptr - // rsi = source ptr - // rdx = length remaining (0..4095) - - sfence // required by non-temporal stores - testl %edx,%edx // anything left to copy? - jz 1f - call _memcpy -1: - popq %rbp // restore frame ptr - ret diff --git a/src/libc/x86_64/string/memcmp.S b/src/libc/x86_64/string/memcmp.S deleted file mode 100644 index 398357da6..000000000 --- a/src/libc/x86_64/string/memcmp.S +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -// *************** *********** -// * M E M C M P * and * B C M P * -// *************** *********** -// -// int memcmp(const char *s1, const char *s2, size_t len); -// int bcmp(const char *s1, const char *s2, size_t len); -// -// Bcmp returns (+,0,-), whereas memcmp returns the true difference -// between the first differing bytes, but we treat them identically. -// -// We optimize the compare by doing it with SSE. This introduces -// a complication: if we blindly did vector loads from both sides until -// finding a difference, we might get a spurious page fault by -// reading bytes past the difference. To avoid this, we never do a load -// that crosses a page boundary. - -#define kShort 18 // too short for vectors (must be >16) - - .text - .align 4 - - .globl _memcmp - .globl _bcmp - -_memcmp: // int memcmp(const char *s1,const char *s2,size_t len); -_bcmp: // int bcmp(const char *s1,const char *s2,size_t len); - cmpq $(kShort),%rdx // worth accelerating? - ja LNotShort // yes - - -// Too short to bother with parallel compares. Loop over bytes. -// %rdi = LHS ptr -// %rsi = RHS ptr -// %edx = length (<= kShort) - -LShort: - testl %edx,%edx // 0-length? - jnz LShortLoop // no - xorq %rax,%rax // return 0 - jmp LExit - .align 4,0x90 // align inner loops to optimize I-fetch -LShortLoop: // loop over bytes - movzb (%rdi),%eax // get LHS byte - movzb (%rsi),%ecx // get RHS byte - addq $1,%rdi - addq $1,%rsi - subl %ecx,%eax // compare them - jnz LExit // done if not equal - subq $1,%rdx // decrement length - jnz LShortLoop -LExit: // return value is in %eax - ret - -LNotEqual: // here from LLoopOverBytes with LHS in eax - movzb (%rsi),%ecx // get RHS byte - subl %ecx,%eax // generate return value (nonzero) - ret - - -// Loop over bytes until we reach end of a page. -// %rdi = LHS ptr -// %edi = RHS ptr -// %rdx = length remaining after end of loop (i.e., already adjusted) -// %ecx = #bytes until next page (1..15) - - .align 4,0x90 // align inner loops to optimize I-fetch -LLoopOverBytes: - movzb (%rdi),%eax // get LHS byte - addq $1,%rdi - cmpb (%rsi),%al // compare to RHS byte - jnz LNotEqual // done if not equal - addq $1,%rsi - subl $1,%ecx // more to go? - jnz LLoopOverBytes - - -// Long enough to justify overhead of setting up vector compares. In order to -// avoid spurious page faults, we loop over: -// -// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4 -// -// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte -// comparison until reaching the next page, then resume the vector comparison. -// %rdi = LHS ptr -// %rsi = RHS ptr -// %rdx = length (> kShort) - -LNotShort: - movq %rdi,%rax // copy ptrs - movq %rsi,%rcx - andq $4095,%rax // mask down to page offsets - andq $4095,%rcx - cmpq %rax,%rcx // which is bigger? - cmova %rcx,%rax // %eax = max(LHS offset, RHS offset); - movl $4096,%ecx - subl %eax,%ecx // get #bytes to next page crossing - cmpq %rdx,%rcx // will operand run out first? - cmova %edx,%ecx // get min(length remaining, bytes to page end) - movl %ecx,%eax - shrl $4,%ecx // get #chunks till end of operand or page - jnz LLoopOverChunks // enter vector loop - -// Too near page end for vectors. - - subq %rax,%rdx // adjust length remaining - movl %eax,%ecx // %ecx <- #bytes to page end - cmpq $(kShort),%rdx // will there be enough after we cross page for vectors? - ja LLoopOverBytes // yes - addq %rax,%rdx // no, restore total length remaining - jmp LShortLoop // compare rest byte-by-byte (%ecx != 0) - - -// Loop over 16-byte chunks. -// %rdi = LHS ptr -// %rsi = RHS ptr -// %rdx = length remaining -// %ecx = chunk count - - .align 4,0x90 // align inner loops to optimize I-fetch -LLoopOverChunks: - movdqu (%rdi),%xmm0 // get LHS - movdqu (%rsi),%xmm1 // get RHS - addq $16,%rdi - pcmpeqb %xmm1,%xmm0 // compare LHS to RHS - addq $16,%rsi - pmovmskb %xmm0,%eax // collect comparison result bits (1 if equal) - subq $16,%rdx // adjust length remaining - xorl $0xFFFF,%eax // all equal? - jne LDifferent // no, we found differing bytes - subl $1,%ecx // more to go? - jnz LLoopOverChunks - - cmpq $(kShort),%rdx // a lot more to compare? - jbe LShort // no - jmp LNotShort // compute distance to next page crossing etc - - -// Found a difference. -// %rdi = LHS ptr, already advanced by 16 -// %rsi = RHS ptr, already advanced by 16 -// %eax = complemented compare vector (ie, 0 == equal) - -LDifferent: - bsf %eax,%edx // which byte differed? - subq $16,%rdi // point to byte 0 while we wait for bit scan - subq $16,%rsi - movzb (%rdi,%rdx),%eax // get LHS byte - movzb (%rsi,%rdx),%ecx // get RHS byte - subl %ecx,%eax // compute difference (ie, return value) - ret diff --git a/src/libc/x86_64/string/memcpy.c b/src/libc/x86_64/string/memcpy.c deleted file mode 100644 index 7a98a4c79..000000000 --- a/src/libc/x86_64/string/memcpy.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse42) -PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse3x) - -static const platfunc_descriptor *memcpy_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse42), - PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse3x), - 0 -}; - -void *memcpy_chooser() __asm__("_memcpy"); -void *memcpy_chooser() { - __asm__(".desc _memcpy, 0x100"); - return find_platform_function((const platfunc_descriptor **) memcpy_platfunc_descriptors); -} diff --git a/src/libc/x86_64/string/memmove.c b/src/libc/x86_64/string/memmove.c deleted file mode 100644 index 64764235d..000000000 --- a/src/libc/x86_64/string/memmove.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse42) -PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse3x) - -static const platfunc_descriptor *memmove_platfunc_descriptors[] = { - PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse42), - PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse3x), - 0 -}; - -void *memmove_chooser() __asm__("_memmove"); -void *memmove_chooser() { - __asm__(".desc _memmove, 0x100"); - return find_platform_function((const platfunc_descriptor **) memmove_platfunc_descriptors); -} diff --git a/src/libc/x86_64/string/memset.S b/src/libc/x86_64/string/memset.S deleted file mode 100644 index e79c214b3..000000000 --- a/src/libc/x86_64/string/memset.S +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - - -/* This file contains the following functions: - * - * void *memset(void *b, int c, size_t len); - * void memset_pattern4(void *b, const void *c4, size_t len); - * void memset_pattern8(void *b, const void *c8, size_t len); - * void memset_pattern16(void *b, const void *c16, size_t len); - * - * Calls of memset() with c==0 are routed to the bzero() routine. Most of the - * others go to _memset_pattern, which is entered as follows: - * %rdi = ptr to memory to set (aligned) - * %edx = length (which can be short, though we bias in favor of long operands) - * %xmm0 = the pattern to store - * Return conditions: - * %eax, %edi, %esi, %ecx, and %edx all trashed - * - * NB: we avoid "stos" family of instructions (stosl, stosb), as they are very slow - * on P4s and probably other processors. - */ - -#define kShort 255 // for nonzero memset(), too short for commpage - - - .text - .globl _memset - .align 2 -_memset: // void *memset(void *b, int c, size_t len); - andl $0xFF,%esi // (c==0) ? - jnz LNonzero // not a bzero - - movq %rdx,%rsi // put count where bzero() expects it - jmp _bzero // enter _bzero - - -// Handle memset of a nonzero value. - -LNonzero: - movq %rdi,%r8 // preserve the original pointer so we can return it - movl %esi,%eax // replicate byte in %esi into all four bytes - shll $8,%esi - orl %esi,%eax - movl %eax,%esi - shll $16,%esi - orl %esi,%eax // now %eax has "c" in all 4 bytes - cmpq $(kShort),%rdx // is operand too short for SSE? - ja LCallCommpage // no - - // Nonzero memset() too short to call commpage. - // %eax = replicated 4-byte pattern - // %rdi = ptr - // %edx = length (<= kShort) - - cmpl $16,%edx // long enough to word align? - jge 3f // yes - test %edx,%edx // length==0? - jz 6f -1: - movb %al,(%rdi) // pack in a byte - addq $1,%rdi - subl $1,%edx - jnz 1b - jmp 6f -2: - movb %al,(%rdi) // pack in a byte - addq $1,%rdi - subl $1,%edx -3: - test $3,%edi // is ptr doubleword aligned? - jnz 2b // no - movl %edx,%ecx // copy length - shrl $2,%edx // #doublewords to store -4: - movl %eax,(%rdi) // store aligned doubleword - addq $4,%rdi - subl $1,%edx - jnz 4b - andl $3,%ecx // any leftover bytes? - jz 6f // no -5: - movb %al,(%rdi) // pack in a byte - addq $1,%rdi - subl $1,%ecx - jnz 5b -6: - movq %r8,%rax // get return value (ie, original ptr) - ret - - // Nonzero memset() is long enough to call commpage. - // %eax = replicated 4-byte pattern - // %rdi = ptr - // %rdx = length (> kShort) - -LCallCommpage: - movd %eax,%xmm0 // move %eax to low 4 bytes of %xmm0 - pshufd $(0x00),%xmm0,%xmm0 // replicate across the vector - movq %rdi,%rcx // copy dest ptr - negl %ecx - andl $15,%ecx // get #bytes to align ptr - jz 2f // skip if already aligned - subq %rcx,%rdx // decrement length -1: - movb %al,(%rdi) // pack in a byte - addq $1,%rdi - subl $1,%ecx - jnz 1b -2: // ptr aligned, length long enough to justify - call Lmemset_pattern // call commpage to do the heavy lifting - movq %r8,%rax // get return value (ie, original ptr) - ret - - - // Handle memset of a 16-byte pattern. - - .globl _memset_pattern16 - .align 2, 0x90 -_memset_pattern16: // void memset_pattern16(void *b, const void *c16, size_t len); - movdqu (%rsi),%xmm0 // load the pattern - jmp LAlignPtr - - - // Handle memset of an 8-byte pattern. - - .globl _memset_pattern8 - .align 2, 0x90 -_memset_pattern8: // void memset_pattern8(void *b, const void *c8, size_t len); - movq (%rsi),%xmm0 // load pattern into low 8 bytes - punpcklqdq %xmm0,%xmm0 // replicate into all 16 - jmp LAlignPtr - - // Handle memset of a 4-byte pattern. - - .globl _memset_pattern4 - .align 2, 0x90 -_memset_pattern4: // void memset_pattern4(void *b, const void *c4, size_t len); - movd (%rsi),%xmm0 // load pattern into low 4 bytes - pshufd $(0x00),%xmm0,%xmm0 // replicate the 4 bytes across the vector - - - // Align ptr if necessary. We must rotate the pattern right for each byte we - // store while aligning the ptr. Since there is no rotate instruction in SSE3, - // we have to synthesize the rotates. - // %rdi = ptr - // %rdx = length - // %xmm0 = pattern - -LAlignPtr: // NB: can drop down to here! - cmpq $100,%rdx // long enough to bother aligning ptr? - movq %rdi,%rcx // copy ptr - jb LReady // not long enough - negl %ecx - andl $15,%ecx // get #bytes to align ptr - jz LReady // already aligned - subq %rcx,%rdx // adjust length - - test $1,%cl // 1-byte store required? - movd %xmm0,%eax // get 4 low bytes in %eax - jz 2f // no - movdqa %xmm0,%xmm1 // copy pattern so we can shift in both directions - movb %al,(%rdi) // pack in the low-order byte - psrldq $1,%xmm0 // shift pattern right 1 byte - addq $1,%rdi - pslldq $15,%xmm1 // shift pattern left 15 bytes - shrl $8,%eax // in case 2-byte store is required - por %xmm1,%xmm0 // complete right rotate of pattern by 1 byte -2: - test $2,%cl // 2-byte store required? - jz 4f // no - psrldq $2,%xmm0 // shift pattern down 2 bytes - movw %ax,(%rdi) // pack in next two bytes - pinsrw $7,%eax,%xmm0 // insert low word of %eax into high word of %xmm0 - addq $2,%rdi // adjust ptr -4: - test $4,%cl // 4-byte store required? - jz 8f // no - movd %xmm0,(%rdi) // store low 4 bytes of %xmm0 - pshufd $(0x39),%xmm0,%xmm0 // rotate %xmm0 right 4 bytes (mask == 00 11 10 01) - addq $4,%rdi // adjust ptr -8: - test $8,%cl // 8-byte store required? - jz LReady // no - movq %xmm0,(%rdi) // store low 8 bytes of %xmm0 - pshufd $(0x4e),%xmm0,%xmm0 // rotate %xmm0 right 8 bytes (mask == 01 00 11 10) - addq $8,%rdi // adjust ptr - - // Ptr is aligned if practical, we're ready to call commpage to do the heavy lifting. - -LReady: - call Lmemset_pattern // call commpage to do the heavy lifting - ret - - -#define kLShort 63 -#define kVeryLong (1024*1024) - -Lmemset_pattern: - cmpq $(kLShort),%rdx // long enough to bother aligning? - ja LNotShort // yes - jmp LShort // no - - // Here for short operands or the end of long ones. - // %rdx = length (<= kLShort) - // %rdi = ptr (may not be not aligned) - // %xmm0 = pattern - -LUnalignedStore16: - movdqu %xmm0,(%rdi) // stuff in another 16 bytes - subl $16,%edx - addq $16,%rdi -LShort: - cmpl $16,%edx // room for another vector? - jge LUnalignedStore16 // yes -LLessThan16: // here at end of copy with < 16 bytes remaining - test $8,%dl // 8-byte store required? - jz 2f // no - movq %xmm0,(%rdi) // pack in 8 low bytes - psrldq $8,%xmm0 // then shift vector down 8 bytes - addq $8,%rdi -2: - test $4,%dl // 4-byte store required? - jz 3f // no - movd %xmm0,(%rdi) // pack in 4 low bytes - psrldq $4,%xmm0 // then shift vector down 4 bytes - addq $4,%rdi -3: - andl $3,%edx // more to go? - jz 5f // no - movd %xmm0,%eax // move remainders out into %eax -4: // loop on up to three bytes - movb %al,(%rdi) // pack in next byte - shrl $8,%eax // shift next byte into position - incq %rdi - dec %edx - jnz 4b -5: ret - -// Long enough to justify aligning ptr. Note that we have to rotate the -// pattern to account for any alignment. We do this by doing two unaligned -// stores, and then an aligned load from the middle of the two stores. -// This will stall on store forwarding alignment mismatch, and the unaligned -// stores can be pretty slow too, but the alternatives aren't any better. -// Fortunately, in most cases our caller has already aligned the ptr. -// %rdx = length (> kLShort) -// %rdi = ptr (may not be aligned) -// %xmm0 = pattern - -LNotShort: - movl %edi,%ecx // copy low bits of dest ptr - negl %ecx - andl $15,%ecx // mask down to #bytes to 16-byte align - jz LAligned // skip if already aligned - movdqu %xmm0,(%rdi) // store 16 unaligned bytes - movdqu %xmm0,16(%rdi) // and 16 more, to be sure we have an aligned chunk - addq %rcx,%rdi // now point to the aligned chunk - subq %rcx,%rdx // adjust remaining count - movdqa (%rdi),%xmm0 // get the rotated pattern (probably stalling) - addq $16,%rdi // skip past the aligned chunk - subq $16,%rdx - -// Set up for 64-byte loops. -// %rdx = length remaining -// %rdi = ptr (aligned) -// %xmm0 = rotated pattern - -LAligned: - movq %rdx,%rcx // copy length remaining - andl $63,%edx // mask down to residual length (0..63) - andq $-64,%rcx // %ecx <- #bytes we will zero in by-64 loop - jz LNoMoreChunks // no 64-byte chunks - addq %rcx,%rdi // increment ptr by length to move - cmpq $(kVeryLong),%rcx // long enough to justify non-temporal stores? - jge LVeryLong // yes - negq %rcx // negate length to move - jmp 1f - -// Loop over 64-byte chunks, storing into cache. - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movdqa %xmm0,(%rdi,%rcx) - movdqa %xmm0,16(%rdi,%rcx) - movdqa %xmm0,32(%rdi,%rcx) - movdqa %xmm0,48(%rdi,%rcx) - addq $64,%rcx - jne 1b - - jmp LNoMoreChunks - -// Very long operands: use non-temporal stores to bypass cache. - -LVeryLong: - negq %rcx // negate length to move - jmp 1f - - .align 4,0x90 // keep inner loops 16-byte aligned -1: - movntdq %xmm0,(%rdi,%rcx) - movntdq %xmm0,16(%rdi,%rcx) - movntdq %xmm0,32(%rdi,%rcx) - movntdq %xmm0,48(%rdi,%rcx) - addq $64,%rcx - jne 1b - - sfence // required by non-temporal stores - jmp LNoMoreChunks - -// Handle leftovers: loop by 16. -// %edx = length remaining (<64) -// %edi = ptr (aligned) -// %xmm0 = rotated pattern - -LLoopBy16: - movdqa %xmm0,(%rdi) // pack in 16 more bytes - subl $16,%edx // decrement count - addq $16,%rdi // increment ptr -LNoMoreChunks: - cmpl $16,%edx // more to go? - jge LLoopBy16 // yes - jmp LLessThan16 // handle up to 15 remaining bytes diff --git a/src/libc/x86_64/string/strcmp.S b/src/libc/x86_64/string/strcmp.S deleted file mode 100644 index 6a069c0a5..000000000 --- a/src/libc/x86_64/string/strcmp.S +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -// *************** -// * S T R C M P * -// *************** -// -// int strcmp(const char *s1, const char *s2); -// -// We optimize the compare by doing it in parallel, using SSE. This introduces -// a complication: if we blindly did vector loads from both sides until -// finding a difference (or 0), we might get a spurious page fault by -// reading bytes past the difference. To avoid this, we never do a load -// that crosses a page boundary. - - .text - .globl _strcmp - - .align 4 -_strcmp: // int strcmp(const char *s1,const char *s2); - -// In order to avoid spurious page faults, we loop over: -// -// min( bytes_in_LHS_page, bytes_in_RHS_page) >> 4 -// -// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte -// comparison until reaching the next page, then resume the vector comparison. -// %rdi = LHS ptr -// %rsi = RHS ptr - -LNextChunk: - movl %edi,%eax // copy low 4 bytes of each ptr - movl %esi,%edx - andl $4095,%eax // mask down to page offsets - andl $4095,%edx - cmpl %eax,%edx // which is bigger? - cmova %edx,%eax // %eax = max(LHS offset, RHS offset); - movl $4096,%edx - subl %eax,%edx // get #bytes to next page crossing - movl %edx,%eax - shrl $4,%edx // get #chunks till end of operand or page - jnz LLoopOverChunks // enter vector loop - movl %eax,%edx // no chunks... - jmp LLoopOverBytes // ...so loop over bytes until page end - - -// Loop over bytes. -// %rdi = LHS ptr -// %rsi = RHS ptr -// %edx = byte count - - .align 4,0x90 // align inner loops to optimize I-fetch -LLoopOverBytes: - movzb (%rdi),%eax // get LHS byte - movzb (%rsi),%ecx // get RHS byte - addq $1,%rdi - addq $1,%rsi - testl %eax,%eax // 0? - jz LExit0 // yes, we're done - subl %ecx,%eax // compare them - jnz LExit // done if not equal - subl $1,%edx // more to go? - jnz LLoopOverBytes - - jmp LNextChunk // we've come to end of page - - -// Loop over 16-byte chunks. -// %rdi = LHS ptr -// %rsi = RHS ptr -// %edx = chunk count - - .align 4,0x90 // align inner loops to optimize I-fetch -LLoopOverChunks: - movdqu (%rdi),%xmm1 // get LHS - movdqu (%rsi),%xmm2 // get RHS - pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads - addq $16,%rdi - pcmpeqb %xmm1,%xmm2 // compare LHS to RHS - pcmpeqb %xmm1,%xmm0 // compare LHS to 0s - addq $16,%rsi - pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS - pmovmskb %xmm0,%ecx // get result mask for 0 check - xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal" - orl %ecx,%eax // combine the masks and check for 1-bits - jnz LFoundDiffOr0 // we found differing bytes or a 0-byte - subl $1,%edx // more to go? - jnz LLoopOverChunks - - jmp LNextChunk // compare up to next page boundary - - -// Found a zero and/or a difference in vector compare. -// %rdi = LHS ptr, already advanced by 16 -// %rsi = RHS ptr, already advanced by 16 -// %eax = bit n set if bytes n differed or were 0 - -LFoundDiffOr0: - bsf %eax,%edx // which byte differed or was 0? - subq $16,%rdi // point to start of vectors while we wait for bit scan - subq $16,%rsi - movzb (%rdi,%rdx),%eax // get LHS byte - movzb (%rsi,%rdx),%ecx // get RHS byte - subl %ecx,%eax // compute difference (ie, return value) - ret - - -// Found a zero and/or difference in byte loop. -// %eax = LHS byte -// %ecx = RHS byte - -LExit0: - subl %ecx,%eax // compute difference (ie, return value) -LExit: // here with difference already in %eax - ret diff --git a/src/libc/x86_64/string/strcpy.S b/src/libc/x86_64/string/strcpy.S index d667b05f1..74cf9db4a 100644 --- a/src/libc/x86_64/string/strcpy.S +++ b/src/libc/x86_64/string/strcpy.S @@ -1,14 +1,19 @@ /* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2012 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -18,131 +23,149 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + * + * This file implements strcpy( ) for the x86_64 architecture. */ +.globl _strcpy -// *************** -// * S T R C P Y * -// *************** -// -// char *strcpy(const char *dst, const char *src); -// -// We optimize the move by doing it vector parallel. This introduces -// a complication: if we blindly did vector load/stores until finding -// a 0, we might get a spurious page fault by touching bytes past it. -// To avoid this, we never do a load that crosses a page boundary, -// and never store a byte we don't have to. -// -// We align the destination, because unaligned vector stores are slow. +/***************************************************************************** + * Macros * + *****************************************************************************/ + +.macro EstablishFrame + push %rbp + mov %rsp, %rbp +.endm - .text - .globl _strcpy +.macro ClearFrameAndReturn + pop %rbp + ret +.endm + +/***************************************************************************** + * Entrypoint * + *****************************************************************************/ - .align 4 -_strcpy: // char *strcpy(const char *dst, const char *src); - movq %rdi,%rcx // preserve dest ptr so we can return it - movl %edi,%edx // copy low 4 bytes of dest ptr - negl %edx - andl $15,%edx // how many bytes to align dest ptr? - jnz LLoopOverBytes // not aligned, so go do so - - -// In order to avoid spurious page faults, we loop until nearing the source page -// end. Then we revert to a byte-by-byte loop for 16 bytes until the page is crossed, -// then resume the vector loop. -// %rsi = source ptr (unaligned) -// %rdi = dest ptr (aligned) +.text +.align 5 +_strcpy: +// char *strcpy(char * restrict d, const char * restrict s); +// +// copies the string s to d, and returns d. We look for NUL bytes using +// pcmpeqb on 16-byte aligned blocks. Although this may read past the +// end of the string, because all access is aligned, it will never +// read past the end of the string across a page boundary, or even +// accross a cacheline. + EstablishFrame + mov %rsi, %rcx -LNextChunk: - movl %esi,%eax // copy low 4 bytes of source ptr - movl $4096,%edx - andl $4095,%eax // get offset into source page - subl %eax,%edx // get #bytes remaining in source page - shrl $4,%edx // get #chunks till end of page - jnz LLoopOverChunks // enter vector loop - movl $16,%edx // move 16 bytes to cross page but keep dest aligned - jmp LLoopOverBytes +// Load the 16-byte block containing the first byte of the string, and +// compare each byte to zero. If any NUL bytes are present in this +// block, the corresponding *bit* in esi will be set to 1. + and $-16, %rsi + pxor %xmm0, %xmm0 + pcmpeqb (%rsi), %xmm0 + pmovmskb %xmm0, %eax +// The 16 bytes that we checked for NUL included some bytes preceeding +// the start of the string, if s is not 16-byte aligned. We create a +// mask based on the alignment of s which covers only those bits +// corresponding to bytes that do not preceed s, and check for NULs +// only in those bits. If we find one, the string is too small to use +// a vector copy, so jump to dedicated small-buffer implementation. + and $0xf, %rcx + or $-1, %rdx + shl %cl, %rdx + and %edx, %eax + jnz L_strcpyGPR -// Loop over bytes. -// %rsi = source ptr -// %rdi = dest ptr -// %edx = byte count +// Check the next 16-byte block for NUL. If none are found, that guarantees +// that the string is at least 16 bytes long, which means that we can use a +// single unaligned vector copy to handle any edging at the start of the +// string. If instead a NUL is found, fall into the byte-by-byte copy loop. + movdqa 16(%rsi), %xmm1 + pxor %xmm0, %xmm0 + pcmpeqb %xmm1, %xmm0 + pmovmskb %xmm0, %edx + test %edx, %edx + jz L_strcpySSE - .align 4,0x90 // align inner loops to optimize I-fetch -LLoopOverBytes: - movzb (%rsi),%eax // get source byte - addq $1,%rsi - movb %al,(%rdi) // pack into dest - addq $1,%rdi - testl %eax,%eax // 0? - jz LDone // yes, we're done - subl $1,%edx // more to go? - jnz LLoopOverBytes - - jmp LNextChunk // we've come to end of page +/***************************************************************************** + * GPR copy implementation * + *****************************************************************************/ +// There is at least one NUL in the 32 aligned bytes containing the start +// of the string being copied. We assemble a bitmap for those 32 bytes from +// eax and edx, then shift it right by cl to throw out any bits preceeding +// the start of the string. We can then identify the position of the +// first NUL byte using BSF. + shl $16, %edx + or %edx, %eax +L_strcpyGPR: + shr %cl, %eax + bsf %eax, %edx +// Restore the original source pointer, and copy the destination pointer +// to rax so that it is returned on exit. + add %rcx, %rsi + mov %rdi, %rax + add $1, %rdx + call _memcpy + ClearFrameAndReturn +/* +// At this point we simply need to copy rdx + 1 bytes from rsi to rdi. If +// the length is >= 8, start by doing a word-by-word copy; otherwise, use +// a byte-by-byte copy loop. + sub $7, %rdx // 7 instead of 8 to account for NUL + jb 1f +0: mov (%rsi,%rdx),%rcx + mov %rcx, (%rdi,%rdx) + sub $8, %rdx + jae 0b +1: add $8, %rdx + jz 3f +2: movzb -1(%rsi,%rdx),%rcx + movb %cl, -1(%rdi,%rdx) + sub $1, %rdx + jnz 2b +3: ClearFrameAndReturn + */ -// Loop over 16-byte chunks. -// %rsi = source ptr (unaligned) -// %rdi = dest ptr (aligned) -// %edx = chunk count +/***************************************************************************** + * SSE copy implementation * + *****************************************************************************/ - .align 4,0x90 // align inner loops to optimize I-fetch -LLoopOverChunks: - movdqu (%rsi),%xmm1 // get source - pxor %xmm0,%xmm0 // get some 0s - addq $16,%rsi - pcmpeqb %xmm1,%xmm0 // compare source to 0s - pmovmskb %xmm0,%eax // get result mask for 0 check - testl %eax,%eax // any 0s? - jnz LFound0 // yes, exit loop - movdqa %xmm1,(%rdi) // no 0s so do aligned store into destination - addq $16,%rdi - subl $1,%edx // more to go? - jnz LLoopOverChunks - - movl $16,%edx // move 16 bytes - jmp LLoopOverBytes // cross page but keep dest aligned - +L_strcpySSE: +// Begin by doing a single unaligned vector copy for edging. We no longer +// have the original source pointer, but we can reconstruct it as rsi + rcx. + movdqu (%rsi,%rcx),%xmm0 + movdqu %xmm0, (%rdi) +// Next copy the original destination pointer to rax so that it is returned +// on exit, and adjust the destination pointer to correspond to rsi. + mov %rdi, %rax + sub %rcx, %rdi + xor %rcx, %rcx +// Main copy loop: store the 16 bytes loaded in the previous iteration of the +// loop, as they are already known to not contain a NUL. The load the next +// 16 bytes and check for NUL. +0: movdqu %xmm1, 16(%rdi,%rcx) + add $16, %rcx + movdqa 16(%rsi,%rcx),%xmm1 + pxor %xmm0, %xmm0 + pcmpeqb %xmm1, %xmm0 + pmovmskb %xmm0, %edx + test %edx, %edx + jz 0b -// Found a zero in the vector. Figure out where it is, and store the bytes -// up to it. -// %rdi = dest ptr (aligned) -// %eax = result mask -// %xmm1 = source vector +// Cleanup: at least one of the bytes in the last 16 that were loaded was +// NUL. The corresponding bits of dx are set, and all other bits are zero. +// Thus, we can use BSF to find the position of the first NUL. Once we have +// this information, we use an unaligned copy that runs precisely up to this +// position to handle edging. + bsf %edx, %edx + add %rdx, %rcx + movdqu 1(%rsi,%rcx),%xmm0 // offset is 1 so that we copy the trailing + movdqu %xmm0, 1(%rdi,%rcx) // NUL byte as well. + ClearFrameAndReturn -LFound0: - bsf %eax,%edx // find first 0 - addl $1,%edx // we need to store the 0 too - test $16,%dl // was 0 last byte? - jz 8f // no - movdqa %xmm1,(%rdi) // yes, store entire vector - jmp LDone -8: - test $8,%dl // 8-byte store required? - jz 4f // no - movq %xmm1,(%rdi) // pack in 8 low bytes - psrldq $8,%xmm1 // then shift vector down 8 bytes - addq $8,%rdi -4: - test $4,%dl // 4-byte store required? - jz 3f // no - movd %xmm1,(%rdi) // pack in 4 low bytes - psrldq $4,%xmm1 // then shift vector down 4 bytes - addq $4,%rdi -3: - andl $3,%edx // more to go? - jz LDone // no - movd %xmm1,%eax // move remainders out of vector into %eax -1: // loop on up to three bytes - movb %al,(%rdi) // pack in next byte - shrl $8,%eax // shift next byte into position - addq $1,%rdi - dec %edx - jnz 1b - -LDone: - movq %rcx,%rax // original dest ptr is return value - ret diff --git a/src/libc/x86_64/string/strlcat.S b/src/libc/x86_64/string/strlcat.S deleted file mode 100644 index 50a45a85d..000000000 --- a/src/libc/x86_64/string/strlcat.S +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -// ***************** -// * S T R L C A T * -// ***************** -// -// size_t strlcat(char *dst, const char *src, size_t size); -// -// Using 8- or 16-byte parallel loops introduce a complication: -// if we blindly did parallel load/stores until finding -// a 0, we might get a spurious page fault by touching bytes past it. -// To avoid this, we never do a load that crosses a page boundary, -// or store unnecessary bytes. -// -// The word parallel test for 0s relies on the following inobvious -// but very efficient test: -// x = dataWord + 0xFEFEFEFF -// y = ~dataWord & 0x80808080 -// if (x & y) == 0 then no zero found -// The test maps any non-zero byte to zero, and any zero byte to 0x80, -// with one exception: 0x01 bytes preceeding the first zero are also -// mapped to 0x80. -// -// On Core2 class machines, this algorithm seems to be faster than the -// naive byte-by-byte version for operands longer than about 11 bytes. - - .text - .globl _strlcat - - - -// Use SSE to find the 0-byte at current end of buffer. -// This is just a minor variant of strlen(). -// Initial registers: -// %rdi = dest or buffer ptr -// %rsi = source ptr -// %rdx = size - - .align 4 -_strlcat: // size_t *strlcat(char *dst, const char *src, size_t size); - movl %edi,%ecx // copy buffer ptr - movq %rdi,%r10 // save copies of buffer ptr and length - movq %rdx,%r11 - andq $(-16),%rdi // 16-byte align buffer ptr - pxor %xmm0,%xmm0 // get some 0s - andl $15,%ecx // get #bytes in dq before start of buffer - movl $16,%r8d - orl $(-1),%eax - subl %ecx,%r8d // #bytes from buffer start to end of dq - subq %r8,%rdx // does buffer end before end of dq? - jb LShortBuf1 // yes, drop into byte-by-byte mode - movdqa (%rdi),%xmm1 // get first aligned chunk of buffer - addq $16,%rdi - pcmpeqb %xmm0,%xmm1 // check for 0s - shl %cl,%eax // create mask for the bytes of aligned dq in operand - pmovmskb %xmm1,%ecx // collect mask of 0-bytes - andl %eax,%ecx // mask out any 0s that occur before buffer start - jnz 2f // found end of buffer -1: - subq $16,%rdx // another dq in buffer? - jb LShortBuf2 // no, drop into byte-by-byte mode - movdqa (%rdi),%xmm1 // get next chunk - addq $16,%rdi - pcmpeqb %xmm0,%xmm1 // check for 0s - pmovmskb %xmm1,%ecx // collect mask of 0-bytes - testl %ecx,%ecx // any 0-bytes? - jz 1b // no -2: - bsf %ecx,%ecx // find first 1-bit (ie, first 0-byte) - subq $16,%rdi // back up ptr into buffer - addq $16,%rdx // recover length remaining as of start of dq - addq %rcx,%rdi // point to 0-byte - subq %rcx,%rdx // compute #bytes remaining in buffer - - -// Copy byte-by-byte until source is 8-byte aligned. -// %rdi = points to 1st byte available in buffer -// %rsi = src ptr -// %rdx = buffer length remaining (ie, starting at %rdi) -// %r10 = original buffer ptr - - movl %esi,%ecx // copy source ptr - negl %ecx - andl $7,%ecx // how many bytes to align source ptr? - jz LAligned // already aligned - - -// Loop over bytes. -// %rdi = dest ptr -// %rsi = source ptr -// %rdx = length remaining in buffer -// %ecx = number of bytes to copy (>0, may not fit in buffer) -// %r10 = original buffer ptr - -LLoopOverBytes: - movzb (%rsi),%eax // get source byte before checking buffer length - testq %rdx,%rdx // buffer full? - jz L0NotFound // yes - incq %rsi - decq %rdx - movb %al,(%rdi) // pack into dest - incq %rdi - testl %eax,%eax // 0? - jz LDone // yes, done - decl %ecx // more to go? - jnz LLoopOverBytes - - -// Source is aligned. Loop over quadwords until end of buffer. We -// align the source, rather than the dest, to avoid getting spurious page faults. -// %rdi = dest ptr (unaligned) -// %rsi = source ptr (quadword aligned) -// %rdx = length remaining in buffer -// %r10 = original buffer ptr - -LAligned: - movl $9,%ecx // if buffer almost exhausted, prepare to copy rest byte-by-byte - cmpq $8,%rdx // enough for at least one quadword? - jb LLoopOverBytes - movq $0xFEFEFEFEFEFEFEFF,%r8 // get magic constants - movq $0x8080808080808080,%r9 - - -// Loop over quadwords. -// %rdi = dest ptr (unaligned) -// %rsi = source ptr (quadword aligned) -// %rdx = length remaining in buffer (>=8) -// %r8 = 0xFEFEFEFEFEFEFEFF -// %r9 = 0x8080808080808080 -// %r10 = original buffer ptr - -LLoopOverQuads: - movq (%rsi),%rax // get next 8 bytes of source - subq $8,%rdx - addq $8,%rsi - movq %rax,%r11 // make 2 copies of quadword - movq %rax,%rcx - notq %r11 // use magic word-parallel test for 0s - addq %r8,%rcx - andq %r9,%r11 - testq %rcx,%r11 - jnz L0Found // one of the bytes of %rax is a 0 - movq %rax,(%rdi) // pack 8 bytes into destination - addq $8,%rdi - cmpq $8,%rdx // room in buffer for another quadword? - jae LLoopOverQuads // yes - - movl %edx,%ecx // copy leftovers in byte loop - jmp LLoopOverBytes - -// Found a 0-byte in the quadword of source. Store a byte at a time until the 0. -// %rdi = dest ptr (unaligned) -// %rax = last word of source, known to have a 0-byte -// %r10 = original buffer ptr - -LNextByte: - shrq $8,%rax // next byte -L0Found: - movb %al,(%rdi) // pack in next byte - incq %rdi - testb %al,%al // 0? - jnz LNextByte - - -// Done storing string. -// %rdi = ptr to byte after 0-byte -// %r10 = original buffer ptr - -LDone: - subq %r10,%rdi // subtract original dest ptr to get length stored - lea -1(%rdi),%rax // minus one for 0-byte, and move to return value - ret - -// Buffer filled but 0-byte not found. We return the length of the buffer plus the length -// of the source string. This is not optimized, as it is an error condition. -// %edi = dest ptr (ie, 1 past end of buffer) -// %esi = source ptr (ptr to 1st byte that does not fit) -// %rdx = 0 (ie, length remaining in buffer) -// %r10 = original buffer ptr - -L0NotFound: - movq %rdi,%rax // buffer end... - subq %r10,%rax // ...minus start is buffer length - jz LScanSourceTo0 // buffer is null so cannot store a 0 - movb %dl,-1(%rdi) // store a 0 at end of buffer to delimit string - - -// Scan source to end. -// %rsi = ptr to rest of source -// %rax = return value so far - -LScanSourceTo0: - movzb (%rsi),%ecx // get next byte of source - incq %rsi - incq %rax // increment length - testl %ecx,%ecx // 0? - jnz LScanSourceTo0 - decq %rax // don't count the 0-byte - ret - - -// Buffer too short to reach end of even one 16-byte aligned chunk. -// %rsi = src ptr -// %r10 = original buffer ptr -// %r11 = original buffer length - -LShortBuf1: - movq %r10,%rdi // recover buffer ptr - movq %r11,%rdx // recover buffer length - jmp LShortBuf3 - - -// Out of aligned dq's of buffer, 0-byte still not found. -// %rsi = src ptr -// %rdi = ptr to 1st buffer byte not checked for 0 -// %rdx = length remaining - 16 -// %r10 = original buffer ptr -// %r11 = original buffer length - -LShortBuf2: - addq $16,%rdx // recover length remaining -LShortBuf3: - movq %r11,%rax // in case we goto LScanSourceTo0 - movl $17,%ecx // in case we goto LLoopOverBytes -1: - testq %rdx,%rdx // no 0s in buffer at all? - jz LScanSourceTo0 // yes, cannot store a 0 - cmpb $0,(%rdi) // is this the 0? - jz LLoopOverBytes // yes, append source - incq %rdi - decq %rdx - jmp 1b // loop looking for 0 diff --git a/src/libc/x86_64/string/strlcpy.S b/src/libc/x86_64/string/strlcpy.S deleted file mode 100644 index 6564dd235..000000000 --- a/src/libc/x86_64/string/strlcpy.S +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -// ***************** -// * S T R L C P Y * -// ***************** -// -// size_t strlcpy(char *dst, const char *src, size_t size); -// -// We optimize the move by doing it quadword parallel. This introduces -// a complication: if we blindly did quadword load/stores until finding -// a 0, we might get a spurious page fault by touching bytes past it. -// To avoid this, we never do a load that crosses a page boundary, -// or store unnecessary bytes. -// -// The test for 0s relies on the following inobvious but very efficient -// word-parallel test: -// x = dataWord + 0xFEFEFEFF -// y = ~dataWord & 0x80808080 -// if (x & y) == 0 then no zero found -// The test maps any non-zero byte to zero, and any zero byte to 0x80, -// with one exception: 0x01 bytes preceeding the first zero are also -// mapped to 0x80. - - .text - .globl _strlcpy - -// When initially entered: -// %rdi = dest buffer ptr -// %rsi = source ptr -// %rdx = length - - .align 4 -_strlcpy: // size_t *strlcpy(char *dst, const char *src, size_t size); - movl %esi,%ecx // copy source ptr - movq %rdi,%r10 // copy dest ptr - negl %ecx - andl $7,%ecx // how many bytes to align source ptr? - jz LAligned // already aligned - - -// Loop over bytes. -// %rdi = dest ptr -// %rsi = source ptr -// %rdx = length remaining in buffer -// %ecx = number of bytes to copy (>0, may not fit in buffer) -// %r10 = original dest ptr - -LLoopOverBytes: - movzb (%rsi),%eax // get source byte before checking buffer length - testq %rdx,%rdx // buffer full? - jz L0NotFound // yes - incq %rsi - decq %rdx - movb %al,(%rdi) // pack into dest - incq %rdi - testl %eax,%eax // 0? - jz LDone // yes, done - decl %ecx // more to go? - jnz LLoopOverBytes - - -// Source is aligned. Loop over quadwords until end of buffer. We -// align the source, rather than the dest, to avoid getting spurious page faults. -// %rdi = dest ptr (unaligned) -// %rsi = source ptr (quadword aligned) -// %rdx = length remaining in buffer -// %r10 = original dest ptr - -LAligned: - movl $9,%ecx // if buffer almost exhausted, prepare to copy rest byte-by-byte - cmpq $8,%rdx // enough for at least one word? - jb LLoopOverBytes - movq $0xFEFEFEFEFEFEFEFF,%rcx // load magic constants - movq $0x8080808080808080,%r11 - - -// Loop over quadwords. -// %rdi = dest ptr (unaligned) -// %rsi = source ptr (word aligned) -// %rdx = length remaining in buffer (>=8) -// %rcx = 0xFEFEFEFEFEFEFEFF -// %r11 = 0x8080808080808080 -// %r10 = original dest ptr - -LLoopOverQuads: - movq (%rsi),%rax // get next 8 bytes of source - subq $8,%rdx - addq $8,%rsi - movq %rax,%r8 // make 2 copies of quadword - movq %rax,%r9 - notq %r8 // use magic word-parallel test for 0s - addq %rcx,%r9 - andq %r11,%r8 - testq %r8,%r9 - jnz L0Found // one of the bytes of %rax is a 0 - movq %rax,(%rdi) // pack 8 bytes into destination - addq $8,%rdi - cmpq $8,%rdx // room in buffer for another quadword? - jae LLoopOverQuads // yes - - movl %edx,%ecx // copy leftovers in byte loop - jmp LLoopOverBytes - -// Found a 0-byte in the quadword of source. Store a byte at a time until the 0. -// %rdi = dest ptr (unaligned) -// %rax = last quadword of source, known to have a 0-byte -// %r10 = original dest ptr - -LNextByte: - shrq $8,%rax // next byte -L0Found: - movb %al,(%rdi) // pack in next byte - incq %rdi - testb %al,%al // 0? - jnz LNextByte - -// Done storing string. -// %rdi = ptr to byte after 0-byte -// %r10 = original dest ptr - -LDone: - subq %r10,%rdi // subtract original dest ptr to get length stored - lea -1(%rdi),%rax // minus one for 0-byte, and move to return value - ret - -// Buffer filled but 0-byte not found. We return the length of the source string. -// This is not optimized, as it is an error condition. -// %rdi = dest ptr (ie, 1 past end of buffer) -// %rsi = source ptr (ptr to 1st byte that does not fit) -// %r10 = original dest ptr - -L0NotFound: - movq %rdi,%rax // end of buffer... - subq %r10,%rax // ...minus start is buffer length - jz 1f // 0-length buffer, cannot store a 0 - xorl %edx,%edx // get a 0 - movb %dl,-1(%rdi) // store a 0 at end of buffer to delimit string -1: - movzb (%rsi),%ecx // get next byte of source - incq %rsi - incq %rax - testl %ecx,%ecx // 0? - jnz 1b - decq %rax // don't count the 0-byte - ret diff --git a/src/libc/x86_64/string/strlen.S b/src/libc/x86_64/string/strlen.S index 54ea653ac..623f39e1c 100644 --- a/src/libc/x86_64/string/strlen.S +++ b/src/libc/x86_64/string/strlen.S @@ -1,75 +1,105 @@ /* - * Copyright (c) 2005-2007 Apple Inc. All rights reserved. + * Copyright (c) 2005-2012 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ * - * @APPLE_LICENSE_HEADER_END@ + * This file implements strlen( ) for the x86_64 architecture. */ -/* - * Strlen, for processors with SSE3. - * - * Note that all memory references must be aligned, in order to avoid spurious - * page faults. Thus we have to load the aligned 16-byte chunk containing the - * first byte of the operand, then mask out false 0s that may occur before the - * first byte. - * - * We favor the fall-through (ie, short operand) path. - */ +.globl _strlen - .text - .globl _strlen - .align 4, 0x90 -_strlen: // size_t strlen(char *b); - pxor %xmm0,%xmm0 // zero %xmm0 - movl %edi,%ecx // copy low half of ptr - movq %rdi,%rdx // make another full copy - andq $(-16),%rdi // 16-byte align ptr - orl $(-1),%eax - pcmpeqb (%rdi),%xmm0 // check whole qw for 0s - andl $15,%ecx // get #bytes in aligned dq before operand - shl %cl,%eax // create mask for the bytes of aligned dq in operand - pmovmskb %xmm0,%ecx // collect mask of 0-bytes - andl %eax,%ecx // mask out any 0s that occur before 1st byte - jz LEnterLoop // no 0-bytes (ie, 1-bits), so enter by-16 loop - -// We've found a 0-byte. -// %rdi = aligned address of 16-byte block containing the terminating 0-byte -// %ecx = compare bit vector +/***************************************************************************** + * Macros * + *****************************************************************************/ -LFoundIt: - bsf %ecx,%eax // find first 1-bit (ie, first 0-byte) - subq %rdx,%rdi // get length to start of 16-byte block while we wait - addq %rdi,%rax // add bytes in 16-byte block +.macro EstablishFrame + push %rbp + mov %rsp, %rbp +.endm + +.macro ClearFrameAndReturn + pop %rbp ret - -// Loop over aligned 16-byte blocks: -// %rdi = address of previous block +.endm + +/***************************************************************************** + * Entrypoint * + *****************************************************************************/ + +.text +.align 5 +_strlen: +// size_t strlen(const char *s); +// +// returns the length of the string s (i.e. the distance in bytes from +// s to the first NUL byte following s). We look for NUL bytes using +// pcmpeqb on 16-byte aligned blocks. Although this may read past the +// end of the string, because all access is aligned, it will never +// read past the end of the string across a page boundary, or even +// accross a cacheline. + EstablishFrame + mov %rdi, %rcx + mov %rdi, %rdx + +// Load the 16-byte block containing the first byte of the string, and +// compare each byte to zero. If any NUL bytes are present in this +// block, the corresponding *bit* in esi will be set to 1. + and $-16, %rdi + pxor %xmm0, %xmm0 + pcmpeqb (%rdi), %xmm0 + pmovmskb %xmm0, %esi + +// The 16 bytes that we checked for NUL included some bytes preceeding +// the start of the string, if s is not 16-byte aligned. We create a +// mask based on the alignment of s which covers only those bits +// corresponding to bytes that do not preceed s, and check for NULs +// only in those bits. If we do not find one, we jump to our main +// search loop. + and $0xf, %rcx + or $-1, %rax + shl %cl, %rax + and %eax, %esi + jz L_loop -LEnterLoop: - pxor %xmm0,%xmm0 // get some 0-bytes - addq $16,%rdi // advance ptr -LLoop: - movdqa (%rdi),%xmm1 // get next chunk - addq $16,%rdi - pcmpeqb %xmm0,%xmm1 // check for 0s - pmovmskb %xmm1,%ecx // collect mask of 0-bytes - test %ecx,%ecx // any 0-bytes? - jz LLoop // no 0-bytes, so get next dq +L_foundNUL: +// The last 16-byte block that we searched contained at least one NUL. +// We use bsf to identify the first NUL, and compute the distance from +// that byte to the start of the string. + bsf %esi, %eax + sub %rdx, %rdi + add %rdi, %rax + ClearFrameAndReturn - subq $16,%rdi // back up ptr - jmp LFoundIt +.align 4 +L_loop: +// Main search loop: check for NUL in a 16-byte block, continuing +// loop until one is found. + add $16, %rdi + pxor %xmm0, %xmm0 + pcmpeqb (%rdi), %xmm0 + pmovmskb %xmm0, %esi + test %esi, %esi + jz L_loop + jmp L_foundNUL diff --git a/src/libc/x86_64/string/strncmp.S b/src/libc/x86_64/string/strncmp.S deleted file mode 100644 index 8608e7002..000000000 --- a/src/libc/x86_64/string/strncmp.S +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -// ***************** -// * S T R N C M P * -// ***************** -// -// int strncmp(const char *s1, const char *s2, size_t len); -// -// We optimize the compare by doing it vector parallel. This introduces -// a complication: if we blindly did vector loads from both sides until -// finding a difference (or 0), we might get a spurious page fault by -// reading bytes past the difference. To avoid this, we never do a load -// that crosses a page boundary. - -#define kShort 20 // too short for vectors (must be >16) - - .text - .globl _strncmp - - .align 4 -_strncmp: // int strncmp(const char *s1, const char *s2, size_t len); - cmpq $(kShort),%rdx // worth accelerating? - ja LNotShort // yes - - -// Too short to bother with parallel compares. Loop over bytes. -// %rdi = LHS ptr -// %rsi = RHS ptr -// %edx = length (<= kShort) - -LShort: - testl %edx,%edx // 0-length? - jnz LShortLoop // no - jmp LReturn0 // yes, return 0 - .align 4,0x90 // align inner loops to optimize I-fetch -LShortLoop: // loop over bytes - movzb (%rdi),%eax // get LHS byte - movzb (%rsi),%ecx // get RHS byte - incq %rdi - incq %rsi - testl %eax,%eax // LHS==0 ? - jz LNotEqual // yes, this terminates comparison - cmpl %ecx,%eax // compare them (sub won't fuse, but cmp will) - jnz LNotEqual // done if not equal - decl %edx // decrement length - jnz LShortLoop -LReturn0: - xorl %eax,%eax // all bytes equal, so return 0 - ret - -LNotEqual: // LHS in eax, RHS in ecx - subl %ecx,%eax // generate return value (nonzero) - ret - - -// Loop over bytes until we reach end of a page. -// %rdi = LHS ptr -// %rsi = RHS ptr -// %rdx = length remaining after end of loop (ie, already adjusted) -// %r8d = #bytes until next page (1..15) - - .align 4,0x90 // align inner loops to optimize I-fetch -LLoopOverBytes: - movzb (%rdi),%eax // get LHS byte - movzb (%rsi),%ecx // get RHS byte - incq %rdi - incq %rsi - testl %eax,%eax // LHS==0 ? - jz LNotEqual // yes, this terminates comparison - cmpl %ecx,%eax // compare them (sub won't fuse, but cmp will) - jnz LNotEqual // done if not equal - decl %r8d // more to go? - jnz LLoopOverBytes - - -// Long enough to justify overhead of setting up vector compares. In order to -// avoid spurious page faults, we loop over: -// -// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4 -// -// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte -// comparison until reaching the next page, then resume the vector comparison. -// %rdi = LHS ptr -// %rsi = RHS ptr -// %rdx = length (> kShort) - -LNotShort: - movl %edi,%eax // copy ptrs - movl %esi,%r8d - andl $4095,%eax // mask down to page offsets - andl $4095,%r8d - cmpl %eax,%r8d // which is bigger? - cmova %r8d,%eax // %eax = max(LHS offset, RHS offset); - movl $4096,%r8d - subl %eax,%r8d // get #bytes to next page crossing - cmpq %rdx,%r8 // will operand run out first? - cmova %rdx,%r8 // get min(length remaining, bytes to page end) - movl %r8d,%eax // copy #bytes - shrl $4,%r8d // get #chunks till end of operand or page - testl %r8d,%r8d // test %r8d for 0 without partial flag update stall - jnz LLoopOverChunks // enter vector loop - -// Too near page end for vectors. - - subq %rax,%rdx // adjust length remaining - movl %eax,%r8d // %r8d <- #bytes to page end - cmpq $(kShort),%rdx // will there be enough after we cross page for vectors? - ja LLoopOverBytes // yes - addq %rax,%rdx // no, restore total length remaining - jmp LShortLoop // compare rest byte-by-byte (%rdx != 0) - - -// Loop over 16-byte chunks. -// %rdi = LHS ptr -// %rsi = RHS ptr -// %rdx = length remaining -// %r8d = chunk count - - .align 4,0x90 // align inner loops to optimize I-fetch -LLoopOverChunks: - movdqu (%rdi),%xmm1 // get LHS - movdqu (%rsi),%xmm2 // get RHS - pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads - addq $16,%rdi - pcmpeqb %xmm1,%xmm2 // compare LHS to RHS - pcmpeqb %xmm1,%xmm0 // compare LHS to 0s - addq $16,%rsi - pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS - pmovmskb %xmm0,%ecx // get result mask for 0 check - subq $16,%rdx // decrement length remaining - xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal" - orl %ecx,%eax // combine the masks and check for 1-bits - jnz LFoundDiffOr0 // we found differing bytes or a 0-byte - decl %r8d // more to go? - jnz LLoopOverChunks // yes - - cmpq $(kShort),%rdx // a lot more to compare? - jbe LShort // no - jmp LNotShort // compute distance to next page crossing etc - - -// Found a zero and/or a difference in vector compare. -// %rdi = LHS ptr, already advanced by 16 -// %rsi = RHS ptr, already advanced by 16 -// %eax = bit n set if bytes n differed or were 0 - -LFoundDiffOr0: - bsf %eax,%edx // which byte differed or was 0? - movzb -16(%rdi,%rdx),%eax // get LHS byte - movzb -16(%rsi,%rdx),%edx // get RHS byte - subl %edx,%eax // compute difference (ie, return value) - ret diff --git a/src/libc/x86_64/string/strncpy.S b/src/libc/x86_64/string/strncpy.S index c926083d9..f18ca3456 100644 --- a/src/libc/x86_64/string/strncpy.S +++ b/src/libc/x86_64/string/strncpy.S @@ -174,7 +174,9 @@ LFound0: LZeroBuffer: movq %rdx,%rsi // remaining buffer size (2nd argument) + subq $8,%rsp // align stack to 16B before call call _bzero + addq $8,%rsp // restore stack LDone: movq %r8,%rax // original dest ptr is return value diff --git a/src/libc/x86_64/string/strnlen.S b/src/libc/x86_64/string/strnlen.S new file mode 100644 index 000000000..8b9600363 --- /dev/null +++ b/src/libc/x86_64/string/strnlen.S @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2012 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + * + * This file implements strnlen( ) for the x86_64 architecture. + */ + +.globl _strnlen + +/***************************************************************************** + * Macros * + *****************************************************************************/ + +.macro EstablishFrame + push %rbp + mov %rsp, %rbp +.endm + +.macro ClearFrameAndReturn + pop %rbp + ret +.endm + +/***************************************************************************** + * Entrypoint * + *****************************************************************************/ + +.text +.align 4 +_strnlen: +// size_t strnlen(char *s, size_t maxlen); + +// If maxlen is larger than any object that can be allocated, we know a priori +// that it does not effect the operation of the function in any way; we can +// simply call strlen instead, which is more efficient and makes handling the +// edge cases here much cleaner. + test %rsi, %rsi + js _strlen + +// The strnlen() function attempts to compute the length of s, but never +// scans beyond the first maxlen bytes of s. +// +// Thus, we need to early-out without doing any reads at all if maxlen == 0. + EstablishFrame + mov %rsi, %rax + jz L_maxlenExhausted + +// We are going to check the string in aligned 16-byte blocks. The first such +// block may contain characters that preceed the start of the string, so we +// construct a mask based on the string's alignment to use in processing this +// initial block. We also need to account for these characters in maxlen. + mov %rdi, %rcx + and $0xf, %rcx + or $-1, %rdx + shl %cl, %rdx // mask + add %rcx, %rsi // adjust maxlen + +// Load the 16-byte block containing the start of the string. If any NUL +// bytes are present in this block, the corresponding *bit* in ecx will be 1. +// We check only the bits that are set in the mask, to avoid detecting NULs +// that preceed the start of the string. + and $-16, %rdi + pxor %xmm0, %xmm0 + pcmpeqb (%rdi), %xmm0 + pmovmskb %xmm0, %ecx + and %rdx, %rcx + jnz L_foundNUL + +// Now subtract 16 from maxlen. If this causes a borrow, then we exhausted +// maxlen somewhere in this 16-byte block (formally, we have read past maxlen +// bytes, but that is not a problem; because the accesses are all aligned, we +// cannot read accross a page--or even cacheline--boundary, so the observable +// behavior is not different from if we had stopped at maxlen). If the result +// is exactly zero, we need to stop before reading the *next* 16 bytes. + sub $16, %rsi + jbe L_maxlenExhausted + +L_loop: + add $16, %rdi + pxor %xmm0, %xmm0 + pcmpeqb (%rdi), %xmm0 + pmovmskb %xmm0, %ecx + test %rcx, %rcx + jnz L_foundNUL + sub $16, %rsi + ja L_loop + +L_maxlenExhausted: +// If we exhaust maxlen bytes without finding a NUL, we return maxlen. + ClearFrameAndReturn + +L_foundNUL: +// The last 16-byte block that we searched contained at least one NUL. +// We use bsf to identify the first NUL. + bsf %rcx, %rdx +// Handle the case where the NUL that we found is preceeded by the maxlen'th +// byte of the string, returning maxlen. + cmp %rdx, %rsi + jb L_maxlenExhausted +// Otherwise, return the length of the string. + sub %rsi, %rax + add %rdx, %rax + ClearFrameAndReturn diff --git a/src/libc/x86_64/sys/OSAtomic.S b/src/libc/x86_64/sys/OSAtomic.S deleted file mode 100644 index abc6bdef6..000000000 --- a/src/libc/x86_64/sys/OSAtomic.S +++ /dev/null @@ -1,378 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007 Apple Inc. All rights reserved. - * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" -#include - -#define DECLARE(x) \ - .align 2 ; \ - .globl x ; \ - .globl x ## Barrier ; \ -x: ; \ -x ## Barrier: - -.text - -#define ATOMIC_UP 0 -#define ATOMIC_MP 1 -#define ATOMIC_RET_ORIG 0 -#define ATOMIC_RET_NEW 1 - -#ifndef DARLING__DISABLED -// compare and exchange 32-bit -// xchg32 -.macro xchg32 - .if $2 == ATOMIC_MP - lock - .endif - cmpxchgl $0, ($1) -.endm - -// xchg64 -.macro xchg64 - .if $2 == ATOMIC_MP - lock - .endif - cmpxchg $0, ($1) -.endm -#else -// compare and exchange 32-bit -// xchg32 -.macro xchg32 a0, a1, a2 - .if \a2 == ATOMIC_MP - lock - .endif - cmpxchgl \a0, (\a1) -.endm - -// xchg64 -.macro xchg64 a0, a1, a2 - .if \a2 == ATOMIC_MP - lock - .endif - cmpxchg \a0, (\a1) -.endm - -#define _OSMemoryBarrier OSMemoryBarrier -#define _OSAtomicEnqueue OSAtomicEnqueue -#define _OSAtomicDequeue OSAtomicDequeue -#endif - -#define ATOMIC_ARITHMETIC(instr, orig, mp) \ - movl (%rsi), %eax /* get 2nd arg -> eax */ ;\ -1: movl %eax, %edx /* copy value to new reg */ ;\ - instr %edi, %edx /* apply instr to %edx with arg2 */ ;\ - xchg32 %edx, %rsi, mp /* do the compare swap (see macro above) */ ;\ - jnz 1b /* jump if failed */ ;\ - .if orig == 1 /* to return the new value, overwrite eax */ ;\ - movl %edx, %eax /* return the new value */ ;\ - .endif - -// Used in OSAtomicTestAndSet( uint32_t n, void *value ), assumes ABI parameter loctions -// Manpage says bit to test/set is (0x80 >> (n & 7)) of byte (addr + (n >> 3)) -#define ATOMIC_BIT_OP(instr, mp) \ - xorl $7, %edi /* bit position is numbered big endian so convert to little endian */ ;\ - shlq $3, %rsi ;\ - addq %rdi, %rsi /* generate bit address */ ;\ - movq %rsi, %rdi ;\ - andq $31, %rdi /* keep bit offset in range 0..31 */ ;\ - xorq %rdi, %rsi /* 4-byte align address */ ;\ - shrq $3, %rsi /* get 4-byte aligned address */ ;\ - .if mp == ATOMIC_MP /* don't plant the lock in UP code */ ;\ - lock /* lock the bit test */ ;\ - .endif ;\ - instr %edi, (%rsi) /* do the bit test, supplied into the macro */ ;\ - setc %al ;\ - movzbl %al,%eax /* widen in case caller assumes we return an int */ - -// uint32_t OSAtomicAnd32( uint32_t mask, uint32_t *value); -PLATFUNC_FUNCTION_START(OSAtomicAnd32, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicAnd32Barrier, up, 64, 2) - ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Barrier, mp, 64, 2) - ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_MP) - ret - -// uint32_t OSAtomicOr32( uint32_t mask, uint32_t *value); -PLATFUNC_FUNCTION_START(OSAtomicOr32, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicOr32Barrier, up, 64, 2) - ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Barrier, mp, 64, 2) - ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_MP) - ret - -// uint32_t OSAtomicXor32( uint32_t mask, uint32_t *value); -PLATFUNC_FUNCTION_START(OSAtomicXor32, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicXor32Barrier, up, 64, 2) - ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Barrier, mp, 64, 2) - ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_MP) - ret - -// uint32_t OSAtomicAnd32Orig( uint32_t mask, uint32_t *value); -PLATFUNC_FUNCTION_START(OSAtomicAnd32Orig, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicAnd32OrigBarrier, up, 64, 2) - ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Orig, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32OrigBarrier, mp, 64, 2) - ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_MP) - ret - -// uint32_t OSAtomicOr32Orig( uint32_t mask, uint32_t *value); -PLATFUNC_FUNCTION_START(OSAtomicOr32Orig, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicOr32OrigBarrier, up, 64, 2) - ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Orig, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32OrigBarrier, mp, 64, 2) - ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_MP) - ret - -// uint32_t OSAtomicXor32Orig( uint32_t mask, uint32_t *value); -PLATFUNC_FUNCTION_START(OSAtomicXor32Orig, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicXor32OrigBarrier, up, 64, 2) - ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Orig, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32OrigBarrier, mp, 64, 2) - ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_MP) - ret - -// bool OSAtomicCompareAndSwap32( int32_t old, int32_t new, int32_t *value); -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapInt, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapIntBarrier, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32Barrier, up, 64, 2) - movl %edi, %eax - xchg32 %esi, %rdx, ATOMIC_UP - sete %al - movzbl %al,%eax // widen in case caller assumes we return an int - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapInt, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapIntBarrier, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32Barrier, mp, 64, 2) - movl %edi, %eax - xchg32 %esi, %rdx, ATOMIC_MP - sete %al - movzbl %al,%eax // widen in case caller assumes we return an int - ret - -// bool OSAtomicCompareAndSwap64( int64_t old, int64_t new, int64_t *value); -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtr, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtrBarrier, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLong, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLongBarrier, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64Barrier, up, 64, 2) - mov %rdi, %rax - xchg64 %rsi, %rdx, ATOMIC_UP - sete %al - movzbl %al,%eax // widen in case caller assumes we return an int - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtr, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtrBarrier, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLong, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLongBarrier, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64Barrier, mp, 64, 2) - mov %rdi, %rax - xchg64 %rsi, %rdx, ATOMIC_MP - sete %al - movzbl %al,%eax // widen in case caller assumes we return an int - ret - -// int32_t OSAtomicAdd32( int32_t amt, int32_t *value ); -PLATFUNC_FUNCTION_START(OSAtomicAdd32, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicAdd32Barrier, up, 64, 2) - movl %edi, %eax // save amt to add - xaddl %edi, (%rsi) // swap and add value, returns old value in %edi - addl %edi, %eax // add old value to amt as return value - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32Barrier, mp, 64, 2) - movl %edi, %eax // save amt to add - lock // lock prefix breaks tabs ;) - xaddl %edi, (%rsi) // swap and add value, returns old value in %edi - addl %edi, %eax // add old value to amt as return value - ret - -// int64_t OSAtomicAdd64( int64_t amt, int64_t *value ); -PLATFUNC_FUNCTION_START(OSAtomicAdd64, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicAdd64Barrier, up, 64, 2) - movq %rdi, %rax // save amt to add - xadd %rdi, (%rsi) // swap and add value, returns old value in %rsi - addq %rdi, %rax // add old value to amt as return value - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64Barrier, mp, 64, 2) - movq %rdi, %rax // save amt to add - lock - xadd %rdi, (%rsi) // swap and add value, returns old value in %rsi - addq %rdi, %rax // add old value to amt as return value - ret - -// bool OSAtomicTestAndSet( uint32_t n, void *value ); -PLATFUNC_FUNCTION_START(OSAtomicTestAndSet, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicTestAndSetBarrier, up, 64, 2) - ATOMIC_BIT_OP(btsl, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSet, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSetBarrier, mp, 64, 2) - ATOMIC_BIT_OP(btsl, ATOMIC_MP) - ret - -// bool OSAtomicTestAndClear( uint32_t n, void *value ); -PLATFUNC_FUNCTION_START(OSAtomicTestAndClear, up, 64, 2) -PLATFUNC_FUNCTION_START(OSAtomicTestAndClearBarrier, up, 64, 2) - ATOMIC_BIT_OP(btrl, ATOMIC_UP) - ret - -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClear, mp, 64, 2) -PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClearBarrier, mp, 64, 2) - ATOMIC_BIT_OP(btrl, ATOMIC_MP) - ret - -// void OSMemoryBarrier( void ); - .align 2, 0x90 - .globl _OSMemoryBarrier -_OSMemoryBarrier: - mfence - ret - -/* - * typedef volatile struct { - * void *opaque1; <-- ptr to 1st queue element or null - * long opaque2; <-- generation count - * } OSQueueHead; - * - * void OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset); - */ - .align 2 - .globl _OSAtomicEnqueue -_OSAtomicEnqueue: // %rdi == list head, %rsi == new, %rdx == offset - pushq %rbx - movq %rsi,%rbx // %rbx == new - movq %rdx,%rsi // %rsi == offset - movq (%rdi),%rax // %rax == ptr to 1st element in Q - movq 8(%rdi),%rdx // %rdx == current generation count -1: - movq %rax,(%rbx,%rsi)// link to old list head from new element - movq %rdx,%rcx - incq %rcx // increment generation count - lock // always lock for now... - cmpxchg16b (%rdi) // ...push on new element - jnz 1b - popq %rbx - ret - - - /* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */ - .align 2 - .globl _OSAtomicDequeue -_OSAtomicDequeue: // %rdi == list head, %rsi == offset - pushq %rbx - movq (%rdi),%rax // %rax == ptr to 1st element in Q - movq 8(%rdi),%rdx // %rdx == current generation count -1: - testq %rax,%rax // list empty? - jz 2f // yes - movq (%rax,%rsi),%rbx // point to 2nd in Q - movq %rdx,%rcx - incq %rcx // increment generation count - lock // always lock for now... - cmpxchg16b (%rdi) // ...pop off 1st element - jnz 1b -2: - popq %rbx - ret // ptr to 1st element in Q still in %rax - -#ifndef DARLING // PFZ stuff not supported -/* - * typedef volatile struct { - * void *opaque1; <-- ptr to first queue element or null - * void *opaque2; <-- ptr to last queue element or null - * int opaque3; <-- spinlock - * } OSFifoQueueHead; - * - * void OSAtomicFifoEnqueue( OSFifoQueueHead *list, void *new, size_t offset); - */ - .align 2 - .globl _OSAtomicFifoEnqueue -_OSAtomicFifoEnqueue: - pushq %rbx - xorl %ebx,%ebx // clear "preemption pending" flag - movq _commpage_pfz_base(%rip),%rcx - addq $(_COMM_TEXT_PFZ_ENQUEUE_OFFSET), %rcx - call *%rcx - testl %ebx,%ebx // pending preemption? - jz 1f - call _preempt // call into the kernel to pfz_exit -1: - popq %rbx - ret - - -/* void* OSAtomicFifoDequeue( OSFifoQueueHead *list, size_t offset); */ - .align 2 - .globl _OSAtomicFifoDequeue -_OSAtomicFifoDequeue: - pushq %rbx - xorl %ebx,%ebx // clear "preemption pending" flag - movq _commpage_pfz_base(%rip), %rcx - movq %rsi,%rdx // move offset to %rdx to be like the Enqueue case - addq $(_COMM_TEXT_PFZ_DEQUEUE_OFFSET), %rcx - call *%rcx - testl %ebx,%ebx // pending preemption? - jz 1f - call _preempt // call into the kernel to pfz_exit -1: - popq %rbx - ret // ptr to 1st element in Q in %rax - -#endif - -// Local Variables: -// tab-width: 8 -// End: diff --git a/src/libc/x86_64/sys/_sigtramp.S b/src/libc/x86_64/sys/_sigtramp.S deleted file mode 100644 index 4ec4cb180..000000000 --- a/src/libc/x86_64/sys/_sigtramp.S +++ /dev/null @@ -1,257 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007, 2011 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include - -#define UC_TRAD 1 -#define UC_FLAVOR 30 - -/* Structure fields for ucontext and mcontext. */ -#define UCONTEXT_UC_MCONTEXT 48 - -#define MCONTEXT_ES_EXCEPTION 0 -#define MCONTEXT_SS_RAX 16 -#define MCONTEXT_SS_RBX 24 -#define MCONTEXT_SS_RCX 32 -#define MCONTEXT_SS_RDX 40 -#define MCONTEXT_SS_RDI 48 -#define MCONTEXT_SS_RSI 56 -#define MCONTEXT_SS_RBP 64 -#define MCONTEXT_SS_RSP 72 -#define MCONTEXT_SS_R8 80 -#define MCONTEXT_SS_RIP 144 - -/* register use: - %rbx uctx - -void -_sigtramp( - union __sigaction_u __sigaction_u, %rdi - int sigstyle, %rsi - int sig, %rdx - siginfo_t *sinfo, %rcx - ucontext_t *uctx %r8 -) -*/ - - .globl __sigtramp - .text - .align 4 -__sigtramp: -Lstart: - /* Although this routine does not need any stack frame, various parts - of the OS can't analyse the stack without them. */ - pushq %rbp - movq %rsp, %rbp - - movq %rdi, %rax # set up address for call - -#if defined(__DYNAMIC__) - incl ___in_sigtramp(%rip) -#endif - /* Save uctx in %rbx. */ - movq %r8, %rbx - /* Call the signal handler. - Some variants are not supposed to get the last two parameters, - but the test to prevent this is more expensive than just passing - them. */ - movl %edx, %edi - movq %rcx, %rsi - movq %r8, %rdx -Lcall_start: - call *%rax -Lcall_end: -#if defined(__DYNAMIC__) - decl ___in_sigtramp(%rip) -#endif - movq %rbx, %rdi - movl $ UC_FLAVOR, %esi - callq ___sigreturn - ret -Lend: - -/* DWARF unwind table #defines. */ -#define DW_CFA_advance_loc_4 0x44 -#define DW_CFA_def_cfa 0x0c -#define DW_CFA_def_cfa_expression 0x0F -#define DW_CFA_expression 0x10 -#define DW_CFA_val_expression 0x16 -#define DW_CFA_offset(column) 0x80+(column) - -/* DWARF expression #defines. */ -#define DW_OP_deref 0x06 -#define DW_OP_const1u 0x08 -#define DW_OP_dup 0x12 -#define DW_OP_drop 0x13 -#define DW_OP_over 0x14 -#define DW_OP_pick 0x15 -#define DW_OP_swap 0x16 -#define DW_OP_rot 0x17 -#define DW_OP_abs 0x19 -#define DW_OP_and 0x1a -#define DW_OP_div 0x1b -#define DW_OP_minus 0x1c -#define DW_OP_mod 0x1d -#define DW_OP_mul 0x1e -#define DW_OP_neg 0x1f -#define DW_OP_not 0x20 -#define DW_OP_or 0x21 -#define DW_OP_plus 0x22 -#define DW_OP_plus_uconst 0x23 -#define DW_OP_shl 0x24 -#define DW_OP_shr 0x25 -#define DW_OP_shra 0x26 -#define DW_OP_xor 0x27 -#define DW_OP_skip 0x2f -#define DW_OP_bra 0x28 -#define DW_OP_eq 0x29 -#define DW_OP_ge 0x2A -#define DW_OP_gt 0x2B -#define DW_OP_le 0x2C -#define DW_OP_lt 0x2D -#define DW_OP_ne 0x2E -#define DW_OP_lit(n) 0x30+(n) -#define DW_OP_breg(n) 0x70+(n) -#define DW_OP_deref_size 0x94 - -/* The location expression we'll use. */ - -#define loc_expr_for_reg(regno, offs) \ - .byte DW_CFA_expression, regno, 5 /* block length */, \ - DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \ - DW_OP_plus_uconst, offs - -/* For r8 through r13 */ -#define loc_expr_rN(regno) \ - loc_expr_for_reg(regno, MCONTEXT_SS_R8+(8*(regno-8))) - -/* For r14 through r15 */ -#define loc_expr_rN_long(regno) \ - .byte DW_CFA_expression, regno, 6 /* block length */, \ - DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \ - DW_OP_plus_uconst, MCONTEXT_SS_R8+(8*(regno-8)), 1 - - /* Unwind tables. */ - .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support - -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 # Length of Common Information Entry -LSCIE1: - .long 0 # CIE Identifier Tag - .byte 0x1 # CIE Version - .ascii "zRS\0" # CIE Augmentation - .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor - .byte 0x78 # sleb128 -8; CIE Data Alignment Factor - .byte 0x10 # CIE RA Column - .byte 0x1 # uleb128 0x1; Augmentation size - .byte 0x10 # FDE Encoding (pcrel) - .byte DW_CFA_def_cfa - .byte 0x7 # uleb128 0x5 - .byte 0x8 # uleb128 0x4 - .byte DW_CFA_offset(16) - .byte 0x1 # uleb128 0x1 - .byte DW_CFA_offset(16) // duplicate DW_CFA_offset (rip, -8) tells linker to not make compact unwind - .byte 0x1 # uleb128 0x1 - .align 1<<3 -LECIE1: - .globl _sigtramp.eh -_sigtramp.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 # FDE Length -LASFDE1: - .long LASFDE1-EH_frame1 # FDE CIE offset - .quad Lstart-. # FDE initial location - .set L$set$2,Lend-Lstart - .quad L$set$2 # FDE address range - .byte 0x0 # uleb128 0x0; Augmentation size - - /* Now for the expressions, which all compute - uctx->uc_mcontext->register - for each register. - - Describe even the registers that are not call-saved because they - might be being used in the prologue to save other registers. - Only integer registers are described at present. */ - - loc_expr_for_reg (0, MCONTEXT_SS_RAX) - loc_expr_for_reg (1, MCONTEXT_SS_RDX) - loc_expr_for_reg (2, MCONTEXT_SS_RCX) - loc_expr_for_reg (3, MCONTEXT_SS_RBX) - loc_expr_for_reg (4, MCONTEXT_SS_RSI) - loc_expr_for_reg (5, MCONTEXT_SS_RDI) - loc_expr_for_reg (6, MCONTEXT_SS_RBP) - loc_expr_for_reg (7, MCONTEXT_SS_RSP) - loc_expr_rN (8) - loc_expr_rN (9) - loc_expr_rN (10) - loc_expr_rN (11) - loc_expr_rN (12) - loc_expr_rN (13) - loc_expr_rN_long (14) - loc_expr_rN_long (15) - - /* The Intel architecture classifies exceptions into three categories, - 'faults' which put the address of the faulting instruction - in EIP, 'traps' which put the following instruction in EIP, - and 'aborts' which don't typically report the instruction - causing the exception. - - The traps are #BP and #OF. */ - - .byte DW_CFA_val_expression, 16 - .set L$set$3,Lpc_end-Lpc_start - .byte L$set$3 -Lpc_start: - /* Push the mcontext address twice. */ - .byte DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, DW_OP_dup - /* Find the value of EIP. */ - .byte DW_OP_plus_uconst, MCONTEXT_SS_RIP, MCONTEXT_SS_RIP >> 7 - .byte DW_OP_deref, DW_OP_swap - /* Determine the exception type. */ - .byte DW_OP_plus_uconst, MCONTEXT_ES_EXCEPTION, DW_OP_deref_size, 4 - /* Check whether it is #BP (3) or #OF (4). */ - .byte DW_OP_dup, DW_OP_lit(3), DW_OP_ne - .byte DW_OP_swap, DW_OP_lit(4), DW_OP_ne, DW_OP_and - /* If it is not, then add 1 to the instruction address, so as to point - within or past the faulting instruction. */ - .byte DW_OP_plus -Lpc_end: - - /* The CFA will have been saved as the value of RSP (it is not - RSP+8). */ - .byte DW_CFA_def_cfa_expression - .set L$set$4,Lcfa_end-Lcfa_start - .byte L$set$4 -Lcfa_start: - .byte DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref - .byte DW_OP_plus_uconst, MCONTEXT_SS_RSP, DW_OP_deref -Lcfa_end: - - .align 3 -LEFDE1: - - .subsections_via_symbols - diff --git a/src/libc/x86_64/sys/atomic.c b/src/libc/x86_64/sys/atomic.c deleted file mode 100644 index 46ae5c7d9..000000000 --- a/src/libc/x86_64/sys/atomic.c +++ /dev/null @@ -1,76 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -#ifndef VARIANT_DYLD -#define RESOLVER_UP_MP(symbol) \ - PLATFUNC_DESCRIPTOR(symbol, up, kUP, 0); \ - PLATFUNC_DESCRIPTOR(symbol, mp, 0, kUP); \ - static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \ - PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \ - PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \ - 0 \ - }; \ - void* symbol ## _chooser() __asm__("_" #symbol); \ - void* symbol ## _chooser() { \ - __asm__(".symbol_resolver _" #symbol); \ - return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \ - } - -#else -#define RESOLVER_UP_MP(symbol) __asm__(".globl _" #symbol); __asm__("_"#symbol ": jmp _" #symbol "$VARIANT$mp"); -#endif - -RESOLVER_UP_MP(OSAtomicAnd32) -RESOLVER_UP_MP(OSAtomicAnd32Barrier) -RESOLVER_UP_MP(OSAtomicOr32) -RESOLVER_UP_MP(OSAtomicOr32Barrier) -RESOLVER_UP_MP(OSAtomicXor32) -RESOLVER_UP_MP(OSAtomicXor32Barrier) -RESOLVER_UP_MP(OSAtomicAnd32Orig) -RESOLVER_UP_MP(OSAtomicAnd32OrigBarrier) -RESOLVER_UP_MP(OSAtomicOr32Orig) -RESOLVER_UP_MP(OSAtomicOr32OrigBarrier) -RESOLVER_UP_MP(OSAtomicXor32Orig) -RESOLVER_UP_MP(OSAtomicXor32OrigBarrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwapInt) -RESOLVER_UP_MP(OSAtomicCompareAndSwapIntBarrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwap32) -RESOLVER_UP_MP(OSAtomicCompareAndSwap32Barrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwapPtr) -RESOLVER_UP_MP(OSAtomicCompareAndSwapPtrBarrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwapLong) -RESOLVER_UP_MP(OSAtomicCompareAndSwapLongBarrier) -RESOLVER_UP_MP(OSAtomicCompareAndSwap64) -RESOLVER_UP_MP(OSAtomicCompareAndSwap64Barrier) -RESOLVER_UP_MP(OSAtomicAdd32) -RESOLVER_UP_MP(OSAtomicAdd32Barrier) -RESOLVER_UP_MP(OSAtomicAdd64) -RESOLVER_UP_MP(OSAtomicAdd64Barrier) -RESOLVER_UP_MP(OSAtomicTestAndSet) -RESOLVER_UP_MP(OSAtomicTestAndSetBarrier) -RESOLVER_UP_MP(OSAtomicTestAndClear) -RESOLVER_UP_MP(OSAtomicTestAndClearBarrier) diff --git a/src/libc/x86_64/sys/i386_gettimeofday_asm.S b/src/libc/x86_64/sys/i386_gettimeofday_asm.S deleted file mode 100644 index 15c4ff906..000000000 --- a/src/libc/x86_64/sys/i386_gettimeofday_asm.S +++ /dev/null @@ -1,89 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2003-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include -#include "platfunc.h" - -#define NSEC_PER_SEC 1000*1000*1000 -#define NSEC_PER_USEC 1000 - - .private_extern ___commpage_gettimeofday - .align 4 -___commpage_gettimeofday: -// %rdi = ptr to timeval - pushq %rbp // set up a frame for backtraces - pushq %r12 // push callee-saved registers we want to use - pushq %r13 - pushq %r14 - subq $8, %rsp - movq %rsp,%rbp - movq %rdi,%r12 // save ptr to timeval - -#ifndef DARLING - movq $(_COMM_PAGE_TIME_DATA_START),%r13 -0: - movl _GTOD_GENERATION(%r13),%r14d // get generation (0 if disabled) - testl %r14d,%r14d // disabled? - jz 4f -#endif - - call _mach_absolute_time // get %rax <- nanotime() - -#ifndef DARLING - movl _GTOD_SEC_BASE(%r13),%r8d // get _COMM_PAGE_TIMESTAMP - subq _GTOD_NS_BASE(%r13),%rax // generate nanoseconds since timestamp - cmpl _GTOD_GENERATION(%r13),%r14d // has data changed out from under us? - jne 0b -#endif - - movl $ NSEC_PER_SEC,%ecx - movq %rax,%rdx - shrq $32,%rdx // get high half of delta in %edx - divl %ecx // %eax <- seconds since timestamp, %edx <- nanoseconds - addl %eax,%r8d // add seconds elapsed to timestamp seconds - - movl $ NSEC_PER_USEC,%ecx - movl %edx,%eax - xorl %edx,%edx - divl %ecx // divide residual ns by 1000 to get residual us in %eax - - movq %r8,(%r12) // store 64-bit seconds into timeval - movl %eax,8(%r12) // store 32-bit useconds into timeval - xorl %eax,%eax // return 0 for success -3: - addq $8, %rsp - popq %r14 - popq %r13 - popq %r12 - popq %rbp - ret -4: // fail - movl $1,%eax - jmp 3b diff --git a/src/libc/x86_64/sys/nanotime.S b/src/libc/x86_64/sys/nanotime.S deleted file mode 100644 index f5413be6c..000000000 --- a/src/libc/x86_64/sys/nanotime.S +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2003-2007 Apple Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include - -/* - * 64-bit version _mach_absolute_time. We return the 64-bit nanotime in %rax, - */ - .globl _mach_absolute_time -_mach_absolute_time: - pushq %rbp // set up a frame for backtraces - movq %rsp,%rbp - movq $(_COMM_PAGE_TIME_DATA_START),%rsi -1: - movl _NT_GENERATION(%rsi),%r8d // get generation - testl %r8d,%r8d // if 0, data is being changed... - jz 1b // ...so loop until stable - lfence - rdtsc // edx:eax := tsc - lfence - shlq $32,%rdx // rax := ((edx << 32) | eax), ie 64-bit tsc - orq %rdx,%rax - subq _NT_TSC_BASE(%rsi), %rax // rax := (tsc - base_tsc) - movl _NT_SCALE(%rsi),%ecx - mulq %rcx // rdx:rax := (tsc - base_tsc) * scale - shrdq $32,%rdx,%rax // _COMM_PAGE_NT_SHIFT is always 32 - addq _NT_NS_BASE(%rsi),%rax // (((tsc - base_tsc) * scale) >> 32) + ns_base - - cmpl _NT_GENERATION(%rsi),%r8d // did the data change during computation? - jne 1b - popq %rbp - ret diff --git a/src/libc/x86_64/sys/setjmp.S b/src/libc/x86_64/sys/setjmp.S deleted file mode 100644 index 870959725..000000000 --- a/src/libc/x86_64/sys/setjmp.S +++ /dev/null @@ -1,142 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* - * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved - */ -/* - * NeXT 386 setjmp/longjmp - * - * Written by Bruce Martin, NeXT Inc. 4/9/92 - */ - -/* - * C library -- setjmp, longjmp - * - * longjmp(a,v) - * will generate a "return(v)" from - * the last call to - * setjmp(a) - * by restoring registers from the stack, - * The previous value of the signal mask is - * restored. - * - */ - -#ifdef DARLING__DISABLED -# define x__setjmp _setjmp -# define x_setjmp setjmp -# define x_longjmp longjmp -# define x__longjmp _longjmp -# define _mach_absolute_time mach_absolute_time -# define _sigaltstack sigaltstack -# define __sigunaltstack _sigunaltstack -# define _sigprocmask sigprocmask -# define _sigsetjmp sigsetjmp -# define _siglongjmp siglongjmp -#else -# define x__setjmp __setjmp -# define x__longjmp __longjmp -# define x_setjmp _setjmp -# define x_longjmp _longjmp -#endif - -#include - -#define JB_RBX 0 -#define JB_RBP 8 -#define JB_RSP 16 -#define JB_R12 24 -#define JB_R13 32 -#define JB_R14 40 -#define JB_R15 48 -#define JB_RIP 56 -#define JB_RFLAGS 64 -#define JB_MXCSR 72 -#define JB_FPCONTROL 76 -#define JB_MASK 80 -#define JB_SAVEMASK 84 // sigsetjmp/siglongjmp only -#define JB_ONSTACK 88 - -#define STACK_SSFLAGS 16 // offsetof(stack_t, ss_flags) - -LEAF(_sigsetjmp, 0) - // %rdi is sigjmp_buf * jmpbuf; - // %esi is int savemask - movl %esi, JB_SAVEMASK(%rdi) // jmpbuf[_JBLEN] = savemask; - cmpl $0, %esi // if savemask != 0 - jne x_setjmp // setjmp(jmpbuf); - jmp L_do__setjmp // else _setjmp(jmpbuf); - -LEAF(x_setjmp, 0) - pushq %rdi // Preserve the jmp_buf across the call - movl $1, %edi // how = SIG_BLOCK - xorq %rsi, %rsi // set = NULL - subq $16, %rsp // Allocate space for the return from sigprocmask + 8 to align stack - movq %rsp, %rdx // oset = allocated space - CALL_EXTERN(_sigprocmask) - popq %rax // Save the mask - addq $8, %rsp // Restore the stack to before we align it - movq (%rsp), %rdi // jmp_buf (struct sigcontext *). Leave pointer on the stack for _sigaltstack call) - movl %eax, JB_MASK(%rdi) - - // Get current sigaltstack status (stack_t) - subq $32, %rsp // 24 bytes for a stack_t, + 8 for the jmp_buf pointer, + 8 is correctly aligned - movq %rsp, %rsi // oss - xorq %rdi, %rdi // ss == NULL - CALL_EXTERN(_sigaltstack) // sigaltstack(NULL, oss) - movl STACK_SSFLAGS(%rsp), %eax // oss.ss_flags - movq 32(%rsp), %rdi // jmpbuf (will be first argument to subsequent call) - movl %eax, JB_ONSTACK(%rdi) // Store ss_flags in jmpbuf - addq $40, %rsp // restore %rsp - -L_do__setjmp: - BRANCH_EXTERN(x__setjmp) - -LEAF(_siglongjmp, 0) - // %rdi is sigjmp_buf * jmpbuf; - cmpl $0, JB_SAVEMASK(%rdi) // if jmpbuf[_JBLEN] != 0 - jne x_longjmp // longjmp(jmpbuf, var); - jmp L_do__longjmp // else _longjmp(jmpbuf, var); - -LEAF(x_longjmp, 0) - // %rdi is address of jmp_buf (saved context) - pushq %rdi // Preserve the jmp_buf across the call - pushq %rsi // Preserve the value across the call - pushq JB_MASK(%rdi) // Put the mask on the stack - movq $3, %rdi // how = SIG_SETMASK - movq %rsp, %rsi // set = address where we stored the mask - xorq %rdx, %rdx // oset = NULL - CALL_EXTERN_AGAIN(_sigprocmask) - - // Restore sigaltstack status - movq 16(%rsp), %rdi // Grab jmpbuf but leave it on the stack - movl JB_ONSTACK(%rdi), %edi // Pass old state to _sigunaltstack() - CALL_EXTERN(__sigunaltstack) - addq $8, %rsp // Restore stack - popq %rsi - popq %rdi // Pass jmpbuf to _longjmp - -L_do__longjmp: - BRANCH_EXTERN(x__longjmp) // else -END(_longjmp) diff --git a/src/libc/x86_64/sys/spinlocks.c b/src/libc/x86_64/sys/spinlocks.c deleted file mode 100644 index 5d046a219..000000000 --- a/src/libc/x86_64/sys/spinlocks.c +++ /dev/null @@ -1,53 +0,0 @@ -// Modified by Lubos Dolezel by Darling -/* - * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include "platfunc.h" - -#ifndef VARIANT_DYLD -#define RESOLVER_UP_MP(symbol) \ - PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, up); \ - PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, mp); \ - static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \ - PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \ - PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \ - 0 \ - }; \ - void* symbol ## _chooser() __asm__("_" #symbol); \ - void* symbol ## _chooser() { \ - __asm__(".symbol_resolver _" #symbol); \ - return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \ - } - -#else - -#define RESOLVER_UP_MP(symbol) __asm__(".globl _" #symbol); __asm__("_"#symbol ": jmp _" #symbol "$VARIANT$mp"); // __weak_reference(symbol ## $VARIANT$mp, symbol); - -#endif - -RESOLVER_UP_MP(OSSpinLockTry) -RESOLVER_UP_MP(_spin_lock_try) -RESOLVER_UP_MP(OSSpinLockLock) -RESOLVER_UP_MP(_spin_lock) -RESOLVER_UP_MP(spin_lock) diff --git a/src/libc/x86_64/sys/spinlocks_asm.S b/src/libc/x86_64/sys/spinlocks_asm.S deleted file mode 100644 index 9a882d396..000000000 --- a/src/libc/x86_64/sys/spinlocks_asm.S +++ /dev/null @@ -1,132 +0,0 @@ -// Modified by Lubos Dolezel for Darling -/* - * Copyright (c) 2003-2009 Apple, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include "platfunc.h" - -PLATFUNC_FUNCTION_START(OSSpinLockTry, up, 64, 4) -PLATFUNC_FUNCTION_START(_spin_lock_try, up, 64, 4) - xorl %eax, %eax - orl $-1, %edx - cmpxchgl %edx, (%rdi) - setz %dl - movzbl %dl, %eax - ret -PLATFUNC_DESCRIPTOR(OSSpinLockTry,up,kUP,0) -PLATFUNC_DESCRIPTOR(_spin_lock_try,up,kUP,0) - -PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockTry, mp, 64, 4) -PLATFUNC_FUNCTION_START_GENERIC(_spin_lock_try, mp, 64, 4) - xorl %eax, %eax - orl $-1, %edx - lock - cmpxchgl %edx, (%rdi) - setz %dl - movzbl %dl, %eax - ret -PLATFUNC_DESCRIPTOR(OSSpinLockTry,mp,0,kUP) -PLATFUNC_DESCRIPTOR(_spin_lock_try,mp,0,kUP) - - -PLATFUNC_FUNCTION_START(OSSpinLockLock, up, 64, 4) -PLATFUNC_FUNCTION_START(_spin_lock, up, 64, 4) -PLATFUNC_FUNCTION_START(spin_lock, up, 64, 4) - movq %rdi,%r8 -0: - xorl %eax, %eax - orl $-1, %edx - cmpxchgl %edx, (%r8) -#ifdef DARLING - jnz 0b - ret -#else - jnz 1f - ret -1: - /* failed to get lock so relinquish the processor immediately on UP */ - xorl %edi,%edi /* THREAD_NULL */ - movl $1,%esi /* SWITCH_OPTION_DEPRESS */ - movl $1,%edx /* 1 ms */ - movl $(SYSCALL_CONSTRUCT_MACH(61)),%eax /* 61 = thread_switch */ - syscall - jmp 0b -#endif -PLATFUNC_DESCRIPTOR(OSSpinLockLock,up,kUP,0) -PLATFUNC_DESCRIPTOR(_spin_lock,up,kUP,0) -PLATFUNC_DESCRIPTOR(spin_lock,up,kUP,0) - - -PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockLock, mp, 64, 4) -PLATFUNC_FUNCTION_START_GENERIC(_spin_lock, mp, 64, 4) -PLATFUNC_FUNCTION_START_GENERIC(spin_lock, mp, 64, 4) - movq %rdi,%r8 -0: - xorl %eax, %eax - orl $-1, %edx - lock - cmpxchgl %edx, (%r8) - jnz 1f - ret -1: - xorl %eax, %eax - movl $(MP_SPIN_TRIES), %edx -2: /* spin for awhile before relinquish */ - pause -#ifdef DARLING - jmp 0b -#else - cmpl %eax, (%r8) - jz 0b - decl %edx - jnz 2b - /* failed to get lock after spinning so relinquish */ - xorl %edi,%edi /* THREAD_NULL */ - movl $1,%esi /* SWITCH_OPTION_DEPRESS */ - movl $1,%edx /* 1 ms */ - movl $(SYSCALL_CONSTRUCT_MACH(61)),%eax /* 61 = thread_switch */ - syscall - jmp 0b -#endif -PLATFUNC_DESCRIPTOR(OSSpinLockLock,mp,0,kUP) -PLATFUNC_DESCRIPTOR(_spin_lock,mp,0,kUP) -PLATFUNC_DESCRIPTOR(spin_lock,mp,0,kUP) - -// void OSSpinLockUnlock( OSSpinLock *lock ); - .align 2, 0x90 - .globl _OSSpinLockUnlock - .globl _spin_unlock - .globl __spin_unlock -_OSSpinLockUnlock: -_spin_unlock: -__spin_unlock: - movl $0, (%rdi) - ret - diff --git a/src/libc/xcodescripts/Libc.order b/src/libc/xcodescripts/Libc.order new file mode 100644 index 000000000..ec19af8aa --- /dev/null +++ b/src/libc/xcodescripts/Libc.order @@ -0,0 +1,100 @@ +libBase.a(nanosleep.o):_clock_sem +libBase.a(nanosleep.o):_clock_port +libFortifySource.a(chk_fail.o):___chk_assert_no_overlap +libBase.a(xlocale.o):___locale_key +libBase.a(fork.o):__MergedGlobals +libFreeBSD.a(atexit.o):___atexit_new_registration +libBase.a(fork.o):__libSystem_atfork_prepare +libBase.a(fork.o):__libSystem_atfork_parent +libBase.a(fork.o):__libSystem_atfork_child +libFreeBSD.a(atexit.o):__MergedGlobals +libFreeBSD.a(atexit.o):___atexit +libBase.a(confstr):__dirhelper_func +libBase.a(crt_externs.o):__MergedGlobals +libBase.a(crt_externs.o):_NXArgv_pointer +libBase.a(crt_externs.o):_NXArgc_pointer +libBase.a(crt_externs.o):_environ_pointer +libBase.a(crt_externs.o):___progname_pointer +libBase.a(crt_externs.o):__mh_execute_header_pointer +libFreeBSD.a(stack_protector.o):___stack_chk_guard +libFreeBSD.a(atexit.o):_atexit_mutex +libBase.a(xlocale.o):__MergedGlobals +libBase.a(xlocale.o):___c_locale +libBase.a(xlocale.o):___global_locale +libFreeBSD.a(findfp.o):__MergedGlobals +libFreeBSD.a(exit.o):___cleanup +libFreeBSD.a(findfp.o):___sdidinit +libFreeBSD.a(findfp.o):___sglue +libFreeBSD.a(findfp.o):__MergedGlobals1 +libFreeBSD.a(findfp.o):___stream_max +libFreeBSD.a(findfp.o):___scounted +libFreeBSD.a(findfp.o):_thread_lock +libFreeBSD.a(findfp.o):_lastglue +libBase.a(timezone_unix03.o):_timezone +libFreeBSD.a(localtime.o):_daylight +libFreeBSD.a(localtime.o):___darwin_altzone +libFreeBSD.a(localtime.o):_lclptr +libFreeBSD.a(localtime.o):_tzname +libFreeBSD.a(localtime.o):_lcl_notify +libFreeBSD.a(localtime.o):_lcl_rwlock +libFreeBSD.a(localtime.o):__MergedGlobals +libFreeBSD.a(localtime.o):__MergedGlobals8 +libFreeBSD.a(getpagesize.o):_getpagesize.value +libFreeBSD.a(setenv.o):___env_owned +libFreeBSD.a(arc4random.o):_rs_stired +libFreeBSD.a(arc4random.o):_rs.0 +libFreeBSD.a(arc4random.o):_rs.1 +libFreeBSD.a(arc4random.o):__MergedGlobals +libFreeBSD.a(arc4random.o):_rs_data_available +libFreeBSD.a(arc4random.o):_lock +libFreeBSD.a(arc4random.o):_arc4_count +libFreeBSD.a(arc4random.o):_rdat +libFreeBSD.a(arc4random.o):_rs.2 +libFreeBSD.a(gdtoa-misc.o):_gdtoa_tsd_key +libFreeBSD.a(gdtoa-misc.o):_gdtoa_tsd_lock +libvDarwinExtsn.a(realpath.o):_realpath$DARWIN_EXTSN.rootdev_inited +libvDarwinExtsn.a(realpath.o):_realpath$DARWIN_EXTSN.rootdev +libFreeBSD.a(gdtoa-misc.o):_p5s +libFreeBSD.a(glue.o):___gdtoa_locks +libFreeBSD.a(findfp.o):___sFX +libFreeBSD.a(getopt.o):_optreset +libFreeBSD.a(strerror.o):___strerror_ebuf +libBase.a(NSSystemDirectories.o):_nextRoot +libFreeBSD.a(getopt.o):_optarg +libBase.a(NSSystemDirectories.o):_nextRoot_init_once +libFreeBSD.a(findfp.o):___sF +libFreeBSD.a(localtime.o):_localtime.localtime_key +libFreeBSD.a(getopt.o):_getopt.place +libFreeBSD.a(getopt_long.o):__MergedGlobals +libFreeBSD.a(random.o):__MergedGlobals +libFreeBSD.a(random.o):_fptr +libFreeBSD.a(random.o):_rptr +libFreeBSD.a(localtime.o):_localtime.localtime_mutex +libFreeBSD.a(random.o):_randtbl +libFreeBSD.a(getopt_long.o):_nonopt_end +libFreeBSD.a(getopt_long.o):_nonopt_start +libFreeBSD.a(getopt_long.o):_place +libFreeBSD.a(rand.o):_next +libBase.a(OSThermalNotification.o):_predicates +libBase.a(OSThermalNotification.o):_tokens +libFreeBSD.a(getopt.o):_optind +libBase.a(OSThermalNotification.o):__MergedGlobals +libBase.a(OSThermalNotification.o):_thermalLevelsReady +libFreeBSD.a(asctime.o):_buf_asctime +libFreeBSD.a(getopt.o):_opterr +libFreeBSD.a(basename.o):_basename.bname +libFreeBSD.a(getopt.o):_optopt +libFreeBSD.a(localtime.o):_gmtptr +libFreeBSD.a(localtime.o):_gmt_notify +libFreeBSD.a(localtime.o):_gmt_mutex +libFreeBSD.a(vfscanf.o):___parsefloat_buf.parsefloat_tsd_key +libFreeBSD.a(vfscanf.o):___parsefloat_buf.bsiz +libFreeBSD.a(vfscanf.o):___parsefloat_buf.parsefloat_tsd_lock +libNetBSD.a(utmpx.o):___utx__ +libFreeBSD.a(strtok.o):_strtok.last +libNetBSD.a(utmpx.o):___default_utx.once +libBase.a(assumes.o):__os_abort_on_assumes.once +libFreeBSD.a(inet_ntoa.o):_inet_ntoa.ret +libFreeBSD.a(strsignal.o):_sig_init_once +libFreeBSD.a(strsignal.o):__MergedGlobals +libFreeBSD.a(localtime.o):_lcl_TZname diff --git a/src/libc/xcodescripts/abort_unsupported.sh b/src/libc/xcodescripts/abort_unsupported.sh new file mode 100755 index 000000000..b817d2854 --- /dev/null +++ b/src/libc/xcodescripts/abort_unsupported.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +for platform in ${SUPPORTED_PLATFORMS} ; do + [[ "${platform}" == "${PLATFORM_NAME}" ]] && exit 0 +done + +echo "Unsupported platform encountered:" >&2 +echo " PLATFORM_NAME: ${PLATFORM_NAME}" >&2 +echo " SUPPORTED_PLATFORMS: ${SUPPORTED_PLATFORMS}" >&2 +echo "Please contact the Darwin Runtime Team for help with your new platform bringup needs" >&2 +exit 1 diff --git a/src/libc/xcodescripts/alias.list b/src/libc/xcodescripts/alias.list new file mode 100644 index 000000000..651244eed --- /dev/null +++ b/src/libc/xcodescripts/alias.list @@ -0,0 +1,14 @@ +__platform_bzero _bzero +__platform_memccpy _memccpy +__platform_memchr _memchr +__platform_memcmp _memcmp +__platform_memcmp _bcmp +__platform_memmove _memmove +__platform_memmove _memcpy +__platform_memset _memset +__platform_memset_pattern16 _memset_pattern16 +__platform_memset_pattern4 _memset_pattern4 +__platform_memset_pattern8 _memset_pattern8 +__platform_strchr _strchr +__platform_strcmp _strcmp +__platform_strncmp _strncmp diff --git a/src/libc/xcodescripts/build_linklists.sh b/src/libc/xcodescripts/build_linklists.sh index 097d6b713..59bf260cc 100755 --- a/src/libc/xcodescripts/build_linklists.sh +++ b/src/libc/xcodescripts/build_linklists.sh @@ -5,26 +5,38 @@ # Skip script during installhdrs if [ "$ACTION" == installhdrs ]; then exit 0; fi +# BUILD_ARCHIVES needs to be set in the project settings +if [ -z "$BUILD_ARCHIVES" ]; then exit 0; fi -ARCHIVES=(Platform Base FreeBSD FreeBSD_gcc NetBSD TRE vCancelable vDarwinExtsn vDarwinExtsnCancelable vPre1050 vLegacy vInode32) +[ ! -d "$BUILT_PRODUCTS_DIR" ] && mkdir -p "$BUILT_PRODUCTS_DIR" +[ ! -d "$DERIVED_FILES_DIR" ] && mkdir -p "$DERIVED_FILES_DIR" NORMAL_LIST="$BUILT_PRODUCTS_DIR/normal.linklist" DEBUG_LIST="$BUILT_PRODUCTS_DIR/debug.linklist" INTERPOSABLE_LIST="$DERIVED_FILES_DIR/interposable.list" +UNEXPORT_LIST="$DERIVED_FILES_DIR/unexport.list" -rm -f $NORMAL_LIST -rm -f $DEBUG_LIST -rm -f $INTERPOSABLE_LIST +rm -f "$NORMAL_LIST" +rm -f "$DEBUG_LIST" +rm -f "$INTERPOSABLE_LIST" +rm -f "$UNEXPORT_LIST" -for x in ${ARCHIVES[@]}; do +for x in ${BUILD_ARCHIVES[@]}; do nm -AUamgf "$BUILT_PRODUCTS_DIR/lib${x}.a" 2>/dev/null | \ grep '__TEXT,__text' | \ - grep -v '\[symbol resolver\]' | \ - grep -vE '\$VARIANT\$(m|u)p' | \ - awk '{ print $NF }' >> $INTERPOSABLE_LIST + grep -vE '\$VARIANT' | \ + awk '{ print $NF }' >> "$INTERPOSABLE_LIST" - echo "-l$x" >> $NORMAL_LIST - echo "-l${x}_debug" >> $DEBUG_LIST + nm -AUamgf "$BUILT_PRODUCTS_DIR/lib${x}.a" 2>/dev/null | \ + awk '/\$VARIANT/ { print $NF }' >> "$UNEXPORT_LIST" + + echo "$BUILT_PRODUCTS_DIR/lib${x}.a" >> "$NORMAL_LIST.libtool" + filename=$(printf %s "$BUILT_PRODUCTS_DIR/lib${x}.a" | sed "s/\ /\\\ /g") + echo "$filename" >> "$NORMAL_LIST" + + echo "$BUILT_PRODUCTS_DIR/lib${x}_debug.a" >> "$DEBUG_LIST.libtool" + filename=$(printf %s "$BUILT_PRODUCTS_DIR/lib${x}_debug.a" | sed "s/\ /\\\ /g") + echo "$filename" >> "$DEBUG_LIST" done touch "$BUILT_PRODUCTS_DIR/deps.c" diff --git a/src/libc/xcodescripts/clean_simulator.sh b/src/libc/xcodescripts/clean_simulator.sh deleted file mode 100644 index 39c4f3858..000000000 --- a/src/libc/xcodescripts/clean_simulator.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -# clean_simulator.sh -if [ "$ACTION" = installhdrs ]; then exit 0; fi - -if [ "$PLATFORM_NAME" = iphonesimulator ]; then - rm -rf "${DSTROOT}"/usr/local/lib/dyld -fi diff --git a/src/libc/xcodescripts/eos.xcconfig b/src/libc/xcodescripts/eos.xcconfig new file mode 100644 index 000000000..f2cbedd0e --- /dev/null +++ b/src/libc/xcodescripts/eos.xcconfig @@ -0,0 +1,31 @@ +#include "libc.xcconfig" + +BUILD_ARCHIVES = Base FreeBSD TRE vCancelable vDarwinExtsn +BUILD_VARIANTS = normal +EXECUTABLE_PREFIX = lib +INSTALL_PATH = /usr/local/lib/eOS +OTHER_LIBTOOLFLAGS = -filelist $(BUILT_PRODUCTS_DIR)/$(CURRENT_VARIANT).linklist.libtool +PRODUCT_NAME = c_eOS +SKIP_INSTALL = YES +SKIP_INSTALL[sdk=iphoneos*] = NO +STRIP_INSTALLED_PRODUCT = NO +VARIANT = EOS +VERSIONING_SYSTEM = apple-generic + +// Variants. All variants contain all source files but all excluded. Specific variants then include the files they need. +EXCLUDED_SOURCE_FILE_NAMES = * +EXCLUDED_SOURCE_FILE_NAMES[sdk=iphoneos*] = $(VARIANT_EOS_EXCLUDED_FILES) +EXCLUDED_SOURCE_FILE_NAMES[sdk=watchos*] = $(VARIANT_EOS_EXCLUDED_FILES) +EXCLUDED_SOURCE_FILE_NAMES[sdk=appletvos*] = $(VARIANT_EOS_EXCLUDED_FILES) +INCLUDED_SOURCE_FILE_NAMES = +INCLUDED_SOURCE_FILE_NAMES[sdk=iphoneos*] = $(VARIANT_EOS_INCLUDED_FILES) +INCLUDED_SOURCE_FILE_NAMES[sdk=watchos*] = $(VARIANT_EOS_INCLUDED_FILES) +INCLUDED_SOURCE_FILE_NAMES[sdk=appletvos*] = $(VARIANT_EOS_INCLUDED_FILES) +VARIANT_PREPROCESSOR_MACROS = -UBUILDING_VARIANT -DVARIANT_STATIC -DVARIANT_EOS -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0 + +SYSTEM_FRAMEWORK_HEADERS = $(DERIVED_FILES_DIR)/System.framework/Versions/B/PrivateHeaders +HEADER_SEARCH_PATHS = $(FreeBSD_SEARCH_PATHS) $(inherited) + +// EOS (libc_eOS.a) +VARIANT_EOS_EXCLUDED_FILES = * +VARIANT_EOS_INCLUDED_FILES = secure/*.c $(ARCH_FAMILY_$(CURRENT_ARCH))/*/*.c $(ARCH_FAMILY_$(CURRENT_ARCH))/*/*.S $(ARCH_FAMILY_$(CURRENT_ARCH))/*/*.s diff --git a/src/libc/xcodescripts/force_libc_to_build.sh b/src/libc/xcodescripts/force_libc_to_build.sh index d4ed3029c..28b1c1eda 100644 --- a/src/libc/xcodescripts/force_libc_to_build.sh +++ b/src/libc/xcodescripts/force_libc_to_build.sh @@ -10,4 +10,4 @@ if [ "x$ACTION" == "xinstallhdrs" ]; then exit 0; fi DEPS_C="$BUILT_PRODUCTS_DIR/deps.c" -[ -e $DEPS_C ] && rm -f $DEPS_C +[ -e "$DEPS_C" ] && rm -f "$DEPS_C" diff --git a/src/libc/xcodescripts/generate_features.pl b/src/libc/xcodescripts/generate_features.pl index ce710f4b9..e2d689f5e 100755 --- a/src/libc/xcodescripts/generate_features.pl +++ b/src/libc/xcodescripts/generate_features.pl @@ -1,9 +1,5 @@ #!/usr/bin/perl -if ($ENV{"ACTION"} eq "installhdrs") { - exit 0; -} - # Generates the libc-features.h files used to control #ifdef behaviour in Libc use warnings; use Data::Dumper; @@ -23,9 +19,15 @@ for my $arch (split(/ /, $ENV{"ARCHS"})) { # set ENV{"CURRENT_ARCH"} so we can predicate on it $ENV{"CURRENT_ARCH"} = $arch; - + + # BridgeOS shares the same platform name than the watch so + # we need to fix it and pick the right configuration. my $platformName = $ENV{"PLATFORM_NAME"}; - $platformName = "iphoneos" if ($platformName eq "iphonesimulator"); + if ($ENV{"RC_BRIDGE"} eq "YES") { + $platformName = "bridgeos"; + } + + $platformName =~ s/simulator/os/; my $platformPath = $ENV{"SRCROOT"} . "/Platforms/" . $platformName . "/Makefile.inc"; my $featuresHeaderDir = $ENV{"DERIVED_FILES_DIR"}."/".$arch; @@ -51,7 +53,7 @@ for my $arch (split(/ /, $ENV{"ARCHS"})) my $regex = $2; $nested++; - if ($ENV{$envvar} !~ /$regex/) { + if (!defined($ENV{$envvar}) || ($ENV{$envvar} !~ /$regex/)) { $skip += 1; } } @@ -78,12 +80,16 @@ for my $arch (split(/ /, $ENV{"ARCHS"})) } elsif ($unifdef == 1) { + if ($platformName eq "macosx") { + $unifdefs{"__OSX_OPEN_SOURCE__"} = 1; + } # assume FEATURE_BLOCKS was on by default $unifdefs{"UNIFDEF_BLOCKS"} = 1; $unifdefs{"UNIFDEF_LEGACY_64_APIS"} = defined($features{"FEATURE_LEGACY_64_APIS"}); $unifdefs{"UNIFDEF_LEGACY_RUNE_APIS"} = defined($features{"FEATURE_LEGACY_RUNE_APIS"}); $unifdefs{"UNIFDEF_LEGACY_UTMP_APIS"} = defined($features{"FEATURE_LEGACY_UTMP_APIS"}); $unifdefs{"UNIFDEF_MOVE_LOCALTIME"} = defined($features{"FEATURE_MOVE_LOCALTIME"}); + $unifdefs{"UNIFDEF_TZDIR_SYMLINK"} = defined($features{"FEATURE_TZDIR_SYMLINK"}); my $output = ""; for my $d (keys %unifdefs) { @@ -100,7 +106,7 @@ for my $arch (split(/ /, $ENV{"ARCHS"})) my $platform_mtime = (stat($platformPath))[9]; my $header_mtime = (stat($featuresHeader))[9]; - if ($header_mtime > $platform_mtime) { + if (defined($header_mtime) && defined($platform_mtime) && ($header_mtime > $platform_mtime)) { exit 0; } @@ -122,6 +128,7 @@ for my $arch (split(/ /, $ENV{"ARCHS"})) my $shortarch = $arch; $shortarch =~ s/armv\d+[a-z]?/arm/g; + $shortarch =~ s/arm64_32/arm64/g; printf HEADER "#if !defined(__".$shortarch."__)\n"; printf HEADER "#error Mismatched libc-features.h architecture\n"; @@ -151,6 +158,12 @@ for my $arch (split(/ /, $ENV{"ARCHS"})) printf HEADER "/* #undef UNIFDEF_MOVE_LOCALTIME */\n"; } + if (defined($features{"FEATURE_TZDIR_SYMLINK"})) { + printf HEADER "#define UNIFDEF_TZDIR_SYMLINK 1\n"; + } else { + printf HEADER "/* #undef UNIFDEF_TZDIR_SYMLINK */\n"; + } + if (defined($features{"FEATURE_ONLY_1050_VARIANTS"})) { printf HEADER "#if !__DARWIN_ONLY_VERS_1050\n"; printf HEADER "# error Feature mismatch: __DARWIN_ONLY_VERS_1050 == 0\n"; @@ -187,12 +200,6 @@ for my $arch (split(/ /, $ENV{"ARCHS"})) printf HEADER "/* #undef __APPLE_PR3417676_HACK__ */\n"; } - if (defined($features{"FEATURE_PATCH_5243343"})) { - printf HEADER "#define PR_5243343 1\n"; - } else { - printf HEADER "/* #undef PR_5243343 */\n"; - } - if (defined($features{"FEATURE_PLOCKSTAT"})) { printf HEADER "#define PLOCKSTAT 1\n"; } else { @@ -211,10 +218,22 @@ for my $arch (split(/ /, $ENV{"ARCHS"})) printf HEADER "/* #undef LIBC_NO_LIBCRASHREPORTERCLIENT */\n"; } - if (defined($features{"FEATURE_MEMORYSTATUS"})) { - printf HEADER "#define CONFIG_MEMORYSTATUS 1\n"; + if (defined($features{"FEATURE_SMALL_STDIOBUF"})) { + printf HEADER "#define FEATURE_SMALL_STDIOBUF 1\n"; + } else { + printf HEADER "/* #undef FEATURE_SMALL_STDIOBUF */\n"; + } + + if (defined($features{"FEATURE_XPRINTF_PERF"})) { + printf HEADER "#define XPRINTF_PERF 1\n"; + } else { + printf HEADER "/* #undef XPRINTF_PERF */\n"; + } + + if (defined($features{"FEATURE_SIGNAL_RESTRICTION"})) { + printf HEADER "#define FEATURE_SIGNAL_RESTRICTION 1\n"; } else { - printf HEADER "/* #undef CONFIG_MEMORYSTATUS */\n"; + printf HEADER "/* #undef FEATURE_SIGNAL_RESTRICTION */\n"; } printf HEADER "#endif // _LIBC_FEATURES_H_\n"; diff --git a/src/libc/xcodescripts/headers.sh b/src/libc/xcodescripts/headers.sh old mode 100644 new mode 100755 index 47028ea17..d447595b7 --- a/src/libc/xcodescripts/headers.sh +++ b/src/libc/xcodescripts/headers.sh @@ -28,31 +28,94 @@ LOCINCDIR=${DSTROOT}/${PRIVATE_HEADERS_FOLDER_PATH} SYSTEMFRAMEWORK=${DSTROOT}/System/Library/Frameworks/System.framework KERNELFRAMEWORK=${DSTROOT}/System/Library/Frameworks/Kernel.framework -if [ "$PLATFORM_NAME" = iphonesimulator ]; then - SYSTEMFRAMEWORK=${DSTROOT}/${SDKROOT}/System/Library/Frameworks/System.framework - KERNELFRAMEWORK=${DSTROOT}/${SDKROOT}/System/Library/Frameworks/Kernel.framework -fi - PRIVHDRS=${SYSTEMFRAMEWORK}/Versions/B/PrivateHeaders PRIVKERNELHDRS=${KERNELFRAMEWORK}/Versions/A/PrivateHeaders INSTALLMODE=$([[ `id -u` -eq 0 ]] && echo 444 || echo 644) INSTHDRS=( - ${SRCROOT}/darwin/libproc.h ${SRCROOT}/gen/get_compat.h ${SRCROOT}/gen/execinfo.h ) INC_INSTHDRS=( - NSSystemDirectories.h _locale.h _structs.h _types.h _wctype.h _xlocale.h aio.h alloca.h \ - ar.h asl.h assert.h asm.h bitstring.h cpio.h crt_externs.h ctype.h db.h dirent.h disktab.h err.h \ - errno.h fcntl.h fmtmsg.h fnmatch.h fsproperties.h fstab.h fts.h ftw.h getopt.h glob.h inttypes.h \ - iso646.h langinfo.h libc.h libgen.h limits.h locale.h memory.h monetary.h monitor.h mpool.h ndbm.h \ - nlist.h paths.h poll.h ranlib.h readpassphrase.h regex.h runetype.h search.h \ - semaphore.h setjmp.h sgtty.h signal.h spawn.h stab.h standards.h stdbool.h stddef.h stdio.h stdint.h \ - stdlib.h strhash.h string.h stringlist.h strings.h struct.h sysexits.h syslog.h tar.h termios.h time.h \ - timeconv.h ttyent.h ucontext.h ulimit.h unistd.h util.h utime.h vis.h wchar.h wctype.h \ - wordexp.h xlocale.h + _locale.h + _types.h + _wctype.h + _xlocale.h + aio.h + alloca.h + ar.h + assert.h + asm.h + bitstring.h + cpio.h + crt_externs.h + ctype.h + db.h + dirent.h + disktab.h + err.h + errno.h + fcntl.h + fmtmsg.h + fnmatch.h + fsproperties.h + fstab.h + fts.h + ftw.h + getopt.h + glob.h + inttypes.h + iso646.h + langinfo.h + libc.h + libgen.h + limits.h + locale.h + memory.h + monetary.h + monitor.h + mpool.h + ndbm.h + nlist.h + paths.h + printf.h + poll.h + ranlib.h + readpassphrase.h + regex.h + runetype.h + search.h + semaphore.h + sgtty.h + signal.h + stab.h + standards.h + stddef.h + stdio.h + stdint.h + stdlib.h + strhash.h + string.h + stringlist.h + strings.h + struct.h + sysexits.h + syslog.h + tar.h + termios.h + time.h + timeconv.h + ttyent.h + ulimit.h + unistd.h + util.h + utime.h + vis.h + wchar.h + wctype.h + wordexp.h + xlocale.h ) if [ "x${FEATURE_LEGACY_RUNE_APIS}" == "x1" ]; then INC_INSTHDRS=( "${INC_INSTHDRS[@]}" rune.h ) @@ -67,26 +130,17 @@ INC_INSTHDRS=( ${SRCROOT}/include/NetBSD/utmpx.h ${SRCROOT}/stdtime/FreeBSD/tzfile.h ) -INC_PTHREADHDRS=( - ${SRCROOT}/pthreads/pthread.h - ${SRCROOT}/pthreads/pthread_spis.h - ${SRCROOT}/pthreads/pthread_impl.h - ${SRCROOT}/pthreads/sched.h -) -INSTHDRS=( "${INSTHDRS[@]}" "${INC_INSTHDRS[@]}" "${INC_PTHREADHDRS[@]}" ) +INSTHDRS=( "${INSTHDRS[@]}" "${INC_INSTHDRS[@]}" ) -INC_ARPA_INSTHDRS=( ftp.h nameser_compat.h telnet.h tftp.h ) +INC_ARPA_INSTHDRS=( ftp.h inet.h nameser_compat.h telnet.h tftp.h ) ARPA_INSTHDRS=( "${INC_ARPA_INSTHDRS[@]/#/${SRCROOT}/include/arpa/}" ) -INC_LIBKERN_INSTHDRS=( OSAtomic.h OSCacheControl.h ) -if [ "x${FEATURE_MEM_THERM_NOTIFICATION_APIS}" == "x1" ]; then - INC_LIBKERN_INSTHDRS+=( OSMemoryNotification.h OSThermalNotification.h ) +if [ "x${FEATURE_THERM_NOTIFICATION_APIS}" == "x1" ]; then + INC_THERM_INSTHDRS=( OSThermalNotification.h ) + THERM_INSTHDRS=( "${INC_THERM_INSTHDRS[@]/#/${SRCROOT}/include/libkern/}" ) fi -LIBKERN_INSTHDRS=( "${INC_LIBKERN_INSTHDRS[@]/#/${SRCROOT}/include/libkern/}" ) -MALLOC_INSTHDRS=( ${SRCROOT}/include/malloc/malloc.h ) - -INC_PROTO_INSTHDRS=(routed.h rwhod.h talkd.h timed.h ) +INC_PROTO_INSTHDRS=( routed.h rwhod.h talkd.h timed.h ) PROTO_INSTHDRS=( "${INC_PROTO_INSTHDRS[@]/#/${SRCROOT}/include/protocols/}" ) INC_SECURE_INSTHDRS=( _common.h _string.h _stdio.h ) @@ -95,35 +149,42 @@ SECURE_INSTHDRS=( "${INC_SECURE_INSTHDRS[@]/#/${SRCROOT}/include/secure/}" ) SYS_INSTHDRS=( ${SRCROOT}/include/sys/acl.h ${SRCROOT}/include/sys/statvfs.h ) INC_XLOCALE_INSTHDRS=( - __wctype.h _ctype.h _inttypes.h _langinfo.h _monetary.h _regex.h - _stdio.h _stdlib.h _string.h _time.h _wchar.h _wctype.h + __wctype.h + _ctype.h + _inttypes.h + _langinfo.h + _monetary.h + _regex.h + _stdio.h + _stdlib.h + _string.h + _time.h + _wchar.h + _wctype.h ) XLOCALE_INSTHDRS=( "${INC_XLOCALE_INSTHDRS[@]/#/${SRCROOT}/include/xlocale/}" ) +TYPES_INSTHDRS=( + ${SRCROOT}/include/_types/_intmax_t.h + ${SRCROOT}/include/_types/_nl_item.h + ${SRCROOT}/include/_types/_uint16_t.h + ${SRCROOT}/include/_types/_uint32_t.h + ${SRCROOT}/include/_types/_uint64_t.h + ${SRCROOT}/include/_types/_uint8_t.h + ${SRCROOT}/include/_types/_uintmax_t.h + ${SRCROOT}/include/_types/_wctrans_t.h + ${SRCROOT}/include/_types/_wctype_t.h +) + LOCALHDRS=( - ${SRCROOT}/darwin/dirhelper.defs - ${SRCROOT}/darwin/dirhelper_priv.h - ${SRCROOT}/darwin/libproc.h - ${SRCROOT}/darwin/libproc_internal.h - ${SRCROOT}/gen/asl_core.h - ${SRCROOT}/gen/asl_file.h - ${SRCROOT}/gen/asl_ipc.defs - ${SRCROOT}/gen/asl_legacy1.h - ${SRCROOT}/gen/asl_msg.h - ${SRCROOT}/gen/asl_private.h - ${SRCROOT}/gen/asl_store.h - ${SRCROOT}/gen/assumes.h - ${SRCROOT}/gen/_simple.h - ${SRCROOT}/gen/stack_logging.h + ${SRCROOT}/darwin/libc_private.h ${SRCROOT}/gen/utmpx_thread.h - ${SRCROOT}/include/spawn_private.h ${SRCROOT}/nls/FreeBSD/msgcat.h - ${SRCROOT}/pthreads/pthread_workqueue.h ) +OS_LOCALHDRS=( ${SRCROOT}/os/assumes.h ${SRCROOT}/os/debug_private.h ) + PRIV_INSTHDRS=( - ${SRCROOT}/gen/stack_logging.h - ${SRCROOT}/pthreads/pthread_machdep.h ${SRCROOT}/stdlib/FreeBSD/atexit.h ) @@ -132,7 +193,11 @@ PRIV_BTREEHDRS=( ${SRCROOT}/db/btree/FreeBSD/bt_extern.h ) -SYS_INSTHDRS=( ${SRCROOT}/include/sys/acl.h ${SRCROOT}/include/sys/statvfs.h ) +SYS_INSTHDRS=( + ${SRCROOT}/include/sys/acl.h + ${SRCROOT}/include/sys/rbtree.h + ${SRCROOT}/include/sys/statvfs.h +) PRIVUUID_INSTHDRS=( ${SRCROOT}/uuid/namespace.h ) ${MKDIR} ${INCDIR}/arpa @@ -142,16 +207,24 @@ ${MKDIR} ${INCDIR}/protocols ${MKDIR} ${INCDIR}/secure ${MKDIR} ${INCDIR}/sys ${MKDIR} ${INCDIR}/xlocale +${MKDIR} ${INCDIR}/_types ${INSTALL} -m ${INSTALLMODE} ${INSTHDRS[@]} ${INCDIR} ${INSTALL} -m ${INSTALLMODE} ${ARPA_INSTHDRS[@]} ${INCDIR}/arpa -${INSTALL} -m ${INSTALLMODE} ${LIBKERN_INSTHDRS[@]} ${INCDIR}/libkern -${INSTALL} -m ${INSTALLMODE} ${MALLOC_INSTHDRS[@]} ${INCDIR}/malloc +if [ "x${FEATURE_MEM_NOTIFICATION_APIS}" == "x1" ]; then +${INSTALL} -m ${INSTALLMODE} ${MEM_INSTHDRS[@]} ${INCDIR}/libkern +fi +if [ "x${FEATURE_THERM_NOTIFICATION_APIS}" == "x1" ]; then +${INSTALL} -m ${INSTALLMODE} ${THERM_INSTHDRS[@]} ${INCDIR}/libkern +fi ${INSTALL} -m ${INSTALLMODE} ${PROTO_INSTHDRS[@]} ${INCDIR}/protocols ${INSTALL} -m ${INSTALLMODE} ${SECURE_INSTHDRS[@]} ${INCDIR}/secure ${INSTALL} -m ${INSTALLMODE} ${SYS_INSTHDRS[@]} ${INCDIR}/sys ${INSTALL} -m ${INSTALLMODE} ${XLOCALE_INSTHDRS[@]} ${INCDIR}/xlocale +${INSTALL} -m ${INSTALLMODE} ${TYPES_INSTHDRS[@]} ${INCDIR}/_types ${MKDIR} ${LOCINCDIR} +${MKDIR} ${LOCINCDIR}/os ${INSTALL} -m ${INSTALLMODE} ${LOCALHDRS[@]} ${LOCINCDIR} +${INSTALL} -m ${INSTALLMODE} ${OS_LOCALHDRS[@]} ${LOCINCDIR}/os ${MKDIR} ${PRIVHDRS}/btree ${MKDIR} ${PRIVHDRS}/machine ${MKDIR} ${PRIVHDRS}/uuid @@ -170,7 +243,7 @@ for i in `${FIND} "${DSTROOT}" -name \*.h -print0 | ${XARGS} -0 ${GREP} -l '^//B ${ED} - $i < ${SRCROOT}/xcodescripts/strip-header.ed && ${CHMOD} u-w $i || exit 1; done -for i in `${FIND} "${DSTROOT}" -name \*.h -print0 | ${XARGS} -0 ${FGREP} -l UNIFDEF`; do +for i in `${FIND} "${DSTROOT}" -name \*.h -print0 | ${XARGS} -0 ${FGREP} -l -e UNIFDEF -e OPEN_SOURCE`; do ${CHMOD} u+w $i && ${CP} $i $i.orig && ${ECHO} ${UNIFDEF} ${UNIFDEFARGS} $i.orig \> $i && diff --git a/src/libc/xcodescripts/libc.xcconfig b/src/libc/xcodescripts/libc.xcconfig index ac40d926e..3559c3499 100644 --- a/src/libc/xcodescripts/libc.xcconfig +++ b/src/libc/xcodescripts/libc.xcconfig @@ -1,10 +1,10 @@ #include "/Makefiles/CoreOS/Xcode/BSD.xcconfig" // Standard settings -SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator -SRCROOT_SEARCH_PATHS = $(SRCROOT)/include $(SRCROOT)/gen $(SRCROOT)/locale $(SRCROOT)/locale/FreeBSD $(SRCROOT)/pthreads $(SRCROOT)/stdtime/FreeBSD +SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator iphoneosnano iphonesimulatornano +SRCROOT_SEARCH_PATHS = $(SRCROOT) $(SRCROOT)/include $(SRCROOT)/gen $(SRCROOT)/locale $(SRCROOT)/locale/FreeBSD $(SRCROOT)/stdtime/FreeBSD $(SRCROOT)/darwin SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders -HEADER_SEARCH_PATHS = $($(TARGET_NAME)_SEARCH_PATHS) $(DERIVED_FILES_DIR)/dtrace $(DERIVED_FILES_DIR)/$(CURRENT_ARCH) $(SRCROOT_SEARCH_PATHS) $(SYSTEM_FRAMEWORK_HEADERS) $(SDKROOT)/usr/local/include $(inherited) +HEADER_SEARCH_PATHS = $($(TARGET_NAME)_SEARCH_PATHS) $(DERIVED_FILES_DIR)/dtrace $(SRCROOT_SEARCH_PATHS) $(SYSTEM_FRAMEWORK_HEADERS) $(SDKROOT)/usr/local/include $(inherited) ALWAYS_SEARCH_USER_PATHS = YES USE_HEADERMAP = NO BUILD_VARIANTS = normal @@ -14,6 +14,18 @@ GCC_ENABLE_OBJC_EXCEPTIONS = YES GCC_SYMBOLS_PRIVATE_EXTERN = NO GCC_DYNAMIC_NO_PIC = NO GCC_THUMB_SUPPORT = YES +GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; + +//CLANG_WARN_INT_CONVERSION = YES +//CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES +//GCC_WARN_64_TO_32_BIT_CONVERSION = YES +//GCC_WARN_SHADOW = YES +GCC_WARN_UNINITIALIZED_AUTOS = YES; +GCC_WARN_UNUSED_VARIABLE = YES; +GCC_WARN_ABOUT_RETURN_TYPE = YES; +//WARNING_CFLAGS = -Wall -Wextra +WARNING_CFLAGS = -Wall -Werror=incompatible-pointer-types -Wno-error=incompatible-pointer-types-discards-qualifiers -Wno-nullability-completeness + COPY_PHASE_STRIP = NO SKIP_INSTALL = YES INSTALLHDRS_SCRIPT_PHASE = YES @@ -23,7 +35,9 @@ STRIP_INSTALLED_PRODUCT = NO LD_DYLIB_INSTALL_NAME = /usr/lib/system/$(EXECUTABLE_NAME) BUILD_VARIANTS = normal debug +BUILD_ARCHIVES = Platform Base FreeBSD NetBSD TRE vCancelable vDarwinExtsn vDarwinExtsnCancelable vPre1050 vLegacy vInode32 FortifySource +// clang is desired over llvm-gcc for OSAtomics. However, it isn't capable of building armv6 correctly. GCC_VERSION = com.apple.compilers.llvm.clang.1_0 GCC_VERSION[arch=armv6] = com.apple.compilers.llvmgcc42 @@ -33,24 +47,28 @@ PUBLIC_HEADERS_FOLDER_PATH = /usr/include PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include // Simulator -EXECUTABLE_PREFIX[sdk=iphonesimulator*] = libsystem_sim_ -PUBLIC_HEADERS_FOLDER_PATH[sdk=iphonesimulator*] = $(SDKROOT)/usr/include -PRIVATE_HEADERS_FOLDER_PATH[sdk=iphonesimulator*] = $(SDKROOT)/usr/local/include -INSTALL_PATH[sdk=iphonesimulator*] = $(SDKROOT)/usr/lib/system - BASE_PREPROCESSOR_MACROS = __LIBC__ __DARWIN_UNIX03=1 __DARWIN_64_BIT_INO_T=1 __DARWIN_NON_CANCELABLE=1 __DARWIN_VERS_1050=1 _FORTIFY_SOURCE=0 -OTHER_CFLAGS = -fdollars-in-identifiers $($(TARGET_NAME)_CFLAGS) $(VARIANT_PREPROCESSOR_MACROS) +OTHER_CFLAGS = -fdollars-in-identifiers -fno-common -fverbose-asm $($(TARGET_NAME)_CFLAGS) $(VARIANT_PREPROCESSOR_MACROS) OTHER_CFLAGS_debug = -fstack-protector -fno-inline -O0 -DDEBUG=1 +SIM_SUFFIX[sdk=*simulator*] = _sim GCC_PREPROCESSOR_DEFINITIONS = $(BASE_PREPROCESSOR_MACROS) -GCC_PREPROCESSOR_DEFINITIONS[sdk=iphoneos*] = $(BASE_PREPROCESSOR_MACROS) LIBC_NO_LIBCRASHREPORTERCLIENT=1 -GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*] = $(BASE_PREPROCESSOR_MACROS) LIBC_NO_LIBCRASHREPORTERCLIENT=1 +GCC_PREPROCESSOR_DEFINITIONS[sdk=iphone*] = $(BASE_PREPROCESSOR_MACROS) LIBC_NO_LIBCRASHREPORTERCLIENT=1 // libsystem_c.dylib linking -CR_LDFLAGS[sdk=macosx*] = -lCrashReporterClient +CR_LDFLAGS = -lCrashReporterClient LIBCOMPILER_RT_LDFLAGS = -lcompiler_rt -LIBSYSTEM_C_LDFLAGS = -all_load -nostdlib -L/usr/lib/system -Wl,-interposable_list,$(DERIVED_FILES_DIR)/interposable.list -umbrella System $(CR_LDFLAGS) -lSystem -lsystem_kernel $(LIBCOMPILER_RT_LDFLAGS) @$(BUILT_PRODUCTS_DIR)/$(CURRENT_VARIANT).linklist -LIBSYSTEM_C_LDFLAGS[sdk=iphonesimulator*] = +LIBMALLOC_LDFLAGS = -lsystem_malloc +LIBPLATFORM_LDFLAGS = -lsystem$(SIM_SUFFIX)_platform +LIBPTHREAD_LDFLAGS = -lsystem$(SIM_SUFFIX)_pthread +LIBSYSCALL_LDFLAGS = -lsystem$(SIM_SUFFIX)_kernel +LIBM_LDFLAGS = -lsystem$(SIM_SUFFIX)_m +LIBDYLD_LDFLAGS = -ldyld +LIBSYSTEM_C_LDFLAGS = -all_load -nostdlib -L/usr/lib/system -umbrella System $(CR_LDFLAGS) $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(UPWARD_LDFLAGS) -Wl,-interposable_list,$(DERIVED_FILES_DIR)/interposable.list -Wl,-unexported_symbols_list,$(DERIVED_FILES_DIR)/unexport.list -Wl,-alias_list,$(SRCROOT)/xcodescripts/alias.list -Wl,-order_file,$(SRCROOT)/xcodescripts/Libc.order -Wl,-sectalign,__DATA,__data,1000 @$(BUILT_PRODUCTS_DIR)/$(CURRENT_VARIANT).linklist + +// TODO: Remove upward links - mostly , macho is for assumes.c +UPWARD_LDFLAGS = -Wl,-upward-ldispatch -Wl,-upward-llaunch -Wl,-upward-lmacho -Wl,-upward-lsystem_asl -Wl,-upward-lsystem_blocks -Wl,-upward-lsystem_info -Wl,-upward-lsystem_notify -Wl,-upward-lxpc -Wl,-upward-lcorecrypto +UPWARD_LDFLAGS[sdk=*simulator*] = -Wl,-upward-ldispatch -Wl,-upward-lmacho_sim -Wl,-upward-lsystem_asl -Wl,-upward-lsystem_sim_blocks -Wl,-upward-lsystem_sim_info -Wl,-upward-lsystem_notify -Wl,-upward-lxpc -Wl,-upward-lcorecrypto // libPlatform.a architectures ARCH_FAMILY = $(ARCH_FAMILY_$(CURRENT_ARCH)) @@ -58,9 +76,16 @@ ARCH_FAMILY_x86_64 = x86_64 ARCH_FAMILY_i386 = i386 ARCH_FAMILY_armv6 = arm ARCH_FAMILY_armv7 = arm +ARCH_FAMILY_armv7s = arm ARCH_FAMILY_armv7f = arm ARCH_FAMILY_armv7k = arm +// Platform target +Platform_INCLUDED_SOURCE_FILE_NAMES = $(Platform_INCLUDED_SOURCE_FILE_NAMES_gen) $(Platform_INCLUDED_SOURCE_FILE_NAMES_stdlib) $(Platform_INCLUDED_SOURCE_FILE_NAMES_string) +Platform_INCLUDED_SOURCE_FILE_NAMES_gen = $(ARCH_FAMILY)/gen/*.c $(ARCH_FAMILY)/gen/*.s $(ARCH_FAMILY)/gen/*.S +Platform_INCLUDED_SOURCE_FILE_NAMES_stdlib = $(ARCH_FAMILY)/stdlib/*.c $(ARCH_FAMILY)/stdlib/*.s $(ARCH_FAMILY)/stdlib/*.S +Platform_INCLUDED_SOURCE_FILE_NAMES_string = $(ARCH_FAMILY)/string/*.c $(ARCH_FAMILY)/string/*.s $(ARCH_FAMILY)/string/*.S + // FreeBSD target FreeBSD_CFLAGS = -include $(SRCROOT)/fbsdcompat/_fbsd_compat_.h FreeBSD_SEARCH_PATHS = $(SRCROOT)/fbsdcompat $(SRCROOT)/gdtoa $(SRCROOT)/gdtoa/FreeBSD @@ -69,14 +94,11 @@ FreeBSD_EXCLUDED_SOURCE_GDTOA = gdtoa/FreeBSD/machdep* gdtoa-strtopx.c FreeBSD_INCLUDED_SOURCE_FILE_NAMES_x86_64 = gdtoa-strtopx.c machdep_ldisx.c FreeBSD_INCLUDED_SOURCE_FILE_NAMES_i386 = $(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_x86_64) FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7 = machdep_ldisd.c +FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7s = $(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7) FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7k = $(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7) FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7f = $(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7) FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv6 = $(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7) -// FreeBSD_gcc target -FreeBSD_gcc_CFLAGS = -include $(SRCROOT)/fbsdcompat/_fbsd_compat_.h -FreeBSD_gcc_SEARCH_PATHS = $(SRCROOT)/fbsdcompat $(SRCROOT)/gdtoa $(SRCROOT)/gdtoa/FreeBSD - // NetBSD target NetBSD_CFLAGS = -include $(SRCROOT)/nbsdcompat/_nbsd_compat_.h NetBSD_SEARCH_PATHS = $(SRCROOT)/nbsdcompat @@ -87,17 +109,26 @@ TRE_SEARCH_PATHS = $(SRCROOT)/regex/TRE $(SRCROOT)/regex/FreeBSD // Files per architecture to exclude from the non-platform builds (because optimised versions exist in Platform) BASE_EXCLUDED_SOURCE_FILE_NAMES = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH)) $(BASE_EXCLUDED_SOURCE_FILE_NAMES_$(PLATFORM_NAME)) -BASE_EXCLUDED_SOURCE_FILE_NAMES_x86_64 = MKGetTimeBaseInfo.c bcmp.c context-stubs.c kvm.c memcmp.c memset.c memset_pattern.c nlist.c strcpy.c strlcat.c strlcpy.c strlen.c strncmp.c strncpy.c -BASE_EXCLUDED_SOURCE_FILE_NAMES_i386 = bcmp.c context-stubs.c memcmp.c memset.c memset_pattern.c strcpy.c strlcat.c strlcpy.c strlen.c strncmp.c strncpy.c -BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7 = bcmp.c memcmp.c memset.c memset_pattern.c strchr.c strlen.c strncmp.c strnlen.c strstr.c +BASE_EXCLUDED_SOURCE_FILE_NAMES_x86_64 = kvm.c nlist.c strcpy.c strlen.c strncpy.c strnlen.c +BASE_EXCLUDED_SOURCE_FILE_NAMES_i386 = strcpy.c strlcat.c strlcpy.c strlen.c strncpy.c +BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7 = strlen.c strnlen.c strstr.c +BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7s = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7) BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7k = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7) BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7f = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7) BASE_EXCLUDED_SOURCE_FILE_NAMES_armv6 = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7) // Rune support isn't included on iOS but there's no better way to exclude their complication -BASE_EXCLUDED_SOURCE_FILE_NAMES_macosx = OSMemoryNotification.c OSThermalNotification.c +BASE_EXCLUDED_SOURCE_FILE_NAMES_macosx = OSMemoryNotification.c BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos = frune.c login.c logout.c mbrune.c runedepreciated.c setinvalidrune.c getmntinfo64.c BASE_EXCLUDED_SOURCE_FILE_NAMES_iphonesimulator = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos) +BASE_EXCLUDED_SOURCE_FILE_NAMES_appletvos = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos) +BASE_EXCLUDED_SOURCE_FILE_NAMES_appletvsimulator = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphonesimulator) +BASE_EXCLUDED_SOURCE_FILE_NAMES_watchos = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos) +BASE_EXCLUDED_SOURCE_FILE_NAMES_watchsimulator = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphonesimulator) + +// TODO: Remove these legacy platform names: +BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneosnano = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_watchos) +BASE_EXCLUDED_SOURCE_FILE_NAMES_iphonesimulatornano = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_watchsimulator) // - collate.c crashes llvm-gcc on armv6 with -Os + -gdwarf-2 COLLATE_C_CFLAGS_macosx_armv6 = -O1 @@ -105,3 +136,7 @@ COLLATE_C_CFLAGS_macosx_armv6 = -O1 // ARMv6 thumb doesn't support all the instructions needed for OSAtomics OSATOMIC_C_CFLAGS_macosx_armv6 = -mno-thumb OSATOMIC_C_CFLAGS_iphoneos_armv6 = -mno-thumb + +// Make sure that OSAtomic isn't build unoptimised, otherwise the inlines +// don't do what they are designed to do. +OSATOMIC_C_CFLAGS = -Os -momit-leaf-frame-pointer $(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH)) diff --git a/src/libc/xcodescripts/libc_static.xcconfig b/src/libc/xcodescripts/libc_static.xcconfig new file mode 100644 index 000000000..d6f776573 --- /dev/null +++ b/src/libc/xcodescripts/libc_static.xcconfig @@ -0,0 +1,21 @@ +#include "libc.xcconfig" + +BUILD_ARCHIVES = Base FreeBSD TRE vCancelable vDarwinExtsn +BUILD_VARIANTS = normal debug +EXECUTABLE_PREFIX = lib +INSTALL_PATH = /usr/local/lib/system +OTHER_LIBTOOLFLAGS = -filelist $(BUILT_PRODUCTS_DIR)/$(CURRENT_VARIANT).linklist.libtool +PRODUCT_NAME = c +SKIP_INSTALL = NO +STRIP_INSTALLED_PRODUCT = NO +VARIANT = STATIC_VERSION +VERSIONING_SYSTEM = apple-generic + +// Only include what's needed +EXCLUDED_SOURCE_FILE_NAMES = * +INCLUDED_SOURCE_FILE_NAMES = secure/*.c $(ARCH_FAMILY_$(CURRENT_ARCH))/*/*.c $(ARCH_FAMILY_$(CURRENT_ARCH))/*/*.S $(ARCH_FAMILY_$(CURRENT_ARCH))/*/*.s + +VARIANT_PREPROCESSOR_MACROS = -UBUILDING_VARIANT -DVARIANT_STATIC -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0 + +SYSTEM_FRAMEWORK_HEADERS = $(DERIVED_FILES_DIR)/System.framework/Versions/B/PrivateHeaders +HEADER_SEARCH_PATHS = $(FreeBSD_SEARCH_PATHS) $(inherited) diff --git a/src/libc/xcodescripts/manpages.sh b/src/libc/xcodescripts/manpages.sh index fa84889cd..317cf2e6d 100644 --- a/src/libc/xcodescripts/manpages.sh +++ b/src/libc/xcodescripts/manpages.sh @@ -1,8 +1,7 @@ #!/bin/bash -e if [ "$ACTION" = installhdrs ]; then exit 0; fi -if [ "$PLATFORM_NAME" = iphoneos ]; then exit 0; fi -if [ "$PLATFORM_NAME" = iphonesimulator ]; then exit 0; fi +if [ "${PLATFORM_NAME}" != "macosx" ]; then exit 0; fi UNIFDEF_FLAGS=`${SRCROOT}/xcodescripts/generate_features.pl --unifdef` MANPAGES_LIST="${SRCROOT}/man/manpages.lst" @@ -13,6 +12,13 @@ cat ${MANPAGES_LIST} | grep -v -E '(^#|^\s*$)' | while read first solid rest; do ${FILES} EOF ) + + # This is a subshell, the real exit is after the loop. + if [ -z "${SOURCE}" ]; then + echo "Error: ${first} not found" + exit 1 + fi + SECTION=$(echo ${first} | tail -c 2) DESTDIR=${DSTROOT}/usr/share/man/man${SECTION} @@ -32,6 +38,11 @@ EOF done done +if [ $? -ne 0 ]; then + echo "Exiting due to previous error(s)." + exit 1 +fi + # grrr, uuid special case for page in libuuid.3 uuid_clear.3 uuid_compare.3 uuid_copy.3 uuid_generate.3 uuid_is_null.3 uuid_parse.3 uuid_unparse.3; do SECTION=$(echo ${page} | tail -c 2) diff --git a/src/libc/xcodescripts/mig_headers.sh b/src/libc/xcodescripts/mig_headers.sh deleted file mode 100644 index a0176565c..000000000 --- a/src/libc/xcodescripts/mig_headers.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -e - -export MIG=`xcrun -find mig` -export MIGCC=`xcrun -find cc` - -BASE=`basename ${SCRIPT_INPUT_FILE_0} .defs`.h - -for a in ${ARCHS}; do - mkdir -p "${DERIVED_FILE_DIR}/${a}" - "${MIG}" -arch $a -header "${DERIVED_FILE_DIR}/${a}/${BASE}" \ - -sheader /dev/null -user /dev/null \ - -server /dev/null "${SCRIPT_INPUT_FILE_0}" -done diff --git a/src/libc/xcodescripts/patch_headers_variants.pl b/src/libc/xcodescripts/patch_headers_variants.pl index b404cbcee..24da93534 100644 --- a/src/libc/xcodescripts/patch_headers_variants.pl +++ b/src/libc/xcodescripts/patch_headers_variants.pl @@ -55,6 +55,11 @@ sub process { } } + my($fname, $dirs, $suffix) = File::Basename::fileparse($file, ".h"); + if ($suffix ne ".h") { + return; + } + my $p = IO::File->new($path, 'r'); die "$MyName: Can't open $path: $!\n" unless defined($p); my $f = IO::File->new($file, 'w'); diff --git a/src/libc/xcodescripts/sim-compat-symlink.sh b/src/libc/xcodescripts/sim-compat-symlink.sh new file mode 100755 index 000000000..7c1826aa7 --- /dev/null +++ b/src/libc/xcodescripts/sim-compat-symlink.sh @@ -0,0 +1,9 @@ +#!/bin/bash -ex + +if [[ "${ACTION}" == "installhdrs" ]]; then + exit 0 +fi + +if [[ "${PLATFORM_NAME}" =~ "simulator" ]]; then + ln -s libsystem_c.dylib ${DSTROOT}${INSTALL_PATH}/libsystem_sim_c.dylib +fi diff --git a/src/libc/xcodescripts/skip_installhdrs.sh b/src/libc/xcodescripts/skip_installhdrs.sh new file mode 100644 index 000000000..925641821 --- /dev/null +++ b/src/libc/xcodescripts/skip_installhdrs.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [[ "x${ACTION}" == "xinstallhdrs" ]]; then + exit 0 +fi + +$@ diff --git a/src/libc/xcodescripts/variants.xcconfig b/src/libc/xcodescripts/variants.xcconfig index fd3480f85..6134dccf7 100644 --- a/src/libc/xcodescripts/variants.xcconfig +++ b/src/libc/xcodescripts/variants.xcconfig @@ -10,12 +10,11 @@ HEADER_SEARCH_PATHS = $(FreeBSD_SEARCH_PATHS) $(inherited) VARIANT_CANCELABLE_MACROS = -DVARIANT_CANCELABLE -VARIANT_CANCELABLE_INCLUDE = $(VARIANT_CANCELABLE_INCLUDE_compat) $(VARIANT_CANCELABLE_INCLUDE_gen) $(VARIANT_CANCELABLE_INCLUDE_net) $(VARIANT_CANCELABLE_INCLUDE_pthreads) $(VARIANT_CANCELABLE_INCLUDE_sys) +VARIANT_CANCELABLE_INCLUDE = $(VARIANT_CANCELABLE_INCLUDE_compat) $(VARIANT_CANCELABLE_INCLUDE_gen) $(VARIANT_CANCELABLE_INCLUDE_net) $(VARIANT_CANCELABLE_INCLUDE_sys) VARIANT_CANCELABLE_INCLUDE_compat = creat.c sigcompat.c -VARIANT_CANCELABLE_INCLUDE_gen = lockf.c nanosleep.c pause.c pselect.c sleep.c termios.c usleep.c wait.c waitpid.c +VARIANT_CANCELABLE_INCLUDE_gen = lockf.c nanosleep.c pause.c sleep.c termios.c usleep.c wait.c waitpid.c VARIANT_CANCELABLE_INCLUDE_net = recv.c send.c -VARIANT_CANCELABLE_INCLUDE_pthreads = pthread_cancelable.c VARIANT_CANCELABLE_INCLUDE_sys = system.c // $DARWINEXTSN @@ -24,7 +23,7 @@ VARIANT_DARWINEXTSN_MACROS = -DVARIANT_DARWINEXTSN VARIANT_DARWINEXTSN_INCLUDE = $(VARIANT_DARWINEXTSN_INCLUDE_gen) $(VARIANT_DARWINEXTSN_INCLUDE_stdio) $(VARIANT_DARWINEXTSN_INCLUDE_stdlib) $(VARIANT_DARWINEXTSN_INCLUDE_sys) -VARIANT_DARWINEXTSN_INCLUDE_gen = pselect.c popen.c +VARIANT_DARWINEXTSN_INCLUDE_gen = popen.c VARIANT_DARWINEXTSN_INCLUDE_stdio = fdopen.c fopen.c VARIANT_DARWINEXTSN_INCLUDE_stdlib = realpath.c VARIANT_DARWINEXTSN_INCLUDE_sys = getgroups.c @@ -32,7 +31,6 @@ VARIANT_DARWINEXTSN_INCLUDE_sys = getgroups.c // $DARWINEXTSN + no cancel (everyone else is cancelable anyway) VARIANT_DARWINEXTSN_CANCELABLE_MACROS = -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN -VARIANT_DARWINEXTSN_CANCELABLE_INCLUDE = pselect.c // Pre-1050 symbols @@ -40,20 +38,19 @@ VARIANT_PRE1050_MACROS = $(VARIANT_PRE1050_MACROS_$(PLATFORM_NAME)) VARIANT_PRE1050_MACROS_macosx = -U__DARWIN_VERS_1050 -D__DARWIN_VERS_1050=0 -DVARIANT_PRE1050 VARIANT_PRE1050_INCLUDE = $(VARIANT_PRE1050_INCLUDE_$(PLATFORM_NAME)) VARIANT_PRE1050_INCLUDE_macosx = daemon.c $(VARIANT_PRE1050_INCLUDE_$(PLATFORM_NAME)_$(CURRENT_ARCH)) -VARIANT_PRE1050_INCLUDE_macosx_x86_64 = pselect.c // Legacy symbols VARIANT_LEGACY_MACROS = -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0 -U__DARWIN_64_BIT_INO_T -D__DARWIN_64_BIT_INO_T=0 -DVARIANT_LEGACY -VARIANT_LEGACY_INCLUDE = $(VARIANT_LEGACY_INCLUDE_$(CURRENT_ARCH)) -VARIANT_LEGACY_INCLUDE_i386 = $(VARIANT_LEGACY_INCLUDE_compat) $(VARIANT_LEGACY_INCLUDE_gdtoa) $(VARIANT_LEGACY_INCLUDE_gen) $(VARIANT_LEGACY_INCLUDE_locale) $(VARIANT_LEGACY_INCLUDE_net) $(VARIANT_LEGACY_INCLUDE_pthreads) $(VARIANT_LEGACY_INCLUDE_regex) $(VARIANT_LEGACY_INCLUDE_stdio) $(VARIANT_LEGACY_INCLUDE_stdlib) $(VARIANT_LEGACY_INCLUDE_stdtime) $(VARIANT_LEGACY_INCLUDE_string) $(VARIANT_LEGACY_INCLUDE_sys) +VARIANT_LEGACY_INCLUDE = $(VARIANT_LEGACY_INCLUDE_$(PLATFORM_NAME)) +VARIANT_LEGACY_INCLUDE_macosx = $(VARIANT_LEGACY_INCLUDE_$(PLATFORM_NAME)_$(CURRENT_ARCH)) +VARIANT_LEGACY_INCLUDE_macosx_i386 = $(VARIANT_LEGACY_INCLUDE_compat) $(VARIANT_LEGACY_INCLUDE_gdtoa) $(VARIANT_LEGACY_INCLUDE_gen) $(VARIANT_LEGACY_INCLUDE_locale) $(VARIANT_LEGACY_INCLUDE_net) $(VARIANT_LEGACY_INCLUDE_regex) $(VARIANT_LEGACY_INCLUDE_stdio) $(VARIANT_LEGACY_INCLUDE_stdlib) $(VARIANT_LEGACY_INCLUDE_stdtime) $(VARIANT_LEGACY_INCLUDE_string) $(VARIANT_LEGACY_INCLUDE_sys) VARIANT_LEGACY_INCLUDE_compat = creat.c setregid.c setreuid.c sigcompat.c killpg.c VARIANT_LEGACY_INCLUDE_gdtoa = gdtoa-strtof.c gdtoa-strtod.c gdtoa-strtodg.c -VARIANT_LEGACY_INCLUDE_gen = clock.c closedir.c confstr.c crypt.c fnmatch.c lockf.c nanosleep.c nftw.c nice.c opendir.c pause.c popen.c pselect.c rewinddir.c seekdir.c setmode.c sleep.c telldir.c termios.c timezone.c ttyname.c usleep.c wait.c waitpid.c +VARIANT_LEGACY_INCLUDE_gen = clock.c closedir.c confstr.c crypt.c fnmatch.c lockf.c nanosleep.c nftw.c nice.c opendir.c pause.c popen.c rewinddir.c seekdir.c setmode.c sleep.c telldir.c termios.c timezone.c ttyname.c usleep.c wait.c waitpid.c VARIANT_LEGACY_INCLUDE_locale = wcsftime.c VARIANT_LEGACY_INCLUDE_net = recv.c send.c -VARIANT_LEGACY_INCLUDE_pthreads = pthread.c pthread_cancelable.c pthread_cond.c pthread_mutex.c pthread_rwlock.c VARIANT_LEGACY_INCLUDE_regex = regcomp.c VARIANT_LEGACY_INCLUDE_stdio = fdopen.c fopen.c fputs.c freopen.c fwrite.c tempnam.c VARIANT_LEGACY_INCLUDE_stdlib = getopt.c putenv.c realpath.c setenv.c system.c @@ -65,35 +62,31 @@ VARIANT_LEGACY_INCLUDE_sys = msgctl.c semctl.c shmctl.c VARIANT_INODE32_MACROS = -U__DARWIN_64_BIT_INO_T -D__DARWIN_64_BIT_INO_T=0 -DVARIANT_INODE32 -VARIANT_INODE32_INCLUDE = $(VARIANT_INODE32_INCLUDE_$(CURRENT_ARCH)) -VARIANT_INODE32_INCLUDE_i386 = $(VARIANT_INODE32_INCLUDE_gen) $(VARIANT_INODE32_INCLUDE_sys) -VARIANT_INODE32_INCLUDE_x86_64 = $(VARIANT_INODE32_INCLUDE_gen) $(VARIANT_INODE32_INCLUDE_sys) +VARIANT_INODE32_INCLUDE = $(VARIANT_INODE32_INCLUDE_$(PLATFORM_NAME)) +VARIANT_INODE32_INCLUDE_macosx = $(VARIANT_INODE32_INCLUDE_$(PLATFORM_NAME)_$(CURRENT_ARCH)) +VARIANT_INODE32_INCLUDE_macosx_i386 = $(VARIANT_INODE32_INCLUDE_gen) $(VARIANT_INODE32_INCLUDE_sys) +VARIANT_INODE32_INCLUDE_macosx_x86_64 = $(VARIANT_INODE32_INCLUDE_gen) $(VARIANT_INODE32_INCLUDE_sys) VARIANT_INODE32_INCLUDE_gen = fts.c getmntinfo.c glob.c nftw.c opendir.c readdir.c rewinddir.c scandir.c seekdir.c telldir.c scandir_b.c VARIANT_INODE32_INCLUDE_sys = statx_np.c // DYLD (libc.a) -VARIANT_DYLD_MACROS = -UBUILDING_VARIANT -DVARIANT_DYLD -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0 +VARIANT_DYLD_MACROS = -UBUILDING_VARIANT -DVARIANT_STATIC -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0 VARIANT_DYLD_INCLUDE = $(VARIANT_DYLD_INCLUDE_generic) $(VARIANT_DYLD_INCLUDE_$(CURRENT_ARCH)) -VARIANT_DYLD_INCLUDE_generic = $(VARIANT_DYLD_INCLUDE_gen) $(VARIANT_DYLD_INCLUDE_pthreads) $(VARIANT_DYLD_INCLUDE_stdlib) $(VARIANT_DYLD_INCLUDE_string) $(VARIANT_DYLD_INCLUDE_sys) $(VARIANT_DYLD_INCLUDE_threads) -VARIANT_DYLD_INCLUDE_gen = _simple.c arc4random.c closedir.c dirfd.c getcwd.c getpagesize.c nanosleep.c opendir.c readdir.c scandir.c sysctl.c sysctlbyname.c telldir.c usleep.c -VARIANT_DYLD_INCLUDE_pthreads = pthread.c pthread_mutex.c pthread_tsd.c +VARIANT_DYLD_INCLUDE_generic = $(VARIANT_DYLD_INCLUDE_gen) $(VARIANT_DYLD_INCLUDE_stdlib) $(VARIANT_DYLD_INCLUDE_string) $(VARIANT_DYLD_INCLUDE_sys) +VARIANT_DYLD_INCLUDE_gen = arc4random.c closedir.c dirfd.c getcwd.c getpagesize.c nanosleep.c opendir.c readdir.c scandir.c sysctl.c sysctlbyname.c telldir.c usleep.c VARIANT_DYLD_INCLUDE_stdlib = atexit.c exit.c gettimeofday.c heapsort.c merge.c qsort.c reallocf.c realpath.c -VARIANT_DYLD_INCLUDE_string = strcat.c strchr.c strcpy.c strdup.c strlcat.c strlcpy.c strncmp.c strnlen.c strrchr.c strstr.c -VARIANT_DYLD_INCLUDE_sys = errno.c -VARIANT_DYLD_INCLUDE_threads = mig_support.c +VARIANT_DYLD_INCLUDE_string = bcopy.c libplatform.s strcat.c strchr.c strcpy.c strdup.c strlcat.c strlcpy.c strncmp.c strnlen.c strrchr.c strstr.c +VARIANT_DYLD_INCLUDE_sys = _libc_init.c -VARIANT_DYLD_INCLUDE_x86_64 = x86_64/pthreads/pthread_set_self.s x86_64/pthreads/pthread_self.s x86_64/pthreads/pthread_getspecific.s x86_64/pthreads/preempt.s x86_64/string/__bzero.s x86_64/string/bcopy_sse3x.s x86_64/string/bzero_sse2.s x86_64/string/ffs.s x86_64/string/longcopy_sse3x.s x86_64/string/strcmp.s x86_64/string/strlen.s x86_64/string/strncpy.s x86_64/sys/OSAtomic.s x86_64/sys/i386_gettimeofday_asm.s x86_64/sys/spinlocks_asm.s x86_64/sys/nanotime.s - -VARIANT_DYLD_INCLUDE_i386 = i386/gen/icacheinval.s i386/gen/cpu_number.s i386/pthreads/preempt.s i386/pthreads/pthread_set_self.s i386/pthreads/pthread_self.s i386/pthreads/pthread_getspecific.s i386/string/__bzero.s i386/string/bcopy_scalar.s i386/string/bzero_scalar.s i386/string/ffs.s i386/string/memcmp.s i386/string/memset_pattern_sse2.s i386/string/strcmp.s i386/string/strlen.s i386/string/strncpy.s i386/sys/OSAtomic.s i386/sys/i386_gettimeofday_asm.s i386/sys/mach_absolute_time_asm.s i386/sys/spinlocks_asm.s - -VARIANT_DYLD_INCLUDE_armv7 = arm/gen/icacheinval.s arm/pthreads/pthread_getspecific.s arm/pthreads/pthread_self.s arm/pthreads/pthread_set_self.s arm/string/bcopy_Generic.s arm/string/bzero_Generic.s arm/string/ffs.s arm/string/strcmp.s arm/string/strlen.s arm/string/strnlen.s strncpy.c arm/sys/OSAtomic.c arm/sys/OSAtomicUP.c arm/sys/OSAtomic_resolvers.c arm/sys/Spinlocks.c arm/sys/SpinlocksUP.c arm/sys/SpinlocksWFE.c arm/sys/arm_commpage_gettimeofday.c arm/sys/mach_absolute_time.s +VARIANT_DYLD_INCLUDE_x86_64 = x86_64/string/strcpy.s x86_64/string/strlen.s x86_64/string/strncpy.s x86_64/string/strnlen.s strstr.c +VARIANT_DYLD_INCLUDE_i386 = i386/string/strcpy.s i386/string/strlen.s i386/string/strncpy.s strnlen.c strstr.c +VARIANT_DYLD_INCLUDE_armv7 = strcpy.c arm/string/strlen.s strncpy.c arm/string/strnlen.s arm/string/strstr.s +VARIANT_DYLD_INCLUDE_armv7s = $(VARIANT_DYLD_INCLUDE_armv7) VARIANT_DYLD_INCLUDE_armv7k = $(VARIANT_DYLD_INCLUDE_armv7) VARIANT_DYLD_INCLUDE_armv7f = $(VARIANT_DYLD_INCLUDE_armv7) -VARIANT_DYLD_INCLUDE_armv6 = $(VARIANT_DYLD_INCLUDE_armv7) arm/sys/OSAtomic-v4.c - diff --git a/src/libm/CMakeLists.txt b/src/libm/CMakeLists.txt index 2d2e43694..0e91384ee 100644 --- a/src/libm/CMakeLists.txt +++ b/src/libm/CMakeLists.txt @@ -10,6 +10,7 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib -Wl,-flat_ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Source/Intel) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kernel-include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../libc/darwin) add_definitions(-Dmovsxw=movswl -DPRIVATE) set(libm_sources diff --git a/src/libmacho/CMakeLists.txt b/src/libmacho/CMakeLists.txt index def531e18..22c211cee 100644 --- a/src/libmacho/CMakeLists.txt +++ b/src/libmacho/CMakeLists.txt @@ -10,6 +10,8 @@ add_definitions(-D__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=1080) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc -D__DARWIN_UNIX03 -fPIC -w") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib -Wl,-bind_at_load -Wl,-flat_namespace -Wl,-undefined,suppress") +include_directories(${CMAKE_SOURCE_DIR}/src/libc/darwin) + SET(libmacho_sources arch.c get_end.c @@ -29,5 +31,6 @@ SET(libmacho_sources set(DYLIB_INSTALL_NAME "/usr/lib/system/libmacho.dylib") add_darling_library(macho SHARED ${libmacho_sources}) target_link_libraries(macho system_kernel) +make_fat(macho) install(TARGETS macho DESTINATION libexec/darling/usr/lib/system) diff --git a/src/libmalloc/.clang-format b/src/libmalloc/.clang-format new file mode 100644 index 000000000..2faab1266 --- /dev/null +++ b/src/libmalloc/.clang-format @@ -0,0 +1,126 @@ +# Format of this file is YAML +# Minimum clang-format version required: clang-format version 3.6.0 +# Detailed description of options available at http://clang.llvm.org/docs/ClangFormatStyleOptions.html + +AlignEscapedNewlinesLeft: true +# Bad: +# void foo() { +# someFunction(); +# someOtherFunction(); +# } +# Good: +# void foo() { +# someFunction(); +# someOtherFunction(); +# } + +AlignTrailingComments: true +# align all comments to right based of // +# == Avoid using // based comments altogether == + +AlignAfterOpenBracket: false +# don't align after a bracket, uses indentation rules to indent + +AllowAllParametersOfDeclarationOnNextLine: false +# allow funtion definition as +# someFunction(foo, +# bar, +# baz); + +AlignConsecutiveAssignments: false +# does not align consecutive assignments with '=' operator + +AllowShortBlocksOnASingleLine: true +# single statement block can be merged on one line +# e.g if (a) { return; } + +AllowShortCaseLabelsOnASingleLine: false +# Single statement case statements should be on their own lines + +AllowShortFunctionsOnASingleLine: None +# Bad: +# int foo() { return 123; } + +AllowShortIfStatementsOnASingleLine: false +# Bad: +# if (someOtherVar) return; +# Good: +# if (someOtherVar) +# return; + +AllowShortLoopsOnASingleLine: false +# Bad: +# while(i>0) i--; +# Good: +# while(i>0) { +# i--; +# } + +AlwaysBreakAfterDefinitionReturnType: true +# Ensures return type is one its own line +# e.g. unsigned int +# function(char param) { } + +AlwaysBreakBeforeMultilineStrings: true +# multine strings should begin on new line + +BinPackArguments: true +BinPackParameters: false +# functions arguments should all be on one line or have a single line for each param + +BreakBeforeBinaryOperators: None +# break for new line after binary operator in case of length is over ColumnLimit +# e.g. +# int foo = bar + +# baz; + +BreakBeforeBraces: Linux +# Always attach braces to surrounding context except - +# break before braces on function, namespace and class definitions + +ColumnLimit: 132 +# every body has wide screen now. 132 seems to be reasonable limit now. + +ContinuationIndentWidth: 8 +# indent continued lines by two tabs + +IndentCaseLabels: false +# case labels have same indentation as switch statement. + +IndentWidth: 4 +# 4 spaces for indentation +TabWidth: 4 +# tabwidth is 4 spaces + +UseTab: Always +# always indent lines with tabs + +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +# remove excess empty lines at start of blocks. + +PointerAlignment: Right +# "void *foo" (vs. "void* foo" or "void * foo") + +SpaceAfterCStyleCast: false +# No space after (cast). E.g +# int blah = (int)((void *)foo + bar) + +SpaceBeforeAssignmentOperators: true +# Assignment = should be seperated by spaces on both sides. + +SpaceBeforeParens: ControlStatements +# for control statements a space is required before '{' +# Bad: for(){ statement; } +# Good: for() { statement; } + +SpaceInEmptyParentheses: false +# No spaces required for empty () + +SpacesInCStyleCastParentheses: false +# No spaces required for (unsigned int) type cast + +SpacesInParentheses: false + +SpacesInSquareBrackets: false +# No spaces in [count] style invocations of [] diff --git a/src/libmalloc/.gitignore b/src/libmalloc/.gitignore new file mode 100644 index 000000000..02aa0f4f0 --- /dev/null +++ b/src/libmalloc/.gitignore @@ -0,0 +1,3 @@ +# /libmalloc.xcodeproj/ +/libmalloc.xcodeproj/*.xcworkspace +/libmalloc.xcodeproj/xcuserdata diff --git a/src/libmalloc/CMakeLists.txt b/src/libmalloc/CMakeLists.txt index aeb437fd5..63d7166ac 100644 --- a/src/libmalloc/CMakeLists.txt +++ b/src/libmalloc/CMakeLists.txt @@ -6,35 +6,38 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse -msse2 -msse3 -w -fblocks -ggdb") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__DARWIN_UNIX03 -fPIC -w -include ${CMAKE_CURRENT_SOURCE_DIR}/../duct/include/commpage.h -nostdinc") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-flat_namespace -Wl,-undefined,suppress") -if(CMAKE_SIZEOF_VOID_P EQUAL 4 OR CMAKE_INSTALL_LIBDIR STREQUAL "lib32") - set(BITS 32) - add_definitions(-DTARGET_CPU_X86=1) -else(CMAKE_SIZEOF_VOID_P EQUAL 4 OR CMAKE_INSTALL_LIBDIR STREQUAL "lib32") - set(BITS 64) - add_definitions(-DTARGET_CPU_X86_64=1) -endif(CMAKE_SIZEOF_VOID_P EQUAL 4 OR CMAKE_INSTALL_LIBDIR STREQUAL "lib32") - add_definitions(-DTARGET_OS_MAC=1) add_definitions(-DHAVE_STDINT_H=1) -add_definitions(-D__APPLE__ -D__DYNAMIC__) +add_definitions(-D__APPLE__ -D__DYNAMIC__ -DPRIVATE) add_definitions("'-DMAGMALLOC_MALLOCERRORBREAK()='") include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/malloc) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/private) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../libc/gen) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../libc/darwin) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kernel/libsyscall/wrappers/) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../kernel/libsyscall) set(libmalloc_sources src/bitarray.c + src/frozen_malloc.c + src/legacy_malloc.c + src/magazine_large.c + src/magazine_lite.c src/magazine_malloc.c + src/magazine_small.c + src/magazine_tiny.c src/malloc.c src/nano_malloc.c - src/stack_logging.c + src/purgeable_malloc.c src/stack_logging_disk.c ) set(DYLIB_INSTALL_NAME "/usr/lib/system/libsystem_malloc.dylib") add_darling_library(system_malloc SHARED ${libmalloc_sources}) target_link_libraries(system_malloc PRIVATE system_kernel) +make_fat(system_malloc) install(TARGETS system_malloc DESTINATION libexec/darling/usr/lib/system) diff --git a/src/libmalloc/include/malloc/malloc.h b/src/libmalloc/include/malloc/malloc.h index 53e555f2b..3ec3ef087 100644 --- a/src/libmalloc/include/malloc/malloc.h +++ b/src/libmalloc/include/malloc/malloc.h @@ -52,7 +52,7 @@ typedef struct _malloc_zone_t { struct malloc_introspection_t *introspect; unsigned version; - + /* aligned memory allocation. The callback may be NULL. Present in version >= 5. */ void *(*memalign)(struct _malloc_zone_t *zone, size_t alignment, size_t size); @@ -199,6 +199,7 @@ typedef struct malloc_introspection_t { #else void *enumerate_unavailable_without_blocks; #endif /* __BLOCKS__ */ + void (*reinit_lock)(malloc_zone_t *zone); /* Reinitialize zone locks, called only from atfork_child handler. Present in version >= 9. */ } malloc_introspection_t; extern void malloc_printf(const char *format, ...); diff --git a/src/libmalloc/libmalloc.xcodeproj/project.pbxproj b/src/libmalloc/libmalloc.xcodeproj/project.pbxproj index 720f14266..361f815cd 100644 --- a/src/libmalloc/libmalloc.xcodeproj/project.pbxproj +++ b/src/libmalloc/libmalloc.xcodeproj/project.pbxproj @@ -15,34 +15,107 @@ 3FE9201D16A9143E00D1238A /* Sanitise Headers (rdar://problem/10241868) */, ); dependencies = ( + C0CE45501C52CCBD00C24048 /* PBXTargetDependency */, 3FE9201816A9111600D1238A /* PBXTargetDependency */, 3FE9201616A9111400D1238A /* PBXTargetDependency */, ); name = libmalloc; productName = libmalloc; }; + 45039161198FFF73004EE2A3 /* libmalloc_test */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 45039162198FFF73004EE2A3 /* Build configuration list for PBXAggregateTarget "libmalloc_test" */; + buildPhases = ( + ); + dependencies = ( + 45039168198FFFA6004EE2A3 /* PBXTargetDependency */, + 925383D91BD03D0000F745DB /* PBXTargetDependency */, + ); + name = libmalloc_test; + productName = libmalloc_test; + }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ - 3F5732E116A9478E00EC61B4 /* stack_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F5732E016A9478E00EC61B4 /* stack_logging.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0D468DCF1C7BEF51006FACF5 /* magazine_lite.c in Sources */ = {isa = PBXBuildFile; fileRef = 0D468DCC1C7BEE56006FACF5 /* magazine_lite.c */; }; + 0D468DD01C7BEF71006FACF5 /* stack_logging_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D468DCD1C7BEE65006FACF5 /* stack_logging_internal.h */; }; 3FE91FED16A90B9200D1238A /* bitarray.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD116A90A8D00D1238A /* bitarray.c */; }; - 3FE91FEE16A90B9200D1238A /* bitarray.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FE91FD216A90A8D00D1238A /* bitarray.h */; }; 3FE91FF016A90B9200D1238A /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD616A90A8D00D1238A /* magazine_malloc.c */; }; 3FE91FF116A90B9200D1238A /* magmallocProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD716A90A8D00D1238A /* magmallocProvider.d */; }; 3FE91FF216A90B9200D1238A /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD816A90A8D00D1238A /* malloc.c */; }; - 3FE91FF316A90B9200D1238A /* malloc_printf.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FE91FD916A90A8D00D1238A /* malloc_printf.h */; }; 3FE91FF416A90B9200D1238A /* nano_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FDA16A90A8D00D1238A /* nano_malloc.c */; }; - 3FE91FF516A90B9200D1238A /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FDB16A90A8D00D1238A /* stack_logging.c */; }; 3FE91FF616A90B9200D1238A /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FDC16A90A8D00D1238A /* stack_logging_disk.c */; }; 3FE91FFA16A90BEF00D1238A /* malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FE91FF916A90BEF00D1238A /* malloc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3FE91FFC16A90E6C00D1238A /* scalable_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FE91FFB16A90E6C00D1238A /* scalable_malloc.h */; }; 3FE91FFF16A9109E00D1238A /* bitarray.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD116A90A8D00D1238A /* bitarray.c */; }; 3FE9200116A9109E00D1238A /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD616A90A8D00D1238A /* magazine_malloc.c */; }; 3FE9200216A9109E00D1238A /* magmallocProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD716A90A8D00D1238A /* magmallocProvider.d */; }; 3FE9200316A9109E00D1238A /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD816A90A8D00D1238A /* malloc.c */; }; 3FE9200416A9109E00D1238A /* nano_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FDA16A90A8D00D1238A /* nano_malloc.c */; }; - 3FE9200516A9109E00D1238A /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FDB16A90A8D00D1238A /* stack_logging.c */; }; 3FE9200616A9109E00D1238A /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FDC16A90A8D00D1238A /* stack_logging_disk.c */; }; + 925383DA1BD03D5100F745DB /* stress_test.c in Sources */ = {isa = PBXBuildFile; fileRef = 925383D11BD03B4A00F745DB /* stress_test.c */; }; + C0352EC71C3F3C4400DB5126 /* malloc_private.h in Headers */ = {isa = PBXBuildFile; fileRef = C0352EC61C3F3C3600DB5126 /* malloc_private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C0CE45311C52C90500C24048 /* bitarray.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD116A90A8D00D1238A /* bitarray.c */; }; + C0CE45321C52C90500C24048 /* purgeable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C957429E1BF681B00027269A /* purgeable_malloc.c */; }; + C0CE45331C52C90500C24048 /* magazine_large.c in Sources */ = {isa = PBXBuildFile; fileRef = C957429B1BF672F80027269A /* magazine_large.c */; }; + C0CE45341C52C90500C24048 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD616A90A8D00D1238A /* magazine_malloc.c */; }; + C0CE45351C52C90500C24048 /* magazine_small.c in Sources */ = {isa = PBXBuildFile; fileRef = C95742981BF670D00027269A /* magazine_small.c */; }; + C0CE45361C52C90500C24048 /* legacy_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C95742AA1BF685CB0027269A /* legacy_malloc.c */; }; + C0CE45371C52C90500C24048 /* magmallocProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD716A90A8D00D1238A /* magmallocProvider.d */; }; + C0CE45381C52C90500C24048 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FD816A90A8D00D1238A /* malloc.c */; }; + C0CE45391C52C90500C24048 /* frozen_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C95742A41BF6842F0027269A /* frozen_malloc.c */; }; + C0CE453A1C52C90500C24048 /* nano_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FDA16A90A8D00D1238A /* nano_malloc.c */; }; + C0CE453C1C52C90500C24048 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FE91FDC16A90A8D00D1238A /* stack_logging_disk.c */; }; + C0CE453D1C52C90500C24048 /* magazine_tiny.c in Sources */ = {isa = PBXBuildFile; fileRef = C957428F1BF419DF0027269A /* magazine_tiny.c */; }; + C0CE45401C52C90500C24048 /* magazine_inline.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742921BF41C970027269A /* magazine_inline.h */; }; + C0CE45411C52C90500C24048 /* nano_zone.h in Headers */ = {isa = PBXBuildFile; fileRef = C957427E1BF33D130027269A /* nano_zone.h */; }; + C0CE45421C52C90500C24048 /* thresholds.h in Headers */ = {isa = PBXBuildFile; fileRef = C957428C1BF411330027269A /* thresholds.h */; }; + C0CE45431C52C90500C24048 /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = C957427B1BF2C8DE0027269A /* debug.h */; }; + C0CE45441C52C90500C24048 /* frozen_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742A51BF6842F0027269A /* frozen_malloc.h */; }; + C0CE45451C52C90500C24048 /* magazine_zone.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742861BF3F9550027269A /* magazine_zone.h */; }; + C0CE45461C52C90500C24048 /* magazine_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742951BF41E480027269A /* magazine_malloc.h */; }; + C0CE45471C52C90500C24048 /* purgeable_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C957429F1BF681B00027269A /* purgeable_malloc.h */; }; + C0CE45481C52C90500C24048 /* base.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742891BF3FD290027269A /* base.h */; }; + C0CE454E1C52C9E600C24048 /* libmalloc.a in CopyFiles */ = {isa = PBXBuildFile; fileRef = C0CE454C1C52C90500C24048 /* libmalloc.a */; }; + C938BBD31C74F7A400522BBD /* trace.h in Headers */ = {isa = PBXBuildFile; fileRef = C938BBD21C74F7A400522BBD /* trace.h */; }; + C9571C3A1C18AA1D00A67EE3 /* stack_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = C9571C391C18AA1D00A67EE3 /* stack_logging.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C95742721BF2C2880027269A /* bitarray.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FE91FD216A90A8D00D1238A /* bitarray.h */; }; + C95742731BF2C2880027269A /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C957426D1BF2C0C80027269A /* internal.h */; }; + C95742741BF2C2880027269A /* locking.h in Headers */ = {isa = PBXBuildFile; fileRef = C957426E1BF2C1480027269A /* locking.h */; }; + C95742751BF2C2880027269A /* printf.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FE91FD916A90A8D00D1238A /* printf.h */; }; + C95742761BF2C2880027269A /* platform.h in Headers */ = {isa = PBXBuildFile; fileRef = C9F77BBA1BF2B84800812E13 /* platform.h */; }; + C95742771BF2C2880027269A /* legacy_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FE91FFB16A90E6C00D1238A /* legacy_malloc.h */; }; + C957427A1BF2C67E0027269A /* nano_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742791BF2C5F40027269A /* nano_malloc.h */; }; + C957427C1BF2C8DE0027269A /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = C957427B1BF2C8DE0027269A /* debug.h */; }; + C957427D1BF2C8DE0027269A /* debug.h in Headers */ = {isa = PBXBuildFile; fileRef = C957427B1BF2C8DE0027269A /* debug.h */; }; + C957427F1BF33D130027269A /* nano_zone.h in Headers */ = {isa = PBXBuildFile; fileRef = C957427E1BF33D130027269A /* nano_zone.h */; }; + C95742801BF33D130027269A /* nano_zone.h in Headers */ = {isa = PBXBuildFile; fileRef = C957427E1BF33D130027269A /* nano_zone.h */; }; + C95742871BF3F9550027269A /* magazine_zone.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742861BF3F9550027269A /* magazine_zone.h */; }; + C95742881BF3F9550027269A /* magazine_zone.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742861BF3F9550027269A /* magazine_zone.h */; }; + C957428A1BF3FD290027269A /* base.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742891BF3FD290027269A /* base.h */; }; + C957428B1BF3FD290027269A /* base.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742891BF3FD290027269A /* base.h */; }; + C957428D1BF411330027269A /* thresholds.h in Headers */ = {isa = PBXBuildFile; fileRef = C957428C1BF411330027269A /* thresholds.h */; }; + C957428E1BF411330027269A /* thresholds.h in Headers */ = {isa = PBXBuildFile; fileRef = C957428C1BF411330027269A /* thresholds.h */; }; + C95742901BF419DF0027269A /* magazine_tiny.c in Sources */ = {isa = PBXBuildFile; fileRef = C957428F1BF419DF0027269A /* magazine_tiny.c */; }; + C95742911BF419DF0027269A /* magazine_tiny.c in Sources */ = {isa = PBXBuildFile; fileRef = C957428F1BF419DF0027269A /* magazine_tiny.c */; }; + C95742931BF41C970027269A /* magazine_inline.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742921BF41C970027269A /* magazine_inline.h */; }; + C95742941BF41C970027269A /* magazine_inline.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742921BF41C970027269A /* magazine_inline.h */; }; + C95742961BF41E480027269A /* magazine_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742951BF41E480027269A /* magazine_malloc.h */; }; + C95742971BF41E480027269A /* magazine_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742951BF41E480027269A /* magazine_malloc.h */; }; + C95742991BF670D00027269A /* magazine_small.c in Sources */ = {isa = PBXBuildFile; fileRef = C95742981BF670D00027269A /* magazine_small.c */; }; + C957429A1BF670D00027269A /* magazine_small.c in Sources */ = {isa = PBXBuildFile; fileRef = C95742981BF670D00027269A /* magazine_small.c */; }; + C957429C1BF672F80027269A /* magazine_large.c in Sources */ = {isa = PBXBuildFile; fileRef = C957429B1BF672F80027269A /* magazine_large.c */; }; + C957429D1BF672F80027269A /* magazine_large.c in Sources */ = {isa = PBXBuildFile; fileRef = C957429B1BF672F80027269A /* magazine_large.c */; }; + C95742A01BF681B00027269A /* purgeable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C957429E1BF681B00027269A /* purgeable_malloc.c */; }; + C95742A11BF681B00027269A /* purgeable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C957429E1BF681B00027269A /* purgeable_malloc.c */; }; + C95742A21BF681B00027269A /* purgeable_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C957429F1BF681B00027269A /* purgeable_malloc.h */; }; + C95742A31BF681B00027269A /* purgeable_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C957429F1BF681B00027269A /* purgeable_malloc.h */; }; + C95742A61BF6842F0027269A /* frozen_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C95742A41BF6842F0027269A /* frozen_malloc.c */; }; + C95742A71BF6842F0027269A /* frozen_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C95742A41BF6842F0027269A /* frozen_malloc.c */; }; + C95742A81BF6842F0027269A /* frozen_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742A51BF6842F0027269A /* frozen_malloc.h */; }; + C95742A91BF6842F0027269A /* frozen_malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = C95742A51BF6842F0027269A /* frozen_malloc.h */; }; + C95742AB1BF685CB0027269A /* legacy_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C95742AA1BF685CB0027269A /* legacy_malloc.c */; }; + C95742AC1BF685CB0027269A /* legacy_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C95742AA1BF685CB0027269A /* legacy_malloc.c */; }; + C9ABCA051CB6FC6800ECB399 /* empty.s in Sources */ = {isa = PBXBuildFile; fileRef = C9ABCA041CB6FC6800ECB399 /* empty.s */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,31 +133,140 @@ remoteGlobalIDString = 3FE91FE716A90AEC00D1238A; remoteInfo = libsystem_malloc; }; + 45039167198FFFA6004EE2A3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3FFC1BE516A908F800027192 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 456E51C8197DF0D600A7E488; + remoteInfo = libmalloc_stress_test; + }; + 925383D81BD03D0000F745DB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3FFC1BE516A908F800027192 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 925383D41BD03C0500F745DB; + remoteInfo = darwintests; + }; + C0CE454F1C52CCBD00C24048 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3FFC1BE516A908F800027192 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C0CE452F1C52C90500C24048; + remoteInfo = libmalloc_static; + }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + 456E51C7197DF0D600A7E488 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + C0CE454D1C52C9D900C24048 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/local/lib/loaderd; + dstSubfolderSpec = 0; + files = ( + C0CE454E1C52C9E600C24048 /* libmalloc.a in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ - 3F5732E016A9478E00EC61B4 /* stack_logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack_logging.h; sourceTree = ""; }; + 0D468DCC1C7BEE56006FACF5 /* magazine_lite.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = magazine_lite.c; sourceTree = ""; }; + 0D468DCD1C7BEE65006FACF5 /* stack_logging_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack_logging_internal.h; sourceTree = ""; }; + 0D468DCE1C7BEE74006FACF5 /* stack_logging_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stack_logging_test.c; sourceTree = ""; }; 3FC452FF18E4ABFE003D6A38 /* manpages.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = manpages.sh; sourceTree = ""; }; 3FE91FC916A90A8D00D1238A /* malloc.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = malloc.3; sourceTree = ""; }; 3FE91FCA16A90A8D00D1238A /* malloc_size.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = malloc_size.3; sourceTree = ""; }; 3FE91FCB16A90A8D00D1238A /* malloc_zone_malloc.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = malloc_zone_malloc.3; sourceTree = ""; }; 3FE91FD116A90A8D00D1238A /* bitarray.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bitarray.c; sourceTree = ""; }; 3FE91FD216A90A8D00D1238A /* bitarray.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bitarray.h; sourceTree = ""; }; - 3FE91FD616A90A8D00D1238A /* magazine_malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = magazine_malloc.c; sourceTree = ""; tabWidth = 4; }; + 3FE91FD616A90A8D00D1238A /* magazine_malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = magazine_malloc.c; sourceTree = ""; }; 3FE91FD716A90A8D00D1238A /* magmallocProvider.d */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.dtrace; path = magmallocProvider.d; sourceTree = ""; }; 3FE91FD816A90A8D00D1238A /* malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = malloc.c; sourceTree = ""; }; - 3FE91FD916A90A8D00D1238A /* malloc_printf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = malloc_printf.h; sourceTree = ""; }; - 3FE91FDA16A90A8D00D1238A /* nano_malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = nano_malloc.c; sourceTree = ""; tabWidth = 4; }; - 3FE91FDB16A90A8D00D1238A /* stack_logging.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stack_logging.c; sourceTree = ""; }; + 3FE91FD916A90A8D00D1238A /* printf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = printf.h; sourceTree = ""; }; + 3FE91FDA16A90A8D00D1238A /* nano_malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = nano_malloc.c; sourceTree = ""; }; 3FE91FDC16A90A8D00D1238A /* stack_logging_disk.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stack_logging_disk.c; sourceTree = ""; usesTabs = 1; }; 3FE91FE016A90A8D00D1238A /* libmalloc.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = libmalloc.xcconfig; sourceTree = ""; }; 3FE91FE116A90A8D00D1238A /* libmalloc_eos.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = libmalloc_eos.xcconfig; sourceTree = ""; }; 3FE91FE316A90A8D00D1238A /* sanitise_headers.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = sanitise_headers.sh; sourceTree = ""; }; 3FE91FE816A90AEC00D1238A /* libsystem_malloc.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_malloc.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 3FE91FF916A90BEF00D1238A /* malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = malloc.h; sourceTree = ""; }; - 3FE91FFB16A90E6C00D1238A /* scalable_malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scalable_malloc.h; sourceTree = ""; }; + 3FE91FFB16A90E6C00D1238A /* legacy_malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = legacy_malloc.h; sourceTree = ""; }; 3FE9201016A9109E00D1238A /* libmalloc_eOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libmalloc_eOS.a; sourceTree = BUILT_PRODUCTS_DIR; }; - E47677CF17A899C9007D4A00 /* malloc_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = malloc_internal.h; sourceTree = ""; }; + 456E51C9197DF0D600A7E488 /* libmalloc_stress_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = libmalloc_stress_test; sourceTree = BUILT_PRODUCTS_DIR; }; + 925383D01BD03B4A00F745DB /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 925383D11BD03B4A00F745DB /* stress_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stress_test.c; sourceTree = ""; }; + 925383D31BD03B8F00F745DB /* manpages.lst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = manpages.lst; sourceTree = ""; }; + C0352EC61C3F3C3600DB5126 /* malloc_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = malloc_private.h; sourceTree = ""; }; + C0CE450E1C52B9E300C24048 /* libmalloc_static.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = libmalloc_static.xcconfig; sourceTree = ""; }; + C0CE454C1C52C90500C24048 /* libmalloc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libmalloc.a; sourceTree = BUILT_PRODUCTS_DIR; }; + C92853A01C767F08001FEAF3 /* install-codes.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "install-codes.sh"; sourceTree = ""; }; + C931B58F1C81248100D0D230 /* madvise.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = madvise.c; sourceTree = ""; }; + C938BBD21C74F7A400522BBD /* trace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trace.h; sourceTree = ""; }; + C9571C391C18AA1D00A67EE3 /* stack_logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack_logging.h; sourceTree = ""; }; + C9571C3C1C18AD5F00A67EE3 /* balloon.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = balloon.cpp; sourceTree = ""; }; + C9571C3D1C18AD5F00A67EE3 /* balloon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = balloon.h; sourceTree = ""; }; + C9571C3E1C18AD5F00A67EE3 /* Benchmark.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Benchmark.cpp; sourceTree = ""; }; + C9571C3F1C18AD5F00A67EE3 /* Benchmark.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Benchmark.h; sourceTree = ""; }; + C9571C401C18AD5F00A67EE3 /* big.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = big.cpp; sourceTree = ""; }; + C9571C411C18AD5F00A67EE3 /* big.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = big.h; sourceTree = ""; }; + C9571C421C18AD5F00A67EE3 /* churn.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = churn.cpp; sourceTree = ""; }; + C9571C431C18AD5F00A67EE3 /* churn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = churn.h; sourceTree = ""; }; + C9571C441C18AD5F00A67EE3 /* CommandLine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CommandLine.cpp; sourceTree = ""; }; + C9571C451C18AD5F00A67EE3 /* CommandLine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommandLine.h; sourceTree = ""; }; + C9571C461C18AD5F00A67EE3 /* CPUCount.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CPUCount.cpp; sourceTree = ""; }; + C9571C471C18AD5F00A67EE3 /* CPUCount.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPUCount.h; sourceTree = ""; }; + C9571C4C1C18AD5F00A67EE3 /* fragment.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = fragment.cpp; sourceTree = ""; }; + C9571C4D1C18AD5F00A67EE3 /* fragment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fragment.h; sourceTree = ""; }; + C9571C4E1C18AD5F00A67EE3 /* Interpreter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Interpreter.cpp; sourceTree = ""; }; + C9571C4F1C18AD5F00A67EE3 /* Interpreter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Interpreter.h; sourceTree = ""; }; + C9571C501C18AD5F00A67EE3 /* list.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = list.cpp; sourceTree = ""; }; + C9571C511C18AD5F00A67EE3 /* list.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = ""; }; + C9571C521C18AD5F00A67EE3 /* mbmalloc.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = mbmalloc.cpp; sourceTree = ""; }; + C9571C531C18AD5F00A67EE3 /* mbmalloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mbmalloc.h; sourceTree = ""; }; + C9571C541C18AD5F00A67EE3 /* medium.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = medium.cpp; sourceTree = ""; }; + C9571C551C18AD5F00A67EE3 /* medium.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = medium.h; sourceTree = ""; }; + C9571C561C18AD5F00A67EE3 /* memalign.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = memalign.cpp; sourceTree = ""; }; + C9571C571C18AD5F00A67EE3 /* memalign.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = memalign.h; sourceTree = ""; }; + C9571C581C18AD5F00A67EE3 /* message.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = message.cpp; sourceTree = ""; }; + C9571C591C18AD5F00A67EE3 /* message.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = message.h; sourceTree = ""; }; + C9571C5A1C18AD5F00A67EE3 /* realloc.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = realloc.cpp; sourceTree = ""; }; + C9571C5B1C18AD5F00A67EE3 /* realloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = realloc.h; sourceTree = ""; }; + C9571C5E1C18AD5F00A67EE3 /* stress_aligned.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = stress_aligned.cpp; sourceTree = ""; }; + C9571C5F1C18AD5F00A67EE3 /* stress_aligned.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stress_aligned.h; sourceTree = ""; }; + C9571C601C18AD5F00A67EE3 /* stress.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = stress.cpp; sourceTree = ""; }; + C9571C611C18AD5F00A67EE3 /* stress.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stress.h; sourceTree = ""; }; + C9571C641C18AD5F00A67EE3 /* tree.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = tree.cpp; sourceTree = ""; }; + C9571C651C18AD5F00A67EE3 /* tree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tree.h; sourceTree = ""; }; + C9571C661C18AD6A00A67EE3 /* MallocBench.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MallocBench.cpp; sourceTree = ""; }; + C957426D1BF2C0C80027269A /* internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = ""; }; + C957426E1BF2C1480027269A /* locking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = locking.h; sourceTree = ""; }; + C95742791BF2C5F40027269A /* nano_malloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = nano_malloc.h; sourceTree = ""; }; + C957427B1BF2C8DE0027269A /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = ""; }; + C957427E1BF33D130027269A /* nano_zone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nano_zone.h; sourceTree = ""; }; + C95742861BF3F9550027269A /* magazine_zone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = magazine_zone.h; sourceTree = ""; }; + C95742891BF3FD290027269A /* base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base.h; sourceTree = ""; }; + C957428C1BF411330027269A /* thresholds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = thresholds.h; sourceTree = ""; }; + C957428F1BF419DF0027269A /* magazine_tiny.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = magazine_tiny.c; sourceTree = ""; }; + C95742921BF41C970027269A /* magazine_inline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = magazine_inline.h; sourceTree = ""; }; + C95742951BF41E480027269A /* magazine_malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = magazine_malloc.h; sourceTree = ""; }; + C95742981BF670D00027269A /* magazine_small.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = magazine_small.c; sourceTree = ""; }; + C957429B1BF672F80027269A /* magazine_large.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = magazine_large.c; sourceTree = ""; }; + C957429E1BF681B00027269A /* purgeable_malloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = purgeable_malloc.c; sourceTree = ""; }; + C957429F1BF681B00027269A /* purgeable_malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = purgeable_malloc.h; sourceTree = ""; }; + C95742A41BF6842F0027269A /* frozen_malloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = frozen_malloc.c; sourceTree = ""; }; + C95742A51BF6842F0027269A /* frozen_malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = frozen_malloc.h; sourceTree = ""; }; + C95742AA1BF685CB0027269A /* legacy_malloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = legacy_malloc.c; sourceTree = ""; }; + C9ABCA041CB6FC6800ECB399 /* empty.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = empty.s; sourceTree = ""; }; + C9F77BBA1BF2B84800812E13 /* platform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = platform.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -102,12 +284,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 456E51C6197DF0D600A7E488 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C0CE453E1C52C90500C24048 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 3FE91FC816A90A8D00D1238A /* man */ = { isa = PBXGroup; children = ( + 925383D31BD03B8F00F745DB /* manpages.lst */, 3FE91FC916A90A8D00D1238A /* malloc.3 */, 3FE91FCA16A90A8D00D1238A /* malloc_size.3 */, 3FE91FCB16A90A8D00D1238A /* malloc_zone_malloc.3 */, @@ -118,18 +315,38 @@ 3FE91FCC16A90A8D00D1238A /* src */ = { isa = PBXGroup; children = ( + C95742891BF3FD290027269A /* base.h */, 3FE91FD116A90A8D00D1238A /* bitarray.c */, 3FE91FD216A90A8D00D1238A /* bitarray.h */, - E47677CF17A899C9007D4A00 /* malloc_internal.h */, + C957427B1BF2C8DE0027269A /* debug.h */, + C95742A41BF6842F0027269A /* frozen_malloc.c */, + C95742A51BF6842F0027269A /* frozen_malloc.h */, + C957426D1BF2C0C80027269A /* internal.h */, + C95742AA1BF685CB0027269A /* legacy_malloc.c */, + 3FE91FFB16A90E6C00D1238A /* legacy_malloc.h */, + C957426E1BF2C1480027269A /* locking.h */, + C95742921BF41C970027269A /* magazine_inline.h */, + C957429B1BF672F80027269A /* magazine_large.c */, + 0D468DCC1C7BEE56006FACF5 /* magazine_lite.c */, 3FE91FD616A90A8D00D1238A /* magazine_malloc.c */, + C95742951BF41E480027269A /* magazine_malloc.h */, + C95742981BF670D00027269A /* magazine_small.c */, + C957428F1BF419DF0027269A /* magazine_tiny.c */, + C95742861BF3F9550027269A /* magazine_zone.h */, 3FE91FD716A90A8D00D1238A /* magmallocProvider.d */, 3FE91FD816A90A8D00D1238A /* malloc.c */, - 3FE91FD916A90A8D00D1238A /* malloc_printf.h */, 3FE91FDA16A90A8D00D1238A /* nano_malloc.c */, - 3FE91FFB16A90E6C00D1238A /* scalable_malloc.h */, - 3FE91FDB16A90A8D00D1238A /* stack_logging.c */, - 3F5732E016A9478E00EC61B4 /* stack_logging.h */, + C95742791BF2C5F40027269A /* nano_malloc.h */, + C957427E1BF33D130027269A /* nano_zone.h */, + C9F77BBA1BF2B84800812E13 /* platform.h */, + 3FE91FD916A90A8D00D1238A /* printf.h */, + C957429E1BF681B00027269A /* purgeable_malloc.c */, + C957429F1BF681B00027269A /* purgeable_malloc.h */, 3FE91FDC16A90A8D00D1238A /* stack_logging_disk.c */, + 0D468DCD1C7BEE65006FACF5 /* stack_logging_internal.h */, + C9ABCA041CB6FC6800ECB399 /* empty.s */, + C957428C1BF411330027269A /* thresholds.h */, + C938BBD21C74F7A400522BBD /* trace.h */, ); path = src; sourceTree = ""; @@ -139,6 +356,7 @@ children = ( 3FE91FE016A90A8D00D1238A /* libmalloc.xcconfig */, 3FE91FE116A90A8D00D1238A /* libmalloc_eos.xcconfig */, + C0CE450E1C52B9E300C24048 /* libmalloc_static.xcconfig */, ); path = xcodeconfig; sourceTree = ""; @@ -148,6 +366,7 @@ children = ( 3FC452FF18E4ABFE003D6A38 /* manpages.sh */, 3FE91FE316A90A8D00D1238A /* sanitise_headers.sh */, + C92853A01C767F08001FEAF3 /* install-codes.sh */, ); path = xcodescripts; sourceTree = ""; @@ -157,6 +376,8 @@ children = ( 3FE91FE816A90AEC00D1238A /* libsystem_malloc.dylib */, 3FE9201016A9109E00D1238A /* libmalloc_eOS.a */, + 456E51C9197DF0D600A7E488 /* libmalloc_stress_test */, + C0CE454C1C52C90500C24048 /* libmalloc.a */, ); name = Products; sourceTree = ""; @@ -182,15 +403,80 @@ children = ( 3FE91FF716A90BEF00D1238A /* include */, 3FE91FC816A90A8D00D1238A /* man */, + C9571C381C18AA0A00A67EE3 /* private */, 3FE91FCC16A90A8D00D1238A /* src */, + 925383BD1BD03B4A00F745DB /* tests */, 3FE91FDF16A90A8D00D1238A /* xcodeconfig */, 3FE91FE216A90A8D00D1238A /* xcodescripts */, 3FE91FE916A90AEC00D1238A /* Products */, ); sourceTree = ""; - tabWidth = 8; + tabWidth = 4; usesTabs = 1; }; + 925383BD1BD03B4A00F745DB /* tests */ = { + isa = PBXGroup; + children = ( + 0D468DCE1C7BEE74006FACF5 /* stack_logging_test.c */, + C931B58F1C81248100D0D230 /* madvise.c */, + C9571C3B1C18AD4F00A67EE3 /* MallocBench */, + 925383D01BD03B4A00F745DB /* Makefile */, + C9571C661C18AD6A00A67EE3 /* MallocBench.cpp */, + 925383D11BD03B4A00F745DB /* stress_test.c */, + ); + path = tests; + sourceTree = ""; + }; + C9571C381C18AA0A00A67EE3 /* private */ = { + isa = PBXGroup; + children = ( + C9571C391C18AA1D00A67EE3 /* stack_logging.h */, + C0352EC61C3F3C3600DB5126 /* malloc_private.h */, + ); + path = private; + sourceTree = ""; + }; + C9571C3B1C18AD4F00A67EE3 /* MallocBench */ = { + isa = PBXGroup; + children = ( + C9571C3C1C18AD5F00A67EE3 /* balloon.cpp */, + C9571C3D1C18AD5F00A67EE3 /* balloon.h */, + C9571C3E1C18AD5F00A67EE3 /* Benchmark.cpp */, + C9571C3F1C18AD5F00A67EE3 /* Benchmark.h */, + C9571C401C18AD5F00A67EE3 /* big.cpp */, + C9571C411C18AD5F00A67EE3 /* big.h */, + C9571C421C18AD5F00A67EE3 /* churn.cpp */, + C9571C431C18AD5F00A67EE3 /* churn.h */, + C9571C441C18AD5F00A67EE3 /* CommandLine.cpp */, + C9571C451C18AD5F00A67EE3 /* CommandLine.h */, + C9571C461C18AD5F00A67EE3 /* CPUCount.cpp */, + C9571C471C18AD5F00A67EE3 /* CPUCount.h */, + C9571C4C1C18AD5F00A67EE3 /* fragment.cpp */, + C9571C4D1C18AD5F00A67EE3 /* fragment.h */, + C9571C4E1C18AD5F00A67EE3 /* Interpreter.cpp */, + C9571C4F1C18AD5F00A67EE3 /* Interpreter.h */, + C9571C501C18AD5F00A67EE3 /* list.cpp */, + C9571C511C18AD5F00A67EE3 /* list.h */, + C9571C521C18AD5F00A67EE3 /* mbmalloc.cpp */, + C9571C531C18AD5F00A67EE3 /* mbmalloc.h */, + C9571C541C18AD5F00A67EE3 /* medium.cpp */, + C9571C551C18AD5F00A67EE3 /* medium.h */, + C9571C561C18AD5F00A67EE3 /* memalign.cpp */, + C9571C571C18AD5F00A67EE3 /* memalign.h */, + C9571C581C18AD5F00A67EE3 /* message.cpp */, + C9571C591C18AD5F00A67EE3 /* message.h */, + C9571C5A1C18AD5F00A67EE3 /* realloc.cpp */, + C9571C5B1C18AD5F00A67EE3 /* realloc.h */, + C9571C5E1C18AD5F00A67EE3 /* stress_aligned.cpp */, + C9571C5F1C18AD5F00A67EE3 /* stress_aligned.h */, + C9571C601C18AD5F00A67EE3 /* stress.cpp */, + C9571C611C18AD5F00A67EE3 /* stress.h */, + C9571C641C18AD5F00A67EE3 /* tree.cpp */, + C9571C651C18AD5F00A67EE3 /* tree.h */, + ); + path = MallocBench; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -198,11 +484,27 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + C957428A1BF3FD290027269A /* base.h in Headers */, + C0352EC71C3F3C4400DB5126 /* malloc_private.h in Headers */, + 0D468DD01C7BEF71006FACF5 /* stack_logging_internal.h in Headers */, + C95742731BF2C2880027269A /* internal.h in Headers */, + C95742721BF2C2880027269A /* bitarray.h in Headers */, + C938BBD31C74F7A400522BBD /* trace.h in Headers */, + C95742A81BF6842F0027269A /* frozen_malloc.h in Headers */, + C957428D1BF411330027269A /* thresholds.h in Headers */, + C95742741BF2C2880027269A /* locking.h in Headers */, + C95742931BF41C970027269A /* magazine_inline.h in Headers */, + C95742761BF2C2880027269A /* platform.h in Headers */, + C957427A1BF2C67E0027269A /* nano_malloc.h in Headers */, + C957427C1BF2C8DE0027269A /* debug.h in Headers */, + C95742961BF41E480027269A /* magazine_malloc.h in Headers */, + C9571C3A1C18AA1D00A67EE3 /* stack_logging.h in Headers */, 3FE91FFA16A90BEF00D1238A /* malloc.h in Headers */, - 3F5732E116A9478E00EC61B4 /* stack_logging.h in Headers */, - 3FE91FEE16A90B9200D1238A /* bitarray.h in Headers */, - 3FE91FF316A90B9200D1238A /* malloc_printf.h in Headers */, - 3FE91FFC16A90E6C00D1238A /* scalable_malloc.h in Headers */, + C95742871BF3F9550027269A /* magazine_zone.h in Headers */, + C95742771BF2C2880027269A /* legacy_malloc.h in Headers */, + C95742A21BF681B00027269A /* purgeable_malloc.h in Headers */, + C957427F1BF33D130027269A /* nano_zone.h in Headers */, + C95742751BF2C2880027269A /* printf.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -210,11 +512,53 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + C95742941BF41C970027269A /* magazine_inline.h in Headers */, + C95742801BF33D130027269A /* nano_zone.h in Headers */, + C957428E1BF411330027269A /* thresholds.h in Headers */, + C957427D1BF2C8DE0027269A /* debug.h in Headers */, + C95742A91BF6842F0027269A /* frozen_malloc.h in Headers */, + C95742881BF3F9550027269A /* magazine_zone.h in Headers */, + C95742971BF41E480027269A /* magazine_malloc.h in Headers */, + C95742A31BF681B00027269A /* purgeable_malloc.h in Headers */, + C957428B1BF3FD290027269A /* base.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C0CE453F1C52C90500C24048 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C0CE45401C52C90500C24048 /* magazine_inline.h in Headers */, + C0CE45411C52C90500C24048 /* nano_zone.h in Headers */, + C0CE45421C52C90500C24048 /* thresholds.h in Headers */, + C0CE45431C52C90500C24048 /* debug.h in Headers */, + C0CE45441C52C90500C24048 /* frozen_malloc.h in Headers */, + C0CE45451C52C90500C24048 /* magazine_zone.h in Headers */, + C0CE45461C52C90500C24048 /* magazine_malloc.h in Headers */, + C0CE45471C52C90500C24048 /* purgeable_malloc.h in Headers */, + C0CE45481C52C90500C24048 /* base.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ +/* Begin PBXLegacyTarget section */ + 925383D41BD03C0500F745DB /* darwintests */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = 925383D51BD03C0500F745DB /* Build configuration list for PBXLegacyTarget "darwintests" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + buildWorkingDirectory = tests; + dependencies = ( + ); + name = darwintests; + passBuildSettingsInEnvironment = 1; + productName = darwintests; + }; +/* End PBXLegacyTarget section */ + /* Begin PBXNativeTarget section */ 3FE91FE716A90AEC00D1238A /* libsystem_malloc */ = { isa = PBXNativeTarget; @@ -223,6 +567,7 @@ 3FE91FE416A90AEC00D1238A /* Sources */, 3FE91FE516A90AEC00D1238A /* Frameworks */, 3FE91FE616A90AEC00D1238A /* Headers */, + C92853A11C767F78001FEAF3 /* Install Codes File */, ); buildRules = ( ); @@ -250,13 +595,60 @@ productReference = 3FE9201016A9109E00D1238A /* libmalloc_eOS.a */; productType = "com.apple.product-type.library.static"; }; + 456E51C8197DF0D600A7E488 /* libmalloc_stress_test */ = { + isa = PBXNativeTarget; + buildConfigurationList = 456E51CF197DF0D600A7E488 /* Build configuration list for PBXNativeTarget "libmalloc_stress_test" */; + buildPhases = ( + 456E51C5197DF0D600A7E488 /* Sources */, + 456E51C6197DF0D600A7E488 /* Frameworks */, + 456E51C7197DF0D600A7E488 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = libmalloc_stress_test; + productName = libmalloc_stress_test; + productReference = 456E51C9197DF0D600A7E488 /* libmalloc_stress_test */; + productType = "com.apple.product-type.tool"; + }; + C0CE452F1C52C90500C24048 /* libmalloc_static */ = { + isa = PBXNativeTarget; + buildConfigurationList = C0CE45491C52C90500C24048 /* Build configuration list for PBXNativeTarget "libmalloc_static" */; + buildPhases = ( + C0CE45301C52C90500C24048 /* Sources */, + C0CE453E1C52C90500C24048 /* Frameworks */, + C0CE453F1C52C90500C24048 /* Headers */, + C0CE454D1C52C9D900C24048 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = libmalloc_static; + productName = libmalloc; + productReference = C0CE454C1C52C90500C24048 /* libmalloc.a */; + productType = "com.apple.product-type.library.static"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 3FFC1BE516A908F800027192 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0500; + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 0710; + TargetAttributes = { + 45039161198FFF73004EE2A3 = { + CreatedOnToolsVersion = 6.0; + }; + 456E51C8197DF0D600A7E488 = { + CreatedOnToolsVersion = 6.0; + }; + 925383D41BD03C0500F745DB = { + CreatedOnToolsVersion = 7.1; + }; + }; }; buildConfigurationList = 3FFC1BE816A908F800027192 /* Build configuration list for PBXProject "libmalloc" */; compatibilityVersion = "Xcode 3.2"; @@ -271,8 +663,12 @@ projectRoot = ""; targets = ( 3FE9201116A9111000D1238A /* libmalloc */, + 45039161198FFF73004EE2A3 /* libmalloc_test */, 3FE91FE716A90AEC00D1238A /* libsystem_malloc */, 3FE91FFD16A9109E00D1238A /* libmalloc_eOS */, + C0CE452F1C52C90500C24048 /* libmalloc_static */, + 456E51C8197DF0D600A7E488 /* libmalloc_stress_test */, + 925383D41BD03C0500F745DB /* darwintests */, ); }; /* End PBXProject section */ @@ -308,6 +704,22 @@ shellPath = /bin/sh; shellScript = ". \"${SCRIPT_INPUT_FILE_0}\""; }; + C92853A11C767F78001FEAF3 /* Install Codes File */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/src/trace.h", + ); + name = "Install Codes File"; + outputPaths = ( + "$(DSTROOT)/usr/local/share/misc/libmalloc.codes", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/bash; + shellScript = ". \"$PROJECT_DIR\"/xcodescripts/install-codes.sh"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -316,12 +728,18 @@ buildActionMask = 2147483647; files = ( 3FE91FED16A90B9200D1238A /* bitarray.c in Sources */, + C95742A01BF681B00027269A /* purgeable_malloc.c in Sources */, + C957429C1BF672F80027269A /* magazine_large.c in Sources */, 3FE91FF016A90B9200D1238A /* magazine_malloc.c in Sources */, + C95742991BF670D00027269A /* magazine_small.c in Sources */, + C95742AB1BF685CB0027269A /* legacy_malloc.c in Sources */, 3FE91FF116A90B9200D1238A /* magmallocProvider.d in Sources */, + 0D468DCF1C7BEF51006FACF5 /* magazine_lite.c in Sources */, 3FE91FF216A90B9200D1238A /* malloc.c in Sources */, + C95742A61BF6842F0027269A /* frozen_malloc.c in Sources */, 3FE91FF416A90B9200D1238A /* nano_malloc.c in Sources */, - 3FE91FF516A90B9200D1238A /* stack_logging.c in Sources */, 3FE91FF616A90B9200D1238A /* stack_logging_disk.c in Sources */, + C95742901BF419DF0027269A /* magazine_tiny.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -330,12 +748,45 @@ buildActionMask = 2147483647; files = ( 3FE91FFF16A9109E00D1238A /* bitarray.c in Sources */, + C95742A11BF681B00027269A /* purgeable_malloc.c in Sources */, + C957429D1BF672F80027269A /* magazine_large.c in Sources */, 3FE9200116A9109E00D1238A /* magazine_malloc.c in Sources */, + C957429A1BF670D00027269A /* magazine_small.c in Sources */, + C95742AC1BF685CB0027269A /* legacy_malloc.c in Sources */, 3FE9200216A9109E00D1238A /* magmallocProvider.d in Sources */, 3FE9200316A9109E00D1238A /* malloc.c in Sources */, + C95742A71BF6842F0027269A /* frozen_malloc.c in Sources */, 3FE9200416A9109E00D1238A /* nano_malloc.c in Sources */, - 3FE9200516A9109E00D1238A /* stack_logging.c in Sources */, 3FE9200616A9109E00D1238A /* stack_logging_disk.c in Sources */, + C95742911BF419DF0027269A /* magazine_tiny.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 456E51C5197DF0D600A7E488 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 925383DA1BD03D5100F745DB /* stress_test.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C0CE45301C52C90500C24048 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C0CE45311C52C90500C24048 /* bitarray.c in Sources */, + C0CE45321C52C90500C24048 /* purgeable_malloc.c in Sources */, + C0CE45331C52C90500C24048 /* magazine_large.c in Sources */, + C0CE45341C52C90500C24048 /* magazine_malloc.c in Sources */, + C9ABCA051CB6FC6800ECB399 /* empty.s in Sources */, + C0CE45351C52C90500C24048 /* magazine_small.c in Sources */, + C0CE45361C52C90500C24048 /* legacy_malloc.c in Sources */, + C0CE45371C52C90500C24048 /* magmallocProvider.d in Sources */, + C0CE45381C52C90500C24048 /* malloc.c in Sources */, + C0CE45391C52C90500C24048 /* frozen_malloc.c in Sources */, + C0CE453A1C52C90500C24048 /* nano_malloc.c in Sources */, + C0CE453C1C52C90500C24048 /* stack_logging_disk.c in Sources */, + C0CE453D1C52C90500C24048 /* magazine_tiny.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -352,6 +803,21 @@ target = 3FE91FE716A90AEC00D1238A /* libsystem_malloc */; targetProxy = 3FE9201716A9111600D1238A /* PBXContainerItemProxy */; }; + 45039168198FFFA6004EE2A3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 456E51C8197DF0D600A7E488 /* libmalloc_stress_test */; + targetProxy = 45039167198FFFA6004EE2A3 /* PBXContainerItemProxy */; + }; + 925383D91BD03D0000F745DB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 925383D41BD03C0500F745DB /* darwintests */; + targetProxy = 925383D81BD03D0000F745DB /* PBXContainerItemProxy */; + }; + C0CE45501C52CCBD00C24048 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C0CE452F1C52C90500C24048 /* libmalloc_static */; + targetProxy = C0CE454F1C52CCBD00C24048 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -415,6 +881,138 @@ }; name = Release; }; + 45039163198FFF73004EE2A3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 45039164198FFF73004EE2A3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 456E51CD197DF0D600A7E488 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.10; + METAL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = ""; + SKIP_INSTALL = NO; + SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos"; + }; + name = Debug; + }; + 456E51CE197DF0D600A7E488 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.10; + METAL_ENABLE_DEBUG_INFO = NO; + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = ""; + SKIP_INSTALL = NO; + "SKIP_INSTALL[sdk=iphonesimulator*]" = YES; + SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos"; + }; + name = Release; + }; + 925383D61BD03C0500F745DB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx.internal; + SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos"; + }; + name = Debug; + }; + 925383D71BD03C0500F745DB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx.internal; + SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos"; + }; + name = Release; + }; + C0CE454A1C52C90500C24048 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C0CE450E1C52B9E300C24048 /* libmalloc_static.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + PRODUCT_NAME = "$(PRODUCT_NAME)"; + }; + name = Debug; + }; + C0CE454B1C52C90500C24048 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C0CE450E1C52B9E300C24048 /* libmalloc_static.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + PRODUCT_NAME = "$(PRODUCT_NAME)"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -454,6 +1052,42 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 45039162198FFF73004EE2A3 /* Build configuration list for PBXAggregateTarget "libmalloc_test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 45039163198FFF73004EE2A3 /* Debug */, + 45039164198FFF73004EE2A3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 456E51CF197DF0D600A7E488 /* Build configuration list for PBXNativeTarget "libmalloc_stress_test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 456E51CD197DF0D600A7E488 /* Debug */, + 456E51CE197DF0D600A7E488 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 925383D51BD03C0500F745DB /* Build configuration list for PBXLegacyTarget "darwintests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 925383D61BD03C0500F745DB /* Debug */, + 925383D71BD03C0500F745DB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C0CE45491C52C90500C24048 /* Build configuration list for PBXNativeTarget "libmalloc_static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C0CE454A1C52C90500C24048 /* Debug */, + C0CE454B1C52C90500C24048 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 3FFC1BE516A908F800027192 /* Project object */; diff --git a/src/libmalloc/private/malloc_private.h b/src/libmalloc/private/malloc_private.h new file mode 100644 index 000000000..ff9eec107 --- /dev/null +++ b/src/libmalloc/private/malloc_private.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1999-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _MALLOC_PRIVATE_H_ +#define _MALLOC_PRIVATE_H_ + +/* Here be dragons (SPIs) */ + +#include +#include + +/********* Callbacks ************/ + +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) +__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +void malloc_enter_process_memory_limit_warn_mode(void); + /* A callback invoked once the process receives a warning for approaching + * memory limit. */ + +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) +__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +void malloc_memory_event_handler(unsigned long); + /* A function invoked when malloc needs to handle any flavor of + * memory pressure notification or process memory limit notification. */ + +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) +__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +void * reallocarray(void * in_ptr, size_t nmemb, size_t size) __DARWIN_EXTSN(reallocarray); + +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) +__TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +void * reallocarrayf(void * in_ptr, size_t nmemb, size_t size) __DARWIN_EXTSN(reallocarrayf); + +#endif /* _MALLOC_PRIVATE_H_ */ diff --git a/src/libmalloc/private/stack_logging.h b/src/libmalloc/private/stack_logging.h new file mode 100644 index 000000000..25c15266a --- /dev/null +++ b/src/libmalloc/private/stack_logging.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#import + +#define STACK_LOGGING_MAX_STACK_SIZE 512 + +#define stack_logging_type_free 0 +#define stack_logging_type_generic 1 /* anything that is not allocation/deallocation */ +#define stack_logging_type_alloc 2 /* malloc, realloc, etc... */ +#define stack_logging_type_dealloc 4 /* free, realloc, etc... */ +#define stack_logging_type_vm_allocate 16 /* vm_allocate or mmap */ +#define stack_logging_type_vm_deallocate 32 /* vm_deallocate or munmap */ +#define stack_logging_type_mapped_file_or_shared_mem 128 + +// The valid flags include those from VM_FLAGS_ALIAS_MASK, which give the user_tag of allocated VM regions. +#define stack_logging_valid_type_flags ( \ + stack_logging_type_generic | \ + stack_logging_type_alloc | \ + stack_logging_type_dealloc | \ + stack_logging_type_vm_allocate | \ + stack_logging_type_vm_deallocate | \ + stack_logging_type_mapped_file_or_shared_mem | \ + VM_FLAGS_ALIAS_MASK); + +// Following flags are absorbed by stack_logging_log_stack() +#define stack_logging_flag_zone 8 /* NSZoneMalloc, etc... */ +#define stack_logging_flag_cleared 64 /* for NewEmptyHandle */ + +#define STACK_LOGGING_VM_USER_TAG(flags) (((flags) & VM_FLAGS_ALIAS_MASK) >> 24) + + +/* Macro used to disguise addresses so that leak finding can work */ +#define STACK_LOGGING_DISGUISE(address) ((address) ^ 0x00005555) /* nicely idempotent */ + +typedef enum { + stack_logging_mode_none = 0, + stack_logging_mode_all, + stack_logging_mode_malloc, + stack_logging_mode_vm, + stack_logging_mode_lite +} stack_logging_mode_type; + +extern boolean_t turn_on_stack_logging(stack_logging_mode_type mode); +extern void turn_off_stack_logging(); + +extern void __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip); + /* Fits as the malloc_logger; logs malloc/free/realloc events and can log custom events if called directly */ + + +/* 64-bit-aware stack log access. As new SPI, these routines are prefixed with double-underscore to avoid conflict with Libsystem clients. */ + +typedef struct mach_stack_logging_record { + uint32_t type_flags; + uint64_t stack_identifier; + uint64_t argument; + mach_vm_address_t address; +} mach_stack_logging_record_t; + +extern kern_return_t __mach_stack_logging_start_reading(task_t task, vm_address_t shared_memory_address, boolean_t *uses_lite_mode); +extern kern_return_t __mach_stack_logging_stop_reading(task_t task); + +/* Clients *should* call these start/stop functions to properly initialize stack logging data + * structures and fully clean them up when they're done looking at a process. If the client does *not* + * call these then currently it should still work but some data structures will still remain after + * reading the stack logs (e.g., an extra shared memory segment, an open stack log file, etc). + * NULL can be passed for uses_lite_mode if the client doesn’t need them. + * + * It is recommended that the client suspend the task before actually reading the stacks, and resume the task when done, + * if the task uses lite mode. + */ + +extern kern_return_t __mach_stack_logging_set_file_path(task_t task, char* file_path); + +extern kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); + /* Gets the last allocation record (malloc, realloc, or free) about address */ + +extern kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context); + /* Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records */ + +extern kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); + /* Given a uniqued_stack fills stack_frames_buffer */ + + +struct backtrace_uniquing_table; + +extern kern_return_t +__mach_stack_logging_uniquing_table_read_stack(struct backtrace_uniquing_table *uniquing_table, + uint64_t stackid, + mach_vm_address_t *out_frames_buffer, + uint32_t *out_frames_count, + uint32_t max_frames); + +extern +struct backtrace_uniquing_table * +__mach_stack_logging_copy_uniquing_table(task_t task); +/* returns a retained pointer to copy of the task's uniquing table */ + +extern +void +__mach_stack_logging_uniquing_table_release(struct backtrace_uniquing_table *); + +extern +void +__mach_stack_logging_uniquing_table_retain(struct backtrace_uniquing_table *); + +extern +size_t +__mach_stack_logging_uniquing_table_sizeof(struct backtrace_uniquing_table *); +/* returns the serialized size of a uniquing talbe in bytes */ + +extern +void * +__mach_stack_logging_uniquing_table_serialize(struct backtrace_uniquing_table *table, mach_vm_size_t *size); +/* Writes out a serialized representation of the table. Free it with mach_vm_deallocate. */ + +extern +struct backtrace_uniquing_table * +__mach_stack_logging_uniquing_table_copy_from_serialized(void *buffer, size_t size); +/* creates a malloc uniquing table from a serialized representation */ + + +extern void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *num); + /* Convenience to fill buffer with the PCs of the frames, starting with the hot frames; + num: returned number of frames + */ + diff --git a/src/libmalloc/src/base.h b/src/libmalloc/src/base.h new file mode 100644 index 000000000..21fcb7908 --- /dev/null +++ b/src/libmalloc/src/base.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __BASE_H +#define __BASE_H + +#ifndef __has_extension +#define __has_extension(x) 0 +#endif + +#if __has_extension(c_static_assert) +#define MALLOC_STATIC_ASSERT(x, y) _Static_assert((x), y) +#else +#define MALLOC_STATIC_ASSERT(x, y) +#endif + +#define MALLOC_ASSERT(e) ({ \ + if (__builtin_expect(!(e), 0)) { \ + __asm__ __volatile__ (""); \ + __builtin_trap(); \ + } \ +}) + +#define MALLOC_FATAL_ERROR(cause, message) ({ \ + _os_set_crash_log_cause_and_message((cause), "FATAL ERROR - " message); \ + __asm__ __volatile__ (""); \ + __builtin_trap(); \ +}) + +#define MALLOC_PRINTF_FATAL_ERROR(cause, message) ({ \ + malloc_printf("*** FATAL ERROR - " message ".\n"); \ + MALLOC_FATAL_ERROR((cause), message); \ +}) + +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__) +# define __APPLE_API_PRIVATE +# include +# define _COMM_PAGE_VERSION_REQD 9 +# undef __APPLE_API_PRIVATE +#else +# include +#endif + +#if defined(__i386__) || defined(__x86_64__) +// nano vs. magazine have different definitions +// for this cache-line size. +# define MALLOC_CACHE_LINE 128 +# define MALLOC_NANO_CACHE_LINE 64 +#elif defined(__arm__) || defined(__arm64__) +# define MALLOC_CACHE_LINE 64 +# define MALLOC_NANO_CACHE_LINE 64 +#else +# define MALLOC_CACHE_LINE 32 +# define MALLOC_NANO_CACHE_LINE 32 +#endif + +#define MALLOC_CACHE_ALIGN __attribute__ ((aligned (MALLOC_CACHE_LINE) )) +#define MALLOC_NANO_CACHE_ALIGN __attribute__ ((aligned (MALLOC_NANO_CACHE_LINE) )) +#define MALLOC_EXPORT extern __attribute__((visibility("default"))) +#define MALLOC_NOEXPORT __attribute__((visibility("hidden"))) +#define MALLOC_NOINLINE __attribute__((noinline)) +#define MALLOC_INLINE __inline__ +#define MALLOC_ALWAYS_INLINE __attribute__((always_inline)) +#define MALLOC_PACKED __attribute__((packed)) +#define MALLOC_USED __attribute__((used)) +#define MALLOC_UNUSED __attribute__((unused)) +#define CHECK_MAGAZINE_PTR_LOCKED(szone, mag_ptr, fun) {} + +#define SCRIBBLE_BYTE 0xaa /* allocated scribble */ +#define SCRABBLE_BYTE 0x55 /* free()'d scribble */ +#define SCRUBBLE_BYTE 0xdd /* madvise(..., MADV_FREE) scriblle */ + +#define NDEBUG 1 +#define trunc_page_quanta(x) trunc_page((x)) +#define round_page_quanta(x) round_page((x)) +#define vm_page_quanta_size (vm_page_size) +#define vm_page_quanta_shift (vm_page_shift) + +// add a guard page before and after each VM region to help debug +#define MALLOC_ADD_GUARD_PAGES (1 << 0) +// do not protect prelude page +#define MALLOC_DONT_PROTECT_PRELUDE (1 << 1) +// do not protect postlude page +#define MALLOC_DONT_PROTECT_POSTLUDE (1 << 2) +// write 0x55 onto free blocks +#define MALLOC_DO_SCRIBBLE (1 << 3) +// call abort() on any malloc error, such as double free or out of memory. +#define MALLOC_ABORT_ON_ERROR (1 << 4) +// allocate objects such that they may be used with VM purgability APIs +#define MALLOC_PURGEABLE (1 << 5) +// call abort() on malloc errors, but not on out of memory. +#define MALLOC_ABORT_ON_CORRUPTION (1 << 6) + +/* + * msize - a type to refer to the number of quanta of a tiny or small + * allocation. A tiny block with an msize of 3 would be 3 << SHIFT_TINY_QUANTUM + * bytes in size. + */ +typedef unsigned short msize_t; + +typedef unsigned int grain_t; // N.B. wide enough to index all free slots +typedef struct large_entry_s large_entry_t; +typedef struct szone_s szone_t; +typedef struct magazine_s magazine_t; +typedef int mag_index_t; +typedef void *region_t; + +#endif // __BASE_H diff --git a/src/libmalloc/src/bitarray.c b/src/libmalloc/src/bitarray.c index 61dea1653..3e44f455e 100644 --- a/src/libmalloc/src/bitarray.c +++ b/src/libmalloc/src/bitarray.c @@ -28,15 +28,15 @@ // Copyright (c) 2010 Apple. All rights reserved. // -#include "bitarray.h" -#define NDEBUG 1 -#include +#include "internal.h" /******************************** Utilities ***************************/ #define STATIC_INLINE static __inline -STATIC_INLINE unsigned __ffsll(uint64_t xx) { +STATIC_INLINE unsigned +__ffsll(uint64_t xx) +{ #if defined(__LP64__) return __builtin_ffsl(xx); #else @@ -44,171 +44,232 @@ STATIC_INLINE unsigned __ffsll(uint64_t xx) { #endif } -#define BIT_SET(old,bit) ((old) | (1ULL << (bit))) -#define BIT_GET(old,bit) ((old) & (1ULL << (bit))) -#define BIT_ZAP(old,bit) ((old) & ~ (1ULL << (bit))) +#define BIT_SET(old, bit) ((old) | (1ULL << (bit))) +#define BIT_GET(old, bit) ((old) & (1ULL << (bit))) +#define BIT_ZAP(old, bit) ((old) & ~(1ULL << (bit))) // several variants below of bit setting or zapping to generate minimal code // All these do 1 memory read and (maybe) 1 memory write -STATIC_INLINE bool word_get_bit_simple(uint64_t *word, unsigned bit) { - uint64_t old = *word; +STATIC_INLINE bool +word_get_bit_simple(uint64_t *word, unsigned bit) +{ + uint64_t old = *word; return BIT_GET(old, bit) != 0; } -STATIC_INLINE void word_set_bit_simple(uint64_t *word, unsigned bit) { - uint64_t old = *word; +STATIC_INLINE void +word_set_bit_simple(uint64_t *word, unsigned bit) +{ + uint64_t old = *word; *word = BIT_SET(old, bit); } -STATIC_INLINE bool word_set_bit_changed(uint64_t *word, unsigned bit) { +STATIC_INLINE bool +word_set_bit_changed(uint64_t *word, unsigned bit) +{ // returns 1 iff word has changed - uint64_t old = *word; - uint64_t new = BIT_SET(old, bit); - if (old == new) return 0; + uint64_t old = *word; + uint64_t new = BIT_SET(old, bit); + if (old == new) { + return 0; + } *word = new; return 1; } -STATIC_INLINE bool word_set_bit_changed_go_down(uint64_t *word, unsigned bit, bool *was_non_zero) { +STATIC_INLINE bool +word_set_bit_changed_go_down(uint64_t *word, unsigned bit, bool *was_non_zero) +{ // returns 1 iff word changed // sets was_non_zero (when something changed) - uint64_t old = *word; - uint64_t new = BIT_SET(old, bit); - if (old == new) return 0; + uint64_t old = *word; + uint64_t new = BIT_SET(old, bit); + if (old == new) { + return 0; + } *word = new; *was_non_zero = old != 0; return 1; } -STATIC_INLINE bool word_set_bit_go_down(uint64_t *word, unsigned bit) { +STATIC_INLINE bool +word_set_bit_go_down(uint64_t *word, unsigned bit) +{ // returns 1 iff level below should be set too - uint64_t old = *word; - uint64_t new = BIT_SET(old, bit); - if (old == new) return 0; + uint64_t old = *word; + uint64_t new = BIT_SET(old, bit); + if (old == new) { + return 0; + } *word = new; return !old; } -STATIC_INLINE void word_zap_bit_simple(uint64_t *word, unsigned bit) { - uint64_t old = *word; +STATIC_INLINE void +word_zap_bit_simple(uint64_t *word, unsigned bit) +{ + uint64_t old = *word; *word = BIT_ZAP(old, bit); } -STATIC_INLINE bool word_zap_bit_changed(uint64_t *word, unsigned bit) { +STATIC_INLINE bool +word_zap_bit_changed(uint64_t *word, unsigned bit) +{ // returns 1 iff word changed - uint64_t old = *word; - uint64_t new = BIT_ZAP(old, bit); - if (old == new) return 0; + uint64_t old = *word; + uint64_t new = BIT_ZAP(old, bit); + if (old == new) { + return 0; + } *word = new; return 1; } -STATIC_INLINE bool word_zap_bit_changed_go_down(uint64_t *word, unsigned bit, bool *is_now_zero) { +STATIC_INLINE bool +word_zap_bit_changed_go_down(uint64_t *word, unsigned bit, bool *is_now_zero) +{ // returns 1 iff word changed // sets is_now_zero (when something changed) - uint64_t old = *word; - uint64_t new = BIT_ZAP(old, bit); - if (old == new) return 0; + uint64_t old = *word; + uint64_t new = BIT_ZAP(old, bit); + if (old == new) { + return 0; + } *word = new; - *is_now_zero = ! new; + *is_now_zero = !new; return 1; } -STATIC_INLINE bool word_zap_bit_go_down(uint64_t *word, unsigned bit) { +STATIC_INLINE bool +word_zap_bit_go_down(uint64_t *word, unsigned bit) +{ // returns 1 iff level below might require a bit-zeroing - uint64_t old = *word; - uint64_t new = BIT_ZAP(old, bit); - if (old == new) return 0; + uint64_t old = *word; + uint64_t new = BIT_ZAP(old, bit); + if (old == new) { + return 0; + } *word = new; return !new; } /******************************** Helpers ***************************/ -#define NB 9 // number of bits we process at once +#define NB 9 // number of bits we process at once // must be at least 6 (64-bit) and 9 seems the best on x86 -#define MASKNB ((1 << NB) - 1) // to just keep these bits +#define MASKNB ((1 << NB) - 1) // to just keep these bits #define NUM_64b (1 << (NB - 6)) // number of 64-bit words we process at once // number of uint64_t of summaries -#define LEVEL0 (NUM_64b) -#define LEVEL1 (LEVEL0 + (1 << NB)*NUM_64b) -#define LEVEL2 (LEVEL1 + (1 << (NB+NB))*NUM_64b) -#define LEVEL3 (LEVEL2 + (1 << (NB+NB+NB))*NUM_64b) +#define LEVEL0 (NUM_64b) +#define LEVEL1 (LEVEL0 + (1 << NB) * NUM_64b) +#define LEVEL2 (LEVEL1 + (1 << (NB + NB)) * NUM_64b) +#define LEVEL3 (LEVEL2 + (1 << (NB + NB + NB)) * NUM_64b) -#define MAX_LEVEL 5 +#define MAX_LEVEL 5 -static const unsigned levels_num_words[] = {LEVEL0, LEVEL1, LEVEL2, LEVEL3}; // this encodes the number of words reserved for the bitmap summaries at various levels +static const unsigned levels_num_words[] = { + LEVEL0, LEVEL1, LEVEL2, LEVEL3}; // this encodes the number of words reserved for the bitmap summaries at various levels -STATIC_INLINE bool GET_SIMPLE(uint64_t *word, unsigned bit) { +STATIC_INLINE bool +GET_SIMPLE(uint64_t *word, unsigned bit) +{ return word_get_bit_simple(word + (bit >> 6), bit & 63); } -STATIC_INLINE void SET_SIMPLE(uint64_t *word, unsigned bit) { +STATIC_INLINE void +SET_SIMPLE(uint64_t *word, unsigned bit) +{ word_set_bit_simple(word + (bit >> 6), bit & 63); } -STATIC_INLINE bool SET_CHANGED(uint64_t *word, unsigned bit) { +STATIC_INLINE bool +SET_CHANGED(uint64_t *word, unsigned bit) +{ // returns 1 iff word changed return word_set_bit_changed(word + (bit >> 6), bit & 63); } -STATIC_INLINE bool SET_CHANGED_GO_DOWN(uint64_t *word, unsigned bit, bool *was_non_zero) { +STATIC_INLINE bool +SET_CHANGED_GO_DOWN(uint64_t *word, unsigned bit, bool *was_non_zero) +{ // returns 1 iff word changed // sets was_non_zero (when something changed) return word_set_bit_changed_go_down(word + (bit >> 6), bit & 63, was_non_zero); } -STATIC_INLINE bool SET_GO_DOWN(uint64_t *word, unsigned bit) { +STATIC_INLINE bool +SET_GO_DOWN(uint64_t *word, unsigned bit) +{ // returns 1 iff level below should be set too return word_set_bit_go_down(word + (bit >> 6), bit & 63); } -STATIC_INLINE void ZAP_SIMPLE(uint64_t *word, unsigned bit) { +STATIC_INLINE void +ZAP_SIMPLE(uint64_t *word, unsigned bit) +{ return word_zap_bit_simple(word + (bit >> 6), bit & 63); } -STATIC_INLINE bool ZAP_CHANGED(uint64_t *word, unsigned bit) { +STATIC_INLINE bool +ZAP_CHANGED(uint64_t *word, unsigned bit) +{ // returns 1 iff word changed return word_zap_bit_changed(word + (bit >> 6), bit & 63); } -STATIC_INLINE bool all_zeros(uint64_t *words) { +STATIC_INLINE bool +all_zeros(uint64_t *words) +{ for (unsigned w = 0; w < NUM_64b; w++) { - if (words[w]) return 0; + if (words[w]) { + return 0; + } } return 1; } -STATIC_INLINE bool ZAP_CHANGED_GO_DOWN(uint64_t *word, unsigned bit, bool *is_now_zero) { +STATIC_INLINE bool +ZAP_CHANGED_GO_DOWN(uint64_t *word, unsigned bit, bool *is_now_zero) +{ // returns 1 iff word changed // sets is_now_zero (when something changed) bool changed = word_zap_bit_changed_go_down(word + (bit >> 6), bit & 63, is_now_zero); if (changed && (NUM_64b != 1)) { // One component went entirely zero, now examine all components in the level - if (!all_zeros(word)) *is_now_zero = 0; + if (!all_zeros(word)) { + *is_now_zero = 0; + } } return changed; } -STATIC_INLINE bool ZAP_GO_DOWN(uint64_t *word, unsigned bit) { +STATIC_INLINE bool +ZAP_GO_DOWN(uint64_t *word, unsigned bit) +{ // returns 1 iff level below should be changed too bool changed = word_zap_bit_go_down(word + (bit >> 6), bit & 63); if (changed && (NUM_64b != 1)) { // One component went entirely zero, now examine all components in the level - if (!all_zeros(word)) return 0; + if (!all_zeros(word)) { + return 0; + } } return changed; } -STATIC_INLINE unsigned FFS(uint64_t *word) { - // does NUM_64b memory reads, at most -#if NB==6 +STATIC_INLINE unsigned +FFS(uint64_t *word) +{ +// does NUM_64b memory reads, at most +#if NB == 6 return __ffsll(*word); #else for (unsigned w = 0; w < NUM_64b; w++) { - unsigned f = __ffsll(word[w]); - if (f) return f + (w << 6); + unsigned f = __ffsll(word[w]); + if (f) { + return f + (w << 6); + } } return 0; #endif @@ -216,231 +277,325 @@ STATIC_INLINE unsigned FFS(uint64_t *word) { /******************************** Entry Points ***************************/ -size_t bitarray_size(unsigned log_size) { +size_t +bitarray_size(unsigned log_size) +{ assert(log_size <= MAX_LEVEL * NB); - unsigned num = NUM_64b; + unsigned num = NUM_64b; if (log_size > NB) { - unsigned level = (log_size - NB - 1) / NB; + unsigned level = (log_size - NB - 1) / NB; num = levels_num_words[level] + (1 << (log_size - 6)); } return num * sizeof(uint64_t); } -bitarray_t bitarray_create(unsigned log_size) { +bitarray_t +bitarray_create(unsigned log_size) +{ return calloc(1, bitarray_size(log_size)); } -bool bitarray_get(bitarray_t bits, unsigned log_size, index_t index) { +bool +bitarray_get(bitarray_t bits, unsigned log_size, index_t index) +{ assert(log_size <= MAX_LEVEL * NB); assert(index < (1 << log_size)); - if (log_size <= NB) return GET_SIMPLE(bits, index); - unsigned level = (log_size - NB - 1) / NB; - unsigned bit; - bit = index & MASKNB; index >>= NB; - return GET_SIMPLE(bits + levels_num_words[level] + index*NUM_64b, bit); + if (log_size <= NB) { + return GET_SIMPLE(bits, index); + } + unsigned level = (log_size - NB - 1) / NB; + unsigned bit; + bit = index & MASKNB; + index >>= NB; + return GET_SIMPLE(bits + levels_num_words[level] + index * NUM_64b, bit); } -bool bitarray_set(bitarray_t bits, unsigned log_size, index_t index) { +bool +bitarray_set(bitarray_t bits, unsigned log_size, index_t index) +{ // returns whether changed assert(log_size <= MAX_LEVEL * NB); assert(index < (1 << log_size)); - if (log_size <= NB) return SET_CHANGED(bits, index); - unsigned level = (log_size - NB - 1) / NB; - bool was_non_zero; - unsigned bit; - bit = index & MASKNB; index >>= NB; + if (log_size <= NB) { + return SET_CHANGED(bits, index); + } + unsigned level = (log_size - NB - 1) / NB; + bool was_non_zero; + unsigned bit; + bit = index & MASKNB; + index >>= NB; // printf("SET_CHANGED_GO_DOWN(bits + %d, %d,…)\n", levels_num_words[level] + index, bit); - if (!SET_CHANGED_GO_DOWN(bits + levels_num_words[level] + index*NUM_64b, bit, &was_non_zero)) return 0; - if (was_non_zero) return 1; + if (!SET_CHANGED_GO_DOWN(bits + levels_num_words[level] + index * NUM_64b, bit, &was_non_zero)) { + return 0; + } + if (was_non_zero) { + return 1; + } switch (level) { - case 3: - bit = index & MASKNB; index >>= NB; - if (!SET_GO_DOWN(bits + LEVEL2 + index*NUM_64b, bit)) return 1; - /* no break */ - case 2: - bit = index & MASKNB; index >>= NB; - if (!SET_GO_DOWN(bits + LEVEL1 + index*NUM_64b, bit)) return 1; - /* no break */ - case 1: - bit = index & MASKNB; index >>= NB; - if (!SET_GO_DOWN(bits + LEVEL0 + index*NUM_64b, bit)) return 1; - /* no break */ - case 0: - SET_SIMPLE(bits, index & MASKNB); + case 3: + bit = index & MASKNB; + index >>= NB; + if (!SET_GO_DOWN(bits + LEVEL2 + index * NUM_64b, bit)) { + return 1; + } + /* no break */ + case 2: + bit = index & MASKNB; + index >>= NB; + if (!SET_GO_DOWN(bits + LEVEL1 + index * NUM_64b, bit)) { + return 1; + } + /* no break */ + case 1: + bit = index & MASKNB; + index >>= NB; + if (!SET_GO_DOWN(bits + LEVEL0 + index * NUM_64b, bit)) { return 1; - default: abort(); + } + /* no break */ + case 0: + SET_SIMPLE(bits, index & MASKNB); + return 1; + default: + MALLOC_FATAL_ERROR(level, "invalid bitarray level"); } } -bool bitarray_zap(bitarray_t bits, unsigned log_size, index_t index) { +bool +bitarray_zap(bitarray_t bits, unsigned log_size, index_t index) +{ assert(log_size <= MAX_LEVEL * NB); assert(index < (1 << log_size)); - if (log_size <= NB) return ZAP_CHANGED(bits, index); - unsigned level = (log_size - NB - 1) / NB; - bool is_now_zero; - unsigned bit; - bit = index & MASKNB; index >>= NB; - if (!ZAP_CHANGED_GO_DOWN(bits + levels_num_words[level] + index*NUM_64b, bit, &is_now_zero)) return 0; - if (!is_now_zero) return 1; + if (log_size <= NB) { + return ZAP_CHANGED(bits, index); + } + unsigned level = (log_size - NB - 1) / NB; + bool is_now_zero; + unsigned bit; + bit = index & MASKNB; + index >>= NB; + if (!ZAP_CHANGED_GO_DOWN(bits + levels_num_words[level] + index * NUM_64b, bit, &is_now_zero)) { + return 0; + } + if (!is_now_zero) { + return 1; + } switch (level) { - case 3: - bit = index & MASKNB; index >>= NB; - if (!ZAP_GO_DOWN(bits + LEVEL2 + index*NUM_64b, bit)) return 1; - /* no break */ - case 2: - bit = index & MASKNB; index >>= NB; - if (!ZAP_GO_DOWN(bits + LEVEL1 + index*NUM_64b, bit)) return 1; - /* no break */ - case 1: - bit = index & MASKNB; index >>= NB; - if (!ZAP_GO_DOWN(bits + LEVEL0 + index*NUM_64b, bit)) return 1; - /* no break */ - case 0: - ZAP_SIMPLE(bits, index & MASKNB); + case 3: + bit = index & MASKNB; + index >>= NB; + if (!ZAP_GO_DOWN(bits + LEVEL2 + index * NUM_64b, bit)) { return 1; - default: abort(); + } + /* no break */ + case 2: + bit = index & MASKNB; + index >>= NB; + if (!ZAP_GO_DOWN(bits + LEVEL1 + index * NUM_64b, bit)) { + return 1; + } + /* no break */ + case 1: + bit = index & MASKNB; + index >>= NB; + if (!ZAP_GO_DOWN(bits + LEVEL0 + index * NUM_64b, bit)) { + return 1; + } + /* no break */ + case 0: + ZAP_SIMPLE(bits, index & MASKNB); + return 1; + default: + MALLOC_FATAL_ERROR(level, "invalid bitarray level"); } } // Note in the following macro that "words" and "base" are variables being written -#define ADJUST_OFFSET_FOR_FFS(words, base, current_level) { \ -words += (1 << (NB * current_level)) * NUM_64b; \ -base = (base << NB) + FFS(words + base*NUM_64b) - 1; \ -} +#define ADJUST_OFFSET_FOR_FFS(words, base, current_level) \ + { \ + words += (1 << (NB * current_level)) * NUM_64b; \ + base = (base << NB) + FFS(words + base * NUM_64b) - 1; \ + } // Note in the following macro that "words" and "base" are variables being written -#define ADJUST_OFFSET_FOR_FFS_ACROSS_SUMMARIES(words, base, level) {\ -switch (level) { \ -case 4: \ -ADJUST_OFFSET_FOR_FFS(words, base, 0); \ -ADJUST_OFFSET_FOR_FFS(words, base, 1); \ -ADJUST_OFFSET_FOR_FFS(words, base, 2); \ -break; \ -case 3: \ -ADJUST_OFFSET_FOR_FFS(words, base, 0); \ -ADJUST_OFFSET_FOR_FFS(words, base, 1); \ -break; \ -case 2: \ -ADJUST_OFFSET_FOR_FFS(words, base, 0); \ -break; \ -case 1: \ -break; \ -default: abort(); \ -} \ -} +#define ADJUST_OFFSET_FOR_FFS_ACROSS_SUMMARIES(words, base, level) \ + { \ + switch (level) { \ + case 4: \ + ADJUST_OFFSET_FOR_FFS(words, base, 0); \ + ADJUST_OFFSET_FOR_FFS(words, base, 1); \ + ADJUST_OFFSET_FOR_FFS(words, base, 2); \ + break; \ + case 3: \ + ADJUST_OFFSET_FOR_FFS(words, base, 0); \ + ADJUST_OFFSET_FOR_FFS(words, base, 1); \ + break; \ + case 2: \ + ADJUST_OFFSET_FOR_FFS(words, base, 0); \ + break; \ + case 1: \ + break; \ + default: \ + MALLOC_FATAL_ERROR(level, "invalid bitarray level"); \ + } \ + } // Note in the following macro that "ix" and "bit" are variables being written -#define ZAP_SUMMARIES(bits, ix, level) {\ -unsigned bit; \ -switch (level) { \ -case 3: \ -bit = ix & MASKNB; ix >>= NB; \ -if (!ZAP_GO_DOWN(bits + LEVEL2 + ix*NUM_64b, bit)) break; \ -case 2: \ -bit = ix & MASKNB; ix >>= NB; \ -if (!ZAP_GO_DOWN(bits + LEVEL1 + ix*NUM_64b, bit)) break; \ -case 1: \ -bit = ix & MASKNB; ix >>= NB; \ -if (!ZAP_GO_DOWN(bits + LEVEL0 + ix*NUM_64b, bit)) break; \ -case 0: \ -ZAP_SIMPLE(bits, ix & MASKNB); \ -break; \ -default: abort(); \ -} \ -} - -index_t bitarray_first_set(const bitarray_t bits, unsigned log_size) { +#define ZAP_SUMMARIES(bits, ix, level) \ + { \ + unsigned bit; \ + switch (level) { \ + case 3: \ + bit = ix & MASKNB; \ + ix >>= NB; \ + if (!ZAP_GO_DOWN(bits + LEVEL2 + ix * NUM_64b, bit)) { \ + break; \ + } \ + case 2: \ + bit = ix & MASKNB; \ + ix >>= NB; \ + if (!ZAP_GO_DOWN(bits + LEVEL1 + ix * NUM_64b, bit)) { \ + break; \ + } \ + case 1: \ + bit = ix & MASKNB; \ + ix >>= NB; \ + if (!ZAP_GO_DOWN(bits + LEVEL0 + ix * NUM_64b, bit)) { \ + break; \ + } \ + case 0: \ + ZAP_SIMPLE(bits, ix &MASKNB); \ + break; \ + default: \ + MALLOC_FATAL_ERROR(level, "invalid bitarray level"); \ + } \ + } + +index_t +bitarray_first_set(const bitarray_t bits, unsigned log_size) +{ // return 0 if none set assert(log_size <= MAX_LEVEL * NB); - uint64_t *words = bits; - unsigned bit = FFS(words); - if (log_size <= NB) return bit; - if (!bit) return 0; - unsigned level = (log_size - 1) / NB; - index_t base = bit - 1; // offset, in number of uin64_t words + uint64_t *words = bits; + unsigned bit = FFS(words); + if (log_size <= NB) { + return bit; + } + if (!bit) { + return 0; + } + unsigned level = (log_size - 1) / NB; + index_t base = bit - 1; // offset, in number of uin64_t words ADJUST_OFFSET_FOR_FFS_ACROSS_SUMMARIES(words, base, level); - words += (1 << (NB * (level-1))) * NUM_64b; - base = (base << NB) + FFS(words + base*NUM_64b) - 1; - return base+1; //+1 because bit N is encoded as N+1 + words += (1 << (NB * (level - 1))) * NUM_64b; + base = (base << NB) + FFS(words + base * NUM_64b) - 1; + return base + 1; //+1 because bit N is encoded as N+1 } -bool bitarray_zap_first_set(bitarray_t bits, unsigned log_size, index_t *index) { +bool +bitarray_zap_first_set(bitarray_t bits, unsigned log_size, index_t *index) +{ assert(log_size <= MAX_LEVEL * NB); - uint64_t *words = bits; - index_t ix = FFS(words); - if (!ix) return 0; - unsigned level = (log_size - 1) / NB; - if (! level) { + uint64_t *words = bits; + index_t ix = FFS(words); + if (!ix) { + return 0; + } + unsigned level = (log_size - 1) / NB; + if (!level) { ix--; *index = ix; ZAP_SIMPLE(bits, ix); return 1; } - index_t base = ix - 1; // offset, in number of uin64_t words + index_t base = ix - 1; // offset, in number of uin64_t words ADJUST_OFFSET_FOR_FFS_ACROSS_SUMMARIES(words, base, level); - words += (1 << (NB * (level-1))) * NUM_64b; - base = (base << NB) + FFS(words + base*NUM_64b) - 1; + words += (1 << (NB * (level - 1))) * NUM_64b; + base = (base << NB) + FFS(words + base * NUM_64b) - 1; ix = base; *index = ix; assert(ix < (1 << log_size)); level--; - bool is_now_zero; - unsigned bit; - bit = ix & MASKNB; ix >>= NB; - if (!ZAP_CHANGED_GO_DOWN(bits + levels_num_words[level] + ix*NUM_64b, bit, &is_now_zero)) return 1; - if (!is_now_zero) return 1; + bool is_now_zero; + unsigned bit; + bit = ix & MASKNB; + ix >>= NB; + if (!ZAP_CHANGED_GO_DOWN(bits + levels_num_words[level] + ix * NUM_64b, bit, &is_now_zero)) { + return 1; + } + if (!is_now_zero) { + return 1; + } ZAP_SUMMARIES(bits, ix, level); return 1; } -static unsigned FFS_and_zap_word(uint64_t *words, unsigned max, index_t *indices, index_t to_be_added) { +static unsigned +FFS_and_zap_word(uint64_t *words, unsigned max, index_t *indices, index_t to_be_added) +{ // returns the number of bits zapped - unsigned zapped = 0; + unsigned zapped = 0; for (unsigned w = 0; w < NUM_64b; w++) { - uint64_t word = words[w]; - if (!word) continue; + uint64_t word = words[w]; + if (!word) { + continue; + } while (1) { - unsigned f = __ffsll(word); + unsigned f = __ffsll(word); assert(f); f--; // printf("%d ", f); indices[zapped++] = f + (w << 6) + to_be_added; word = BIT_ZAP(word, f); - if (!word) break; - if (zapped >= max) break; + if (!word) { + break; + } + if (zapped >= max) { + break; + } } words[w] = word; // printf("word=%lld \n", word); - if (zapped >= max) break; + if (zapped >= max) { + break; + } } return zapped; } -unsigned bitarray_zap_first_set_multiple(bitarray_t bits, unsigned log_size, unsigned max, index_t *indices) { +unsigned +bitarray_zap_first_set_multiple(bitarray_t bits, unsigned log_size, unsigned max, index_t *indices) +{ assert(log_size <= MAX_LEVEL * NB); - if (log_size <= NB) return FFS_and_zap_word(bits, max, indices, 0); - unsigned zapped = 0; - unsigned level = (log_size - 1) / NB; + if (log_size <= NB) { + return FFS_and_zap_word(bits, max, indices, 0); + } + unsigned zapped = 0; + unsigned level = (log_size - 1) / NB; while (zapped < max) { - /* the lines in loop could be written just as: - // if (! bitarray_zap_first_set(bits, log_size, indices + zapped)) break; - // zapped++; - but the code is faster because it wont go up and down in the summaries */ - uint64_t *words = bits; - index_t ix = FFS(words); - if (!ix) return zapped; // if the top level summary is 0, no bit is set - index_t base = ix - 1; // offset, in number of uin64_t words + /* + * the lines in loop could be written just as: + * if (! bitarray_zap_first_set(bits, log_size, indices + zapped)) break; + * zapped++; + * but the code is faster because it wont go up and down in the summaries + */ + uint64_t *words = bits; + index_t ix = FFS(words); + if (!ix) { + return zapped; // if the top level summary is 0, no bit is set + } + index_t base = ix - 1; // offset, in number of uin64_t words ADJUST_OFFSET_FOR_FFS_ACROSS_SUMMARIES(words, base, level); - words += (1 << (NB * (level-1))) * NUM_64b; // the beginning of the non-summarized bitarray - uint64_t *word = words + base*NUM_64b; // the first non-zero word + words += (1 << (NB * (level - 1))) * NUM_64b; // the beginning of the non-summarized bitarray + uint64_t *word = words + base * NUM_64b; // the first non-zero word ix = base; // the idea here is that we zap a whole bunch of bits at once - unsigned z = FFS_and_zap_word(word, max - zapped, indices + zapped, base << NB); + unsigned z = FFS_and_zap_word(word, max - zapped, indices + zapped, base << NB); assert(z); zapped += z; if ((zapped < max) /* entire word was zapped */ || all_zeros(word) /* partial zap, a priori */) { // adjust summaries to reflect all zeros in the bitarray - ZAP_SUMMARIES(bits, ix, level-1); + ZAP_SUMMARIES(bits, ix, level - 1); } } return zapped; @@ -450,14 +605,14 @@ unsigned bitarray_zap_first_set_multiple(bitarray_t bits, unsigned log_size, uns /******************************** Test and debug utilities ***************************/ static void print_ones(const uint64_t *bits, unsigned num_big_words) { - unsigned base = 0; - unsigned num = num_big_words * NUM_64b; + unsigned base = 0; + unsigned num = num_big_words * NUM_64b; // printf("In print_ones; num=%d, num_big=%d \n", num, num_big_words); while (num--) { - uint64_t word = *(bits++); + uint64_t word = *(bits++); if (word) { for (unsigned bit = 0; bit < 64; bit++) { - if (word & (1ULL << bit)) printf("%d ", base + bit); + if (word & (1ULL << bit)) { printf("%d ", base + bit); } } } base += 64; @@ -467,18 +622,18 @@ static void print_ones(const uint64_t *bits, unsigned num_big_words) { void bitarray_print(bitarray_t bits, unsigned log_size) { assert(log_size <= MAX_LEVEL * NB); printf("bitarray %p log_size=%d\n", bits, log_size); - if (log_size > 4*NB) { + if (log_size > 4 * NB) { printf("Level 4: "); print_ones(bits, 1); printf("\n"); printf("Level 3: "); print_ones(bits + LEVEL0, 1 << NB); printf("\n"); printf("Level 2: "); print_ones(bits + LEVEL1, 1 << NB); printf("\n"); printf("Level 1: "); print_ones(bits + LEVEL2, 1 << NB); printf("\n"); printf("Level 0: "); print_ones(bits + LEVEL3, 1 << (log_size - NB)); printf("\n"); - } else if (log_size > 3*NB) { + } else if (log_size > 3 * NB) { printf("Level 3: "); print_ones(bits, 1); printf("\n"); printf("Level 2: "); print_ones(bits + LEVEL0, 1 << NB); printf("\n"); printf("Level 1: "); print_ones(bits + LEVEL1, 1 << NB); printf("\n"); printf("Level 0: "); print_ones(bits + LEVEL2, 1 << (log_size - NB)); printf("\n"); - } else if (log_size > 2*NB) { + } else if (log_size > 2 * NB) { printf("Level 2: "); print_ones(bits, 1); printf("\n"); printf("Level 1: "); print_ones(bits + LEVEL0, 1 << NB); printf("\n"); printf("Level 0: "); print_ones(bits + LEVEL1, 1 << (log_size - NB)); printf("\n"); @@ -493,14 +648,14 @@ void bitarray_print(bitarray_t bits, unsigned log_size) { bool compare_to_truth(bitarray_t bits, unsigned nbits, const bool *truth) { uint64_t *start = bits; if (nbits > NB) { - unsigned level = (nbits - NB - 1) / NB; + unsigned level = (nbits - NB - 1) / NB; start += levels_num_words[level]; } - bool ok = 1; + bool ok = 1; for (unsigned bit = 0; bit < (1 << nbits); bit++) { - bool expected = truth[bit]; - uint64_t word = start[bit >> 6]; - bool actual = (word >> (bit & 63)) & 1; + bool expected = truth[bit]; + uint64_t word = start[bit >> 6]; + bool actual = (word >> (bit & 63)) & 1; if (actual != expected) { printf("*** # for bit %d, expected=%d actual=%d\n", bit, expected, actual); ok = 0; @@ -511,7 +666,7 @@ bool compare_to_truth(bitarray_t bits, unsigned nbits, const bool *truth) { unsigned first_set_in_truth(const bool *truth, unsigned log_size) { for (unsigned bit = 0; bit < (1 << log_size); bit++) { - if (truth[bit]) return bit+1; + if (truth[bit]) { return bit + 1; } } return 0; } @@ -519,7 +674,7 @@ unsigned first_set_in_truth(const bool *truth, unsigned log_size) { void truth_print(const bool *truth, unsigned log_size) { printf("Truth: "); for (unsigned bit = 0; bit < (1 << log_size); bit++) { - if (truth[bit]) printf("%d ", bit); + if (truth[bit]) { printf("%d ", bit); } } printf("\n"); } diff --git a/src/libmalloc/src/bitarray.h b/src/libmalloc/src/bitarray.h index 51d90a166..d92eb2e80 100644 --- a/src/libmalloc/src/bitarray.h +++ b/src/libmalloc/src/bitarray.h @@ -20,16 +20,9 @@ * * @APPLE_LICENSE_HEADER_END@ */ -// -// bitarray.h -// bitarray -// -// Created by Bertrand Serlet on 9/26/10. -// Copyright (c) 2010 Apple. All rights reserved. -// -#include -#include +#ifndef __BITARRAY_H +#define __BITARRAY_H typedef uint64_t *bitarray_t; // array of bits, assumed to be mostly 0 typedef uint32_t index_t; // we limit the number of bits to be a 32-bit quantity @@ -62,3 +55,49 @@ extern unsigned bitarray_zap_first_set_multiple(bitarray_t bits, unsigned log_si // finds all the bits set, up to max, and zaps each and sets the index for each // returns number zapped +static MALLOC_INLINE MALLOC_ALWAYS_INLINE void +BITARRAY_SET(uint32_t *bits, msize_t index) +{ + // index >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array + // (index >> 5) << 1 identifies the uint32_t allowing for the actual interleaving + bits[(index >> 5) << 1] |= (1 << (index & 31)); +} + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE void +BITARRAY_CLR(uint32_t *bits, msize_t index) +{ + bits[(index >> 5) << 1] &= ~(1 << (index & 31)); +} + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE boolean_t +BITARRAY_BIT(uint32_t *bits, msize_t index) +{ + return ((bits[(index >> 5) << 1]) >> (index & 31)) & 1; +} + +/* Macros used to manipulate the uint32_t quantity mag_bitmap. */ + +/* BITMAPV variants are used by tiny. */ +#if defined(__LP64__) +// assert(NUM_SLOTS == 64) in which case (slot >> 5) is either 0 or 1 +#define BITMAPV_SET(bitmap, slot) (bitmap[(slot) >> 5] |= 1 << ((slot)&31)) +#define BITMAPV_CLR(bitmap, slot) (bitmap[(slot) >> 5] &= ~(1 << ((slot)&31))) +#define BITMAPV_BIT(bitmap, slot) ((bitmap[(slot) >> 5] >> ((slot)&31)) & 1) +#define BITMAPV_CTZ(bitmap) (__builtin_ctzl(bitmap)) +#else +// assert(NUM_SLOTS == 32) in which case (slot >> 5) is always 0, so code it that way +#define BITMAPV_SET(bitmap, slot) (bitmap[0] |= 1 << (slot)) +#define BITMAPV_CLR(bitmap, slot) (bitmap[0] &= ~(1 << (slot))) +#define BITMAPV_BIT(bitmap, slot) ((bitmap[0] >> (slot)) & 1) +#define BITMAPV_CTZ(bitmap) (__builtin_ctz(bitmap)) +#endif + +/* BITMAPN is used by small. (slot >> 5) takes on values from 0 to 7. */ +#define BITMAPN_SET(bitmap, slot) (bitmap[(slot) >> 5] |= 1 << ((slot)&31)) +#define BITMAPN_CLR(bitmap, slot) (bitmap[(slot) >> 5] &= ~(1 << ((slot)&31))) +#define BITMAPN_BIT(bitmap, slot) ((bitmap[(slot) >> 5] >> ((slot)&31)) & 1) + +/* returns bit # of least-significant one bit, starting at 0 (undefined if !bitmap) */ +#define BITMAP32_CTZ(bitmap) (__builtin_ctz(bitmap[0])) + +#endif // __BITARRAY_H diff --git a/src/libmalloc/src/debug.h b/src/libmalloc/src/debug.h new file mode 100644 index 000000000..66075dc96 --- /dev/null +++ b/src/libmalloc/src/debug.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __DEBUG_H +#define __DEBUG_H + +// set to one to debug malloc itself +#define DEBUG_MALLOC 0 +// set to one to debug malloc client +#define DEBUG_CLIENT 0 +#define DEBUG_MADVISE 0 + +#if DEBUG_MALLOC +# warning DEBUG_MALLOC ENABLED +# undef MALLOC_INLINE +# undef MALLOC_UNUSED +# undef MALLOC_ALWAYS_INLINE +# undef CHECK_MAGAZINE_PTR_LOCKED + +# define MALLOC_INLINE +# define MALLOC_UNUSED +# define MALLOC_ALWAYS_INLINE +# define CHECK_MAGAZINE_PTR_LOCKED(szone, mag_ptr, fun) \ + do { \ + if (TRY_LOCK(mag_ptr->magazine_lock)) { \ + malloc_printf("*** magazine_lock was not set %p in %s\n", \ + mag_ptr->magazine_lock, fun); \ + } \ + } while (0) +#endif // DEBUG_MALLOC + +#if DEBUG_MALLOC || DEBUG_CLIENT +# define CHECK(szone, fun) \ + if ((szone)->debug_flags & CHECK_REGIONS) { \ + szone_check_all(szone, fun) \ + } +#else // DEBUG_MALLOC || DEBUG_CLIENT +# define CHECK(szone, fun) \ + do {} while (0) +#endif // DEBUG_MALLOC || DEBUG_CLIENT + +#endif // __DEBUG_H diff --git a/src/libmalloc/src/empty.s b/src/libmalloc/src/empty.s new file mode 100644 index 000000000..e5c7a3d52 --- /dev/null +++ b/src/libmalloc/src/empty.s @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * This file exists to force clang+ld to produce an link-time optimised + * master object file that contains no bitcode when it is laid down on + * disk. + * + * Adding a non-LTO assembly file to the link step forces ld to perform + * LTO and produce the master object file. + */ + +empty: + nop diff --git a/src/libmalloc/src/frozen_malloc.c b/src/libmalloc/src/frozen_malloc.c new file mode 100644 index 000000000..be1ae6183 --- /dev/null +++ b/src/libmalloc/src/frozen_malloc.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "internal.h" + +/********* Support code for emacs unexec ************/ + +/* History of freezedry version numbers: + * + * 1) Old malloc (before the scalable malloc implementation in this file + * existed). + * 2) Original freezedrying code for scalable malloc. This code was apparently + * based on the old freezedrying code and was fundamentally flawed in its + * assumption that tracking allocated memory regions was adequate to fake + * operations on freezedried memory. This doesn't work, since scalable + * malloc does not store flags in front of large page-aligned allocations. + * 3) Original szone-based freezedrying code. + * 4) Fresher malloc with tiny zone + * 5) 32/64bit compatible malloc + * 6) Metadata within 1MB and 8MB region for tiny and small + * + * No version backward compatibility is provided, but the version number does + * make it possible for malloc_jumpstart() to return an error if the application + * was freezedried with an older version of malloc. + */ +#define MALLOC_FREEZEDRY_VERSION 6 + +typedef struct { + unsigned version; + unsigned nszones; + szone_t *szones; +} malloc_frozen; + +static void * +frozen_malloc(szone_t *zone, size_t new_size) +{ + return malloc(new_size); +} + +static void * +frozen_calloc(szone_t *zone, size_t num_items, size_t size) +{ + return calloc(num_items, size); +} + +static void * +frozen_valloc(szone_t *zone, size_t new_size) +{ + return valloc(new_size); +} + +static void * +frozen_realloc(szone_t *zone, void *ptr, size_t new_size) +{ + size_t old_size = szone_size(zone, ptr); + void *new_ptr; + + if (new_size <= old_size) { + return ptr; + } + new_ptr = malloc(new_size); + if (old_size > 0) { + memcpy(new_ptr, ptr, old_size); + } + return new_ptr; +} + +static void +frozen_free(szone_t *zone, void *ptr) +{ +} + +static void +frozen_destroy(szone_t *zone) +{ +} + +/********* Pseudo-private API for emacs unexec ************/ + +/* + * malloc_freezedry() records all of the szones in use, so that they can be + * partially reconstituted by malloc_jumpstart(). Due to the differences + * between reconstituted memory regions and those created by the szone code, + * care is taken not to reallocate from the freezedried memory, except in the + * case of a non-growing realloc(). + * + * Due to the flexibility provided by the zone registration mechanism, it is + * impossible to implement generic freezedrying for any zone type. This code + * only handles applications that use the szone allocator, so malloc_freezedry() + * returns 0 (error) if any non-szone zones are encountered. + */ + +uintptr_t +malloc_freezedry(void) +{ + extern unsigned malloc_num_zones; + extern malloc_zone_t **malloc_zones; + malloc_frozen *data; + unsigned i; + + /* Allocate space in which to store the freezedry state. */ + data = (malloc_frozen *)malloc(sizeof(malloc_frozen)); + + /* Set freezedry version number so that malloc_jumpstart() can check for compatibility. */ + data->version = MALLOC_FREEZEDRY_VERSION; + + /* Allocate the array of szone pointers. */ + data->nszones = malloc_num_zones; + data->szones = (szone_t *)calloc(malloc_num_zones, sizeof(szone_t)); + + /* + * Fill in the array of szone structures. They are copied rather than + * referenced, since the originals are likely to be clobbered during malloc + * initialization. + */ + for (i = 0; i < malloc_num_zones; i++) { + if (strcmp(malloc_zones[i]->zone_name, "DefaultMallocZone")) { + /* Unknown zone type. */ + free(data->szones); + free(data); + return 0; + } + memcpy(&data->szones[i], malloc_zones[i], sizeof(szone_t)); + } + + return ((uintptr_t)data); +} + +int +malloc_jumpstart(uintptr_t cookie) +{ + malloc_frozen *data = (malloc_frozen *)cookie; + unsigned i; + + if (data->version != MALLOC_FREEZEDRY_VERSION) { + /* Unsupported freezedry version. */ + return 1; + } + + for (i = 0; i < data->nszones; i++) { + /* Set function pointers. Even the functions that stay the same must be + * set, since there are no guarantees that they will be mapped to the + * same addresses. */ + data->szones[i].basic_zone.size = (void *)szone_size; + data->szones[i].basic_zone.malloc = (void *)frozen_malloc; + data->szones[i].basic_zone.calloc = (void *)frozen_calloc; + data->szones[i].basic_zone.valloc = (void *)frozen_valloc; + data->szones[i].basic_zone.free = (void *)frozen_free; + data->szones[i].basic_zone.realloc = (void *)frozen_realloc; + data->szones[i].basic_zone.destroy = (void *)frozen_destroy; + data->szones[i].basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; + + /* Register the freezedried zone. */ + malloc_zone_register(&data->szones[i].basic_zone); + } + + return 0; +} diff --git a/src/libmalloc/src/frozen_malloc.h b/src/libmalloc/src/frozen_malloc.h new file mode 100644 index 000000000..0d2b0513e --- /dev/null +++ b/src/libmalloc/src/frozen_malloc.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#ifndef __FROZEN_MALLOC_H +#define __FROZEN_MALLOC_H + +MALLOC_EXPORT +uintptr_t +malloc_freezedry(void); + +MALLOC_EXPORT +int +malloc_jumpstart(uintptr_t cookie); + +#endif // __FROZEN_MALLOC_H diff --git a/src/libmalloc/src/internal.h b/src/libmalloc/src/internal.h new file mode 100644 index 000000000..4b5f1a446 --- /dev/null +++ b/src/libmalloc/src/internal.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __INTERNAL_H +#define __INTERNAL_H + +#define __OS_EXPOSE_INTERNALS__ 1 + +#include +#include +#include <_simple.h> +#include +static size_t _platform_strlen(const char *s); +static size_t _platform_strlcpy(char * restrict dst, const char * restrict src, size_t maxlen); +#define memcpy _platform_memmove +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "magmallocProvider.h" + +#include "base.h" +#include "trace.h" +#include "platform.h" +#include "debug.h" +#include "locking.h" +#include "bitarray.h" +#include "malloc.h" +#include "printf.h" +#include "frozen_malloc.h" +#include "legacy_malloc.h" +#include "magazine_malloc.h" +#include "nano_malloc.h" +#include "purgeable_malloc.h" +#include "malloc_private.h" +#include "stack_logging.h" +#include "stack_logging_internal.h" +#include "thresholds.h" + +#include "magazine_zone.h" +#include "nano_zone.h" + +#include "magazine_inline.h" + +extern uint64_t malloc_entropy[2]; + +MALLOC_NOEXPORT +extern boolean_t malloc_tracing_enabled; + +MALLOC_NOEXPORT MALLOC_NOINLINE +void +malloc_error_break(void); + +MALLOC_NOEXPORT MALLOC_NOINLINE MALLOC_USED +int +malloc_gdb_po_unsafe(void); + +MALLOC_NOEXPORT +extern uint64_t max_lite_mallocs; + + +#endif // __INTERNAL_H diff --git a/src/libmalloc/src/legacy_malloc.c b/src/libmalloc/src/legacy_malloc.c new file mode 100644 index 000000000..082d505b9 --- /dev/null +++ b/src/libmalloc/src/legacy_malloc.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "internal.h" + +/* + * For use by CheckFix: create a new zone whose behavior is, apart from + * the use of death-row and per-CPU magazines, that of Leopard. + */ +static MALLOC_NOINLINE void * +legacy_valloc(szone_t *szone, size_t size) +{ + void *ptr; + size_t num_kernel_pages; + + num_kernel_pages = round_page_quanta(size) >> vm_page_quanta_shift; + ptr = large_malloc(szone, num_kernel_pages, 0, TRUE); +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("legacy_valloc returned %p\n", ptr); + } +#endif + return ptr; +} + +malloc_zone_t * +create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags) +{ + malloc_zone_t *mzone = create_scalable_zone(initial_size, debug_flags); + szone_t *szone = (szone_t *)mzone; + + if (!szone) { + return NULL; + } + + szone->is_largemem = 0; + szone->num_small_slots = NUM_SMALL_SLOTS; + szone->large_threshold = LARGE_THRESHOLD; + szone->vm_copy_threshold = VM_COPY_THRESHOLD; + + mprotect(szone, sizeof(szone->basic_zone), PROT_READ | PROT_WRITE); + szone->basic_zone.valloc = (void *)legacy_valloc; + szone->basic_zone.free_definite_size = NULL; + mprotect(szone, sizeof(szone->basic_zone), PROT_READ); + + return mzone; +} diff --git a/src/libmalloc/src/legacy_malloc.h b/src/libmalloc/src/legacy_malloc.h new file mode 100644 index 000000000..71ab26da5 --- /dev/null +++ b/src/libmalloc/src/legacy_malloc.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __LEGACY_MALLOC_H +#define __LEGACY_MALLOC_H + +MALLOC_NOEXPORT +malloc_zone_t * +create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags); + +#endif // __LEGACY_MALLOC_H diff --git a/src/libmalloc/src/locking.h b/src/libmalloc/src/locking.h new file mode 100644 index 000000000..e7c46560a --- /dev/null +++ b/src/libmalloc/src/locking.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __LOCKING_H +#define __LOCKING_H + +#if CONFIG_OS_LOCK_UNFAIR + +typedef os_unfair_lock _malloc_lock_s; +#define _MALLOC_LOCK_INIT OS_UNFAIR_LOCK_INIT + +__attribute__((always_inline)) +static inline void +_malloc_lock_init(_malloc_lock_s *lock) { + *lock = OS_UNFAIR_LOCK_INIT; +} + +MALLOC_ALWAYS_INLINE +static inline void +_malloc_lock_lock(_malloc_lock_s *lock) { + os_unfair_lock_lock_with_options_inline(lock, + OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION); +} + +MALLOC_ALWAYS_INLINE +static inline bool +_malloc_lock_trylock(_malloc_lock_s *lock) { + return os_unfair_lock_trylock_inline(lock); +} + +MALLOC_ALWAYS_INLINE +static inline void +_malloc_lock_unlock(_malloc_lock_s *lock) { + os_unfair_lock_unlock_inline(lock); +} + +#else // CONFIG_OS_LOCK_UNFAIR +#if CONFIG_OS_LOCK_HANDOFF + +typedef os_lock_handoff_s _malloc_lock_s; +#define _MALLOC_LOCK_INIT OS_LOCK_HANDOFF_INIT + +__attribute__((always_inline)) +static inline void +_malloc_lock_init(_malloc_lock_s *lock) { + const os_lock_handoff_s _os_lock_handoff_init = OS_LOCK_HANDOFF_INIT; + *lock = _os_lock_handoff_init; +} + +#else //CONFIG_OS_LOCK_HANDOFF + +typedef os_lock_spin_s _malloc_lock_s; +#define _MALLOC_LOCK_INIT OS_LOCK_SPIN_INIT + +MALLOC_ALWAYS_INLINE +static inline void +_malloc_lock_init(_malloc_lock_s *lock) { + const os_lock_spin_s _os_lock_spin_init = OS_LOCK_SPIN_INIT; + *lock = _os_lock_spin_init; +} + +#endif + +MALLOC_ALWAYS_INLINE +static inline void +_malloc_lock_lock(_malloc_lock_s *lock) { + return os_lock_lock(lock); +} + +MALLOC_ALWAYS_INLINE +static inline bool +_malloc_lock_trylock(_malloc_lock_s *lock) { + return os_lock_trylock(lock); +} + +MALLOC_ALWAYS_INLINE +static inline void +_malloc_lock_unlock(_malloc_lock_s *lock) { + return os_lock_unlock(lock); +} + +#endif // !CONFIG_OS_LOCK_UNFAIR + +#endif // __LOCKING_H diff --git a/src/libmalloc/src/magazine_inline.h b/src/libmalloc/src/magazine_inline.h new file mode 100644 index 000000000..0445555d2 --- /dev/null +++ b/src/libmalloc/src/magazine_inline.h @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __MAGAZINE_INLINE_H +#define __MAGAZINE_INLINE_H + +/********************* FREE LIST UTILITIES ************************/ + +// A free list entry is comprised of a pair of pointers, previous and next. +// These are used to implement a doubly-linked list, which permits efficient +// extraction. +// +// Because the free list entries are previously freed objects, a misbehaved +// program may write to a pointer after it has called free() on that pointer, +// either by dereference or buffer overflow from an adjacent pointer. This write +// would then corrupt the free list's previous and next pointers, leading to a +// crash. In order to detect this case, we take advantage of the fact that +// malloc'd pointers are known to be at least 16 byte aligned, and thus have +// at least 4 trailing zero bits. +// +// When an entry is added to the free list, a checksum of the previous and next +// pointers is calculated and written to the high four bits of the respective +// pointers. Upon detection of an invalid checksum, an error is logged and NULL +// is returned. Since all code which un-checksums pointers checks for a NULL +// return, a potentially crashing or malicious dereference is avoided at the +// cost of leaking the corrupted block, and any subsequent blocks on the free +// list of that size. + +#pragma mark forward decls + +static MALLOC_INLINE uintptr_t free_list_gen_checksum(uintptr_t ptr) MALLOC_ALWAYS_INLINE; +static MALLOC_INLINE uintptr_t free_list_checksum_ptr(szone_t *szone, void *p) MALLOC_ALWAYS_INLINE; +static MALLOC_INLINE void *free_list_unchecksum_ptr(szone_t *szone, inplace_union *ptr) MALLOC_ALWAYS_INLINE; +static MALLOC_INLINE unsigned free_list_count(szone_t *szone, free_list_t ptr); + +static MALLOC_INLINE void recirc_list_extract(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) MALLOC_ALWAYS_INLINE; +static MALLOC_INLINE void recirc_list_splice_last(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) MALLOC_ALWAYS_INLINE; +static MALLOC_INLINE void +recirc_list_splice_first(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) MALLOC_ALWAYS_INLINE; + +static MALLOC_INLINE void +yield(void) +{ + thread_switch(MACH_PORT_NULL, SWITCH_OPTION_DEPRESS, 1); +} + +static MALLOC_INLINE kern_return_t +_szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) +{ + *ptr = (void *)address; + return 0; +} + +#pragma mark szone locking + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE void +SZONE_LOCK(szone_t *szone) +{ + _malloc_lock_lock(&szone->large_szone_lock); +} + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE void +SZONE_UNLOCK(szone_t *szone) +{ + _malloc_lock_unlock(&szone->large_szone_lock); +} + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE bool +SZONE_TRY_LOCK(szone_t *szone) +{ + return _malloc_lock_trylock(&szone->large_szone_lock); +} + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE void +SZONE_REINIT_LOCK(szone_t *szone) +{ + _malloc_lock_init(&szone->large_szone_lock); +} + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE void +SZONE_MAGAZINE_PTR_LOCK(szone_t *szone, magazine_t *mag_ptr) +{ + _malloc_lock_lock(&mag_ptr->magazine_lock); +} + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE void +SZONE_MAGAZINE_PTR_UNLOCK(szone_t *szone, magazine_t *mag_ptr) +{ + _malloc_lock_unlock(&mag_ptr->magazine_lock); +} + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE bool +SZONE_MAGAZINE_PTR_TRY_LOCK(szone_t *szone, magazine_t *mag_ptr) +{ + return _malloc_lock_trylock(&mag_ptr->magazine_lock); +} + +static MALLOC_INLINE MALLOC_ALWAYS_INLINE void +SZONE_MAGAZINE_PTR_REINIT_LOCK(szone_t *szone, magazine_t *mag_ptr) +{ + _malloc_lock_init(&mag_ptr->magazine_lock); +} + +#pragma mark free list + +static MALLOC_NOINLINE void +free_list_checksum_botch(szone_t *szone, void *ptr) +{ + szone_error(szone, 1, + "incorrect checksum for freed object " + "- object was probably modified after being freed.", + ptr, NULL); +} + +static MALLOC_INLINE uintptr_t +free_list_gen_checksum(uintptr_t ptr) +{ + uint8_t chk; + + chk = (unsigned char)(ptr >> 0); + chk += (unsigned char)(ptr >> 8); + chk += (unsigned char)(ptr >> 16); + chk += (unsigned char)(ptr >> 24); +#if __LP64__ + chk += (unsigned char)(ptr >> 32); + chk += (unsigned char)(ptr >> 40); + chk += (unsigned char)(ptr >> 48); + chk += (unsigned char)(ptr >> 56); +#endif + + return chk & (uintptr_t)0xF; +} + +static unsigned +free_list_count(szone_t *szone, free_list_t ptr) +{ + unsigned count = 0; + + while (ptr.p) { + count++; + ptr.p = free_list_unchecksum_ptr(szone, &ptr.inplace->next); + } + return count; +} + +#define NYBBLE 4 +#if __LP64__ +#define ANTI_NYBBLE (64 - NYBBLE) +#else +#define ANTI_NYBBLE (32 - NYBBLE) +#endif + +static MALLOC_INLINE uintptr_t +free_list_checksum_ptr(szone_t *szone, void *ptr) +{ + uintptr_t p = (uintptr_t)ptr; + return (p >> NYBBLE) | (free_list_gen_checksum(p ^ szone->cookie) << ANTI_NYBBLE); // compiles to rotate instruction +} + +static MALLOC_INLINE void * +free_list_unchecksum_ptr(szone_t *szone, inplace_union *ptr) +{ + inplace_union p; + uintptr_t t = ptr->u; + + t = (t << NYBBLE) | (t >> ANTI_NYBBLE); // compiles to rotate instruction + p.u = t & ~(uintptr_t)0xF; + + if ((t & (uintptr_t)0xF) != free_list_gen_checksum(p.u ^ szone->cookie)) { + free_list_checksum_botch(szone, ptr); + __builtin_trap(); + } + return p.p; +} + +#undef ANTI_NYBBLE +#undef NYBBLE + +#pragma mark recirc helpers + +static MALLOC_INLINE void +recirc_list_extract(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) +{ + // excise node from list + if (NULL == node->prev) { + mag_ptr->firstNode = node->next; + } else { + node->prev->next = node->next; + } + + if (NULL == node->next) { + mag_ptr->lastNode = node->prev; + } else { + node->next->prev = node->prev; + } + + mag_ptr->recirculation_entries--; +} + +static MALLOC_INLINE void +recirc_list_splice_last(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) +{ + if (NULL == mag_ptr->lastNode) { + mag_ptr->firstNode = node; + node->prev = NULL; + } else { + node->prev = mag_ptr->lastNode; + mag_ptr->lastNode->next = node; + } + mag_ptr->lastNode = node; + node->next = NULL; + node->recirc_suitable = FALSE; + mag_ptr->recirculation_entries++; +} + +static MALLOC_INLINE void +recirc_list_splice_first(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) +{ + if (NULL == mag_ptr->firstNode) { + mag_ptr->lastNode = node; + node->next = NULL; + } else { + node->next = mag_ptr->firstNode; + mag_ptr->firstNode->prev = node; + } + mag_ptr->firstNode = node; + node->prev = NULL; + node->recirc_suitable = FALSE; + mag_ptr->recirculation_entries++; +} + +/******************************************************************************* + * Region hash implementation + * + * This is essentially a duplicate of the existing Large allocator hash, minus + * the ability to remove entries. The two should be combined eventually. + ******************************************************************************/ +#pragma mark region hash + +/* + * hash_lookup_region_no_lock - Scan a hash ring looking for an entry for a + * given region. + * + * FIXME: If consecutive queries of the same region are likely, a one-entry + * cache would likely be a significant performance win here. + */ +static MALLOC_INLINE rgnhdl_t +hash_lookup_region_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) +{ + size_t index, hash_index; + rgnhdl_t entry; + + if (!num_entries) { + return 0; + } + + // Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...] + // Since the values of (((uintptr_t)r >> HASH_BLOCKS_ALIGN) are (roughly) an ascending sequence of integers, + // this hash works really well. See Knuth TAOCP, Vol. 3. +#if __LP64__ + index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 11400714819323198549ULL) >> (64 - shift); +#else + index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 2654435761UL) >> (32 - shift); +#endif + do { + entry = regions + index; + if (*entry == 0) { + return 0; + } + if (*entry == r) { + return entry; + } + if (++index == num_entries) { + index = 0; + } + } while (index != hash_index); + return 0; +} + +/* + * hash_region_insert_no_lock - Insert a region into the hash ring. + */ +static void +hash_region_insert_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) +{ + size_t index, hash_index; + rgnhdl_t entry; + + // Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...] + // Since the values of (((uintptr_t)r >> HASH_BLOCKS_ALIGN) are (roughly) an ascending sequence of integers, + // this hash works really well. See Knuth TAOCP, Vol. 3. +#if __LP64__ + index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 11400714819323198549ULL) >> (64 - shift); +#else + index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 2654435761UL) >> (32 - shift); +#endif + do { + entry = regions + index; + if (*entry == HASHRING_OPEN_ENTRY || *entry == HASHRING_REGION_DEALLOCATED) { + *entry = r; + return; + } + if (++index == num_entries) { + index = 0; + } + } while (index != hash_index); +} + +/* + * hash_regions_alloc_no_lock - Allocate space for a number of entries. This + * must be a VM allocation as to avoid recursing between allocating a new small + * region, and asking the small region to allocate space for the new list of + * regions. + */ +static region_t * +hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries) +{ + size_t size = num_entries * sizeof(region_t); + + return allocate_pages(szone, round_page_quanta(size), 0, 0, VM_MEMORY_MALLOC); +} + +/* + * hash_regions_grow_no_lock - Grow the hash ring, and rehash the entries. + * Return the new region and new size to update the szone. Do not deallocate + * the old entries since someone may still be allocating them. + */ +static MALLOC_INLINE region_t * +hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, size_t *mutable_shift, size_t *new_size) +{ + // double in size and allocate memory for the regions + *new_size = old_size + old_size; + *mutable_shift = *mutable_shift + 1; + region_t *new_regions = hash_regions_alloc_no_lock(szone, *new_size); + + // rehash the entries into the new list + size_t index; + for (index = 0; index < old_size; ++index) { + region_t r = regions[index]; + if (r != HASHRING_OPEN_ENTRY && r != HASHRING_REGION_DEALLOCATED) { + hash_region_insert_no_lock(new_regions, *new_size, *mutable_shift, r); + } + } + return new_regions; +} + +#pragma mark mag lock + +/* + * These commpage routines provide fast access to the logical cpu number + * of the calling processor assuming no pre-emption occurs. + */ + +static MALLOC_INLINE mag_index_t +mag_get_thread_index(szone_t *szone) +{ + return _os_cpu_number() & (TINY_MAX_MAGAZINES - 1); +} + +static MALLOC_INLINE magazine_t * +mag_lock_zine_for_region_trailer(szone_t *szone, magazine_t *magazines, region_trailer_t *trailer, mag_index_t mag_index) +{ + mag_index_t refreshed_index; + magazine_t *mag_ptr = &(magazines[mag_index]); + + // Take the lock on entry. + SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr); + + // Now in the time it took to acquire the lock, the region may have migrated + // from one magazine to another. In which case the magazine lock we obtained + // (namely magazines[mag_index].mag_lock) is stale. If so, keep on tryin' ... + while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment + + SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); + + mag_index = refreshed_index; + mag_ptr = &(magazines[mag_index]); + SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr); + } + + return mag_ptr; +} + +#pragma mark tiny allocator + +/* + * tiny_region_for_ptr_no_lock - Returns the tiny region containing the pointer, + * or NULL if not found. + */ +static MALLOC_INLINE region_t +tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) +{ + rgnhdl_t r = hash_lookup_region_no_lock(szone->tiny_region_generation->hashed_regions, + szone->tiny_region_generation->num_regions_allocated, szone->tiny_region_generation->num_regions_allocated_shift, + TINY_REGION_FOR_PTR(ptr)); + return r ? *r : r; +} + +/* + * Obtain the size of a free tiny block (in msize_t units). + */ +static msize_t +get_tiny_free_size(const void *ptr) +{ + void *next_block = (void *)((uintptr_t)ptr + TINY_QUANTUM); + void *region_end = TINY_REGION_END(TINY_REGION_FOR_PTR(ptr)); + + // check whether the next block is outside the tiny region or a block header + // if so, then the size of this block is one, and there is no stored size. + if (next_block < region_end) { + uint32_t *next_header = TINY_BLOCK_HEADER_FOR_PTR(next_block); + msize_t next_index = TINY_INDEX_FOR_PTR(next_block); + + if (!BITARRAY_BIT(next_header, next_index)) { + return TINY_FREE_SIZE(ptr); + } + } + return 1; +} + +static MALLOC_INLINE msize_t +get_tiny_meta_header(const void *ptr, boolean_t *is_free) +{ + // returns msize and is_free + // may return 0 for the msize component (meaning 65536) + uint32_t *block_header; + msize_t index; + + block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); + index = TINY_INDEX_FOR_PTR(ptr); + + msize_t midx = (index >> 5) << 1; + uint32_t mask = 1 << (index & 31); + *is_free = 0; + if (0 == (block_header[midx] & mask)) { // if (!BITARRAY_BIT(block_header, index)) + return 0; + } + if (0 == (block_header[midx + 1] & mask)) { // if (!BITARRAY_BIT(in_use, index)) + *is_free = 1; + return get_tiny_free_size(ptr); + } + + // index >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array + // (index >> 5) << 1 identifies the uint32_t allowing for the actual interleaving +#if defined(__LP64__) + // The return value, msize, is computed as the distance to the next 1 bit in block_header. + // That's guaranteed to be somewhwere in the next 64 bits. And those bits could span three + // uint32_t block_header elements. Collect the bits into a single uint64_t and measure up with ffsl. + uint32_t *addr = ((uint32_t *)block_header) + ((index >> 5) << 1); + uint32_t bitidx = index & 31; + uint64_t word_lo = addr[0]; + uint64_t word_mid = addr[2]; + uint64_t word_hi = addr[4]; + uint64_t word_lomid = (word_lo >> bitidx) | (word_mid << (32 - bitidx)); + uint64_t word = bitidx ? word_lomid | (word_hi << (64 - bitidx)) : word_lomid; + uint32_t result = __builtin_ffsl(word >> 1); +#else + // The return value, msize, is computed as the distance to the next 1 bit in block_header. + // That's guaranteed to be somwhwere in the next 32 bits. And those bits could span two + // uint32_t block_header elements. Collect the bits into a single uint32_t and measure up with ffs. + uint32_t *addr = ((uint32_t *)block_header) + ((index >> 5) << 1); + uint32_t bitidx = index & 31; + uint32_t word = bitidx ? (addr[0] >> bitidx) | (addr[2] << (32 - bitidx)) : addr[0]; + uint32_t result = __builtin_ffs(word >> 1); +#endif + return result; +} + +#pragma mark small allocator + +/* + * small_region_for_ptr_no_lock - Returns the small region containing the pointer, + * or NULL if not found. + */ +static MALLOC_INLINE region_t +small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) +{ + rgnhdl_t r = hash_lookup_region_no_lock(szone->small_region_generation->hashed_regions, + szone->small_region_generation->num_regions_allocated, szone->small_region_generation->num_regions_allocated_shift, + SMALL_REGION_FOR_PTR(ptr)); + return r ? *r : r; +} + +#endif // __MAGAZINE_INLINE_H diff --git a/src/libmalloc/src/magazine_large.c b/src/libmalloc/src/magazine_large.c new file mode 100644 index 000000000..a0841e078 --- /dev/null +++ b/src/libmalloc/src/magazine_large.c @@ -0,0 +1,764 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "internal.h" + +#if DEBUG_MALLOC +static void +large_debug_print(szone_t *szone) +{ + unsigned index; + large_entry_t *range; + _SIMPLE_STRING b = _simple_salloc(); + + if (b) { + for (index = 0, range = szone->large_entries; index < szone->num_large_entries; index++, range++) { + if (range->address) { + _simple_sprintf(b, "%d: %p(%y); ", index, range->address, range->size); + } + } + + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); + } +} +#endif + +/* + * Scan the hash ring looking for an entry for the given pointer. + */ +large_entry_t * +large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr) +{ + // result only valid with lock held + unsigned num_large_entries = szone->num_large_entries; + unsigned hash_index; + unsigned index; + large_entry_t *range; + + if (!num_large_entries) { + return NULL; + } + + hash_index = ((uintptr_t)ptr >> vm_page_quanta_shift) % num_large_entries; + index = hash_index; + + do { + range = szone->large_entries + index; + if (range->address == (vm_address_t)ptr) { + return range; + } + if (0 == range->address) { + return NULL; // end of chain + } + index++; + if (index == num_large_entries) { + index = 0; + } + } while (index != hash_index); + + return NULL; +} + +static void +large_entry_insert_no_lock(szone_t *szone, large_entry_t range) +{ + unsigned num_large_entries = szone->num_large_entries; + unsigned hash_index = (((uintptr_t)(range.address)) >> vm_page_quanta_shift) % num_large_entries; + unsigned index = hash_index; + large_entry_t *entry; + + // assert(szone->num_large_objects_in_use < szone->num_large_entries); /* must be called with room to spare */ + + do { + entry = szone->large_entries + index; + if (0 == entry->address) { + *entry = range; + return; // end of chain + } + index++; + if (index == num_large_entries) { + index = 0; + } + } while (index != hash_index); + + // assert(0); /* must not fallthrough! */ +} + +// FIXME: can't we simply swap the (now empty) entry with the last entry on the collision chain for this hash slot? +static MALLOC_INLINE void +large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) +{ + unsigned num_large_entries = szone->num_large_entries; + uintptr_t hash_index = entry - szone->large_entries; + uintptr_t index = hash_index; + large_entry_t range; + + // assert(entry->address == 0) /* caller must have cleared *entry */ + + do { + index++; + if (index == num_large_entries) { + index = 0; + } + range = szone->large_entries[index]; + if (0 == range.address) { + return; + } + szone->large_entries[index].address = (vm_address_t)0; + szone->large_entries[index].size = 0; + szone->large_entries[index].did_madvise_reusable = FALSE; + large_entry_insert_no_lock(szone, range); // this will reinsert in the + // proper place + } while (index != hash_index); + + // assert(0); /* since entry->address == 0, must not fallthrough! */ +} + +// FIXME: num should probably be a size_t, since you can theoretically allocate +// more than 2^32-1 large_threshold objects in 64 bit. +static MALLOC_INLINE large_entry_t * +large_entries_alloc_no_lock(szone_t *szone, unsigned num) +{ + size_t size = num * sizeof(large_entry_t); + + // Note that we allocate memory (via a system call) under a spin lock + // That is certainly evil, however it's very rare in the lifetime of a process + // The alternative would slow down the normal case + return allocate_pages(szone, round_page_quanta(size), 0, 0, VM_MEMORY_MALLOC_LARGE); +} + +void +large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate) +{ + size_t size = num * sizeof(large_entry_t); + + range_to_deallocate->address = (vm_address_t)entries; + range_to_deallocate->size = round_page_quanta(size); +} + +static large_entry_t * +large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) +{ + // sets range_to_deallocate + unsigned old_num_entries = szone->num_large_entries; + large_entry_t *old_entries = szone->large_entries; + // always an odd number for good hashing + unsigned new_num_entries = + (old_num_entries) ? old_num_entries * 2 + 1 : (unsigned)((vm_page_quanta_size / sizeof(large_entry_t)) - 1); + large_entry_t *new_entries = large_entries_alloc_no_lock(szone, new_num_entries); + unsigned index = old_num_entries; + large_entry_t oldRange; + + // if the allocation of new entries failed, bail + if (new_entries == NULL) { + return NULL; + } + + szone->num_large_entries = new_num_entries; + szone->large_entries = new_entries; + + /* rehash entries into the new list */ + while (index--) { + oldRange = old_entries[index]; + if (oldRange.address) { + large_entry_insert_no_lock(szone, oldRange); + } + } + + if (old_entries) { + large_entries_free_no_lock(szone, old_entries, old_num_entries, range_to_deallocate); + } else { + range_to_deallocate->address = (vm_address_t)0; + range_to_deallocate->size = 0; + } + + return new_entries; +} + +// frees the specific entry in the size table +// returns a range to truly deallocate +static vm_range_t +large_entry_free_no_lock(szone_t *szone, large_entry_t *entry) +{ + vm_range_t range; + + MALLOC_TRACE(TRACE_large_free, (uintptr_t)szone, (uintptr_t)entry->address, entry->size, 0); + + range.address = entry->address; + range.size = entry->size; + + if (szone->debug_flags & MALLOC_ADD_GUARD_PAGES) { + protect((void *)range.address, range.size, PROT_READ | PROT_WRITE, szone->debug_flags); + range.address -= vm_page_quanta_size; + range.size += 2 * vm_page_quanta_size; + } + + entry->address = 0; + entry->size = 0; + entry->did_madvise_reusable = FALSE; + large_entries_rehash_after_entry_no_lock(szone, entry); + +#if DEBUG_MALLOC + if (large_entry_for_pointer_no_lock(szone, (void *)range.address)) { + malloc_printf("*** freed entry %p still in use; num_large_entries=%d\n", range.address, szone->num_large_entries); + large_debug_print(szone); + szone_sleep(); + } +#endif + return range; +} + +kern_return_t +large_in_use_enumerator(task_t task, + void *context, + unsigned type_mask, + vm_address_t large_entries_address, + unsigned num_entries, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + unsigned index = 0; + vm_range_t buffer[MAX_RECORDER_BUFFER]; + unsigned count = 0; + large_entry_t *entries; + kern_return_t err; + vm_range_t range; + large_entry_t entry; + + err = reader(task, large_entries_address, sizeof(large_entry_t) * num_entries, (void **)&entries); + if (err) { + return err; + } + + index = num_entries; + if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { + range.address = large_entries_address; + range.size = round_page_quanta(num_entries * sizeof(large_entry_t)); + recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &range, 1); + } + if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE)) { + while (index--) { + entry = entries[index]; + if (entry.address) { + range.address = entry.address; + range.size = entry.size; + buffer[count++] = range; + if (count >= MAX_RECORDER_BUFFER) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count); + count = 0; + } + } + } + } + if (count) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count); + } + return 0; +} + +void * +large_malloc(szone_t *szone, size_t num_kernel_pages, unsigned char alignment, boolean_t cleared_requested) +{ + void *addr; + vm_range_t range_to_deallocate; + size_t size; + large_entry_t large_entry; + + MALLOC_TRACE(TRACE_large_malloc, (uintptr_t)szone, num_kernel_pages, alignment, cleared_requested); + + if (!num_kernel_pages) { + num_kernel_pages = 1; // minimal allocation size for this szone + } + size = (size_t)num_kernel_pages << vm_page_quanta_shift; + range_to_deallocate.size = 0; + range_to_deallocate.address = 0; + +#if CONFIG_LARGE_CACHE + if (size < LARGE_CACHE_SIZE_ENTRY_LIMIT) { // Look for a large_entry_t on the death-row cache? + SZONE_LOCK(szone); + + int i, best = -1, idx = szone->large_entry_cache_newest, stop_idx = szone->large_entry_cache_oldest; + size_t best_size = SIZE_T_MAX; + + while (1) { // Scan large_entry_cache for best fit, starting with most recent entry + size_t this_size = szone->large_entry_cache[idx].size; + addr = (void *)szone->large_entry_cache[idx].address; + + if (0 == alignment || 0 == (((uintptr_t)addr) & (((uintptr_t)1 << alignment) - 1))) { + if (size == this_size) { // size match! + best = idx; + best_size = this_size; + break; + } + + if (size <= this_size && this_size < best_size) { // improved fit? + best = idx; + best_size = this_size; + } + } + + if (idx == stop_idx) { // exhausted live ring? + break; + } + + if (idx) { + idx--; // bump idx down + } else { + idx = LARGE_ENTRY_CACHE_SIZE - 1; // wrap idx + } + } + + if (best > -1 && (best_size - size) < size) { // limit fragmentation to 50% + addr = (void *)szone->large_entry_cache[best].address; + boolean_t was_madvised_reusable = szone->large_entry_cache[best].did_madvise_reusable; + + // Compact live ring to fill entry now vacated at large_entry_cache[best] + // while preserving time-order + if (szone->large_entry_cache_oldest < szone->large_entry_cache_newest) { + // Ring hasn't wrapped. Fill in from right. + for (i = best; i < szone->large_entry_cache_newest; ++i) { + szone->large_entry_cache[i] = szone->large_entry_cache[i + 1]; + } + + szone->large_entry_cache_newest--; // Pull in right endpoint. + + } else if (szone->large_entry_cache_newest < szone->large_entry_cache_oldest) { + // Ring has wrapped. Arrange to fill in from the contiguous side. + if (best <= szone->large_entry_cache_newest) { + // Fill from right. + for (i = best; i < szone->large_entry_cache_newest; ++i) { + szone->large_entry_cache[i] = szone->large_entry_cache[i + 1]; + } + + if (0 < szone->large_entry_cache_newest) { + szone->large_entry_cache_newest--; + } else { + szone->large_entry_cache_newest = LARGE_ENTRY_CACHE_SIZE - 1; + } + } else { + // Fill from left. + for (i = best; i > szone->large_entry_cache_oldest; --i) { + szone->large_entry_cache[i] = szone->large_entry_cache[i - 1]; + } + + if (szone->large_entry_cache_oldest < LARGE_ENTRY_CACHE_SIZE - 1) { + szone->large_entry_cache_oldest++; + } else { + szone->large_entry_cache_oldest = 0; + } + } + + } else { + // By trichotomy, large_entry_cache_newest == large_entry_cache_oldest. + // That implies best == large_entry_cache_newest == large_entry_cache_oldest + // and the ring is now empty. + szone->large_entry_cache[best].address = 0; + szone->large_entry_cache[best].size = 0; + szone->large_entry_cache[best].did_madvise_reusable = FALSE; + } + + if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) { + // density of hash table too high; grow table + // we do that under lock to avoid a race + large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate); + if (entries == NULL) { + SZONE_UNLOCK(szone); + return NULL; + } + } + + large_entry.address = (vm_address_t)addr; + large_entry.size = best_size; + large_entry.did_madvise_reusable = FALSE; + large_entry_insert_no_lock(szone, large_entry); + + szone->num_large_objects_in_use++; + szone->num_bytes_in_large_objects += best_size; + if (!was_madvised_reusable) { + szone->large_entry_cache_reserve_bytes -= best_size; + } + + szone->large_entry_cache_bytes -= best_size; + + if (szone->flotsam_enabled && szone->large_entry_cache_bytes < SZONE_FLOTSAM_THRESHOLD_LOW) { + szone->flotsam_enabled = FALSE; + } + + SZONE_UNLOCK(szone); + + if (range_to_deallocate.size) { + // we deallocate outside the lock + deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); + } + + // Perform the madvise() outside the lock. + // Typically the madvise() is successful and we'll quickly return from this routine. + // In the unusual case of failure, reacquire the lock to unwind. +#if TARGET_OS_EMBEDDED + // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large + // cache block twice without MADV_FREE_REUSE in between. +#endif + if (was_madvised_reusable && -1 == madvise(addr, size, MADV_FREE_REUSE)) { + /* -1 return: VM map entry change makes this unfit for reuse. */ +#if DEBUG_MADVISE + szone_error(szone, 0, "large_malloc madvise(..., MADV_FREE_REUSE) failed", addr, "length=%d\n", size); +#endif + + SZONE_LOCK(szone); + szone->num_large_objects_in_use--; + szone->num_bytes_in_large_objects -= large_entry.size; + + // Re-acquire "entry" after interval just above where we let go the lock. + large_entry_t *entry = large_entry_for_pointer_no_lock(szone, addr); + if (NULL == entry) { + szone_error(szone, 1, "entry for pointer being discarded from death-row vanished", addr, NULL); + SZONE_UNLOCK(szone); + } else { + range_to_deallocate = large_entry_free_no_lock(szone, entry); + SZONE_UNLOCK(szone); + + if (range_to_deallocate.size) { + // we deallocate outside the lock + deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); + } + } + /* Fall through to allocate_pages() afresh. */ + } else { + if (cleared_requested) { + memset(addr, 0, size); + } + + return addr; + } + } else { + SZONE_UNLOCK(szone); + } + } + + range_to_deallocate.size = 0; + range_to_deallocate.address = 0; +#endif /* CONFIG_LARGE_CACHE */ + + addr = allocate_pages(szone, size, alignment, szone->debug_flags, VM_MEMORY_MALLOC_LARGE); + if (addr == NULL) { + return NULL; + } + + SZONE_LOCK(szone); + if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) { + // density of hash table too high; grow table + // we do that under lock to avoid a race + large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate); + if (entries == NULL) { + SZONE_UNLOCK(szone); + return NULL; + } + } + + large_entry.address = (vm_address_t)addr; + large_entry.size = size; + large_entry.did_madvise_reusable = FALSE; + large_entry_insert_no_lock(szone, large_entry); + + szone->num_large_objects_in_use++; + szone->num_bytes_in_large_objects += size; + SZONE_UNLOCK(szone); + + if (range_to_deallocate.size) { + // we deallocate outside the lock + deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); + } + return addr; +} + +void +free_large(szone_t *szone, void *ptr) +{ + // We have established ptr is page-aligned and neither tiny nor small + large_entry_t *entry; + vm_range_t vm_range_to_deallocate; + + SZONE_LOCK(szone); + entry = large_entry_for_pointer_no_lock(szone, ptr); + if (entry) { +#if CONFIG_LARGE_CACHE + if (entry->size < LARGE_CACHE_SIZE_ENTRY_LIMIT && + -1 != madvise((void *)(entry->address), entry->size, + MADV_CAN_REUSE)) { // Put the large_entry_t on the death-row cache? + int idx = szone->large_entry_cache_newest, stop_idx = szone->large_entry_cache_oldest; + large_entry_t this_entry = *entry; // Make a local copy, "entry" is volatile when lock is let go. + boolean_t reusable = TRUE; + boolean_t should_madvise = + szone->large_entry_cache_reserve_bytes + this_entry.size > szone->large_entry_cache_reserve_limit; + + // Already freed? + // [Note that repeated entries in death-row risk vending the same entry subsequently + // to two different malloc() calls. By checking here the (illegal) double free + // is accommodated, matching the behavior of the previous implementation.] + while (1) { // Scan large_entry_cache starting with most recent entry + if (szone->large_entry_cache[idx].address == entry->address) { + szone_error(szone, 1, "pointer being freed already on death-row", ptr, NULL); + SZONE_UNLOCK(szone); + return; + } + + if (idx == stop_idx) { // exhausted live ring? + break; + } + + if (idx) { + idx--; // bump idx down + } else { + idx = LARGE_ENTRY_CACHE_SIZE - 1; // wrap idx + } + } + + SZONE_UNLOCK(szone); + + if (szone->debug_flags & MALLOC_PURGEABLE) { // Are we a purgable zone? + int state = VM_PURGABLE_NONVOLATILE; // restore to default condition + + if (KERN_SUCCESS != vm_purgable_control(mach_task_self(), this_entry.address, VM_PURGABLE_SET_STATE, &state)) { + malloc_printf("*** can't vm_purgable_control(..., VM_PURGABLE_SET_STATE) for large freed block at %p\n", + this_entry.address); + reusable = FALSE; + } + } + + if (szone->large_legacy_reset_mprotect) { // Linked for Leopard? + // Accomodate Leopard apps that (illegally) mprotect() their own guard pages on large malloc'd allocations + int err = mprotect((void *)(this_entry.address), this_entry.size, PROT_READ | PROT_WRITE); + if (err) { + malloc_printf("*** can't reset protection for large freed block at %p\n", this_entry.address); + reusable = FALSE; + } + } + + // madvise(..., MADV_REUSABLE) death-row arrivals if hoarding would exceed large_entry_cache_reserve_limit + if (should_madvise) { + // Issue madvise to avoid paging out the dirtied free()'d pages in "entry" + MAGMALLOC_MADVFREEREGION( + (void *)szone, (void *)0, (void *)(this_entry.address), this_entry.size); // DTrace USDT Probe + +#if TARGET_OS_EMBEDDED + // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large + // cache block twice without MADV_FREE_REUSE in between. +#endif + if (-1 == madvise((void *)(this_entry.address), this_entry.size, MADV_FREE_REUSABLE)) { + /* -1 return: VM map entry change makes this unfit for reuse. */ +#if DEBUG_MADVISE + szone_error(szone, 0, "free_large madvise(..., MADV_FREE_REUSABLE) failed", (void *)this_entry.address, + "length=%d\n", this_entry.size); +#endif + reusable = FALSE; + } + } + + SZONE_LOCK(szone); + + // Re-acquire "entry" after interval just above where we let go the lock. + entry = large_entry_for_pointer_no_lock(szone, ptr); + if (NULL == entry) { + szone_error(szone, 1, "entry for pointer being freed from death-row vanished", ptr, NULL); + SZONE_UNLOCK(szone); + return; + } + + // Add "entry" to death-row ring + if (reusable) { + int idx = szone->large_entry_cache_newest; // Most recently occupied + vm_address_t addr; + size_t adjsize; + + if (szone->large_entry_cache_newest == szone->large_entry_cache_oldest && + 0 == szone->large_entry_cache[idx].address) { + // Ring is empty, idx is good as it stands + addr = 0; + adjsize = 0; + } else { + // Extend the queue to the "right" by bumping up large_entry_cache_newest + if (idx == LARGE_ENTRY_CACHE_SIZE - 1) { + idx = 0; // Wrap index + } else { + idx++; // Bump index + } + if (idx == szone->large_entry_cache_oldest) { // Fully occupied + // Drop this entry from the cache and deallocate the VM + addr = szone->large_entry_cache[idx].address; + adjsize = szone->large_entry_cache[idx].size; + szone->large_entry_cache_bytes -= adjsize; + if (!szone->large_entry_cache[idx].did_madvise_reusable) { + szone->large_entry_cache_reserve_bytes -= adjsize; + } + } else { + // Using an unoccupied cache slot + addr = 0; + adjsize = 0; + } + } + + if ((szone->debug_flags & MALLOC_DO_SCRIBBLE)) { + memset((void *)(entry->address), should_madvise ? SCRUBBLE_BYTE : SCRABBLE_BYTE, entry->size); + } + + entry->did_madvise_reusable = should_madvise; // Was madvise()'d above? + if (!should_madvise) { // Entered on death-row without madvise() => up the hoard total + szone->large_entry_cache_reserve_bytes += entry->size; + } + + szone->large_entry_cache_bytes += entry->size; + + if (!szone->flotsam_enabled && szone->large_entry_cache_bytes > SZONE_FLOTSAM_THRESHOLD_HIGH) { + szone->flotsam_enabled = TRUE; + } + + szone->large_entry_cache[idx] = *entry; + szone->large_entry_cache_newest = idx; + + szone->num_large_objects_in_use--; + szone->num_bytes_in_large_objects -= entry->size; + + (void)large_entry_free_no_lock(szone, entry); + + if (0 == addr) { + SZONE_UNLOCK(szone); + return; + } + + // Fall through to drop large_entry_cache_oldest from the cache, + // and then deallocate its pages. + + // Trim the queue on the "left" by bumping up large_entry_cache_oldest + if (szone->large_entry_cache_oldest == LARGE_ENTRY_CACHE_SIZE - 1) { + szone->large_entry_cache_oldest = 0; + } else { + szone->large_entry_cache_oldest++; + } + + // we deallocate_pages, including guard pages, outside the lock + SZONE_UNLOCK(szone); + deallocate_pages(szone, (void *)addr, (size_t)adjsize, 0); + return; + } else { + /* fall through to discard an allocation that is not reusable */ + } + } +#endif /* CONFIG_LARGE_CACHE */ + + szone->num_large_objects_in_use--; + szone->num_bytes_in_large_objects -= entry->size; + + vm_range_to_deallocate = large_entry_free_no_lock(szone, entry); + } else { +#if DEBUG_MALLOC + large_debug_print(szone); +#endif + szone_error(szone, 1, "pointer being freed was not allocated", ptr, NULL); + SZONE_UNLOCK(szone); + return; + } + SZONE_UNLOCK(szone); // we release the lock asap + CHECK(szone, __PRETTY_FUNCTION__); + + // we deallocate_pages, including guard pages, outside the lock + if (vm_range_to_deallocate.address) { +#if DEBUG_MALLOC + // FIXME: large_entry_for_pointer_no_lock() needs the lock held ... + if (large_entry_for_pointer_no_lock(szone, (void *)vm_range_to_deallocate.address)) { + malloc_printf("*** invariant broken: %p still in use num_large_entries=%d\n", vm_range_to_deallocate.address, + szone->num_large_entries); + large_debug_print(szone); + szone_sleep(); + } +#endif + deallocate_pages(szone, (void *)vm_range_to_deallocate.address, (size_t)vm_range_to_deallocate.size, 0); + } +} + +void * +large_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) +{ + size_t shrinkage = old_size - new_good_size; + + if (shrinkage) { + SZONE_LOCK(szone); + /* contract existing large entry */ + large_entry_t *large_entry = large_entry_for_pointer_no_lock(szone, ptr); + if (!large_entry) { + szone_error(szone, 1, "large entry reallocated is not properly in table", ptr, NULL); + SZONE_UNLOCK(szone); + return ptr; + } + + large_entry->address = (vm_address_t)ptr; + large_entry->size = new_good_size; + szone->num_bytes_in_large_objects -= shrinkage; + SZONE_UNLOCK(szone); // we release the lock asap + + deallocate_pages(szone, (void *)((uintptr_t)ptr + new_good_size), shrinkage, 0); + } + return ptr; +} + +int +large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) +{ + vm_address_t addr = (vm_address_t)ptr + old_size; + large_entry_t *large_entry; + kern_return_t err; + + SZONE_LOCK(szone); + large_entry = large_entry_for_pointer_no_lock(szone, (void *)addr); + SZONE_UNLOCK(szone); + + if (large_entry) { // check if "addr = ptr + old_size" is already spoken for + return 0; // large pointer already exists in table - extension is not going to work + } + + new_size = round_page_quanta(new_size); + /* + * Ask for allocation at a specific address, and mark as realloc + * to request coalescing with previous realloc'ed extensions. + */ + err = vm_allocate(mach_task_self(), &addr, new_size - old_size, VM_MAKE_TAG(VM_MEMORY_REALLOC)); + if (err != KERN_SUCCESS) { + return 0; + } + + SZONE_LOCK(szone); + /* extend existing large entry */ + large_entry = large_entry_for_pointer_no_lock(szone, ptr); + if (!large_entry) { + szone_error(szone, 1, "large entry reallocated is not properly in table", ptr, NULL); + SZONE_UNLOCK(szone); + return 0; // Bail, leaking "addr" + } + + large_entry->address = (vm_address_t)ptr; + large_entry->size = new_size; + szone->num_bytes_in_large_objects += new_size - old_size; + SZONE_UNLOCK(szone); // we release the lock asap + + return 1; +} diff --git a/src/libmalloc/src/magazine_lite.c b/src/libmalloc/src/magazine_lite.c new file mode 100644 index 000000000..1d9160b8d --- /dev/null +++ b/src/libmalloc/src/magazine_lite.c @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2016, Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "internal.h" + +typedef uint64_t malloc_stack_id; + +uint64_t max_lite_mallocs = 0; + +static malloc_stack_id +get_stack_id_from_ptr(void *ptr, size_t ptr_size) +{ + void *idptr = ptr + ptr_size - sizeof(malloc_stack_id); + + return * (malloc_stack_id *) idptr; +} + +static void +set_stack_id_in_ptr(void *ptr, size_t requested_size, size_t ptr_size, malloc_stack_id stack_id) +{ + void *idptr = ptr + ptr_size - sizeof(malloc_stack_id); + * (malloc_stack_id *) idptr = stack_id; + void *padding = ptr + requested_size; + bzero(padding, ptr_size - requested_size - sizeof(malloc_stack_id)); +} + +static void +add_stack_to_ptr(szone_t *szone, size_t requested_size, void *ptr) +{ + // enter the stack into the unique table + vm_address_t self_thread = (vm_address_t)_os_tsd_get_direct(__TSD_THREAD_SELF); + + size_t ptr_size = szone_size(szone, ptr); + + __malloc_lock_stack_logging(); + + // if stack logging was turned off behind our backs + if (!is_stack_logging_lite_enabled()) { + __malloc_unlock_stack_logging(); + return; + } + + malloc_stack_id stack_id = __enter_stack_into_table_while_locked(self_thread, 0, false, ptr_size); + + __malloc_unlock_stack_logging(); + + if (stack_id == __invalid_stack_id) { + malloc_printf("bad stack id. turning off stack logging\n"); + turn_off_stack_logging(); + } else { + set_stack_id_in_ptr(ptr, requested_size, ptr_size, stack_id); + } +} + +static boolean_t stack_logging_lite_enabled = false; + +boolean_t is_stack_logging_lite_enabled(void) { + return stack_logging_lite_enabled; +} + +void +enable_stack_logging_lite() +{ + stack_logging_lite_enabled = true; +} + +void +disable_stack_logging_lite() +{ + stack_logging_lite_enabled = false; +} + +static void * +stack_logging_lite_malloc(malloc_zone_t *zone, size_t size) +{ + szone_t *szone = (szone_t *) zone; + void* p = NULL; + static uint64_t num_mallocs = 0; + + if (stack_logging_lite_enabled) { + __prepare_to_log_stacks(true); // do this again in case stack logging was postponed + + p = szone_malloc(szone, size + sizeof(malloc_stack_id)); + + if (p) { + add_stack_to_ptr(szone, size, p); + } + + // this value doesn't need to be exact, so no need for atomic operations + num_mallocs++; + + if (max_lite_mallocs > 0 && num_mallocs > max_lite_mallocs) { + malloc_printf("lite allocations exceeded limit. disabling lite mode\n"); + disable_stack_logging_lite(); + } + } else { + p = szone->helper_zone->basic_zone.malloc((malloc_zone_t *) szone->helper_zone, size); + } + + return p; +} + +static void * +stack_logging_lite_calloc(struct _malloc_zone_t *zone, size_t num_items, size_t size) +{ + szone_t *szone = (szone_t *) zone; + void *p = NULL; + + if (stack_logging_lite_enabled) { + size_t total_bytes = (num_items * size) + sizeof(malloc_stack_id); + + if (num_items > 1) { + +#if __LP64__ /* size_t is uint64_t */ + if ((num_items | size) & 0xffffffff00000000ul) { + // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic + __uint128_t product = (((__uint128_t)num_items) * ((__uint128_t)size)) + sizeof(malloc_stack_id); + if ((uint64_t)(product >> 64)) { // compiles to test on upper register of register pair + return NULL; + } + } +#else /* size_t is uint32_t */ + if ((num_items | size) & 0xffff0000ul) { + // num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic + uint64_t product = ((uint64_t)num_items) * ((uint64_t)size) + sizeof(malloc_stack_id);; + if ((uint32_t)(product >> 32)) { // compiles to test on upper register of register pair + return NULL; + } + } +#endif + + } + + p = szone_malloc_should_clear(szone, total_bytes, 1); + + if (p) { + add_stack_to_ptr(szone, num_items * size, p); + } + } else { + p = szone->helper_zone->basic_zone.calloc((malloc_zone_t *) szone->helper_zone, num_items, size); + } + + return p; +} + +static void * +stack_logging_lite_valloc(malloc_zone_t *zone, size_t size) +{ + szone_t *szone = (szone_t *) zone; + void *p = NULL; + + if (stack_logging_lite_enabled) { + p = szone_valloc(szone, size + sizeof(malloc_stack_id)); + + if (p) { + add_stack_to_ptr(szone, size, p); + } + } else { + p = szone->helper_zone->basic_zone.valloc((malloc_zone_t *) szone->helper_zone, size); + } + + return p; +} + +static void +stack_logging_lite_free(malloc_zone_t *zone, void *ptr) +{ + szone_t *szone = (szone_t *) zone; + size_t size = szone_size(szone, ptr); + + // see if it's in our zone + if (size) { + malloc_stack_id stack_id = get_stack_id_from_ptr(ptr, size); + __decrement_table_slot_refcount(stack_id, size); + szone_free(szone, ptr); + } else { + szone->helper_zone->basic_zone.free((malloc_zone_t *) szone->helper_zone, ptr); + } +} + +static void +stack_logging_lite_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size) +{ + // because we've messed with the size, don't try to be fancy and just call free + stack_logging_lite_free(zone, ptr); +} + +// Three paths: +// 1. do a szone_realloc with padding and add stack id +// 2. do a szone_realloc on the helper zone +// 3. do a manual free / malloc + +static void * +stack_logging_lite_realloc(malloc_zone_t *zone, void *ptr, size_t new_size) +{ + szone_t *szone = (szone_t *) zone; + void *new_ptr = NULL; + + size_t old_size = szone_size(szone, ptr); + + // if we own the ptr and lite enabled do our thing + if (old_size && stack_logging_lite_enabled) { + // need to get the old stackid and decrement + malloc_stack_id stack_id = get_stack_id_from_ptr(ptr, old_size); + new_ptr = szone_realloc(szone, ptr, new_size + sizeof(malloc_stack_id)); + + if (new_ptr) { + __decrement_table_slot_refcount(stack_id, old_size); + add_stack_to_ptr(szone, new_size, new_ptr); + } + } else if (!old_size && !stack_logging_lite_enabled) { + // we don't own the pointer and lite mode is disabled, so just pass the realloc on to the helper zone + return szone->helper_zone->basic_zone.realloc((malloc_zone_t *) szone->helper_zone, ptr, new_size); + } else { + // otherwise perform the realloc by hand: + // 1. malloc new ptr + // 2. copy existing data to new ptr + // 3. free old ptr + + // this will add the stack id if needed + new_ptr = stack_logging_lite_malloc(zone, new_size); + + if (new_ptr) { + size_t old_size = malloc_size(ptr); + size_t new_size = malloc_size(new_ptr); + + // copy as much old data as possible + size_t copy_size = MIN(old_size, new_size); + memcpy(new_ptr, ptr, copy_size); + } + + stack_logging_lite_free(zone, ptr); + } + + return new_ptr; +} + +static void * MALLOC_NOINLINE +stack_logging_lite_memalign(malloc_zone_t *zone, size_t alignment, size_t size) +{ + szone_t *szone = (szone_t *) zone; + void *ptr = NULL; + + if (stack_logging_lite_enabled) { + ptr = szone_memalign(szone, alignment, size + sizeof(malloc_stack_id)); + + if (ptr) { + add_stack_to_ptr(szone, size, ptr); + } + } else { + ptr = szone->helper_zone->basic_zone.memalign((malloc_zone_t *) szone->helper_zone, alignment, size); + } + + return ptr; +} + +static size_t +stack_logging_lite_size(malloc_zone_t *zone, const void *ptr) +{ + szone_t *szone = (szone_t *) zone; + size_t size = szone_size(szone, ptr); + + if (size) { + size -= sizeof(malloc_stack_id); + } else { + size = szone->helper_zone->basic_zone.size((malloc_zone_t *) szone->helper_zone, ptr); + } + + return size; +} + +unsigned +stack_logging_lite_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) +{ + unsigned num_allocated = 0; + + if (stack_logging_lite_enabled) { + num_allocated = szone_batch_malloc(szone, size + sizeof(malloc_stack_id), results, count); + + for (unsigned i = 0; i < num_allocated; i++) { + add_stack_to_ptr(szone, size, results[i]); + } + } else { + num_allocated = szone->helper_zone->basic_zone.batch_malloc((malloc_zone_t *) szone->helper_zone, size, results, count); + } + + return num_allocated; +} + +void +stack_logging_lite_batch_free(szone_t *szone, void **to_be_freed, unsigned count) +{ + for (unsigned i = 0; i < count; i++) { + void *p = to_be_freed[i]; + + if (p) { + size_t size = szone_size(szone, p); + + // see if it's in our zone + if (size) { + malloc_stack_id stack_id = get_stack_id_from_ptr(p, size); + __decrement_table_slot_refcount(stack_id, size); + szone_free(szone, p); + } else { + szone->helper_zone->basic_zone.free((malloc_zone_t *) szone->helper_zone, p); + } + } + } +} + + +malloc_zone_t * +create_stack_logging_lite_zone(size_t initial_size, malloc_zone_t *helper_zone, unsigned debug_flags) +{ + szone_t* zone = create_scalable_szone(initial_size, debug_flags); + + // unprotect function pointers + mprotect(zone, sizeof(zone->basic_zone), PROT_READ | PROT_WRITE); + + // set the function pointers + zone->basic_zone.malloc = stack_logging_lite_malloc; + zone->basic_zone.calloc = stack_logging_lite_calloc; + zone->basic_zone.valloc = stack_logging_lite_valloc; + zone->basic_zone.realloc = stack_logging_lite_realloc; + zone->basic_zone.batch_malloc = (void *) stack_logging_lite_batch_malloc; + zone->basic_zone.batch_free = (void *) stack_logging_lite_batch_free; + zone->basic_zone.memalign = stack_logging_lite_memalign; + zone->basic_zone.free = stack_logging_lite_free; + zone->basic_zone.free_definite_size = stack_logging_lite_free_definite_size; + zone->basic_zone.size = stack_logging_lite_size; + + // protect function pointers + mprotect(zone, sizeof(zone->basic_zone), PROT_READ); + + // set helper zone + zone->helper_zone = (szone_t*) helper_zone; + + return (malloc_zone_t*) zone; +} diff --git a/src/libmalloc/src/magazine_malloc.c b/src/libmalloc/src/magazine_malloc.c index 8f1a17e13..5b09d846c 100644 --- a/src/libmalloc/src/magazine_malloc.c +++ b/src/libmalloc/src/magazine_malloc.c @@ -24,945 +24,32 @@ /* Author: Bertrand Serlet, August 1999 */ /* - Multithread enhancements for "tiny" allocations introduced February 2008. - These are in the spirit of "Hoard". See: - Berger, E.D.; McKinley, K.S.; Blumofe, R.D.; Wilson, P.R. (2000). - "Hoard: a scalable memory allocator for multithreaded applications". - ACM SIGPLAN Notices 35 (11): 117-128. Berger2000. - - Retrieved on 2008-02-22. + * Multithread enhancements for "tiny" allocations introduced February 2008. + * These are in the spirit of "Hoard". See: + * Berger, E.D.; McKinley, K.S.; Blumofe, R.D.; Wilson, P.R. (2000). + * "Hoard: a scalable memory allocator for multithreaded applications". + * ACM SIGPLAN Notices 35 (11): 117-128. Berger2000. + * + * Retrieved on 2008-02-22. */ -/* gcc -g -O3 magazine_malloc.c malloc.c -o libmagmalloc.dylib -I. \ - -I/System/Library/Frameworks/System.framework/PrivateHeaders/ -funit-at-a-time \ - -dynamiclib -Wall -arch x86_64 -arch i386 -arch ppc */ - -#include - -#include "scalable_malloc.h" -#include "malloc_printf.h" -#include "malloc_internal.h" -#include "magmallocProvider.h" - -#include <_simple.h> -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__) -#define __APPLE_API_PRIVATE -#include -#define _COMM_PAGE_VERSION_REQD 9 -#undef __APPLE_API_PRIVATE -#else -#include -#endif - -#include -#include /* for NSVersionOfLinkTimeLibrary() */ -#include /* for _dyld_get_image_slide() */ -#include /* for _NSGetMachExecuteHeader() */ -#include -#include -#include -#include - -#include - -#define trunc_page_quanta(x) (vm_page_size >= vm_kernel_page_size ? trunc_page((x)) : trunc_page_kernel((x))) -#define round_page_quanta(x) (vm_page_size >= vm_kernel_page_size ? round_page((x)) : round_page_kernel((x))) -#define vm_page_quanta_size MAX(vm_page_size, vm_kernel_page_size) -#define vm_page_quanta_shift MAX(vm_page_shift, vm_kernel_page_shift) - -#ifndef PAGE_MAX_SIZE -/* Until xnu exposes these publically in mach/vm_param.h ... */ - -#define PAGE_MAX_SHIFT 14 -#define PAGE_MAX_SIZE (1 << PAGE_MAX_SHIFT) -#define PAGE_MAX_MASK (PAGE_MAX_SIZE-1) - -#define PAGE_MIN_SHIFT 12 -#define PAGE_MIN_SIZE (1 << PAGE_MIN_SHIFT) -#define PAGE_MIN_MASK (PAGE_MIN_MASK-1) - -#endif - -#include - -/********************* DEFINITIONS ************************/ - -#define DEBUG_MALLOC 0 // set to one to debug malloc itself - -#define DEBUG_CLIENT 0 // set to one to debug malloc client - -#define DEBUG_MADVISE 0 - -// -#define RELAXED_INVARIANT_CHECKS 1 - -#if TARGET_OS_EMBEDDED -# define MADVISE_PRESSURE_RELIEF 0 -#else -// -# define MADVISE_PRESSURE_RELIEF 1 -#endif - -#if DEBUG_MALLOC -#warning DEBUG_MALLOC ENABLED -# define INLINE -# define ALWAYSINLINE -# define CHECK_MAGAZINE_PTR_LOCKED(szone, mag_ptr, fun) \ - do { \ - if (TRY_LOCK(mag_ptr->magazine_lock)) { \ - malloc_printf("*** magazine_lock was not set %p in %s\n", \ - mag_ptr->magazine_lock, fun); \ - } \ - } while (0) -#else -# define INLINE __inline__ -# define ALWAYSINLINE __attribute__((always_inline)) -# define CHECK_MAGAZINE_PTR_LOCKED(szone, mag_ptr, fun) {} -#endif - -# define NOINLINE __attribute__((noinline)) - -#if defined(__i386__) || defined(__x86_64__) -#define CACHE_LINE 128 /* Future-proofing at 128B */ -#elif defined(__arm__) || defined(__arm64__) -#define CACHE_LINE 64 -#else -#define CACHE_LINE 32 -#endif -#define CACHE_ALIGN __attribute__ ((aligned (CACHE_LINE) )) - -#if !__LP64__ -#define ASLR_INTERNAL 1 -#endif - -#define SCRIBBLE_BYTE 0xaa /* allocated scribble */ -#define SCRABBLE_BYTE 0x55 /* free()'d scribble */ -#define SCRUBBLE_BYTE 0xdd /* madvise(..., MADV_FREE) scriblle */ - -/* - * msize - a type to refer to the number of quanta of a tiny or small - * allocation. A tiny block with an msize of 3 would be 3 << SHIFT_TINY_QUANTUM - * bytes in size. - */ -typedef unsigned short msize_t; - -typedef union { - void *p; - uintptr_t u; -} ptr_union; - -typedef struct { - ptr_union previous; - ptr_union next; -} free_list_t; - -typedef unsigned int grain_t; // N.B. wide enough to index all free slots - -typedef int mag_index_t; - -#define CHECK_REGIONS (1 << 31) -#define DISABLE_ASLR (1 << 30) - -#define MAX_RECORDER_BUFFER 256 - -/********************* DEFINITIONS for tiny ************************/ - -/* - * Memory in the Tiny range is allocated from regions (heaps) pointed to by the - * szone's hashed_regions pointer. - * - * Each region is laid out as a heap, followed by a header block, all within - * a 1MB (2^20) block. This means there are 64520 16-byte blocks and the header - * is 16138 bytes, making the total 1048458 bytes, leaving 118 bytes unused. - * - * The header block is arranged as in struct tiny_region defined just below, and - * consists of two bitfields (or bit arrays) interleaved 32 bits by 32 bits. - * - * Each bitfield comprises NUM_TINY_BLOCKS bits, and refers to the corresponding - * TINY_QUANTUM block within the heap. - * - * The bitfields are used to encode the state of memory within the heap. The header bit indicates - * that the corresponding quantum is the first quantum in a block (either in use or free). The - * in-use bit is set for the header if the block has been handed out (allocated). If the header - * bit is not set, the in-use bit is invalid. - * - * The szone maintains an array of NUM_TINY_SLOTS freelists, each of which is used to hold - * free objects of the corresponding quantum size. - * - * A free block is laid out depending on its size, in order to fit all free - * blocks in 16 bytes, on both 32 and 64 bit platforms. One quantum blocks do - * not store their size in the block, instead relying on the header information - * to determine their size. Blocks of two or more quanta have room to store - * their size in the block, and store it both after the 'next' pointer, and in - * the last 2 bytes of the block. - * - * 1-quantum block - * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 : previous - * 0x4 0x08 : next - * end end - * - * >1-quantum block - * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 : previous - * 0x4 0x08 : next - * 0x8 0x10 : size (in quantum counts) - * end - 2 end - 2 : size (in quantum counts) - * end end - * - * All fields are pointer-sized, except for the size which is an unsigned short. - * - */ - -#define SHIFT_TINY_QUANTUM 4 // Required for AltiVec -#define TINY_QUANTUM (1 << SHIFT_TINY_QUANTUM) - -#define FOLLOWING_TINY_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM)) - -#ifdef __LP64__ -#define NUM_TINY_SLOTS 64 // number of slots for free-lists -#else -#define NUM_TINY_SLOTS 32 // number of slots for free-lists -#endif - -#define NUM_TINY_BLOCKS 64520 -#define SHIFT_TINY_CEIL_BLOCKS 16 // ceil(log2(NUM_TINY_BLOCKS)) -#define NUM_TINY_CEIL_BLOCKS (1 << SHIFT_TINY_CEIL_BLOCKS) -#define TINY_BLOCKS_ALIGN (SHIFT_TINY_CEIL_BLOCKS + SHIFT_TINY_QUANTUM) // 20 - -#define TINY_ENTROPY_BITS 15 -#define TINY_ENTROPY_MASK ((1 << TINY_ENTROPY_BITS) - 1) - -/* - * Avoid having so much entropy that the end of a valid tiny allocation - * might overrun the end of the tiny region. - */ -#if TINY_ENTROPY_MASK + NUM_TINY_SLOTS > NUM_TINY_BLOCKS -#error Too many entropy bits for tiny region requested -#endif - -/* - * Enough room for the data, followed by the bit arrays (2-bits per block) - * plus rounding to the nearest page. - */ -#define CEIL_NUM_TINY_BLOCKS_WORDS (((NUM_TINY_BLOCKS + 31) & ~31) >> 5) -#define TINY_METADATA_SIZE (sizeof(region_trailer_t) + sizeof(tiny_header_inuse_pair_t) * CEIL_NUM_TINY_BLOCKS_WORDS) -#define TINY_REGION_SIZE \ - ((NUM_TINY_BLOCKS * TINY_QUANTUM + TINY_METADATA_SIZE + PAGE_MAX_SIZE - 1) & ~ (PAGE_MAX_SIZE - 1)) - -#define TINY_METADATA_START (NUM_TINY_BLOCKS * TINY_QUANTUM) - -/* - * Beginning and end pointers for a region's heap. - */ -#define TINY_REGION_ADDRESS(region) ((void *)(region)) -#define TINY_REGION_END(region) ((void *)(((uintptr_t)(region)) + (NUM_TINY_BLOCKS * TINY_QUANTUM))) - -/* - * Locate the heap base for a pointer known to be within a tiny region. - */ -#define TINY_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << TINY_BLOCKS_ALIGN) - 1))) - -/* - * Convert between byte and msize units. - */ -#define TINY_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_TINY_QUANTUM) -#define TINY_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_TINY_QUANTUM) - -#ifdef __LP64__ -# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[8]) -#else -# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[4]) -#endif -#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] - -/* - * Layout of a tiny region - */ -typedef uint32_t tiny_block_t[4]; // assert(TINY_QUANTUM == sizeof(tiny_block_t)) - -typedef struct tiny_header_inuse_pair -{ - uint32_t header; - uint32_t inuse; -} tiny_header_inuse_pair_t; - -typedef struct region_trailer -{ - struct region_trailer *prev; - struct region_trailer *next; - boolean_t recirc_suitable; - volatile int pinned_to_depot; - unsigned bytes_used; - mag_index_t mag_index; -} region_trailer_t; - -typedef struct tiny_region -{ - tiny_block_t blocks[NUM_TINY_BLOCKS]; - - region_trailer_t trailer; - - // The interleaved bit arrays comprising the header and inuse bitfields. - // The unused bits of each component in the last pair will be initialized to sentinel values. - tiny_header_inuse_pair_t pairs[CEIL_NUM_TINY_BLOCKS_WORDS]; - - uint8_t pad[TINY_REGION_SIZE - (NUM_TINY_BLOCKS * sizeof(tiny_block_t)) - TINY_METADATA_SIZE]; -} *tiny_region_t; - -/* - * Per-region meta data for tiny allocator - */ -#define REGION_TRAILER_FOR_TINY_REGION(r) (&(((tiny_region_t)(r))->trailer)) -#define MAGAZINE_INDEX_FOR_TINY_REGION(r) (REGION_TRAILER_FOR_TINY_REGION(r)->mag_index) -#define BYTES_USED_FOR_TINY_REGION(r) (REGION_TRAILER_FOR_TINY_REGION(r)->bytes_used) - -/* - * Locate the block header for a pointer known to be within a tiny region. - */ -#define TINY_BLOCK_HEADER_FOR_PTR(_p) ((void *)&(((tiny_region_t)TINY_REGION_FOR_PTR(_p))->pairs)) - -/* - * Locate the inuse map for a given block header pointer. - */ -#define TINY_INUSE_FOR_HEADER(_h) ((void *)&(((tiny_header_inuse_pair_t *)(_h))->inuse)) - -/* - * Compute the bitmap index for a pointer known to be within a tiny region. - */ -#define TINY_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_CEIL_BLOCKS - 1)) - -#define TINY_CACHE 1 // This governs a last-free cache of 1 that bypasses the free-list - -#if ! TINY_CACHE -#warning TINY_CACHE turned off -#endif - -#define TINY_REGION_PAYLOAD_BYTES (NUM_TINY_BLOCKS * TINY_QUANTUM) - -/********************* DEFINITIONS for small ************************/ - -/* - * Memory in the Small range is allocated from regions (heaps) pointed to by the szone's hashed_regions - * pointer. - * - * Each region is laid out as a heap, followed by the metadata array, all within an 8MB (2^23) block. - * The array is arranged as an array of shorts, one for each SMALL_QUANTUM in the heap. - * This means there are 16320 512-blocks and the array is 16320*2 bytes, which totals 8388480, leaving - * 128 bytes unused. - * - * The MSB of each short is set for the first quantum in a free block. The low 15 bits encode the - * block size (in SMALL_QUANTUM units), or are zero if the quantum is not the first in a block. - * - * The szone maintains an array of 32 freelists, each of which is used to hold free objects - * of the corresponding quantum size. - * - * A free block is laid out as: - * - * Offset (32-bit mode) (64-bit mode) - * 0x0 0x0 : previous - * 0x4 0x08 : next - * 0x8 0x10 : size (in quantum counts) - * end - 2 end - 2 : size (in quantum counts) - * end end - * - * All fields are pointer-sized, except for the size which is an unsigned short. - * - */ - -#define SMALL_IS_FREE (1 << 15) - -#define SHIFT_SMALL_QUANTUM (SHIFT_TINY_QUANTUM + 5) // 9 -#define SMALL_QUANTUM (1 << SHIFT_SMALL_QUANTUM) // 512 bytes - -#define FOLLOWING_SMALL_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_SMALL_QUANTUM)) - -/* - * The number of slots in the free-list for small blocks. To avoid going to - * vm system as often on large memory machines, increase the number of free list - * spots above some amount of RAM installed in the system. - */ -#define NUM_SMALL_SLOTS 32 -#define NUM_SMALL_SLOTS_LARGEMEM 256 -#define SMALL_BITMAP_WORDS 8 - -/* - * We can only represent up to 1<<15 for msize; but we choose to stay even below that to avoid the - * convention msize=0 => msize = (1<<15) - */ -#define NUM_SMALL_BLOCKS 16320 -#define SHIFT_SMALL_CEIL_BLOCKS 14 // ceil(log2(NUM_SMALL_BLOCKs)) -#define NUM_SMALL_CEIL_BLOCKS (1 << SHIFT_SMALL_CEIL_BLOCKS) -#define SMALL_BLOCKS_ALIGN (SHIFT_SMALL_CEIL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23 - -#define SMALL_ENTROPY_BITS 13 -#define SMALL_ENTROPY_MASK ((1 << SMALL_ENTROPY_BITS) - 1) - -/* - * Avoid having so much entropy that the end of a valid small allocation - * might overrun the end of the small region. - */ -#if SMALL_ENTROPY_MASK + NUM_SMALL_SLOTS > NUM_SMALL_BLOCKS -#error Too many entropy bits for small region requested -#endif - -#define SMALL_METADATA_SIZE (sizeof(region_trailer_t) + NUM_SMALL_BLOCKS * sizeof(msize_t)) -#define SMALL_REGION_SIZE \ - ((NUM_SMALL_BLOCKS * SMALL_QUANTUM + SMALL_METADATA_SIZE + PAGE_MAX_SIZE - 1) & ~ (PAGE_MAX_SIZE - 1)) - -#define SMALL_METADATA_START (NUM_SMALL_BLOCKS * SMALL_QUANTUM) - -/* - * Beginning and end pointers for a region's heap. - */ -#define SMALL_REGION_ADDRESS(region) ((unsigned char *)region) -#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region) + (NUM_SMALL_BLOCKS * SMALL_QUANTUM)) - -/* - * Locate the heap base for a pointer known to be within a small region. - */ -#define SMALL_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << SMALL_BLOCKS_ALIGN) - 1))) - -/* - * Convert between byte and msize units. - */ -#define SMALL_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_SMALL_QUANTUM) -#define SMALL_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_SMALL_QUANTUM) - -#define SMALL_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] - -/* - * Layout of a small region - */ -typedef uint32_t small_block_t[SMALL_QUANTUM/sizeof(uint32_t)]; - -typedef struct small_region -{ - small_block_t blocks[NUM_SMALL_BLOCKS]; - - region_trailer_t trailer; - - msize_t small_meta_words[NUM_SMALL_BLOCKS]; - - uint8_t pad[SMALL_REGION_SIZE - (NUM_SMALL_BLOCKS * sizeof(small_block_t)) - SMALL_METADATA_SIZE]; -} *small_region_t; - -/* - * Per-region meta data for small allocator - */ -#define REGION_TRAILER_FOR_SMALL_REGION(r) (&(((small_region_t)(r))->trailer)) -#define MAGAZINE_INDEX_FOR_SMALL_REGION(r) (REGION_TRAILER_FOR_SMALL_REGION(r)->mag_index) -#define BYTES_USED_FOR_SMALL_REGION(r) (REGION_TRAILER_FOR_SMALL_REGION(r)->bytes_used) - -/* - * Locate the metadata base for a pointer known to be within a small region. - */ -#define SMALL_META_HEADER_FOR_PTR(_p) (((small_region_t)SMALL_REGION_FOR_PTR(_p))->small_meta_words) - -/* - * Compute the metadata index for a pointer known to be within a small region. - */ -#define SMALL_META_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_CEIL_BLOCKS - 1)) - -/* - * Find the metadata word for a pointer known to be within a small region. - */ -#define SMALL_METADATA_FOR_PTR(_p) (SMALL_META_HEADER_FOR_PTR(_p) + SMALL_META_INDEX_FOR_PTR(_p)) - -/* - * Determine whether a pointer known to be within a small region points to memory which is free. - */ -#define SMALL_PTR_IS_FREE(_p) (*SMALL_METADATA_FOR_PTR(_p) & SMALL_IS_FREE) - -/* - * Extract the msize value for a pointer known to be within a small region. - */ -#define SMALL_PTR_SIZE(_p) (*SMALL_METADATA_FOR_PTR(_p) & ~SMALL_IS_FREE) - -#define SMALL_CACHE 1 -#if !SMALL_CACHE -#warning SMALL_CACHE turned off -#endif - -#define SMALL_REGION_PAYLOAD_BYTES (NUM_SMALL_BLOCKS * SMALL_QUANTUM) - -/************************* DEFINITIONS for large ****************************/ - -#define LARGE_THRESHOLD (15 * 1024) // strictly above this use "large" -#define LARGE_THRESHOLD_LARGEMEM (127 * 1024) - -#if (LARGE_THRESHOLD > NUM_SMALL_SLOTS * SMALL_QUANTUM) -#error LARGE_THRESHOLD should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM -#endif - -#if (LARGE_THRESHOLD_LARGEMEM > NUM_SMALL_SLOTS_LARGEMEM * SMALL_QUANTUM) -#error LARGE_THRESHOLD_LARGEMEM should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM -#endif - -/* - * When all memory is touched after a copy, vm_copy() is always a lose - * But if the memory is only read, vm_copy() wins over memmove() at 3 or 4 pages - * (on a G3/300MHz) - * - * This must be larger than LARGE_THRESHOLD - */ -#define VM_COPY_THRESHOLD (40 * 1024) -#define VM_COPY_THRESHOLD_LARGEMEM (128 * 1024) - -typedef struct { - vm_address_t address; - vm_size_t size; - boolean_t did_madvise_reusable; -} large_entry_t; - -#if !TARGET_OS_EMBEDDED -#define LARGE_CACHE 1 -#else -#define LARGE_CACHE 0 -#endif -#if !LARGE_CACHE -#warning LARGE_CACHE turned off -#endif -#if defined(__LP64__) -#define LARGE_ENTRY_CACHE_SIZE 16 -#define LARGE_CACHE_SIZE_LIMIT ((vm_size_t)0x80000000) /* 2Gb */ -#else -#define LARGE_ENTRY_CACHE_SIZE 8 -#define LARGE_CACHE_SIZE_LIMIT ((vm_size_t)0x02000000) /* 32Mb */ -#endif -#define LARGE_CACHE_SIZE_ENTRY_LIMIT (LARGE_CACHE_SIZE_LIMIT/LARGE_ENTRY_CACHE_SIZE) - -#define SZONE_FLOTSAM_THRESHOLD_LOW (1024 * 512) -#define SZONE_FLOTSAM_THRESHOLD_HIGH (1024 * 1024) - -/******************************************************************************* - * Definitions for region hash - ******************************************************************************/ - -typedef void * region_t; -typedef region_t * rgnhdl_t; /* A pointer into hashed_regions array. */ - -#define INITIAL_NUM_REGIONS_SHIFT 6 // log2(INITIAL_NUM_REGIONS) -#define INITIAL_NUM_REGIONS (1 << INITIAL_NUM_REGIONS_SHIFT) // Must be a power of 2! -#define HASHRING_OPEN_ENTRY ((region_t) 0) // Initial value and sentinel marking end of collision chain -#define HASHRING_REGION_DEALLOCATED ((region_t)-1) // Region at this slot reclaimed by OS -#define HASH_BLOCKS_ALIGN TINY_BLOCKS_ALIGN // MIN( TINY_BLOCKS_ALIGN, SMALL_BLOCKS_ALIGN, ... ) - -typedef struct region_hash_generation { - size_t num_regions_allocated; - size_t num_regions_allocated_shift; // log2(num_regions_allocated) - region_t *hashed_regions; // hashed by location - struct region_hash_generation *nextgen; -} region_hash_generation_t; - -/******************************************************************************* - * Per-processor magazine for tiny and small allocators - ******************************************************************************/ - -typedef struct { // vm_allocate()'d, so the array of magazines is page-aligned to begin with. - // Take magazine_lock first, Depot lock when needed for recirc, then szone->{tiny,small}_regions_lock when needed for alloc - _malloc_lock_s magazine_lock CACHE_ALIGN; - // Protection for the crtical section that does allocate_pages outside the magazine_lock - volatile boolean_t alloc_underway; - - // One element deep "death row", optimizes malloc/free/malloc for identical size. - void *mag_last_free; // low SHIFT_{TINY,SMALL}_QUANTUM bits indicate the msize - region_t mag_last_free_rgn; // holds the region for mag_last_free - - free_list_t *mag_free_list[256]; // assert( 256 >= MAX( NUM_TINY_SLOTS, NUM_SMALL_SLOTS_LARGEMEM )) - unsigned mag_bitmap[8]; // assert( sizeof(mag_bitmap) << 3 >= sizeof(mag_free_list)/sizeof(free_list_t) ) - - // the first and last free region in the last block are treated as big blocks in use that are not accounted for - size_t mag_bytes_free_at_end; - size_t mag_bytes_free_at_start; - region_t mag_last_region; // Valid iff mag_bytes_free_at_end || mag_bytes_free_at_start > 0 - - // bean counting ... - unsigned mag_num_objects; - size_t mag_num_bytes_in_objects; - size_t num_bytes_in_magazine; - - // recirculation list -- invariant: all regions owned by this magazine that meet the emptiness criteria - // are located nearer to the head of the list than any region that doesn't satisfy that criteria. - // Doubly linked list for efficient extraction. - unsigned recirculation_entries; - region_trailer_t *firstNode; - region_trailer_t *lastNode; - - uintptr_t pad[50-CACHE_LINE/sizeof(uintptr_t)]; -} magazine_t; - -#ifdef __has_extension -#if __has_extension(c_static_assert) -#if __LP64__ -_Static_assert(sizeof(magazine_t) == 2560, "Incorrect padding in magazine_t"); -#else -_Static_assert(sizeof(magazine_t) == 1280, "Incorrect padding in magazine_t"); -#endif -#endif -#endif - -#define TINY_MAX_MAGAZINES 32 /* MUST BE A POWER OF 2! */ -#define TINY_MAGAZINE_PAGED_SIZE \ -(((sizeof(magazine_t) * (TINY_MAX_MAGAZINES + 1)) + vm_page_quanta_size - 1) &\ -~ (vm_page_quanta_size - 1)) /* + 1 for the Depot */ - -#define SMALL_MAX_MAGAZINES 32 /* MUST BE A POWER OF 2! */ -#define SMALL_MAGAZINE_PAGED_SIZE \ -(((sizeof(magazine_t) * (SMALL_MAX_MAGAZINES + 1)) + vm_page_quanta_size - 1) &\ -~ (vm_page_quanta_size - 1)) /* + 1 for the Depot */ - -#define DEPOT_MAGAZINE_INDEX -1 - -/****************************** zone itself ***********************************/ - -/* - * Note that objects whose adddress are held in pointers here must be pursued - * individually in the {tiny,small}_in_use_enumeration() routines. See for - * example the treatment of region_hash_generation and tiny_magazines below. - */ - -typedef struct szone_s { // vm_allocate()'d, so page-aligned to begin with. - malloc_zone_t basic_zone; // first page will be given read-only protection - uint8_t pad[PAGE_MAX_SIZE - sizeof(malloc_zone_t)]; - - unsigned long cpu_id_key; // unused - // remainder of structure is R/W (contains no function pointers) - unsigned debug_flags; - void *log_address; - - /* Regions for tiny objects */ - _malloc_lock_s tiny_regions_lock CACHE_ALIGN; - size_t num_tiny_regions; - size_t num_tiny_regions_dealloc; - region_hash_generation_t *tiny_region_generation; - region_hash_generation_t trg[2]; - - int num_tiny_magazines; - unsigned num_tiny_magazines_mask; - int num_tiny_magazines_mask_shift; - magazine_t *tiny_magazines; // array of per-processor magazines - - uintptr_t last_tiny_advise; - - /* Regions for small objects */ - _malloc_lock_s small_regions_lock CACHE_ALIGN; - size_t num_small_regions; - size_t num_small_regions_dealloc; - region_hash_generation_t *small_region_generation; - region_hash_generation_t srg[2]; - - unsigned num_small_slots; // determined by physmem size - - int num_small_magazines; - unsigned num_small_magazines_mask; - int num_small_magazines_mask_shift; - magazine_t *small_magazines; // array of per-processor magazines - - uintptr_t last_small_advise; - - /* large objects: all the rest */ - _malloc_lock_s large_szone_lock CACHE_ALIGN; // One customer at a time for large - unsigned num_large_objects_in_use; - unsigned num_large_entries; - large_entry_t *large_entries; // hashed by location; null entries don't count - size_t num_bytes_in_large_objects; - -#if LARGE_CACHE - int large_entry_cache_oldest; - int large_entry_cache_newest; - large_entry_t large_entry_cache[LARGE_ENTRY_CACHE_SIZE]; // "death row" for large malloc/free - boolean_t large_legacy_reset_mprotect; - size_t large_entry_cache_reserve_bytes; - size_t large_entry_cache_reserve_limit; - size_t large_entry_cache_bytes; // total size of death row, bytes -#endif - - /* flag and limits pertaining to altered malloc behavior for systems with - large amounts of physical memory */ - unsigned is_largemem; - unsigned large_threshold; - unsigned vm_copy_threshold; - - /* security cookie */ - uintptr_t cookie; - - /* Initial region list */ - region_t initial_tiny_regions[INITIAL_NUM_REGIONS]; - region_t initial_small_regions[INITIAL_NUM_REGIONS]; - - /* The purgeable zone constructed by create_purgeable_zone() would like to hand off tiny and small - * allocations to the default scalable zone. Record the latter as the "helper" zone here. */ - struct szone_s *helper_zone; - - boolean_t flotsam_enabled; -} szone_t; - -#define SZONE_PAGED_SIZE round_page_quanta((sizeof(szone_t))) - -#if DEBUG_MALLOC || DEBUG_CLIENT -static void szone_sleep(void); -#endif -extern void malloc_error_break(void); - -// msg prints after fmt, ... -static NOINLINE void szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...) -__printflike(5, 6); - -static void protect(void *address, size_t size, unsigned protection, unsigned debug_flags); -static void *allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, - int vm_page_label); -static void *allocate_pages_securely(szone_t *szone, size_t size, unsigned char align, - int vm_page_label); -static void deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags); -static int madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi, uintptr_t *last); -static kern_return_t _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr); - -static INLINE mag_index_t mag_get_thread_index(szone_t *szone) ALWAYSINLINE; -static magazine_t *mag_lock_zine_for_region_trailer(szone_t *szone, magazine_t *magazines, region_trailer_t *trailer, - mag_index_t mag_index); - -static INLINE rgnhdl_t hash_lookup_region_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) -ALWAYSINLINE; -static void hash_region_insert_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r); -static region_t *hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries); -static region_t *hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, - size_t *mutable_shift, size_t *new_size); - -static INLINE uintptr_t free_list_gen_checksum(uintptr_t ptr) ALWAYSINLINE; -static INLINE uintptr_t free_list_checksum_ptr(szone_t *szone, void *p) ALWAYSINLINE; -static INLINE void *free_list_unchecksum_ptr(szone_t *szone, ptr_union *ptr) ALWAYSINLINE; -static unsigned free_list_count(szone_t *szone, free_list_t *ptr); - -static INLINE void recirc_list_extract(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) ALWAYSINLINE; -static INLINE void recirc_list_splice_last(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) ALWAYSINLINE; -static INLINE void recirc_list_splice_first(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) ALWAYSINLINE; - -static INLINE void BITARRAY_SET(uint32_t *bits, msize_t index) ALWAYSINLINE; -static INLINE void BITARRAY_CLR(uint32_t *bits, msize_t index) ALWAYSINLINE; -static INLINE boolean_t BITARRAY_BIT(uint32_t *bits, msize_t index) ALWAYSINLINE; - -static msize_t get_tiny_free_size(const void *ptr); -static msize_t get_tiny_previous_free_msize(const void *ptr); -static INLINE msize_t get_tiny_meta_header(const void *ptr, boolean_t *is_free) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_in_use(const void *ptr, msize_t msize) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_in_use_1(const void *ptr) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_middle(const void *ptr) ALWAYSINLINE; -static INLINE void set_tiny_meta_header_free(const void *ptr, msize_t msize) ALWAYSINLINE; -static INLINE boolean_t tiny_meta_header_is_free(const void *ptr) ALWAYSINLINE; -static INLINE void *tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) ALWAYSINLINE; - -static void tiny_free_list_add_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize); -static void tiny_free_list_remove_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize); -static INLINE region_t tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; - -static void tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr); -static int tiny_free_detach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r); -static size_t tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r); -static void tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r); -static region_t tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node); -static boolean_t tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index); -static region_t tiny_find_msize_region(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize); -static boolean_t tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize); - -static INLINE boolean_t tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, - void *ptr, msize_t msize) ALWAYSINLINE; -static void *tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, - msize_t msize, void *fresh_region); -static boolean_t tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size); -static boolean_t tiny_check_region(szone_t *szone, region_t region); -static kern_return_t tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, - memory_reader_t reader, vm_range_recorder_t recorder); -static void *tiny_malloc_from_free_list(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, - msize_t msize); -static INLINE void *tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE; -static INLINE void free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size) ALWAYSINLINE; -static void print_tiny_free_list(szone_t *szone); -static void print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end); -static boolean_t tiny_free_list_check(szone_t *szone, grain_t slot); - -static INLINE void small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize) ALWAYSINLINE; -static INLINE void small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) ALWAYSINLINE; -static INLINE void small_meta_header_set_middle(msize_t *meta_headers, msize_t index) ALWAYSINLINE; -static void small_free_list_add_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize); -static void small_free_list_remove_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize); -static INLINE region_t small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE; - -static void small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr); -static int small_free_detach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r); -static size_t small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r); -static void small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r); -static region_t small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node); -static boolean_t small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index); -static region_t small_find_msize_region(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize); -static boolean_t small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize); -static INLINE boolean_t small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region, - void *ptr, msize_t msize) ALWAYSINLINE; -static void *small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, - msize_t msize, void *fresh_region); -static boolean_t small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size); -static boolean_t small_check_region(szone_t *szone, region_t region); -static kern_return_t small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, - memory_reader_t reader, vm_range_recorder_t recorder); -static void *small_malloc_from_free_list(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, - msize_t msize); -static INLINE void *small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE; -static INLINE void free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size) ALWAYSINLINE; -static void print_small_free_list(szone_t *szone); -static void print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end); -static boolean_t small_free_list_check(szone_t *szone, grain_t grain); - -#if DEBUG_MALLOC -static void large_debug_print(szone_t *szone); -#endif -static large_entry_t *large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr); -static void large_entry_insert_no_lock(szone_t *szone, large_entry_t range); -static INLINE void large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) ALWAYSINLINE; -static INLINE large_entry_t *large_entries_alloc_no_lock(szone_t *szone, unsigned num) ALWAYSINLINE; -static void large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, - vm_range_t *range_to_deallocate); -static large_entry_t *large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate); -static vm_range_t large_entry_free_no_lock(szone_t *szone, large_entry_t *entry); -static NOINLINE kern_return_t large_in_use_enumerator(task_t task, void *context, - unsigned type_mask, vm_address_t large_entries_address, - unsigned num_entries, memory_reader_t reader, - vm_range_recorder_t recorder); -static void *large_malloc(szone_t *szone, size_t num_kernel_pages, unsigned char alignment, boolean_t cleared_requested); -static NOINLINE void free_large(szone_t *szone, void *ptr); -static INLINE int large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE; - -/* - * Mark these NOINLINE to avoid bloating the purgeable zone call backs - */ -static NOINLINE void szone_free(szone_t *szone, void *ptr); -static NOINLINE void *szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested); -static NOINLINE void *szone_malloc(szone_t *szone, size_t size); -static NOINLINE void *szone_calloc(szone_t *szone, size_t num_items, size_t size); -static NOINLINE void *szone_valloc(szone_t *szone, size_t size); -static NOINLINE size_t szone_size_try_large(szone_t *szone, const void *ptr); -static NOINLINE size_t szone_size(szone_t *szone, const void *ptr); -static NOINLINE void *szone_realloc(szone_t *szone, void *ptr, size_t new_size); -static NOINLINE void *szone_memalign(szone_t *szone, size_t alignment, size_t size); -static NOINLINE void szone_free_definite_size(szone_t *szone, void *ptr, size_t size); -static NOINLINE unsigned szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count); -static NOINLINE void szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count); -static void szone_destroy(szone_t *szone); -static NOINLINE size_t szone_good_size(szone_t *szone, size_t size); - -static NOINLINE boolean_t szone_check_all(szone_t *szone, const char *function); -static boolean_t szone_check(szone_t *szone); -static kern_return_t szone_ptr_in_use_enumerator(task_t task, void *context, - unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, vm_range_recorder_t recorder); -static NOINLINE void szone_print(szone_t *szone, boolean_t verbose); -static void szone_log(malloc_zone_t *zone, void *log_address); -static void szone_force_lock(szone_t *szone); -static INLINE void szone_force_lock_magazine(szone_t *szone, magazine_t *mag); -static void szone_force_unlock(szone_t *szone); -static boolean_t szone_locked(szone_t *szone); - -static void szone_statistics(szone_t *szone, malloc_statistics_t *stats); - -static void purgeable_free(szone_t *szone, void *ptr); -static void *purgeable_malloc(szone_t *szone, size_t size); -static void *purgeable_calloc(szone_t *szone, size_t num_items, size_t size); -static void *purgeable_valloc(szone_t *szone, size_t size); -static size_t purgeable_size(szone_t *szone, const void *ptr); -static void *purgeable_realloc(szone_t *szone, void *ptr, size_t new_size); -static void *purgeable_memalign(szone_t *szone, size_t alignment, size_t size); -static void purgeable_free_definite_size(szone_t *szone, void *ptr, size_t size); -static unsigned purgeable_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count); -static void purgeable_batch_free(szone_t *szone, void **to_be_freed, unsigned count); -static void purgeable_destroy(szone_t *szone); -static size_t purgeable_good_size(szone_t *szone, size_t size); - -static boolean_t purgeable_check(szone_t *szone); -static kern_return_t purgeable_ptr_in_use_enumerator(task_t task, void *context, - unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, vm_range_recorder_t recorder); -static void purgeable_print(szone_t *szone, boolean_t verbose); -static void purgeable_log(malloc_zone_t *zone, void *log_address); -static void purgeable_force_lock(szone_t *szone); -static void purgeable_force_unlock(szone_t *szone); -static boolean_t purgeable_locked(szone_t *szone); - -static void purgeable_statistics(szone_t *szone, malloc_statistics_t *stats); - -static void *frozen_malloc(szone_t *zone, size_t new_size); -static void *frozen_calloc(szone_t *zone, size_t num_items, size_t size); -static void *frozen_valloc(szone_t *zone, size_t new_size); -static void *frozen_realloc(szone_t *zone, void *ptr, size_t new_size); -static void frozen_free(szone_t *zone, void *ptr); -static void frozen_destroy(szone_t *zone); +#include "internal.h" static volatile uintptr_t entropic_address = 0; static volatile uintptr_t entropic_limit = 0; #define ENTROPIC_KABILLION 0x10000000 /* 256Mb */ -extern uint64_t malloc_entropy[2]; - -static inline void -SZONE_LOCK(szone_t *szone) { - _malloc_lock_lock(&szone->large_szone_lock); -} - -static inline void -SZONE_UNLOCK(szone_t *szone) { - _malloc_lock_unlock(&szone->large_szone_lock); -} - -static inline bool -SZONE_TRY_LOCK(szone_t *szone) { - return _malloc_lock_trylock(&szone->large_szone_lock); -} - -static inline void -SZONE_MAGAZINE_PTR_LOCK(szone_t *szone, magazine_t *mag_ptr) { - _malloc_lock_lock(&mag_ptr->magazine_lock); -} - -static inline void -SZONE_MAGAZINE_PTR_UNLOCK(szone_t *szone, magazine_t *mag_ptr) { - _malloc_lock_unlock(&mag_ptr->magazine_lock); -} - -static inline bool -SZONE_MAGAZINE_PTR_TRY_LOCK(szone_t *szone, magazine_t *mag_ptr) { - return _malloc_lock_trylock(&mag_ptr->magazine_lock); -} - -static inline void yield(void) { - thread_switch(MACH_PORT_NULL, SWITCH_OPTION_DEPRESS, 1); -} - -#if DEBUG_MALLOC -# define LOG(szone,ptr) \ - (szone->log_address && (((uintptr_t)szone->log_address == -1) || \ - (szone->log_address == (void *)(ptr)))) -#else -# define LOG(szone,ptr) 0 +// align 64bit ARM shift to 32MB PTE entries +#if MALLOC_TARGET_IOS && MALLOC_TARGET_64BIT +#define ENTROPIC_SHIFT 25 +#else // MALLOC_TARGET_IOS && MALLOC_TARGET_64BIT +#define ENTROPIC_SHIFT SMALL_BLOCKS_ALIGN #endif -#if DEBUG_MALLOC || DEBUG_CLIENT -# define CHECK(szone,fun) \ - if ((szone)->debug_flags & CHECK_REGIONS) \ - szone_check_all(szone, fun) +#if DEBUG_MALLOC +#define LOG(szone, ptr) (szone->log_address && (((uintptr_t)szone->log_address == -1) || (szone->log_address == (void *)(ptr)))) #else -# define CHECK(szone,fun) \ - do {} while (0) +#define LOG(szone, ptr) 0 #endif /********************* VERY LOW LEVEL UTILITIES ************************/ @@ -980,7 +67,7 @@ szone_sleep(void) } // msg prints after fmt, ... -static NOINLINE void +void szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...) { va_list ap; @@ -1023,41 +110,40 @@ szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, szone_sleep(); // Call abort() if this is a memory corruption error and the abort on // corruption flag is set, or if any error should abort. - if ((is_corruption && (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_CORRUPTION)) || - (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_ERROR)) { - CRSetCrashLogMessage(b ? _simple_string(b) : msg); + if ((is_corruption && (szone->debug_flags & MALLOC_ABORT_ON_CORRUPTION)) || + (szone->debug_flags & MALLOC_ABORT_ON_ERROR)) { + _os_set_crash_log_message_dynamic(b ? _simple_string(b) : msg); abort(); } else if (b) { _simple_sfree(b); } } -static void +void protect(void *address, size_t size, unsigned protection, unsigned debug_flags) { - kern_return_t err; + kern_return_t err; - if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_PRELUDE)) { + if (!(debug_flags & MALLOC_DONT_PROTECT_PRELUDE)) { err = mprotect((void *)((uintptr_t)address - vm_page_quanta_size), vm_page_quanta_size, protection); if (err) { - malloc_printf("*** can't protect(%p) region for prelude guard page at %p\n", - protection,(uintptr_t)address - vm_page_quanta_size); + malloc_printf("*** can't protect(%p) region for prelude guard page at %p\n", protection, + (uintptr_t)address - vm_page_quanta_size); } } - if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE)) { + if (!(debug_flags & MALLOC_DONT_PROTECT_POSTLUDE)) { err = mprotect((void *)(round_page_quanta(((uintptr_t)address + size))), vm_page_quanta_size, protection); if (err) { - malloc_printf("*** can't protect(%p) region for postlude guard page at %p\n", - protection, (uintptr_t)address + size); + malloc_printf("*** can't protect(%p) region for postlude guard page at %p\n", protection, (uintptr_t)address + size); } } } -static void * +void * allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label) { - boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; - boolean_t purgeable = debug_flags & SCALABLE_MALLOC_PURGEABLE; + boolean_t add_guard_pages = debug_flags & MALLOC_ADD_GUARD_PAGES; + boolean_t purgeable = debug_flags & MALLOC_PURGEABLE; mach_vm_address_t vm_addr; uintptr_t addr; mach_vm_size_t allocation_size = round_page_quanta(size); @@ -1065,27 +151,30 @@ allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_ int alloc_flags = VM_FLAGS_ANYWHERE | VM_MAKE_TAG(vm_page_label); kern_return_t kr; - if (!allocation_size) allocation_size = vm_page_quanta_size; + if (!allocation_size) { + allocation_size = vm_page_quanta_size; + } if (add_guard_pages) { if (align > vm_page_quanta_shift) { /* alignment greater than pagesize needs more work */ - allocation_size += (1< pgLo) { size_t len = pgHi - pgLo; - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) { + if (szone->debug_flags & MALLOC_DO_SCRIBBLE) { memset((void *)pgLo, SCRUBBLE_BYTE, len); // Scribble on MADV_FREEd memory } #if TARGET_OS_EMBEDDED if (last) { - if (*last == pgLo) + if (*last == pgLo) { return 0; + } *last = pgLo; } #endif - MAGMALLOC_MADVFREEREGION((void *)szone, (void *)r, (void *)pgLo, len); // DTrace USDT Probe - if (-1 == madvise((void *)pgLo, len, MADVISE_STYLE)) { - /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ + MAGMALLOC_MADVFREEREGION((void *)szone, (void *)r, (void *)pgLo, (int)len); // DTrace USDT Probe + if (-1 == madvise((void *)pgLo, len, CONFIG_MADVISE_STYLE)) { +/* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ #if DEBUG_MADVISE - szone_error(szone, 0, "madvise_free_range madvise(..., MADV_FREE_REUSABLE) failed", - (void *)pgLo, "length=%d\n", len); + szone_error(szone, 0, "madvise_free_range madvise(..., MADV_FREE_REUSABLE) failed", (void *)pgLo, "length=%d\n", len); #endif } } return 0; } -static int +int madvise_reuse_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t phHi) { -#if !TARGET_OS_EMBEDDED if (phHi > pgLo) { size_t len = phHi - pgLo; if (madvise((void *)pgLo, len, MADV_FREE_REUSE) == -1) { - /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ +/* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ #if DEBUG_MADVISE - szone_error(szone, 0, "madvise_reuse_range madvise(..., MADV_FREE_REUSE) failed", - sparse_region, "length=%d\n", TINY_REGION_PAYLOAD_BYTES); + szone_error(szone, 0, "madvise_reuse_range madvise(..., MADV_FREE_REUSE) failed", sparse_region, "length=%d\n", + TINY_REGION_PAYLOAD_BYTES); #endif return 1; } } -#endif - return 0; -} - -static kern_return_t -_szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) -{ - *ptr = (void *)address; return 0; } +/********************* Zone call backs ************************/ /* - * These commpage routines provide fast access to the logical cpu number - * of the calling processor assuming no pre-emption occurs. + * Mark these MALLOC_NOINLINE to avoid bloating the purgeable zone call backs */ - -static INLINE mag_index_t -mag_get_thread_index(szone_t *szone) -{ - return _os_cpu_number() & (TINY_MAX_MAGAZINES - 1); -} - -static magazine_t * -mag_lock_zine_for_region_trailer(szone_t *szone, magazine_t *magazines, region_trailer_t *trailer, mag_index_t mag_index) +void +szone_free(szone_t *szone, void *ptr) { - mag_index_t refreshed_index; - magazine_t *mag_ptr = &(magazines[mag_index]); - - // Take the lock on entry. - SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr); + region_t tiny_region; + region_t small_region; - // Now in the time it took to acquire the lock, the region may have migrated - // from one magazine to another. In which case the magazine lock we obtained - // (namely magazines[mag_index].mag_lock) is stale. If so, keep on tryin' ... - while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment - - SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in szone_free with %p\n", ptr); + } +#endif + if (!ptr) { + return; + } + /* + * Try to free to a tiny region. + */ + if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) { + szone_error(szone, 1, "Non-aligned pointer being freed", ptr, NULL); + return; + } + if ((tiny_region = tiny_region_for_ptr_no_lock(szone, ptr)) != NULL) { + if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { + szone_error(szone, 1, "Pointer to metadata being freed", ptr, NULL); + return; + } + free_tiny(szone, ptr, tiny_region, 0); + return; + } - mag_index = refreshed_index; - mag_ptr = &(magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr); + /* + * Try to free to a small region. + */ + if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) { + szone_error(szone, 1, "Non-aligned pointer being freed (2)", ptr, NULL); + return; + } + if ((small_region = small_region_for_ptr_no_lock(szone, ptr)) != NULL) { + if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { + szone_error(szone, 1, "Pointer to metadata being freed (2)", ptr, NULL); + return; + } + free_small(szone, ptr, small_region, 0); + return; } - return mag_ptr; + /* check that it's a legal large allocation */ + if ((uintptr_t)ptr & (vm_page_quanta_size - 1)) { + szone_error(szone, 1, "non-page-aligned, non-allocated pointer being freed", ptr, NULL); + return; + } + free_large(szone, ptr); } -/******************************************************************************* - * Region hash implementation - * - * This is essentially a duplicate of the existing Large allocator hash, minus - * the ability to remove entries. The two should be combined eventually. - ******************************************************************************/ -#pragma mark region hash - -/* - * hash_lookup_region_no_lock - Scan a hash ring looking for an entry for a - * given region. - * - * FIXME: If consecutive queries of the same region are likely, a one-entry - * cache would likely be a significant performance win here. - */ -static INLINE rgnhdl_t -hash_lookup_region_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) { - size_t index, hash_index; - rgnhdl_t entry; +void +szone_free_definite_size(szone_t *szone, void *ptr, size_t size) +{ +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in szone_free_definite_size with %p\n", ptr); + } - if (!num_entries) - return 0; + if (0 == size) { + szone_error(szone, 1, "pointer of size zero being freed", ptr, NULL); + return; + } - // Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...] - // Since the values of (((uintptr_t)r >> HASH_BLOCKS_ALIGN) are (roughly) an ascending sequence of integers, - // this hash works really well. See Knuth TAOCP, Vol. 3. -#if __LP64__ - index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 11400714819323198549ULL) >> (64 - shift); -#else - index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 2654435761UL) >> (32 - shift); #endif - do { - entry = regions + index; - if (*entry == 0) - return 0; - if (*entry == r) - return entry; - if (++index == num_entries) - index = 0; - } while (index != hash_index); - return 0; -} + if (!ptr) { + return; + } -/* - * hash_region_insert_no_lock - Insert a region into the hash ring. - */ -static void -hash_region_insert_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) { - size_t index, hash_index; - rgnhdl_t entry; - - // Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...] - // Since the values of (((uintptr_t)r >> HASH_BLOCKS_ALIGN) are (roughly) an ascending sequence of integers, - // this hash works really well. See Knuth TAOCP, Vol. 3. -#if __LP64__ - index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 11400714819323198549ULL) >> (64 - shift); -#else - index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 2654435761UL) >> (32 - shift); -#endif - do { - entry = regions + index; - if (*entry == HASHRING_OPEN_ENTRY || *entry == HASHRING_REGION_DEALLOCATED) { - *entry = r; + /* + * Try to free to a tiny region. + */ + if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) { + szone_error(szone, 1, "Non-aligned pointer being freed", ptr, NULL); + return; + } + if (size <= SMALL_THRESHOLD) { + if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { + szone_error(szone, 1, "Pointer to metadata being freed", ptr, NULL); return; } - if (++index == num_entries) - index = 0; - } while (index != hash_index); -} - -/* - * hash_regions_alloc_no_lock - Allocate space for a number of entries. This - * must be a VM allocation as to avoid recursing between allocating a new small - * region, and asking the small region to allocate space for the new list of - * regions. - */ -static region_t * -hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries) -{ - size_t size = num_entries * sizeof(region_t); - - return allocate_pages(szone, round_page_quanta(size), 0, 0, VM_MEMORY_MALLOC); -} + free_tiny(szone, ptr, TINY_REGION_FOR_PTR(ptr), size); + return; + } -/* - * hash_regions_grow_no_lock - Grow the hash ring, and rehash the entries. - * Return the new region and new size to update the szone. Do not deallocate - * the old entries since someone may still be allocating them. - */ -static region_t * -hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, size_t *mutable_shift, - size_t *new_size) -{ - // double in size and allocate memory for the regions - *new_size = old_size + old_size; - *mutable_shift = *mutable_shift + 1; - region_t *new_regions = hash_regions_alloc_no_lock(szone, *new_size); + /* + * Try to free to a small region. + */ + if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) { + szone_error(szone, 1, "Non-aligned pointer being freed (2)", ptr, NULL); + return; + } + if (size <= szone->large_threshold) { + if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { + szone_error(szone, 1, "Pointer to metadata being freed (2)", ptr, NULL); + return; + } + free_small(szone, ptr, SMALL_REGION_FOR_PTR(ptr), size); + return; + } - // rehash the entries into the new list - size_t index; - for (index = 0; index < old_size; ++index) { - region_t r = regions[index]; - if (r != HASHRING_OPEN_ENTRY && r != HASHRING_REGION_DEALLOCATED) - hash_region_insert_no_lock(new_regions, *new_size, *mutable_shift, r); + /* check that it's a legal large allocation */ + if ((uintptr_t)ptr & (vm_page_quanta_size - 1)) { + szone_error(szone, 1, "non-page-aligned, non-allocated pointer being freed", ptr, NULL); + return; } - return new_regions; + free_large(szone, ptr); } -/********************* FREE LIST UTILITIES ************************/ - -// A free list entry is comprised of a pair of pointers, previous and next. -// These are used to implement a doubly-linked list, which permits efficient -// extraction. -// -// Because the free list entries are previously freed objects, a misbehaved -// program may write to a pointer after it has called free() on that pointer, -// either by dereference or buffer overflow from an adjacent pointer. This write -// would then corrupt the free list's previous and next pointers, leading to a -// crash. In order to detect this case, we take advantage of the fact that -// malloc'd pointers are known to be at least 16 byte aligned, and thus have -// at least 4 trailing zero bits. -// -// When an entry is added to the free list, a checksum of the previous and next -// pointers is calculated and written to the high four bits of the respective -// pointers. Upon detection of an invalid checksum, an error is logged and NULL -// is returned. Since all code which un-checksums pointers checks for a NULL -// return, a potentially crashing or malicious dereference is avoided at the -// cost of leaking the corrupted block, and any subsequent blocks on the free -// list of that size. - -static NOINLINE void -free_list_checksum_botch(szone_t *szone, free_list_t *ptr) +MALLOC_NOINLINE void * +szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested) { - szone_error(szone, 1, "incorrect checksum for freed object " - "- object was probably modified after being freed.", ptr, NULL); -} + void *ptr; + msize_t msize; -static INLINE uintptr_t free_list_gen_checksum(uintptr_t ptr) -{ - uint8_t chk; - - chk = (unsigned char)(ptr >> 0); - chk += (unsigned char)(ptr >> 8); - chk += (unsigned char)(ptr >> 16); - chk += (unsigned char)(ptr >> 24); -#if __LP64__ - chk += (unsigned char)(ptr >> 32); - chk += (unsigned char)(ptr >> 40); - chk += (unsigned char)(ptr >> 48); - chk += (unsigned char)(ptr >> 56); + if (size <= SMALL_THRESHOLD) { + // tiny size: <1024 bytes (64-bit), <512 bytes (32-bit) + // think tiny + msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); + if (!msize) { + msize = 1; + } + ptr = tiny_malloc_should_clear(szone, msize, cleared_requested); + } else if (size <= szone->large_threshold) { + // small size: <15k (<1GB machines), <127k (>1GB machines) + // think small + msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); + if (!msize) { + msize = 1; + } + ptr = small_malloc_should_clear(szone, msize, cleared_requested); + } else { + // large: all other allocations + size_t num_kernel_pages = round_page_quanta(size) >> vm_page_quanta_shift; + if (num_kernel_pages == 0) { /* Overflowed */ + ptr = 0; + } else { + ptr = large_malloc(szone, num_kernel_pages, 0, cleared_requested); + } + } +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("szone_malloc returned %p\n", ptr); + } #endif + /* + * If requested, scribble on allocated memory. + */ + if ((szone->debug_flags & MALLOC_DO_SCRIBBLE) && ptr && !cleared_requested && size) { + memset(ptr, SCRIBBLE_BYTE, szone_size(szone, ptr)); + } - return chk & (uintptr_t)0xF; + return ptr; } -#define NYBBLE 4 -#if __LP64__ -#define ANTI_NYBBLE (64 - NYBBLE) -#else -#define ANTI_NYBBLE (32 - NYBBLE) -#endif - -static INLINE uintptr_t -free_list_checksum_ptr(szone_t *szone, void *ptr) +void * +szone_malloc(szone_t *szone, size_t size) { - uintptr_t p = (uintptr_t)ptr; - return (p >> NYBBLE) | (free_list_gen_checksum(p ^ szone->cookie) << ANTI_NYBBLE); // compiles to rotate instruction + return szone_malloc_should_clear(szone, size, 0); } -static INLINE void * -free_list_unchecksum_ptr(szone_t *szone, ptr_union *ptr) +void * +szone_calloc(szone_t *szone, size_t num_items, size_t size) { - ptr_union p; - uintptr_t t = ptr->u; - - t = (t << NYBBLE) | (t >> ANTI_NYBBLE); // compiles to rotate instruction - p.u = t & ~(uintptr_t)0xF; + size_t total_bytes = num_items * size; - if ((t & (uintptr_t)0xF) != free_list_gen_checksum(p.u ^ szone->cookie)) - { - free_list_checksum_botch(szone, (free_list_t *)ptr); - return NULL; + // Check for overflow of integer multiplication + if (num_items > 1) { +#if __LP64__ /* size_t is uint64_t */ + if ((num_items | size) & 0xffffffff00000000ul) { + // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic + __uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size); + if ((uint64_t)(product >> 64)) { // compiles to test on upper register of register pair + return NULL; + } + } +#else /* size_t is uint32_t */ + if ((num_items | size) & 0xffff0000ul) { + // num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic + uint64_t product = ((uint64_t)num_items) * ((uint64_t)size); + if ((uint32_t)(product >> 32)) { // compiles to test on upper register of register pair + return NULL; + } + } +#endif } - return p.p; -} - -#undef ANTI_NYBBLE -#undef NYBBLE - -static unsigned -free_list_count(szone_t *szone, free_list_t *ptr) -{ - unsigned count = 0; - while (ptr) { - count++; - ptr = free_list_unchecksum_ptr(szone, &ptr->next); - } - return count; + return szone_malloc_should_clear(szone, total_bytes, 1); } -static INLINE void -recirc_list_extract(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) +void * +szone_valloc(szone_t *szone, size_t size) { - // excise node from list - if (NULL == node->prev) - mag_ptr->firstNode = node->next; - else - node->prev->next = node->next; - - if (NULL == node->next) - mag_ptr->lastNode = node->prev; - else - node->next->prev = node->prev; - - mag_ptr->recirculation_entries--; -} + void *ptr; -static INLINE void -recirc_list_splice_last(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) -{ - if (NULL == mag_ptr->lastNode) { - mag_ptr->firstNode = node; - node->prev = NULL; + if (size <= szone->large_threshold) { + ptr = szone_memalign(szone, vm_page_quanta_size, size); } else { - node->prev = mag_ptr->lastNode; - mag_ptr->lastNode->next = node; - } - mag_ptr->lastNode = node; - node->next = NULL; - node->recirc_suitable = FALSE; - mag_ptr->recirculation_entries++; -} + size_t num_kernel_pages; -static INLINE void -recirc_list_splice_first(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) -{ - if (NULL == mag_ptr->firstNode) { - mag_ptr->lastNode = node; - node->next = NULL; - } else { - node->next = mag_ptr->firstNode; - mag_ptr->firstNode->prev = node; + num_kernel_pages = round_page_quanta(size) >> vm_page_quanta_shift; + ptr = large_malloc(szone, num_kernel_pages, 0, 0); } - mag_ptr->firstNode = node; - node->prev = NULL; - node->recirc_suitable = FALSE; - mag_ptr->recirculation_entries++; -} - -/* Macros used to manipulate the uint32_t quantity mag_bitmap. */ -/* BITMAPV variants are used by tiny. */ -#if defined(__LP64__) -// assert(NUM_SLOTS == 64) in which case (slot >> 5) is either 0 or 1 -#define BITMAPV_SET(bitmap,slot) (bitmap[(slot) >> 5] |= 1 << ((slot) & 31)) -#define BITMAPV_CLR(bitmap,slot) (bitmap[(slot) >> 5] &= ~ (1 << ((slot) & 31))) -#define BITMAPV_BIT(bitmap,slot) ((bitmap[(slot) >> 5] >> ((slot) & 31)) & 1) -#define BITMAPV_CTZ(bitmap) (__builtin_ctzl(bitmap)) -#else -// assert(NUM_SLOTS == 32) in which case (slot >> 5) is always 0, so code it that way -#define BITMAPV_SET(bitmap,slot) (bitmap[0] |= 1 << (slot)) -#define BITMAPV_CLR(bitmap,slot) (bitmap[0] &= ~ (1 << (slot))) -#define BITMAPV_BIT(bitmap,slot) ((bitmap[0] >> (slot)) & 1) -#define BITMAPV_CTZ(bitmap) (__builtin_ctz(bitmap)) +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("szone_valloc returned %p\n", ptr); + } #endif - -/* BITMAPN is used by small. (slot >> 5) takes on values from 0 to 7. */ -#define BITMAPN_SET(bitmap,slot) (bitmap[(slot) >> 5] |= 1 << ((slot) & 31)) -#define BITMAPN_CLR(bitmap,slot) (bitmap[(slot) >> 5] &= ~ (1 << ((slot) & 31))) -#define BITMAPN_BIT(bitmap,slot) ((bitmap[(slot) >> 5] >> ((slot) & 31)) & 1) - -/* returns bit # of least-significant one bit, starting at 0 (undefined if !bitmap) */ -#define BITMAP32_CTZ(bitmap) (__builtin_ctz(bitmap[0])) - -/********************* TINY FREE LIST UTILITIES ************************/ - -// We encode the meta-headers as follows: -// Each quantum has an associated set of 2 bits: -// block_header when 1 says this block is the beginning of a block -// in_use when 1 says this block is in use -// so a block in use of size 3 is 1-1 0-X 0-X -// for a free block TINY_FREE_SIZE(ptr) carries the size and the bits are 1-0 X-X X-X -// for a block middle the bits are 0-0 - -// We store the meta-header bit arrays by interleaving them 32 bits at a time. -// Initial 32 bits of block_header, followed by initial 32 bits of in_use, followed -// by next 32 bits of block_header, followed by next 32 bits of in_use, etc. -// This localizes memory references thereby reducing cache and TLB pressures. - -static INLINE void -BITARRAY_SET(uint32_t *bits, msize_t index) -{ - // index >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array - // (index >> 5) << 1 identifies the uint32_t allowing for the actual interleaving - bits[(index >> 5) << 1] |= (1 << (index & 31)); + return ptr; } -static INLINE void -BITARRAY_CLR(uint32_t *bits, msize_t index) +/* Isolate PIC-base load here. */ +size_t +szone_size_try_large(szone_t *szone, const void *ptr) { - bits[(index >> 5) << 1] &= ~(1 << (index & 31)); -} + size_t size = 0; + large_entry_t *entry; -static INLINE boolean_t -BITARRAY_BIT(uint32_t *bits, msize_t index) -{ - return ((bits[(index >> 5) << 1]) >> (index & 31)) & 1; + SZONE_LOCK(szone); + entry = large_entry_for_pointer_no_lock(szone, ptr); + if (entry) { + size = entry->size; + } + SZONE_UNLOCK(szone); +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("szone_size for %p returned %d\n", ptr, (unsigned)size); + } +#endif + return size; } -#if 0 -static INLINE void bitarray_mclr(uint32_t *bits, unsigned start, unsigned end) ALWAYSINLINE; - -static INLINE void -bitarray_mclr(uint32_t *bits, unsigned start, unsigned end) +size_t +szone_size(szone_t *szone, const void *ptr) { - // start >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array - // (start >> 5) << 1 identifies the uint32_t allowing for the actual interleaving - uint32_t *addr = bits + ((start >> 5) << 1); + boolean_t is_free; + msize_t msize, msize_and_free; - uint32_t span = end - start; - start = start & 31; - end = start + span; - - if (end > 31) { - addr[0] &= (0xFFFFFFFFU >> (31 - start)) >> 1; - addr[2] &= (0xFFFFFFFFU << (end - 32)); - } else { - unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1; - mask |= (0xFFFFFFFFU << end); - addr[0] &= mask; + if (!ptr) { + return 0; + } +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in szone_size for %p (szone=%p)\n", ptr, szone); } -} #endif -/* - * Obtain the size of a free tiny block (in msize_t units). - */ -static msize_t -get_tiny_free_size(const void *ptr) -{ - void *next_block = (void *)((uintptr_t)ptr + TINY_QUANTUM); - void *region_end = TINY_REGION_END(TINY_REGION_FOR_PTR(ptr)); - - // check whether the next block is outside the tiny region or a block header - // if so, then the size of this block is one, and there is no stored size. - if (next_block < region_end) - { - uint32_t *next_header = TINY_BLOCK_HEADER_FOR_PTR(next_block); - msize_t next_index = TINY_INDEX_FOR_PTR(next_block); - - if (!BITARRAY_BIT(next_header, next_index)) - return TINY_FREE_SIZE(ptr); - } - return 1; -} - -/* - * Get the size of the previous free block, which is stored in the last two - * bytes of the block. If the previous block is not free, then the result is - * undefined. - */ -static msize_t -get_tiny_previous_free_msize(const void *ptr) -{ - // check whether the previous block is in the tiny region and a block header - // if so, then the size of the previous block is one, and there is no stored - // size. - if (ptr != TINY_REGION_FOR_PTR(ptr)) - { - void *prev_block = (void *)((uintptr_t)ptr - TINY_QUANTUM); - uint32_t *prev_header = TINY_BLOCK_HEADER_FOR_PTR(prev_block); - msize_t prev_index = TINY_INDEX_FOR_PTR(prev_block); - if (BITARRAY_BIT(prev_header, prev_index)) - return 1; - return TINY_PREVIOUS_MSIZE(ptr); - } - // don't read possibly unmapped memory before the beginning of the region - return 0; -} - -static INLINE msize_t -get_tiny_meta_header(const void *ptr, boolean_t *is_free) -{ - // returns msize and is_free - // may return 0 for the msize component (meaning 65536) - uint32_t *block_header; - msize_t index; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - index = TINY_INDEX_FOR_PTR(ptr); - - msize_t midx = (index >> 5) << 1; - uint32_t mask = 1 << (index & 31); - *is_free = 0; - if (0 == (block_header[midx] & mask)) // if (!BITARRAY_BIT(block_header, index)) + /* + * Look for it in a tiny region. + */ + if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) { return 0; - if (0 == (block_header[midx + 1] & mask)) { // if (!BITARRAY_BIT(in_use, index)) - *is_free = 1; - return get_tiny_free_size(ptr); - } - - // index >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array - // (index >> 5) << 1 identifies the uint32_t allowing for the actual interleaving -#if defined(__LP64__) - // The return value, msize, is computed as the distance to the next 1 bit in block_header. - // That's guaranteed to be somewhwere in the next 64 bits. And those bits could span three - // uint32_t block_header elements. Collect the bits into a single uint64_t and measure up with ffsl. - uint32_t *addr = ((uint32_t *)block_header) + ((index >> 5) << 1); - uint32_t bitidx = index & 31; - uint64_t word_lo = addr[0]; - uint64_t word_mid = addr[2]; - uint64_t word_hi = addr[4]; - uint64_t word_lomid = (word_lo >> bitidx) | (word_mid << (32 - bitidx)); - uint64_t word = bitidx ? word_lomid | (word_hi << (64 - bitidx)) : word_lomid; - uint32_t result = __builtin_ffsl(word >> 1); -#else - // The return value, msize, is computed as the distance to the next 1 bit in block_header. - // That's guaranteed to be somwhwere in the next 32 bits. And those bits could span two - // uint32_t block_header elements. Collect the bits into a single uint32_t and measure up with ffs. - uint32_t *addr = ((uint32_t *)block_header) + ((index >> 5) << 1); - uint32_t bitidx = index & 31; - uint32_t word = bitidx ? (addr[0] >> bitidx) | (addr[2] << (32 - bitidx)) : addr[0]; - uint32_t result = __builtin_ffs(word >> 1); -#endif - return result; -} + } + if (tiny_region_for_ptr_no_lock(szone, ptr)) { + if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { + return 0; + } + msize = get_tiny_meta_header(ptr, &is_free); + if (is_free) { + return 0; + } +#if CONFIG_TINY_CACHE + { + mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); + if (DEPOT_MAGAZINE_INDEX != mag_index) { + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); -static INLINE void -set_tiny_meta_header_in_use(const void *ptr, msize_t msize) -{ - uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - msize_t index = TINY_INDEX_FOR_PTR(ptr); - msize_t clr_msize = msize - 1; - msize_t midx = (index >> 5) << 1; - uint32_t val = (1 << (index & 31)); + if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~(TINY_QUANTUM - 1))) { + return 0; + } + } else { + for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); -#if DEBUG_MALLOC - if (msize >= NUM_TINY_SLOTS) - malloc_printf("set_tiny_meta_header_in_use() invariant broken %p %d\n", ptr, msize); - if ((unsigned)index + (unsigned)msize > 0x10000) - malloc_printf("set_tiny_meta_header_in_use() invariant broken (2) %p %d\n", ptr, msize); + if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~(TINY_QUANTUM - 1))) { + return 0; + } + } + } + } #endif + return TINY_BYTES_FOR_MSIZE(msize); + } - block_header[midx] |= val; // BITARRAY_SET(block_header, index); - block_header[midx + 1] |= val; // BITARRAY_SET(in_use, index); - - // bitarray_mclr(block_header, index, end_bit); - // bitarray_mclr(in_use, index, end_bit); - - index++; - midx = (index >> 5) << 1; - - unsigned start = index & 31; - unsigned end = start + clr_msize; - -#if defined(__LP64__) - if (end > 63) { - unsigned mask0 = (0xFFFFFFFFU >> (31 - start)) >> 1; - unsigned mask1 = (0xFFFFFFFFU << (end - 64)); - block_header[midx + 0] &= mask0; // clear header - block_header[midx + 1] &= mask0; // clear in_use - block_header[midx + 2] = 0; // clear header - block_header[midx + 3] = 0; // clear in_use - block_header[midx + 4] &= mask1; // clear header - block_header[midx + 5] &= mask1; // clear in_use - } else -#endif - if (end > 31) { - unsigned mask0 = (0xFFFFFFFFU >> (31 - start)) >> 1; - unsigned mask1 = (0xFFFFFFFFU << (end - 32)); - block_header[midx + 0] &= mask0; - block_header[midx + 1] &= mask0; - block_header[midx + 2] &= mask1; - block_header[midx + 3] &= mask1; - } else { - unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1; - mask |= (0xFFFFFFFFU << end); - block_header[midx + 0] &= mask; - block_header[midx + 1] &= mask; + /* + * Look for it in a small region. + */ + if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) { + return 0; + } + if (small_region_for_ptr_no_lock(szone, ptr)) { + if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { + return 0; } - - // we set the block_header bit for the following block to reaffirm next block is a block - index += clr_msize; - midx = (index >> 5) << 1; - val = (1 << (index & 31)); - block_header[midx] |= val; // BITARRAY_SET(block_header, (index+clr_msize)); -#if DEBUG_MALLOC - { - boolean_t ff; - msize_t mf; - - mf = get_tiny_meta_header(ptr, &ff); - if (msize != mf) { - malloc_printf("setting header for tiny in_use %p : %d\n", ptr, msize); - malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff); + msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); + if (msize_and_free & SMALL_IS_FREE) { + return 0; } - } -#endif -} - -static INLINE void -set_tiny_meta_header_in_use_1(const void *ptr) // As above with msize == 1 -{ - uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - msize_t index = TINY_INDEX_FOR_PTR(ptr); - msize_t midx = (index >> 5) << 1; - uint32_t val = (1 << (index & 31)); - - block_header[midx] |= val; // BITARRAY_SET(block_header, index); - block_header[midx + 1] |= val; // BITARRAY_SET(in_use, index); - - index++; - midx = (index >> 5) << 1; - val = (1 << (index & 31)); +#if CONFIG_SMALL_CACHE + { + mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); + if (DEPOT_MAGAZINE_INDEX != mag_index) { + magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - block_header[midx] |= val; // BITARRAY_SET(block_header, (index+clr_msize)) -} + if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~(SMALL_QUANTUM - 1))) { + return 0; + } + } else { + for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { + magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); -static INLINE void -set_tiny_meta_header_middle(const void *ptr) -{ - // indicates this block is in the middle of an in use block - uint32_t *block_header; - uint32_t *in_use; - msize_t index; + if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~(SMALL_QUANTUM - 1))) { + return 0; + } + } + } + } +#endif + return SMALL_BYTES_FOR_MSIZE(msize_and_free); + } - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); + /* + * If not page-aligned, it cannot have come from a large allocation. + */ + if ((uintptr_t)ptr & (vm_page_quanta_size - 1)) { + return 0; + } - BITARRAY_CLR(block_header, index); - BITARRAY_CLR(in_use, index); + /* + * Look for it in a large entry. + */ + return szone_size_try_large(szone, ptr); } -static INLINE void -set_tiny_meta_header_free(const void *ptr, msize_t msize) +void * +szone_realloc(szone_t *szone, void *ptr, size_t new_size) { - // !msize is acceptable and means 65536 - uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - msize_t index = TINY_INDEX_FOR_PTR(ptr); - msize_t midx = (index >> 5) << 1; - uint32_t val = (1 << (index & 31)); + size_t old_size, new_good_size, valid_size; + void *new_ptr; #if DEBUG_MALLOC - if ((unsigned)index + (unsigned)msize > 0x10000) { - malloc_printf("setting header for tiny free %p msize too large: %d\n", ptr, msize); + if (LOG(szone, ptr)) { + malloc_printf("in szone_realloc for %p, %d\n", ptr, (unsigned)new_size); } #endif - - block_header[midx] |= val; // BITARRAY_SET(block_header, index); - block_header[midx + 1] &= ~val; // BITARRAY_CLR(in_use, index); - - // mark the end of this block if msize is > 1. For msize == 0, the whole - // region is free, so there is no following block. For msize == 1, there is - // no space to write the size on 64 bit systems. The size for 1 quantum - // blocks is computed from the metadata bitmaps. - if (msize > 1) { - void *follower = FOLLOWING_TINY_PTR(ptr, msize); - TINY_PREVIOUS_MSIZE(follower) = msize; - TINY_FREE_SIZE(ptr) = msize; - } - if (msize == 0) { - TINY_FREE_SIZE(ptr) = msize; - } -#if DEBUG_MALLOC - boolean_t ff; - msize_t mf = get_tiny_meta_header(ptr, &ff); - if ((msize != mf) || !ff) { - malloc_printf("setting header for tiny free %p : %u\n", ptr, msize); - malloc_printf("reading header for tiny %p : %u %u\n", ptr, mf, ff); + if (NULL == ptr) { + // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. + return szone_malloc(szone, new_size); + } else if (0 == new_size) { + // If size is 0 and ptr is not a null pointer, the object pointed to is freed. + szone_free(szone, ptr); + // If size is 0, either a null pointer or a unique pointer that can be successfully passed + // to free() shall be returned. + return szone_malloc(szone, 1); } -#endif -} - -static INLINE boolean_t -tiny_meta_header_is_free(const void *ptr) -{ - uint32_t *block_header; - uint32_t *in_use; - msize_t index; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); - if (!BITARRAY_BIT(block_header, index)) - return 0; - return !BITARRAY_BIT(in_use, index); -} - -static INLINE void * -tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) -{ - // returns the previous block, assuming and verifying it's free - uint32_t *block_header; - uint32_t *in_use; - msize_t index; - msize_t previous_msize; - msize_t previous_index; - void *previous_ptr; - - block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); - in_use = TINY_INUSE_FOR_HEADER(block_header); - index = TINY_INDEX_FOR_PTR(ptr); - - if (!index) - return NULL; - if ((previous_msize = get_tiny_previous_free_msize(ptr)) > index) - return NULL; - previous_index = index - previous_msize; - previous_ptr = (void *)((uintptr_t)TINY_REGION_FOR_PTR(ptr) + TINY_BYTES_FOR_MSIZE(previous_index)); - if (!BITARRAY_BIT(block_header, previous_index)) - return NULL; - if (BITARRAY_BIT(in_use, previous_index)) - return NULL; - if (get_tiny_free_size(previous_ptr) != previous_msize) + old_size = szone_size(szone, ptr); + if (!old_size) { + szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL); return NULL; + } - // conservative check did match true check - *prev_msize = previous_msize; - return previous_ptr; -} + new_good_size = szone_good_size(szone, new_size); + if (new_good_size == old_size) { // Existing allocation is best fit evar? + return ptr; + } -/* - * Adds an item to the proper free list, and also marks the meta-header of the - * block properly. - * Assumes szone has been locked - */ -static void -tiny_free_list_add_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize) -{ - grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; - free_list_t *free_ptr = ptr; - free_list_t *free_head = tiny_mag_ptr->mag_free_list[slot]; + /* + * If the new size suits the tiny allocator and the pointer being resized + * belongs to a tiny region, try to reallocate in-place. + */ + if (new_good_size <= SMALL_THRESHOLD) { + if (old_size <= SMALL_THRESHOLD) { + if (new_good_size <= (old_size >> 1)) { + /* + * Serious shrinkage (more than half). free() the excess. + */ + return tiny_try_shrink_in_place(szone, ptr, old_size, new_good_size); + } else if (new_good_size <= old_size) { + /* + * new_good_size smaller than old_size but not by much (less than half). + * Avoid thrashing at the expense of some wasted storage. + */ + if (szone->debug_flags & MALLOC_DO_SCRIBBLE) { + memset(ptr + new_size, SCRIBBLE_BYTE, old_size - new_size); + } + return ptr; + } else if (tiny_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { // try to grow the allocation + if (szone->debug_flags & MALLOC_DO_SCRIBBLE) { + memset(ptr + old_size, SCRIBBLE_BYTE, new_good_size - old_size); + } + return ptr; + } + } -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } - if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { - szone_error(szone, 1, "tiny_free_list_add_ptr: Unaligned ptr", ptr, NULL); - } -#endif - set_tiny_meta_header_free(ptr, msize); - if (free_head) { -#if DEBUG_MALLOC - if (free_list_unchecksum_ptr(szone, &free_head->previous)) { - szone_error(szone, 1, "tiny_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr, - "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, (void *)free_head, free_head->previous.p); + /* + * Else if the new size suits the small allocator and the pointer being resized + * belongs to a small region, and we're not protecting the small allocations + * try to reallocate in-place. + */ + } else if (new_good_size <= szone->large_threshold) { + if (SMALL_THRESHOLD < old_size && old_size <= szone->large_threshold) { + if (new_good_size <= (old_size >> 1)) { + return small_try_shrink_in_place(szone, ptr, old_size, new_good_size); + } else if (new_good_size <= old_size) { + if (szone->debug_flags & MALLOC_DO_SCRIBBLE) { + memset(ptr + new_size, SCRIBBLE_BYTE, old_size - new_size); + } + return ptr; + } else if (small_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { + if (szone->debug_flags & MALLOC_DO_SCRIBBLE) { + memset(ptr + old_size, SCRIBBLE_BYTE, new_good_size - old_size); + } + return ptr; + } } - if (! tiny_meta_header_is_free(free_head)) { - szone_error(szone, 1, "tiny_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, - "ptr=%p slot=%d free_head=%p\n", ptr, slot, (void *)free_head); + /* + * Else if the allocation's a large allocation, try to reallocate in-place there. + */ + } else if (!(szone->debug_flags & MALLOC_PURGEABLE) && // purgeable needs fresh allocation + (old_size > szone->large_threshold) && (new_good_size > szone->large_threshold)) { + if (new_good_size <= (old_size >> 1)) { + return large_try_shrink_in_place(szone, ptr, old_size, new_good_size); + } else if (new_good_size <= old_size) { + if (szone->debug_flags & MALLOC_DO_SCRIBBLE) { + memset(ptr + new_size, SCRIBBLE_BYTE, old_size - new_size); + } + return ptr; + } else if (large_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { + if (szone->debug_flags & MALLOC_DO_SCRIBBLE) { + memset(ptr + old_size, SCRIBBLE_BYTE, new_good_size - old_size); + } + return ptr; } -#endif - free_head->previous.u = free_list_checksum_ptr(szone, free_ptr); - } else { - BITMAPV_SET(tiny_mag_ptr->mag_bitmap, slot); } - free_ptr->previous.u = free_list_checksum_ptr(szone, NULL); - free_ptr->next.u = free_list_checksum_ptr(szone, free_head); - tiny_mag_ptr->mag_free_list[slot] = free_ptr; -} + /* + * Can't reallocate in place for whatever reason; allocate a new buffer and copy. + */ + if (new_good_size <= (old_size >> 1)) { + /* Serious shrinkage (more than half). FALL THROUGH to alloc/copy/free. */ + } else if (new_good_size <= old_size) { + if (szone->debug_flags & MALLOC_DO_SCRIBBLE) { + memset(ptr + new_size, SCRIBBLE_BYTE, old_size - new_size); + } + return ptr; + } -/* - * Removes the item pointed to by ptr in the proper free list. - * Assumes szone has been locked - */ -static void -tiny_free_list_remove_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize) -{ - grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; - free_list_t *free_ptr = ptr, *next, *previous; + new_ptr = szone_malloc(szone, new_size); + if (new_ptr == NULL) { + return NULL; + } - next = free_list_unchecksum_ptr(szone, &free_ptr->next); - previous = free_list_unchecksum_ptr(szone, &free_ptr->previous); + /* + * If the allocation's large enough, try to copy using VM. If that fails, or + * if it's too small, just copy by hand. + */ + valid_size = MIN(old_size, new_size); + if ((valid_size < szone->vm_copy_threshold) || + vm_copy(mach_task_self(), (vm_address_t)ptr, valid_size, (vm_address_t)new_ptr)) { + memcpy(new_ptr, ptr, valid_size); + } + szone_free(szone, ptr); #if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); + if (LOG(szone, ptr)) { + malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size); } #endif - if (!previous) { - // The block to remove is the head of the free list -#if DEBUG_MALLOC - if (tiny_mag_ptr->mag_free_list[slot] != ptr) { - szone_error(szone, 1, "tiny_free_list_remove_ptr: Internal invariant broken (tiny_mag_ptr->mag_free_list[slot])", ptr, - "ptr=%p slot=%d msize=%d tiny_mag_ptr->mag_free_list[slot]=%p\n", - ptr, slot, msize, (void *)tiny_mag_ptr->mag_free_list[slot]); - return; - } -#endif - tiny_mag_ptr->mag_free_list[slot] = next; - if (!next) BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot); - } else { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - previous->next = free_ptr->next; - } - if (next) { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - next->previous = free_ptr->previous; - } + return new_ptr; } -/* - * tiny_region_for_ptr_no_lock - Returns the tiny region containing the pointer, - * or NULL if not found. - */ -static INLINE region_t -tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) +void * +szone_memalign(szone_t *szone, size_t alignment, size_t size) { - rgnhdl_t r = hash_lookup_region_no_lock(szone->tiny_region_generation->hashed_regions, - szone->tiny_region_generation->num_regions_allocated, - szone->tiny_region_generation->num_regions_allocated_shift, - TINY_REGION_FOR_PTR(ptr)); - return r ? *r : r; -} - -static void -tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr) { - void *last_block, *previous_block; - uint32_t *last_header; - msize_t last_msize, previous_msize, last_index; - - // It is possible that the block prior to the last block in the region has - // been free'd, but was not coalesced with the free bytes at the end of the - // block, since we treat the bytes at the end of the region as "in use" in - // the meta headers. Attempt to coalesce the last block with the previous - // block, so we don't violate the "no consecutive free blocks" invariant. - // - // FIXME: Need to investigate how much work would be required to increase - // 'mag_bytes_free_at_end' when freeing the preceding block, rather - // than performing this workaround. - // - - if (tiny_mag_ptr->mag_bytes_free_at_end) { - last_block = (void *) - ((uintptr_t)TINY_REGION_END(tiny_mag_ptr->mag_last_region) - tiny_mag_ptr->mag_bytes_free_at_end); - last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end); - last_header = TINY_BLOCK_HEADER_FOR_PTR(last_block); - last_index = TINY_INDEX_FOR_PTR(last_block); - - // Before anything we transform any remaining mag_bytes_free_at_end into a - // regular free block. We take special care here to update the bitfield - // information, since we are bypassing the normal free codepath. If there - // is more than one quanta worth of memory in mag_bytes_free_at_end, then - // there will be two block headers: - // 1) header for the free space at end, msize = 1 - // 2) header inserted by set_tiny_meta_header_in_use after block - // We must clear the second one so that when the free block's size is - // queried, we do not think the block is only 1 quantum in size because - // of the second set header bit. - if (last_index != (NUM_TINY_BLOCKS - 1)) - BITARRAY_CLR(last_header, (last_index + 1)); - - previous_block = tiny_previous_preceding_free(last_block, &previous_msize); - if (previous_block) { - set_tiny_meta_header_middle(last_block); - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, previous_block, previous_msize); - last_block = previous_block; - last_msize += previous_msize; - } - - // splice last_block into the free list - tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize); - tiny_mag_ptr->mag_bytes_free_at_end = 0; + if (size == 0) { + size = 1; // Ensures we'll return an aligned free()-able pointer + } + if ((size + alignment) < size) { // size_t arithmetic wrapped! + return NULL; } -#if ASLR_INTERNAL - // Coalesce the big free block at start with any following free blocks - if (tiny_mag_ptr->mag_bytes_free_at_start) { - last_block = TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region); - last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start); - - void *next_block = (void *) ((uintptr_t)last_block + tiny_mag_ptr->mag_bytes_free_at_start); + // alignment is gauranteed a power of 2 at least as large as sizeof(void *), hence non-zero. + // Since size + alignment didn't wrap, 0 <= size + alignment - 1 < size + alignment + size_t span = size + alignment - 1; - // clear the in use bit we were using to mark the end of the big start block - set_tiny_meta_header_middle((void *)((uintptr_t)next_block - TINY_QUANTUM)); + if (alignment <= TINY_QUANTUM) { + return szone_malloc(szone, size); // Trivially satisfied by tiny, small, or large - // Coalesce the big start block with any following free blocks - if (tiny_meta_header_is_free(next_block)) { - msize_t next_msize = get_tiny_free_size(next_block); - set_tiny_meta_header_middle(next_block); - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); - last_msize += next_msize; - } + } else if (span <= SMALL_THRESHOLD) { + return tiny_memalign(szone, alignment, size, span); - // splice last_block into the free list - tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize); - tiny_mag_ptr->mag_bytes_free_at_start = 0; - } -#endif + } else if (SMALL_THRESHOLD < size && alignment <= SMALL_QUANTUM) { + return szone_malloc(szone, size); // Trivially satisfied by small or large - tiny_mag_ptr->mag_last_region = NULL; -} + } else if (span <= szone->large_threshold) { + return small_memalign(szone, alignment, size, span); -static int -tiny_free_detach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r) { - uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)TINY_REGION_END(r); - boolean_t is_free; - msize_t msize; - int total_alloc = 0; - - while (current < limit) { - msize = get_tiny_meta_header((void *)current, &is_free); - if (is_free && !msize && (current == start)) { - // first block is all free - break; - } - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_detach_region error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, (void *)current, msize); - } else { - total_alloc++; - } - current += TINY_BYTES_FOR_MSIZE(msize); - } - return total_alloc; -} + } else if (szone->large_threshold < size && alignment <= vm_page_quanta_size) { + return szone_malloc(szone, size); // Trivially satisfied by large -static size_t -tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r) { - uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)TINY_REGION_END(r); - boolean_t is_free; - msize_t msize; - size_t total_alloc = 0; - - while (current < limit) { - msize = get_tiny_meta_header((void *)current, &is_free); - if (is_free && !msize && (current == start)) { - // first block is all free - break; - } - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_reattach_region error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - tiny_free_list_add_ptr(szone, tiny_mag_ptr, (void *)current, msize); + } else { + // ensure block allocated by large does not have a small-possible size + size_t num_kernel_pages = round_page_quanta(MAX(szone->large_threshold + 1, size)) >> vm_page_quanta_shift; + void *p; + + if (num_kernel_pages == 0) { /* Overflowed */ + p = NULL; } else { - total_alloc += TINY_BYTES_FOR_MSIZE(msize); + p = large_malloc(szone, num_kernel_pages, MAX(vm_page_quanta_shift, __builtin_ctz((unsigned)alignment)), 0); } - current += TINY_BYTES_FOR_MSIZE(msize); + + return p; } - return total_alloc; + /* NOTREACHED */ } -typedef struct { - uint8_t pnum, size; -} tiny_pg_pair_t; - -static void NOINLINE /* want private stack frame for automatic array */ -tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) { - uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)TINY_REGION_END(r); - boolean_t is_free; - msize_t msize; - tiny_pg_pair_t advisory[((TINY_REGION_PAYLOAD_BYTES + vm_page_quanta_size - 1) >> vm_page_quanta_shift) >> 1]; // 256bytes stack allocated - int advisories = 0; - - // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list - // management data. - while (current < limit) { - msize = get_tiny_meta_header((void *)current, &is_free); - if (is_free && !msize && (current == start)) { - // first block is all free -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_scan_madvise_free first block is all free! %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - uintptr_t pgLo = round_page_quanta(start + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page_quanta(start + TINY_REGION_SIZE - sizeof(msize_t)); - - if (pgLo < pgHi) { - advisory[advisories].pnum = (pgLo - start) >> vm_page_quanta_shift; - advisory[advisories].size = (pgHi - pgLo) >> vm_page_quanta_shift; - advisories++; - } - break; - } - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_scan_madvise_free error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - uintptr_t pgLo = round_page_quanta(current + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page_quanta(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); +// given a size, returns the number of pointers allocated capable of holding +// that size, up to the limit specified by the 'count' argument. These pointers +// are stored in the 'results' array, which must be allocated by the caller. +// may return zero, since this function is only a best attempt at allocating +// the pointers. clients should be prepared to call malloc for any additional +// blocks they need. +unsigned +szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) +{ + msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); + unsigned found = 0; + mag_index_t mag_index = mag_get_thread_index(szone); + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - if (pgLo < pgHi) { - advisory[advisories].pnum = (pgLo - start) >> vm_page_quanta_shift; - advisory[advisories].size = (pgHi - pgLo) >> vm_page_quanta_shift; - advisories++; - } - } - current += TINY_BYTES_FOR_MSIZE(msize); + // only bother implementing this for tiny + if (size > SMALL_THRESHOLD) { + return 0; + } + // make sure to return objects at least one quantum in size + if (!msize) { + msize = 1; } - if (advisories > 0) { - int i; - - // So long as the following hold for this region: - // (1) No malloc()'s are ever performed from the depot (hence free pages remain free,) - // (2) The region is not handed over to a per-CPU magazine (where malloc()'s could be performed), - // (3) The entire region is not mumap()'d (so the madvise's are applied to the intended addresses), - // then the madvise opportunities collected just above can be applied outside all locks. - // (1) is ensured by design, (2) and (3) are ensured by bumping the globally visible counter node->pinned_to_depot. + CHECK(szone, __PRETTY_FUNCTION__); - OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot)); - SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); - for (i = 0; i < advisories; ++i) { - uintptr_t addr = (advisory[i].pnum << vm_page_quanta_shift) + start; - size_t size = advisory[i].size << vm_page_quanta_shift; + // We must lock the zone now, since tiny_malloc_from_free_list assumes that + // the caller has done so. + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - madvise_free_range(szone, r, addr, addr + size, NULL); + // with the zone locked, allocate objects from the free list until all + // sufficiently large objects have been exhausted, or we have met our quota + // of objects to allocate. + while (found < count) { + void *ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); + if (!ptr) { + break; } - SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); - OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot)); + + *results++ = ptr; + found++; } + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return found; } -static region_t -tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node) +/* Try caching the tiny_region and checking if the next ptr hits there. */ +void +szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) { - if (0 < node->bytes_used || - 0 < node->pinned_to_depot || - depot_ptr->recirculation_entries < (szone->num_tiny_magazines * 2)) { - return NULL; + unsigned cc = 0; + void *ptr; + region_t tiny_region = NULL; + boolean_t is_free; + msize_t msize; + magazine_t *tiny_mag_ptr = NULL; + mag_index_t mag_index = -1; + + // frees all the pointers in to_be_freed + // note that to_be_freed may be overwritten during the process + if (!count) { + return; } - // disconnect node from Depot - recirc_list_extract(szone, depot_ptr, node); + CHECK(szone, __PRETTY_FUNCTION__); + while (cc < count) { + ptr = to_be_freed[cc]; + if (ptr) { + if (NULL == tiny_region || tiny_region != TINY_REGION_FOR_PTR(ptr)) { // region same as last iteration? + if (tiny_mag_ptr) { // non-NULL iff magazine lock taken + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + tiny_mag_ptr = NULL; + } - // Iterate the region pulling its free entries off the (locked) Depot's free list - region_t sparse_region = TINY_REGION_FOR_PTR(node); - int objects_in_use = tiny_free_detach_region(szone, depot_ptr, sparse_region); + tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); - if (0 == objects_in_use) { - // Invalidate the hash table entry for this region with HASHRING_REGION_DEALLOCATED. - // Using HASHRING_REGION_DEALLOCATED preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not. - rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->tiny_region_generation->hashed_regions, - szone->tiny_region_generation->num_regions_allocated, - szone->tiny_region_generation->num_regions_allocated_shift, sparse_region); - if (NULL == pSlot) { - szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region); - return NULL; + if (tiny_region) { + tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, + REGION_TRAILER_FOR_TINY_REGION(tiny_region), MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region)); + mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region); + } + } + if (tiny_region) { + // this is a tiny pointer + if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { + break; // pointer to metadata; let the standard free deal with it + } + msize = get_tiny_meta_header(ptr, &is_free); + if (is_free) { + break; // a double free; let the standard free deal with it + } + if (!tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize)) { + // Arrange to re-acquire magazine lock + tiny_mag_ptr = NULL; + tiny_region = NULL; + } + to_be_freed[cc] = NULL; + } else { + // No region in this zone claims ptr; let the standard free deal with it + break; + } } - *pSlot = HASHRING_REGION_DEALLOCATED; - depot_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; - __sync_fetch_and_add( &(szone->num_tiny_regions_dealloc), 1); // Atomically increment num_tiny_regions_dealloc - - // Caller will transfer ownership of the region back to the OS with no locks held - MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, TINY_REGION_SIZE); // DTrace USDT Probe - return sparse_region; - } else { - szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use); - return NULL; + cc++; } -} - -static boolean_t -tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index) -{ - // The entire magazine crossed the "emptiness threshold". Transfer a region - // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e - // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. - region_trailer_t *node = tiny_mag_ptr->firstNode; - while (node && !node->recirc_suitable) { - node = node->next; + if (tiny_mag_ptr) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + tiny_mag_ptr = NULL; } - if (NULL == node) { -#if DEBUG_MALLOC - malloc_printf("*** tiny_free_do_recirc_to_depot end of list\n"); -#endif - return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + while (count--) { + ptr = to_be_freed[count]; + if (ptr) { + szone_free(szone, ptr); + } } +} - region_t sparse_region = TINY_REGION_FOR_PTR(node); +// FIXME: Suppose one of the locks is held? +static void +szone_destroy(szone_t *szone) +{ + size_t index; + large_entry_t *large; + vm_range_t range_to_deallocate; - // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start - if (sparse_region == tiny_mag_ptr->mag_last_region && (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start)) { - tiny_finalize_region(szone, tiny_mag_ptr); - } +#if CONFIG_LARGE_CACHE + SZONE_LOCK(szone); - // disconnect "suitable" node from magazine - recirc_list_extract(szone, tiny_mag_ptr, node); + /* disable any memory pressure responder */ + szone->flotsam_enabled = FALSE; - // Iterate the region pulling its free entries off its (locked) magazine's free list - int objects_in_use = tiny_free_detach_region(szone, tiny_mag_ptr, sparse_region); - magazine_t *depot_ptr = &(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); + // stack allocated copy of the death-row cache + int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest; + large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE]; - // hand over the region to the (locked) Depot - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - // this will cause tiny_free_list_add_ptr called by tiny_free_reattach_region to use - // the depot as its target magazine, rather than magazine formerly associated with sparse_region - MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX; - node->pinned_to_depot = 0; + memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache)); - // Iterate the region putting its free entries on Depot's free list - size_t bytes_inplay = tiny_free_reattach_region(szone, depot_ptr, sparse_region); + szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0; + szone->large_entry_cache[0].address = 0x0; + szone->large_entry_cache[0].size = 0; + szone->large_entry_cache_bytes = 0; + szone->large_entry_cache_reserve_bytes = 0; - tiny_mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; - tiny_mag_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; - tiny_mag_ptr->mag_num_objects -= objects_in_use; + SZONE_UNLOCK(szone); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); // Unlock the originating magazine + // deallocate the death-row cache outside the zone lock + while (idx != idx_max) { + deallocate_pages(szone, (void *)local_entry_cache[idx].address, local_entry_cache[idx].size, 0); + if (++idx == LARGE_ENTRY_CACHE_SIZE) { + idx = 0; + } + } + if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) { + deallocate_pages(szone, (void *)local_entry_cache[idx].address, local_entry_cache[idx].size, 0); + } +#endif - depot_ptr->mag_num_bytes_in_objects += bytes_inplay; - depot_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; - depot_ptr->mag_num_objects += objects_in_use; + /* destroy large entries */ + index = szone->num_large_entries; + while (index--) { + large = szone->large_entries + index; + if (large->address) { + // we deallocate_pages, including guard pages + deallocate_pages(szone, (void *)(large->address), large->size, szone->debug_flags); + } + } + large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate); + if (range_to_deallocate.size) { + deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0); + } - // connect to Depot as last node - recirc_list_splice_last(szone, depot_ptr, node); + /* destroy tiny regions */ + for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) { + if ((HASHRING_OPEN_ENTRY != szone->tiny_region_generation->hashed_regions[index]) && + (HASHRING_REGION_DEALLOCATED != szone->tiny_region_generation->hashed_regions[index])) { + deallocate_pages(szone, szone->tiny_region_generation->hashed_regions[index], TINY_REGION_SIZE, 0); + } + } - MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE, - (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe + /* destroy small regions */ + for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) { + if ((HASHRING_OPEN_ENTRY != szone->small_region_generation->hashed_regions[index]) && + (HASHRING_REGION_DEALLOCATED != szone->small_region_generation->hashed_regions[index])) { + deallocate_pages(szone, szone->small_region_generation->hashed_regions[index], SMALL_REGION_SIZE, 0); + } + } - // Mark free'd dirty pages with MADV_FREE to reduce memory pressure - tiny_free_scan_madvise_free(szone, depot_ptr, sparse_region); + /* destroy region hash rings, if any */ + if (szone->tiny_region_generation->hashed_regions != szone->initial_tiny_regions) { + size_t size = round_page_quanta(szone->tiny_region_generation->num_regions_allocated * sizeof(region_t)); + deallocate_pages(szone, szone->tiny_region_generation->hashed_regions, size, 0); + } + if (szone->small_region_generation->hashed_regions != szone->initial_small_regions) { + size_t size = round_page_quanta(szone->small_region_generation->num_regions_allocated * sizeof(region_t)); + deallocate_pages(szone, szone->small_region_generation->hashed_regions, size, 0); + } - // If the region is entirely empty vm_deallocate() it outside the depot lock - region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, depot_ptr, node); - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - if (r_dealloc) - deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0); - return FALSE; // Caller need not unlock the originating magazine + /* Now destroy the separate szone region */ + deallocate_pages(szone, (void *)&(szone->tiny_magazines[-1]), TINY_MAGAZINE_PAGED_SIZE, MALLOC_ADD_GUARD_PAGES); + deallocate_pages(szone, (void *)&(szone->small_magazines[-1]), SMALL_MAGAZINE_PAGED_SIZE, MALLOC_ADD_GUARD_PAGES); + deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0); } -static region_t -tiny_find_msize_region(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) +size_t +szone_good_size(szone_t *szone, size_t size) { - free_list_t *ptr; - grain_t slot = msize - 1; - free_list_t **free_list = tiny_mag_ptr->mag_free_list; - free_list_t **the_slot = free_list + slot; - free_list_t **limit; -#if defined(__LP64__) - uint64_t bitmap; -#else - uint32_t bitmap; -#endif - // Assumes we've locked the magazine - CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__); - - // Look for an exact match by checking the freelist for this msize. - ptr = *the_slot; - if (ptr) - return TINY_REGION_FOR_PTR(ptr); - - // Mask off the bits representing slots holding free blocks smaller than the - // size we need. If there are no larger free blocks, try allocating from - // the free space at the end of the tiny region. -#if defined(__LP64__) - bitmap = ((uint64_t *)(tiny_mag_ptr->mag_bitmap))[0] & ~ ((1ULL << slot) - 1); -#else - bitmap = tiny_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1); -#endif - if (!bitmap) - return NULL; - - slot = BITMAPV_CTZ(bitmap); - limit = free_list + NUM_TINY_SLOTS - 1; - free_list += slot; + msize_t msize; - if (free_list < limit) { - ptr = *free_list; - if (ptr) - return TINY_REGION_FOR_PTR(ptr); - else { - /* Shouldn't happen. Fall through to look at last slot. */ -#if DEBUG_MALLOC - malloc_printf("in tiny_find_msize_region(), mag_bitmap out of sync, slot=%d\n",slot); -#endif + // Find a good size for this tiny allocation. + if (size <= SMALL_THRESHOLD) { + msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); + if (!msize) { + msize = 1; } + return TINY_BYTES_FOR_MSIZE(msize); } - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than (NUM_TINY_SLOTS - 1) * tiny quantum size. - ptr = *limit; - if (ptr) - return TINY_REGION_FOR_PTR(ptr); - - return NULL; -} - -static boolean_t -tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - magazine_t *depot_ptr = &(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); + // Find a good size for this small allocation. + if (size <= szone->large_threshold) { + msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); + if (!msize) { + msize = 1; + } + return SMALL_BYTES_FOR_MSIZE(msize); + } - /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ - if (szone->num_tiny_magazines == 1) // Uniprocessor, single magazine, so no recirculation necessary - return 0; + // Check for integer overflow on the size, since unlike the two cases above, + // there is no upper bound on allocation size at this point. + if (size > round_page_quanta(size)) { + return (size_t)(-1LL); + } #if DEBUG_MALLOC - if (DEPOT_MAGAZINE_INDEX == mag_index) { - szone_error(szone, 1, "tiny_get_region_from_depot called for magazine index -1", NULL, NULL); - return 0; + // It is not acceptable to see a size of zero here, since that means we + // failed to catch a request for zero bytes in the tiny check, or the size + // overflowed to zero during some arithmetic. + if (size == 0) { + malloc_printf("szone_good_size() invariant broken %y\n", size); } #endif + return round_page_quanta(size); +} + +unsigned szone_check_counter = 0; +unsigned szone_check_start = 0; +unsigned szone_check_modulo = 1; - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); +static MALLOC_NOINLINE boolean_t +szone_check_all(szone_t *szone, const char *function) +{ + size_t index; - // Appropriate a Depot'd region that can satisfy requested msize. - region_trailer_t *node; - region_t sparse_region; + /* check tiny regions - chould check region count */ + for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) { + region_t tiny = szone->tiny_region_generation->hashed_regions[index]; - while (1) { - sparse_region = tiny_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); - if (NULL == sparse_region) { // Depot empty? - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - return 0; + if (HASHRING_REGION_DEALLOCATED == tiny) { + continue; } - node = REGION_TRAILER_FOR_TINY_REGION(sparse_region); - if (0 >= node->pinned_to_depot) - break; - - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - yield(); - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - } + if (tiny) { + magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer( + szone, szone->tiny_magazines, REGION_TRAILER_FOR_TINY_REGION(tiny), MAGAZINE_INDEX_FOR_TINY_REGION(tiny)); - // disconnect node from Depot - recirc_list_extract(szone, depot_ptr, node); - - // Iterate the region pulling its free entries off the (locked) Depot's free list - int objects_in_use = tiny_free_detach_region(szone, depot_ptr, sparse_region); + if (!tiny_check_region(szone, tiny)) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + szone->debug_flags &= ~CHECK_REGIONS; + szone_error(szone, 1, "check: tiny region incorrect", NULL, + "*** tiny region %ld incorrect szone_check_all(%s) counter=%d\n", index, function, szone_check_counter); + return 0; + } + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + } + } + /* check tiny free lists */ + for (index = 0; index < NUM_TINY_SLOTS; ++index) { + if (!tiny_free_list_check(szone, (grain_t)index)) { + szone->debug_flags &= ~CHECK_REGIONS; + szone_error(szone, 1, "check: tiny free list incorrect", NULL, + "*** tiny free list incorrect (slot=%ld) szone_check_all(%s) counter=%d\n", index, function, + szone_check_counter); + return 0; + } + } - // Transfer ownership of the region - MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = mag_index; - node->pinned_to_depot = 0; + /* check small regions - could check region count */ + for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) { + region_t small = szone->small_region_generation->hashed_regions[index]; - // Iterate the region putting its free entries on its new (locked) magazine's free list - size_t bytes_inplay = tiny_free_reattach_region(szone, tiny_mag_ptr, sparse_region); + if (HASHRING_REGION_DEALLOCATED == small) { + continue; + } - depot_ptr->mag_num_bytes_in_objects -= bytes_inplay; - depot_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; - depot_ptr->mag_num_objects -= objects_in_use; + if (small) { + magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer( + szone, szone->small_magazines, REGION_TRAILER_FOR_SMALL_REGION(small), MAGAZINE_INDEX_FOR_SMALL_REGION(small)); - tiny_mag_ptr->mag_num_bytes_in_objects += bytes_inplay; - tiny_mag_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; - tiny_mag_ptr->mag_num_objects += objects_in_use; + if (!small_check_region(szone, small)) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + szone->debug_flags &= ~CHECK_REGIONS; + szone_error(szone, 1, "check: small region incorrect", NULL, + "*** small region %ld incorrect szone_check_all(%s) counter=%d\n", index, function, szone_check_counter); + return 0; + } + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + } + } + /* check small free lists */ + for (index = 0; index < szone->num_small_slots; ++index) { + if (!small_free_list_check(szone, (grain_t)index)) { + szone->debug_flags &= ~CHECK_REGIONS; + szone_error(szone, 1, "check: small free list incorrect", NULL, + "*** small free list incorrect (slot=%ld) szone_check_all(%s) counter=%d\n", index, function, + szone_check_counter); + return 0; + } + } - // connect to magazine as first node - recirc_list_splice_first(szone, tiny_mag_ptr, node); + return 1; +} - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); +static boolean_t +szone_check(szone_t *szone) +{ + if ((++szone_check_counter % 10000) == 0) { + _malloc_printf(ASL_LEVEL_NOTICE, "at szone_check counter=%d\n", szone_check_counter); + } - // madvise() outside the Depot lock - (void)madvise_reuse_range(szone, sparse_region, sparse_region, sparse_region+TINY_REGION_PAYLOAD_BYTES); + if (szone_check_counter < szone_check_start) { + return 1; + } - MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE, - (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe + if (szone_check_counter % szone_check_modulo) { + return 1; + } - return 1; + return szone_check_all(szone, ""); } -#define K 1.5 // headroom measured in number of 1Mb regions -#define DENSITY_THRESHOLD(a) \ - ((a) - ((a) >> 2)) // "Emptiness" f = 0.25, so "Density" is (1 - f)*a. Generally: ((a) - ((a) >> -log2(f))) - -static INLINE boolean_t -tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, - msize_t msize) +static kern_return_t +szone_ptr_in_use_enumerator(task_t task, + void *context, + unsigned type_mask, + vm_address_t zone_address, + memory_reader_t reader, + vm_range_recorder_t recorder) { - void *original_ptr = ptr; - size_t original_size = TINY_BYTES_FOR_MSIZE(msize); - void *next_block = ((unsigned char *)ptr + original_size); - msize_t previous_msize, next_msize; - void *previous; - free_list_t *big_free_block; - free_list_t *after_next_block; - free_list_t *before_next_block; + szone_t *szone; + kern_return_t err; -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); + if (!reader) { + reader = _szone_default_reader; } - if (!msize) { - szone_error(szone, 1, "trying to free tiny block that is too small", ptr, - "in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); + + err = reader(task, zone_address, sizeof(szone_t), (void **)&szone); + if (err) { + return err; } -#endif - // We try to coalesce this block with the preceeding one - previous = tiny_previous_preceding_free(ptr, &previous_msize); - if (previous) { -#if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone,previous)) { - malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); - } -#endif + err = tiny_in_use_enumerator(task, context, type_mask, szone, reader, recorder); + if (err) { + return err; + } - // clear the meta_header since this is no longer the start of a block - set_tiny_meta_header_middle(ptr); - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, previous, previous_msize); - ptr = previous; - msize += previous_msize; + err = small_in_use_enumerator(task, context, type_mask, szone, reader, recorder); + if (err) { + return err; } - // We try to coalesce with the next block - if ((next_block < TINY_REGION_END(region)) && tiny_meta_header_is_free(next_block)) { - next_msize = get_tiny_free_size(next_block); -#if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone, next_block)) { - malloc_printf("in tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n", - ptr, msize, next_block, next_msize); - } -#endif - // If we are coalescing with the next block, and the next block is in - // the last slot of the free list, then we optimize this case here to - // avoid removing next_block from the slot (NUM_TINY_SLOTS - 1) and then adding ptr back - // to slot (NUM_TINY_SLOTS - 1). - if (next_msize >= NUM_TINY_SLOTS) { - msize += next_msize; - - big_free_block = (free_list_t *)next_block; - after_next_block = free_list_unchecksum_ptr(szone, &big_free_block->next); - before_next_block = free_list_unchecksum_ptr(szone, &big_free_block->previous); - - if (!before_next_block) { - tiny_mag_ptr->mag_free_list[NUM_TINY_SLOTS-1] = ptr; - } else { - before_next_block->next.u = free_list_checksum_ptr(szone, ptr); - } - if (after_next_block) { - after_next_block->previous.u = free_list_checksum_ptr(szone, ptr); - } + err = large_in_use_enumerator( + task, context, type_mask, (vm_address_t)szone->large_entries, szone->num_large_entries, reader, recorder); + return err; +} - // we don't need to checksum these since they are already checksummed - ((free_list_t *)ptr)->previous = big_free_block->previous; - ((free_list_t *)ptr)->next = big_free_block->next; +// Following method is deprecated: use scalable_zone_statistics instead +void +scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) +{ + szone_t *szone = (void *)zone; + unsigned info[13]; - // clear the meta_header to enable coalescing backwards - set_tiny_meta_header_middle(big_free_block); - set_tiny_meta_header_free(ptr, msize); + // We do not lock to facilitate debug - goto tiny_free_ending; - } - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); - set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards - msize += next_msize; - } - - // The tiny cache already scribbles free blocks as they go through the - // cache whenever msize < TINY_QUANTUM , so we do not need to do it here. - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize && (msize >= TINY_QUANTUM)) - memset(ptr, SCRABBLE_BYTE, TINY_BYTES_FOR_MSIZE(msize)); - - tiny_free_list_add_ptr(szone, tiny_mag_ptr, ptr, msize); - -tiny_free_ending: - - tiny_mag_ptr->mag_num_objects--; - // we use original_size and not msize to avoid double counting the coalesced blocks - tiny_mag_ptr->mag_num_bytes_in_objects -= original_size; - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(region); - size_t bytes_used = node->bytes_used - original_size; - node->bytes_used = bytes_used; - -#if !TARGET_OS_EMBEDDED // Always madvise for embedded platforms - /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ - if (szone->num_tiny_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary - /* NOTHING */ - } else if (DEPOT_MAGAZINE_INDEX != mag_index) { - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) { - /* Region has crossed threshold from density to sparsity. Mark it "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = TRUE; - } else { - /* After this free, we've found the region is still dense, so it must have been even more so before - the free. That implies the region is already correctly marked. Do nothing. */ - } + size_t s = 0; + unsigned t = 0; + size_t u = 0; + mag_index_t mag_index; - // Has the entire magazine crossed the "emptiness threshold"? If so, transfer a region - // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e - // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. - size_t a = tiny_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine - size_t u = tiny_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine + for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { + s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; + s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; + t += szone->tiny_magazines[mag_index].mag_num_objects; + u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; + } - if (a - u > ((3 * TINY_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) { - return tiny_free_do_recirc_to_depot(szone, tiny_mag_ptr, mag_index); - } + info[4] = (unsigned)t; + info[5] = (unsigned)u; - } else { -#endif - // Freed to Depot. N.B. Lock on tiny_magazines[DEPOT_MAGAZINE_INDEX] is already held - // Calcuate the first page in the coalesced block that would be safe to mark MADV_FREE - size_t free_header_size = sizeof(free_list_t) + sizeof(msize_t); - uintptr_t safe_ptr = (uintptr_t)ptr + free_header_size; - uintptr_t round_safe = round_page_quanta(safe_ptr); - - // Calcuate the last page in the coalesced block that would be safe to mark MADV_FREE - size_t free_tail_size = sizeof(msize_t); - uintptr_t safe_extent = (uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize) - free_tail_size; - uintptr_t trunc_extent = trunc_page_quanta(safe_extent); - - // The newly freed block may complete a span of bytes that cover a page. Mark it with MADV_FREE. - if (round_safe < trunc_extent) { // Coalesced area covers a page (perhaps many) - // Extend the freed block by the free region header and tail sizes to include pages - // we may have coalesced that no longer host free region tails and headers. - // This may extend over in-use ranges, but the MIN/MAX clamping below will fix that up. - uintptr_t lo = trunc_page_quanta((uintptr_t)original_ptr - free_tail_size); - uintptr_t hi = round_page_quanta((uintptr_t)original_ptr + original_size + free_header_size); - - uintptr_t free_lo = MAX(round_safe, lo); - uintptr_t free_hi = MIN(trunc_extent, hi); - - if (free_lo < free_hi) { - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, ptr, msize); - set_tiny_meta_header_in_use(ptr, msize); - - OSAtomicIncrement32Barrier(&(node->pinned_to_depot)); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - madvise_free_range(szone, region, free_lo, free_hi, &szone->last_tiny_advise); - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - OSAtomicDecrement32Barrier(&(node->pinned_to_depot)); + for (t = 0, u = 0, mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { + s += szone->small_magazines[mag_index].mag_bytes_free_at_start; + s += szone->small_magazines[mag_index].mag_bytes_free_at_end; + t += szone->small_magazines[mag_index].mag_num_objects; + u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; + } - set_tiny_meta_header_free(ptr, msize); - tiny_free_list_add_ptr(szone, tiny_mag_ptr, ptr, msize); - } - } + info[6] = (unsigned)t; + info[7] = (unsigned)u; -#if !TARGET_OS_EMBEDDED - if (0 < bytes_used || 0 < node->pinned_to_depot) { - /* Depot'd region is still live. Leave it in place on the Depot's recirculation list - so as to avoid thrashing between the Depot's free list and a magazines's free list - with detach_region/reattach_region */ - } else { - /* Depot'd region is just now empty. Consider return to OS. */ - region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, tiny_mag_ptr, node); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - if (r_dealloc) - deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0); - return FALSE; // Caller need not unlock - } - } -#endif + info[8] = (unsigned)szone->num_large_objects_in_use; + info[9] = (unsigned)szone->num_bytes_in_large_objects; + + info[10] = 0; // DEPRECATED szone->num_huge_entries; + info[11] = 0; // DEPRECATED szone->num_bytes_in_huge_objects; + + info[12] = szone->debug_flags; + + info[0] = info[4] + info[6] + info[8] + info[10]; + info[1] = info[5] + info[7] + info[9] + info[11]; - return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr) + info[3] = (unsigned)(szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE + + (unsigned)(szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE + info[9] + info[11]; + + info[2] = info[3] - (unsigned)s; + memcpy(info_to_fill, info, sizeof(unsigned) * count); } -// Allocates from the last region or a freshly allocated region -static void * -tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, - msize_t msize, void * aligned_address) +// FIXME: consistent picture requires locking! +static MALLOC_NOINLINE void +szone_print(szone_t *szone, boolean_t verbose) { - void *ptr; - - // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start - if (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start) - tiny_finalize_region(szone, tiny_mag_ptr); - - // We set the unused bits of the header in the last pair to be all ones, and those of the inuse to zeroes. - ((tiny_region_t)aligned_address)->pairs[CEIL_NUM_TINY_BLOCKS_WORDS-1].header = - (NUM_TINY_BLOCKS & 31) ? (0xFFFFFFFFU << (NUM_TINY_BLOCKS & 31)) : 0; - ((tiny_region_t)aligned_address)->pairs[CEIL_NUM_TINY_BLOCKS_WORDS-1].inuse = 0; - - // Here find the only place in tinyland that (infrequently) takes the tiny_regions_lock. - // Only one thread at a time should be permitted to assess the density of the hash - // ring and adjust if needed. - // Only one thread at a time should be permitted to insert its new region on - // the hash ring. - // It is safe for all other threads to read the hash ring (hashed_regions) and - // the associated sizes (num_regions_allocated and num_tiny_regions). - - _malloc_lock_lock(&szone->tiny_regions_lock); - - // Check to see if the hash ring of tiny regions needs to grow. Try to - // avoid the hash ring becoming too dense. - if (szone->tiny_region_generation->num_regions_allocated < (2 * szone->num_tiny_regions)) { - region_t *new_regions; - size_t new_size; - size_t new_shift = szone->tiny_region_generation->num_regions_allocated_shift; // In/Out parameter - new_regions = hash_regions_grow_no_lock(szone, szone->tiny_region_generation->hashed_regions, - szone->tiny_region_generation->num_regions_allocated, - &new_shift, - &new_size); - // Do not deallocate the current hashed_regions allocation since someone may - // be iterating it. Instead, just leak it. - - // Prepare to advance to the "next generation" of the hash ring. - szone->tiny_region_generation->nextgen->hashed_regions = new_regions; - szone->tiny_region_generation->nextgen->num_regions_allocated = new_size; - szone->tiny_region_generation->nextgen->num_regions_allocated_shift = new_shift; - - // Throw the switch to atomically advance to the next generation. - szone->tiny_region_generation = szone->tiny_region_generation->nextgen; - // Ensure everyone sees the advance. - OSMemoryBarrier(); - } - // Tag the region at "aligned_address" as belonging to us, - // and so put it under the protection of the magazine lock we are holding. - // Do this before advertising "aligned_address" on the hash ring(!) - MAGAZINE_INDEX_FOR_TINY_REGION(aligned_address) = mag_index; - - // Insert the new region into the hash ring, and update malloc statistics - hash_region_insert_no_lock(szone->tiny_region_generation->hashed_regions, - szone->tiny_region_generation->num_regions_allocated, - szone->tiny_region_generation->num_regions_allocated_shift, - aligned_address); - - szone->num_tiny_regions++; - _malloc_lock_unlock(&szone->tiny_regions_lock); - - tiny_mag_ptr->mag_last_region = aligned_address; - BYTES_USED_FOR_TINY_REGION(aligned_address) = TINY_BYTES_FOR_MSIZE(msize); -#if ASLR_INTERNAL - int offset_msize = malloc_entropy[0] & TINY_ENTROPY_MASK; -#if DEBUG_MALLOC - if (getenv("MallocASLRForce")) offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & TINY_ENTROPY_MASK; - if (getenv("MallocASLRPrint")) malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize); -#endif -#else - int offset_msize = 0; -#endif - ptr = (void *)((uintptr_t) aligned_address + TINY_BYTES_FOR_MSIZE(offset_msize)); - set_tiny_meta_header_in_use(ptr, msize); - tiny_mag_ptr->mag_num_objects++; - tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(msize); - tiny_mag_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; - - // We put a header on the last block so that it appears in use (for coalescing, etc...) - set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize))); - tiny_mag_ptr->mag_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize - offset_msize); - -#if ASLR_INTERNAL - // Put a header on the previous block for same reason - tiny_mag_ptr->mag_bytes_free_at_start = TINY_BYTES_FOR_MSIZE(offset_msize); - if (offset_msize) { - set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr - TINY_QUANTUM)); - } -#else - tiny_mag_ptr->mag_bytes_free_at_start = 0; -#endif - - // connect to magazine as last node - recirc_list_splice_last(szone, tiny_mag_ptr, REGION_TRAILER_FOR_TINY_REGION(aligned_address)); + unsigned info[13]; + size_t index; + region_t region; -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_region_no_lock(), ptr=%p, msize=%d\n", ptr, msize); + scalable_zone_info((void *)szone, info, 13); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, + "Scalable zone %p: inUse=%u(%y) touched=%y allocated=%y flags=%d\n", szone, info[0], info[1], info[2], info[3], + info[12]); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "\ttiny=%u(%y) small=%u(%y) large=%u(%y) huge=%u(%y)\n", info[4], + info[5], info[6], info[7], info[8], info[9], info[10], info[11]); + // tiny + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%lu tiny regions:\n", szone->num_tiny_regions); + if (szone->num_tiny_regions_dealloc) { + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "[%lu tiny regions have been vm_deallocate'd]\n", + szone->num_tiny_regions_dealloc); + } + for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) { + region = szone->tiny_region_generation->hashed_regions[index]; + if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { + mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(region); + print_tiny_region(verbose, region, (region == szone->tiny_magazines[mag_index].mag_last_region) + ? szone->tiny_magazines[mag_index].mag_bytes_free_at_start + : 0, + (region == szone->tiny_magazines[mag_index].mag_last_region) + ? szone->tiny_magazines[mag_index].mag_bytes_free_at_end + : 0); + } + } + if (verbose) { + print_tiny_free_list(szone); + } + // small + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%lu small regions:\n", szone->num_small_regions); + if (szone->num_small_regions_dealloc) { + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "[%lu small regions have been vm_deallocate'd]\n", + szone->num_small_regions_dealloc); + } + for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) { + region = szone->small_region_generation->hashed_regions[index]; + if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { + mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(region); + print_small_region(szone, verbose, region, (region == szone->small_magazines[mag_index].mag_last_region) + ? szone->small_magazines[mag_index].mag_bytes_free_at_start + : 0, + (region == szone->small_magazines[mag_index].mag_last_region) + ? szone->small_magazines[mag_index].mag_bytes_free_at_end + : 0); + } + } + if (verbose) { + print_small_free_list(szone); } -#endif - return ptr; } -static INLINE void * -tiny_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) +static void +szone_log(malloc_zone_t *zone, void *log_address) { - msize_t new_msize = TINY_MSIZE_FOR_BYTES(new_good_size); - msize_t mshrinkage = TINY_MSIZE_FOR_BYTES(old_size) - new_msize; + szone_t *szone = (szone_t *)zone; - if (mshrinkage) { - void *q = (void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(new_msize)); - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)), - MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr))); + szone->log_address = log_address; +} - // Mark q as block header and in-use, thus creating two blocks. - set_tiny_meta_header_in_use(q, mshrinkage); - tiny_mag_ptr->mag_num_objects++; +// +// When forcing the lock on the entire zone, make sure we are out of the critical section in each magazine +static MALLOC_INLINE void +szone_force_lock_magazine(szone_t *szone, magazine_t *mag) +{ + while (1) { + SZONE_MAGAZINE_PTR_LOCK(szone, mag); + if (!mag->alloc_underway) { + return; + } - SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr); - szone_free(szone, q); // avoid inlining free_tiny(szone, q, ...); + SZONE_MAGAZINE_PTR_UNLOCK(szone, mag); + yield(); } - return ptr; } -static INLINE boolean_t -tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) +static void +szone_force_lock(szone_t *szone) { - // returns 1 on success - msize_t index; - msize_t old_msize; - unsigned next_index; - void *next_block; - boolean_t is_free; - msize_t next_msize, coalesced_msize, leftover_msize; - void *leftover; - - index = TINY_INDEX_FOR_PTR(ptr); - old_msize = TINY_MSIZE_FOR_BYTES(old_size); - next_index = index + old_msize; - - if (next_index >= NUM_TINY_BLOCKS) { - return 0; - } - next_block = (char *)ptr + old_size; - - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)), - MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr))); + mag_index_t i; - /* - * Look for a free block immediately afterwards. If it's large enough, we can consume (part of) - * it. - */ - is_free = tiny_meta_header_is_free(next_block); - if (!is_free) { - SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr); - return 0; // next_block is in use; + for (i = 0; i < szone->num_tiny_magazines; ++i) { + szone_force_lock_magazine(szone, &szone->tiny_magazines[i]); } - next_msize = get_tiny_free_size(next_block); - if (old_size + TINY_BYTES_FOR_MSIZE(next_msize) < new_size) { - SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr); - return 0; // even with next block, not enough + szone_force_lock_magazine(szone, &szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); + + for (i = 0; i < szone->num_small_magazines; ++i) { + szone_force_lock_magazine(szone, &szone->small_magazines[i]); } - /* - * The following block is big enough; pull it from its freelist and chop off enough to satisfy - * our needs. - */ - tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); - set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards - coalesced_msize = TINY_MSIZE_FOR_BYTES(new_size - old_size + TINY_QUANTUM - 1); - leftover_msize = next_msize - coalesced_msize; - if (leftover_msize) { - /* there's some left, so put the remainder back */ - leftover = (void *)((uintptr_t)next_block + TINY_BYTES_FOR_MSIZE(coalesced_msize)); + szone_force_lock_magazine(szone, &szone->small_magazines[DEPOT_MAGAZINE_INDEX]); + + SZONE_LOCK(szone); +} - tiny_free_list_add_ptr(szone, tiny_mag_ptr, leftover, leftover_msize); +static void +szone_force_unlock(szone_t *szone) +{ + mag_index_t i; + + SZONE_UNLOCK(szone); + + for (i = -1; i < szone->num_small_magazines; ++i) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->small_magazines[i]))); } - set_tiny_meta_header_in_use(ptr, old_msize + coalesced_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_try_realloc_in_place(), ptr=%p, msize=%d\n", ptr, old_msize + coalesced_msize); + + for (i = -1; i < szone->num_tiny_magazines; ++i) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->tiny_magazines[i]))); } -#endif - tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(coalesced_msize); +} + +static void +szone_reinit_lock(szone_t *szone) +{ + mag_index_t i; - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); - size_t bytes_used = node->bytes_used + TINY_BYTES_FOR_MSIZE(coalesced_msize); - node->bytes_used = bytes_used; + SZONE_REINIT_LOCK(szone); - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) { - /* After this reallocation the region is still sparse, so it must have been even more so before - the reallocation. That implies the region is already correctly marked. Do nothing. */ - } else { - /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = FALSE; + for (i = -1; i < szone->num_small_magazines; ++i) { + SZONE_MAGAZINE_PTR_REINIT_LOCK(szone, (&(szone->small_magazines[i]))); } - SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return 1; + for (i = -1; i < szone->num_tiny_magazines; ++i) { + SZONE_MAGAZINE_PTR_REINIT_LOCK(szone, (&(szone->tiny_magazines[i]))); + } } static boolean_t -tiny_check_region(szone_t *szone, region_t region) +szone_locked(szone_t *szone) { - uintptr_t start, ptr, region_end; - boolean_t prev_free = 0; - boolean_t is_free; - msize_t msize; - free_list_t *free_head; - void *follower, *previous, *next; - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(region); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - // Assumes locked - CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__); - - /* establish region limits */ - start = (uintptr_t)TINY_REGION_ADDRESS(region); - ptr = start; - if (region == tiny_mag_ptr->mag_last_region) { - ptr += tiny_mag_ptr->mag_bytes_free_at_start; + mag_index_t i; + int tookLock; - /* - * Check the leading block's integrity here also. - */ - if (tiny_mag_ptr->mag_bytes_free_at_start) { - msize = get_tiny_meta_header((void *)(ptr - TINY_QUANTUM), &is_free); - if (is_free || (msize != 1)) { - malloc_printf("*** invariant broken for leader block %p - %d %d\n", ptr - TINY_QUANTUM, msize, is_free); - } - } + tookLock = SZONE_TRY_LOCK(szone); + if (tookLock == 0) { + return 1; } - region_end = (uintptr_t)TINY_REGION_END(region); - - /* - * The last region may have a trailing chunk which has not been converted into inuse/freelist - * blocks yet. - */ - if (region == tiny_mag_ptr->mag_last_region) - region_end -= tiny_mag_ptr->mag_bytes_free_at_end; + SZONE_UNLOCK(szone); - /* - * Scan blocks within the region. - */ - while (ptr < region_end) { - /* - * If the first block is free, and its size is 65536 (msize = 0) then the entire region is - * free. - */ - msize = get_tiny_meta_header((void *)ptr, &is_free); - if (is_free && !msize && (ptr == start)) { + for (i = -1; i < szone->num_small_magazines; ++i) { + tookLock = SZONE_MAGAZINE_PTR_TRY_LOCK(szone, (&(szone->small_magazines[i]))); + if (tookLock == 0) { return 1; } + SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->small_magazines[i]))); + } - /* - * If the block's size is 65536 (msize = 0) then since we're not the first entry the size is - * corrupt. - */ - if (!msize) { - malloc_printf("*** invariant broken for tiny block %p this msize=%d - size is too small\n", - ptr, msize); - return 0; - } - - if (!is_free) { - /* - * In use blocks cannot be more than (NUM_TINY_SLOTS - 1) quanta large. - */ - prev_free = 0; - if (msize > (NUM_TINY_SLOTS - 1)) { - malloc_printf("*** invariant broken for %p this tiny msize=%d - size is too large\n", - ptr, msize); - return 0; - } - /* move to next block */ - ptr += TINY_BYTES_FOR_MSIZE(msize); - } else { -#if !RELAXED_INVARIANT_CHECKS - /* - * Free blocks must have been coalesced, we cannot have a free block following another - * free block. - */ - if (prev_free) { - malloc_printf("*** invariant broken for free block %p this tiny msize=%d: two free blocks in a row\n", - ptr, msize); - return 0; - } -#endif // RELAXED_INVARIANT_CHECKS - prev_free = 1; - /* - * Check the integrity of this block's entry in its freelist. - */ - free_head = (free_list_t *)ptr; - previous = free_list_unchecksum_ptr(szone, &free_head->previous); - next = free_list_unchecksum_ptr(szone, &free_head->next); - if (previous && !tiny_meta_header_is_free(previous)) { - malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", - ptr, previous); - return 0; - } - if (next && !tiny_meta_header_is_free(next)) { - malloc_printf("*** invariant broken for %p (next in free list %p is not a free pointer)\n", - ptr, next); - return 0; - } - /* - * Check the free block's trailing size value. - */ - follower = FOLLOWING_TINY_PTR(ptr, msize); - if (((uintptr_t)follower != region_end) && (get_tiny_previous_free_msize(follower) != msize)) { - malloc_printf("*** invariant broken for tiny free %p followed by %p in region [%p-%p] " - "(end marker incorrect) should be %d; in fact %d\n", - ptr, follower, TINY_REGION_ADDRESS(region), region_end, msize, get_tiny_previous_free_msize(follower)); - return 0; - } - /* move to next block */ - ptr = (uintptr_t)follower; + for (i = -1; i < szone->num_tiny_magazines; ++i) { + tookLock = SZONE_MAGAZINE_PTR_TRY_LOCK(szone, (&(szone->tiny_magazines[i]))); + if (tookLock == 0) { + return 1; } + SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->tiny_magazines[i]))); } - /* - * Ensure that we scanned the entire region - */ - if (ptr != region_end) { - malloc_printf("*** invariant broken for region end %p - %p\n", ptr, region_end); - return 0; - } - /* - * Check the trailing block's integrity. - */ - if (region == tiny_mag_ptr->mag_last_region) { - if (tiny_mag_ptr->mag_bytes_free_at_end) { - msize = get_tiny_meta_header((void *)ptr, &is_free); - if (is_free || (msize != 1)) { - malloc_printf("*** invariant broken for blocker block %p - %d %d\n", ptr, msize, is_free); - } - } - } - return 1; + return 0; } -static kern_return_t -tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, - memory_reader_t reader, vm_range_recorder_t recorder) +size_t +szone_pressure_relief(szone_t *szone, size_t goal) { - size_t num_regions; - size_t index; - region_t *regions; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - kern_return_t err; - region_t region; - vm_range_t range; - vm_range_t admin_range; - vm_range_t ptr_range; - unsigned char *mapped_region; - uint32_t *block_header; - uint32_t *in_use; - unsigned block_index; - unsigned block_limit; - boolean_t is_free; - msize_t msize; - void *mapped_ptr; - unsigned bit; - magazine_t *tiny_mag_base = NULL; - - region_hash_generation_t *trg_ptr; - err = reader(task, (vm_address_t)szone->tiny_region_generation, sizeof(region_hash_generation_t), (void **)&trg_ptr); - if (err) return err; - - num_regions = trg_ptr->num_regions_allocated; - err = reader(task, (vm_address_t)trg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions); - if (err) return err; - - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - // Map in all active magazines. Do this outside the iteration over regions. - err = reader(task, (vm_address_t)(szone->tiny_magazines), - szone->num_tiny_magazines*sizeof(magazine_t),(void **)&tiny_mag_base); - if (err) return err; - } - - for (index = 0; index < num_regions; ++index) { - region = regions[index]; - if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { - range.address = (vm_address_t)TINY_REGION_ADDRESS(region); - range.size = (vm_size_t)TINY_REGION_SIZE; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - admin_range.address = range.address + TINY_METADATA_START; - admin_range.size = TINY_METADATA_SIZE; - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); - } - if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { - ptr_range.address = range.address; - ptr_range.size = NUM_TINY_BLOCKS * TINY_QUANTUM; - recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); - } - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - void *mag_last_free; - vm_address_t mag_last_free_ptr = 0; - msize_t mag_last_free_msize = 0; - - err = reader(task, range.address, range.size, (void **)&mapped_region); - if (err) - return err; - - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(mapped_region); - magazine_t *tiny_mag_ptr = tiny_mag_base + mag_index; - - if (DEPOT_MAGAZINE_INDEX != mag_index) { - mag_last_free = tiny_mag_ptr->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(TINY_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (TINY_QUANTUM - 1); - } - } else { - for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { - if ((void *)range.address == (tiny_mag_base + mag_index)->mag_last_free_rgn) { - mag_last_free = (tiny_mag_base + mag_index)->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(TINY_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (TINY_QUANTUM - 1); - } - } - } - } + size_t total = 0; - block_header = (uint32_t *)(mapped_region + TINY_METADATA_START + sizeof(region_trailer_t)); - in_use = TINY_INUSE_FOR_HEADER(block_header); - block_index = 0; - block_limit = NUM_TINY_BLOCKS; - if (region == tiny_mag_ptr->mag_last_region) { - block_index += TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start); - block_limit -= TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end); - } +#if CONFIG_MADVISE_PRESSURE_RELIEF + mag_index_t mag_index; - while (block_index < block_limit) { - vm_size_t block_offset = TINY_BYTES_FOR_MSIZE(block_index); - is_free = !BITARRAY_BIT(in_use, block_index); - if (is_free) { - mapped_ptr = mapped_region + block_offset; - - // mapped_region, the address at which 'range' in 'task' has been - // mapped into our process, is not necessarily aligned to - // TINY_BLOCKS_ALIGN. - // - // Since the code in get_tiny_free_size() assumes the pointer came - // from a properly aligned tiny region, and mapped_region is not - // necessarily aligned, then do the size calculation directly. - // If the next bit is set in the header bitmap, then the size is one - // quantum. Otherwise, read the size field. - if (!BITARRAY_BIT(block_header, (block_index+1))) - msize = TINY_FREE_SIZE(mapped_ptr); - else - msize = 1; - - } else if (range.address + block_offset != mag_last_free_ptr) { - msize = 1; - bit = block_index + 1; - while (! BITARRAY_BIT(block_header, bit)) { - bit++; - msize ++; - } - buffer[count].address = range.address + block_offset; - buffer[count].size = TINY_BYTES_FOR_MSIZE(msize); - count++; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } else { - // Block is not free but it matches mag_last_free_ptr so even - // though it is not marked free in the bitmap, we treat it as if - // it is and move on - msize = mag_last_free_msize; - } + magazine_t *tiny_depot_ptr = (&szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); + magazine_t *small_depot_ptr = (&szone->small_magazines[DEPOT_MAGAZINE_INDEX]); - if (!msize) - return KERN_FAILURE; // Somethings amiss. Avoid looping at this block_index. + for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { + size_t index; + for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) { + SZONE_LOCK(szone); - block_index += msize; - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } + region_t tiny = szone->tiny_region_generation->hashed_regions[index]; + if (!tiny || tiny == HASHRING_REGION_DEALLOCATED) { + SZONE_UNLOCK(szone); + continue; } - } - } - return 0; -} - -static void * -tiny_malloc_from_free_list(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - free_list_t *ptr; - msize_t this_msize; - grain_t slot = msize - 1; - free_list_t **free_list = tiny_mag_ptr->mag_free_list; - free_list_t **the_slot = free_list + slot; - free_list_t *next; - free_list_t **limit; -#if defined(__LP64__) - uint64_t bitmap; -#else - uint32_t bitmap; -#endif - msize_t leftover_msize; - free_list_t *leftover_ptr; - - // Assumes we've locked the region - CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__); - - // Look for an exact match by checking the freelist for this msize. - // - ptr = *the_slot; - if (ptr) { - next = free_list_unchecksum_ptr(szone, &ptr->next); - if (next) { - next->previous = ptr->previous; - } else { - BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot); - } - *the_slot = next; - this_msize = msize; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize); - } -#endif - goto return_tiny_alloc; - } - // Mask off the bits representing slots holding free blocks smaller than the - // size we need. If there are no larger free blocks, try allocating from - // the free space at the end of the tiny region. -#if defined(__LP64__) - bitmap = ((uint64_t *)(tiny_mag_ptr->mag_bitmap))[0] & ~ ((1ULL << slot) - 1); -#else - bitmap = tiny_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1); -#endif - if (!bitmap) - goto try_tiny_malloc_from_end; + magazine_t *mag_ptr = mag_lock_zine_for_region_trailer( + szone, szone->tiny_magazines, REGION_TRAILER_FOR_TINY_REGION(tiny), MAGAZINE_INDEX_FOR_TINY_REGION(tiny)); + SZONE_UNLOCK(szone); - slot = BITMAPV_CTZ(bitmap); - limit = free_list + NUM_TINY_SLOTS - 1; - free_list += slot; + /* Ordering is important here, the magazine of a region may potentially change + * during mag_lock_zine_for_region_trailer, so src_mag_index must be taken + * after we've obtained the lock. + */ + mag_index_t src_mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny); - if (free_list < limit) { - ptr = *free_list; - if (ptr) { - next = free_list_unchecksum_ptr(szone, &ptr->next); - *free_list = next; - if (next) { - next->previous = ptr->previous; - } else { - BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot); + /* We can (and must) ignore magazines that are already in the recirc depot. */ + if (src_mag_index == DEPOT_MAGAZINE_INDEX) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); + continue; } - this_msize = get_tiny_free_size(ptr); - goto add_leftover_and_proceed; - } -#if DEBUG_MALLOC - malloc_printf("in tiny_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n",slot); -#endif - } - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than (NUM_TINY_SLOTS - 1) * tiny quantum size. - // If the last freelist is not empty, and the head contains a block that is - // larger than our request, then the remainder is put back on the free list. - ptr = *limit; - if (ptr) { - this_msize = get_tiny_free_size(ptr); - next = free_list_unchecksum_ptr(szone, &ptr->next); - if (this_msize - msize >= NUM_TINY_SLOTS) { - // the leftover will go back to the free list, so we optimize by - // modifying the free list rather than a pop and push of the head - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); - *limit = leftover_ptr; - if (next) { - next->previous.u = free_list_checksum_ptr(szone, leftover_ptr); - } - leftover_ptr->previous = ptr->previous; - leftover_ptr->next = ptr->next; - set_tiny_meta_header_free(leftover_ptr, leftover_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", - ptr, msize, this_msize); + if (tiny == mag_ptr->mag_last_region && (mag_ptr->mag_bytes_free_at_end || mag_ptr->mag_bytes_free_at_start)) { + tiny_finalize_region(szone, mag_ptr); } -#endif - this_msize = msize; - goto return_tiny_alloc; - } - if (next) { - next->previous = ptr->previous; - } - *limit = next; - goto add_leftover_and_proceed; - /* NOTREACHED */ - } - -try_tiny_malloc_from_end: - // Let's see if we can use tiny_mag_ptr->mag_bytes_free_at_end - if (tiny_mag_ptr->mag_bytes_free_at_end >= TINY_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)((uintptr_t)TINY_REGION_END(tiny_mag_ptr->mag_last_region) - - tiny_mag_ptr->mag_bytes_free_at_end); - tiny_mag_ptr->mag_bytes_free_at_end -= TINY_BYTES_FOR_MSIZE(msize); - if (tiny_mag_ptr->mag_bytes_free_at_end) { - // let's add an in use block after ptr to serve as boundary - set_tiny_meta_header_in_use_1((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); - } - this_msize = msize; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize); - } -#endif - goto return_tiny_alloc; - } -#if ASLR_INTERNAL - // Try from start if nothing left at end - if (tiny_mag_ptr->mag_bytes_free_at_start >= TINY_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)(TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region) + - tiny_mag_ptr->mag_bytes_free_at_start - TINY_BYTES_FOR_MSIZE(msize)); - tiny_mag_ptr->mag_bytes_free_at_start -= TINY_BYTES_FOR_MSIZE(msize); - if (tiny_mag_ptr->mag_bytes_free_at_start) { - // let's add an in use block before ptr to serve as boundary - set_tiny_meta_header_in_use_1((unsigned char *)ptr - TINY_QUANTUM); - } - this_msize = msize; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), from start ptr=%p, msize=%d\n", ptr, msize); - } -#endif - goto return_tiny_alloc; - } -#endif - return NULL; -add_leftover_and_proceed: - if (!this_msize || (this_msize > msize)) { - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); - } -#endif - tiny_free_list_add_ptr(szone, tiny_mag_ptr, leftover_ptr, leftover_msize); - this_msize = msize; - } + /* Because this region is currently in use, we can't safely madvise it while + * it's attached to the magazine. For this operation we have to remove it from + * the current mag, attach it to the depot and then madvise. + */ -return_tiny_alloc: - tiny_mag_ptr->mag_num_objects++; - tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(this_msize); + recirc_list_extract(szone, mag_ptr, REGION_TRAILER_FOR_TINY_REGION(tiny)); + int objects_in_use = tiny_free_detach_region(szone, mag_ptr, tiny); - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); - size_t bytes_used = node->bytes_used + TINY_BYTES_FOR_MSIZE(this_msize); - node->bytes_used = bytes_used; + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_depot_ptr); + MAGAZINE_INDEX_FOR_TINY_REGION(tiny) = DEPOT_MAGAZINE_INDEX; + REGION_TRAILER_FOR_TINY_REGION(tiny)->pinned_to_depot = 0; - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) { - /* After this allocation the region is still sparse, so it must have been even more so before - the allocation. That implies the region is already correctly marked. Do nothing. */ - } else { - /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = FALSE; - } -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); - } -#endif - if (this_msize > 1) - set_tiny_meta_header_in_use(ptr, this_msize); - else - set_tiny_meta_header_in_use_1(ptr); - return ptr; -} -#undef DENSITY_THRESHOLD -#undef K + size_t bytes_inplay = tiny_free_reattach_region(szone, tiny_depot_ptr, tiny); -static INLINE void * -tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) -{ - void *ptr; - mag_index_t mag_index = mag_get_thread_index(szone); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); + /* Fix up the metadata of the target magazine while the region is in the depot. */ + mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; + mag_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; + mag_ptr->mag_num_objects -= objects_in_use; -#if DEBUG_MALLOC - if (DEPOT_MAGAZINE_INDEX == mag_index) { - szone_error(szone, 1, "malloc called for magazine index -1", NULL, NULL); - return(NULL); - } + /* Now we can drop the magazine lock of the source mag. */ + SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); - if (!msize) { - szone_error(szone, 1, "invariant broken (!msize) in allocation (region)", NULL, NULL); - return(NULL); - } -#endif + tiny_depot_ptr->mag_num_bytes_in_objects += bytes_inplay; + tiny_depot_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; + tiny_depot_ptr->mag_num_objects -= objects_in_use; - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + recirc_list_splice_last(szone, tiny_depot_ptr, REGION_TRAILER_FOR_TINY_REGION(tiny)); -#if TINY_CACHE - ptr = tiny_mag_ptr->mag_last_free; + /* Actually do the scan, done holding the depot lock, the call will drop the lock + * around the actual madvise syscalls. + */ + tiny_free_scan_madvise_free(szone, tiny_depot_ptr, tiny); - if ((((uintptr_t)ptr) & (TINY_QUANTUM - 1)) == msize) { - // we have a winner - tiny_mag_ptr->mag_last_free = NULL; - tiny_mag_ptr->mag_last_free_rgn = NULL; - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - ptr = (void *)((uintptr_t)ptr & ~ (TINY_QUANTUM - 1)); - if (cleared_requested) { - memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); - } -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in tiny_malloc_should_clear(), tiny cache ptr=%p, msize=%d\n", ptr, msize); + /* Now the region is in the recirc depot, the next allocations to require more + * blocks will come along and take one of these regions back out of the depot. + * As OS X madvise's reuse on an per-region basis, we leave as many of these + * regions in the depot as possible after memory pressure. + */ + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_depot_ptr); } -#endif - return ptr; } -#endif /* TINY_CACHE */ - while (1) { - ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } + for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { + size_t index; + for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) { + SZONE_LOCK(szone); - if (tiny_get_region_from_depot(szone, tiny_mag_ptr, mag_index, msize)) { - ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); - } - return ptr; + region_t small = szone->small_region_generation->hashed_regions[index]; + if (!small || small == HASHRING_REGION_DEALLOCATED) { + SZONE_UNLOCK(szone); + continue; } - } - // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc(). - // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first - // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section. - // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the - // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation, - // and retry-ing threads succeed in the code just above. - if (!tiny_mag_ptr->alloc_underway) { - void *fresh_region; - - // time to create a new region (do this outside the magazine lock) - tiny_mag_ptr->alloc_underway = TRUE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - fresh_region = allocate_pages_securely(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, VM_MEMORY_MALLOC_TINY); - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + magazine_t *mag_ptr = mag_lock_zine_for_region_trailer( + szone, szone->small_magazines, REGION_TRAILER_FOR_SMALL_REGION(small), MAGAZINE_INDEX_FOR_SMALL_REGION(small)); + SZONE_UNLOCK(szone); - MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, TINY_REGION_SIZE); // DTrace USDT Probe + /* Ordering is important here, the magazine of a region may potentially change + * during mag_lock_zine_for_region_trailer, so src_mag_index must be taken + * after we've obtained the lock. + */ + mag_index_t src_mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(small); - if (!fresh_region) { // out of memory! - tiny_mag_ptr->alloc_underway = FALSE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return NULL; + /* We can (and must) ignore magazines that are already in the recirc depot. */ + if (src_mag_index == DEPOT_MAGAZINE_INDEX) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); + continue; } - ptr = tiny_malloc_from_region_no_lock(szone, tiny_mag_ptr, mag_index, msize, fresh_region); + if (small == mag_ptr->mag_last_region && (mag_ptr->mag_bytes_free_at_end || mag_ptr->mag_bytes_free_at_start)) { + small_finalize_region(szone, mag_ptr); + } - // we don't clear because this freshly allocated space is pristine - tiny_mag_ptr->alloc_underway = FALSE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return ptr; - } else { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - yield(); - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - } - } - /* NOTREACHED */ -} + /* Because this region is currently in use, we can't safely madvise it while + * it's attached to the magazine. For this operation we have to remove it from + * the current mag, attach it to the depot and then madvise. + */ -static NOINLINE void -free_tiny_botch(szone_t *szone, free_list_t *ptr) -{ - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - szone_error(szone, 1, "double free", ptr, NULL); -} + recirc_list_extract(szone, mag_ptr, REGION_TRAILER_FOR_SMALL_REGION(small)); + int objects_in_use = small_free_detach_region(szone, mag_ptr, small); -static INLINE void -free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size) -{ - msize_t msize; - boolean_t is_free; - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - // ptr is known to be in tiny_region - if (known_size) { - msize = TINY_MSIZE_FOR_BYTES(known_size + TINY_QUANTUM - 1); - } else { - msize = get_tiny_meta_header(ptr, &is_free); - if (is_free) { - free_tiny_botch(szone, ptr); - return; - } - } -#if DEBUG_MALLOC - if (!msize) { - malloc_printf("*** free_tiny() block in use is too large: %p\n", ptr); - return; - } -#endif + SZONE_MAGAZINE_PTR_LOCK(szone, small_depot_ptr); + MAGAZINE_INDEX_FOR_SMALL_REGION(small) = DEPOT_MAGAZINE_INDEX; + REGION_TRAILER_FOR_SMALL_REGION(small)->pinned_to_depot = 0; - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + size_t bytes_inplay = small_free_reattach_region(szone, small_depot_ptr, small); -#if TINY_CACHE - // Depot does not participate in TINY_CACHE since it can't be directly malloc()'d - if (DEPOT_MAGAZINE_INDEX != mag_index) { - if (msize < TINY_QUANTUM) { // to see if the bits fit in the last 4 bits - void *ptr2 = tiny_mag_ptr->mag_last_free; // Might be NULL - region_t rgn2 = tiny_mag_ptr->mag_last_free_rgn; - - /* check that we don't already have this pointer in the cache */ - if (ptr == (void *)((uintptr_t)ptr2 & ~ (TINY_QUANTUM - 1))) { - free_tiny_botch(szone, ptr); - return; - } + /* Fix up the metadata of the target magazine while the region is in the depot. */ + mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; + mag_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; + mag_ptr->mag_num_objects -= objects_in_use; - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) - memset(ptr, SCRABBLE_BYTE, TINY_BYTES_FOR_MSIZE(msize)); + /* Now we can drop the magazine lock of the source mag. */ + SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); - tiny_mag_ptr->mag_last_free = (void *)(((uintptr_t)ptr) | msize); - tiny_mag_ptr->mag_last_free_rgn = tiny_region; + small_depot_ptr->mag_num_bytes_in_objects += bytes_inplay; + small_depot_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; + small_depot_ptr->mag_num_objects -= objects_in_use; - if (!ptr2) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return; - } + recirc_list_splice_last(szone, small_depot_ptr, REGION_TRAILER_FOR_SMALL_REGION(small)); + + /* Actually do the scan, done holding the depot lock, the call will drop the lock + * around the actual madvise syscalls. + */ + small_free_scan_madvise_free(szone, small_depot_ptr, small); - msize = (uintptr_t)ptr2 & (TINY_QUANTUM - 1); - ptr = (void *)(((uintptr_t)ptr2) & ~(TINY_QUANTUM - 1)); - tiny_region = rgn2; + /* Now the region is in the recirc depot, the next allocations to require more + * blocks will come along and take one of these regions back out of the depot. + * As OS X madvise's reuse on an per-region basis, we leave as many of these + * regions in the depot as possible after memory pressure. + */ + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_depot_ptr); } } -#endif /* TINY_CACHE */ - - // Now in the time it took to acquire the lock, the region may have migrated - // from one magazine to another. I.e. trailer->mag_index is volatile. - // In which case the magazine lock we obtained (namely magazines[mag_index].mag_lock) - // is stale. If so, keep on tryin' ... - region_trailer_t *trailer = REGION_TRAILER_FOR_TINY_REGION(tiny_region); - mag_index_t refreshed_index; +#endif - while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment +#if CONFIG_LARGE_CACHE + if (szone->flotsam_enabled) { + SZONE_LOCK(szone); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + // stack allocated copy of the death-row cache + int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest; + large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE]; - mag_index = refreshed_index; - tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - } + memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache)); - if (tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize)) - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0; + szone->large_entry_cache[0].address = 0x0; + szone->large_entry_cache[0].size = 0; + szone->large_entry_cache_bytes = 0; + szone->large_entry_cache_reserve_bytes = 0; - CHECK(szone, __PRETTY_FUNCTION__); -} + szone->flotsam_enabled = FALSE; -static void -print_tiny_free_list(szone_t *szone) -{ - free_list_t *ptr; - _SIMPLE_STRING b = _simple_salloc(); - mag_index_t mag_index; + SZONE_UNLOCK(szone); - if (b) { - _simple_sappend(b, "tiny free sizes:\n"); - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - grain_t slot = 0; - _simple_sprintf(b,"\tMagazine %d: ", mag_index); - while (slot < NUM_TINY_SLOTS) { - ptr = szone->tiny_magazines[mag_index].mag_free_list[slot]; - if (ptr) { - _simple_sprintf(b, "%s%y[%d]; ", (slot == NUM_TINY_SLOTS-1) ? ">=" : "", - (slot+1)*TINY_QUANTUM, free_list_count(szone, ptr)); - } - slot++; - } - _simple_sappend(b,"\n"); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static void -print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end) -{ - unsigned counts[1024]; - unsigned in_use = 0; - uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(region); - uintptr_t current = start + bytes_at_end; - uintptr_t limit = (uintptr_t)TINY_REGION_END(region) - bytes_at_end; - boolean_t is_free; - msize_t msize; - unsigned ci; - _SIMPLE_STRING b; - uintptr_t pgTot = 0; - - if (region == HASHRING_REGION_DEALLOCATED) { - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Tiny region [unknown address] was returned to the OS\n"); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } - return; - } - - memset(counts, 0, sizeof(counts)); - while (current < limit) { - msize = get_tiny_meta_header((void *)current, &is_free); - if (is_free & !msize && (current == start)) { - // first block is all free - uintptr_t pgLo = round_page_quanta(start + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page_quanta(start + TINY_REGION_SIZE - sizeof(msize_t)); - - if (pgLo < pgHi) { - pgTot += (pgHi - pgLo); - } - break; - } - if (!msize) { - malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize); - break; - } - if (!is_free) { - // block in use - if (msize > NUM_TINY_SLOTS) - malloc_printf("*** error at %p msize for in_use is %d\n", (void *)current, msize); - if (msize < 1024) - counts[msize]++; - in_use++; - } else { - uintptr_t pgLo = round_page_quanta(current + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page_quanta(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); - - if (pgLo < pgHi) { - pgTot += (pgHi - pgLo); - } - } - current += TINY_BYTES_FOR_MSIZE(msize); - } - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Tiny region [%p-%p, %y] \t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE); - _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_TINY_REGION(region)); - _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_TINY_REGION(region)); - if (bytes_at_end || bytes_at_start) - _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start); - if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_TINY_REGION(region)) { - _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot); - } else { - _simple_sprintf(b, "Fragments subject to reclamation=%ly", pgTot); - } - if (verbose && in_use) { - _simple_sappend(b, "\n\tSizes in use: "); - for (ci = 0; ci < 1024; ci++) - if (counts[ci]) - _simple_sprintf(b, "%d[%d] ", TINY_BYTES_FOR_MSIZE(ci), counts[ci]); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static boolean_t -tiny_free_list_check(szone_t *szone, grain_t slot) -{ - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - - unsigned count = 0; - free_list_t *ptr = szone->tiny_magazines[mag_index].mag_free_list[slot]; - boolean_t is_free; - free_list_t *previous = NULL; - - while (ptr) { - is_free = tiny_meta_header_is_free(ptr); - if (! is_free) { - malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return 0; - } - if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { - malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return 0; - } - if (!tiny_region_for_ptr_no_lock(szone, ptr)) { - malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return 0; - } - if (free_list_unchecksum_ptr(szone, &ptr->previous) != previous) { - malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return 0; - } - previous = ptr; - ptr = free_list_unchecksum_ptr(szone, &ptr->next); - count++; - } - - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - } - return 1; -} - -/********************* SMALL FREE LIST UTILITIES ************************/ - -/* - * Mark a block as free. Only the first quantum of a block is marked thusly, - * the remainder are marked "middle". - */ -static INLINE void -small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize) -{ - meta_headers[index] = msize | SMALL_IS_FREE; -} - -/* - * Mark a block as in use. Only the first quantum of a block is marked thusly, - * the remainder are marked "middle". - */ -static INLINE void -small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) -{ - meta_headers[index] = msize; -} - -/* - * Mark a quantum as being the second or later in a block. - */ -static INLINE void -small_meta_header_set_middle(msize_t *meta_headers, msize_t index) -{ - meta_headers[index] = 0; -} - -/* - * Adds an item to the proper free list, and also marks the meta-header of the - * block properly. - * Assumes szone has been locked - */ -static void -small_free_list_add_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize) -{ - grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; - free_list_t *free_ptr = ptr; - free_list_t *free_head = small_mag_ptr->mag_free_list[slot]; - void *follower; - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } - if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { - szone_error(szone, 1, "small_free_list_add_ptr: Unaligned ptr", ptr, NULL); - } -#endif - small_meta_header_set_is_free(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), msize); - - if (free_head) { -#if DEBUG_MALLOC - if (free_list_unchecksum_ptr(szone, &free_head->previous)) { - szone_error(szone, 1, "small_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr, - "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, (void *)free_head, free_head->previous.p); - } - if (!SMALL_PTR_IS_FREE(free_head)) { - szone_error(szone, 1, "small_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, - "ptr=%p slot=%d free_head=%p\n", ptr, slot, (void *)free_head); - } -#endif - free_head->previous.u = free_list_checksum_ptr(szone, free_ptr); - } else { - BITMAPN_SET(small_mag_ptr->mag_bitmap, slot); - } - free_ptr->previous.u = free_list_checksum_ptr(szone, NULL); - free_ptr->next.u = free_list_checksum_ptr(szone, free_head); - - small_mag_ptr->mag_free_list[slot] = free_ptr; - - // Store msize at the end of the block denoted by "ptr" (i.e. at a negative offset from "follower") - follower = (void *)((uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(msize)); - SMALL_PREVIOUS_MSIZE(follower) = msize; -} - -/* - * Removes the item pointed to by ptr in the proper free list. - * Assumes szone has been locked - */ -static void -small_free_list_remove_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize) -{ - grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; - free_list_t *free_ptr = ptr, *next, *previous; - - next = free_list_unchecksum_ptr(szone, &free_ptr->next); - previous = free_list_unchecksum_ptr(szone, &free_ptr->previous); - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); - } -#endif - - if (!previous) { - // The block to remove is the head of the free list -#if DEBUG_MALLOC - if (small_mag_ptr->mag_free_list[slot] != ptr) { - szone_error(szone, 1, "small_free_list_remove_ptr: Internal invariant broken (small_mag_ptr->mag_free_list[slot])", ptr, - "ptr=%p slot=%d msize=%d small_mag_ptr->mag_free_list[slot]=%p\n", - ptr, slot, msize, (void *)small_mag_ptr->mag_free_list[slot]); - return; - } -#endif - small_mag_ptr->mag_free_list[slot] = next; - if (!next) BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot); - } else { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - previous->next = free_ptr->next; - } - if (next) { - // We know free_ptr is already checksummed, so we don't need to do it - // again. - next->previous = free_ptr->previous; - } -} - -/* - * small_region_for_ptr_no_lock - Returns the small region containing the pointer, - * or NULL if not found. - */ -static INLINE region_t -small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) -{ - rgnhdl_t r = hash_lookup_region_no_lock(szone->small_region_generation->hashed_regions, - szone->small_region_generation->num_regions_allocated, - szone->small_region_generation->num_regions_allocated_shift, - SMALL_REGION_FOR_PTR(ptr)); - return r ? *r : r; -} - -static void -small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr) { - void *last_block, *previous_block; - msize_t last_msize, previous_msize, last_index; - - // It is possible that the block prior to the last block in the region has - // been free'd, but was not coalesced with the free bytes at the end of the - // block, since we treat the bytes at the end of the region as "in use" in - // the meta headers. Attempt to coalesce the last block with the previous - // block, so we don't violate the "no consecutive free blocks" invariant. - // - // FIXME: If we could calculate the previous small free size in the same - // manner as tiny_previous_preceding_free, it would eliminate the - // index & previous msize checks, which are a guard against reading - // bogus data out of in-use or written-on-freed memory. - // - // FIXME: Need to investigate how much work would be required to increase - // 'mag_bytes_free_at_end' when freeing the preceding block, rather - // than performing this workaround. - // - if (small_mag_ptr->mag_bytes_free_at_end) { - last_block = SMALL_REGION_END(small_mag_ptr->mag_last_region) - small_mag_ptr->mag_bytes_free_at_end; - last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end); - - last_index = SMALL_META_INDEX_FOR_PTR(last_block); - previous_msize = SMALL_PREVIOUS_MSIZE(last_block); - - if (last_index && (previous_msize <= last_index)) { - previous_block = (void *)((uintptr_t)last_block - SMALL_BYTES_FOR_MSIZE(previous_msize)); - if (*SMALL_METADATA_FOR_PTR(previous_block) == (previous_msize | SMALL_IS_FREE)) { - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(last_block); - - small_meta_header_set_middle(meta_headers, last_index); - small_free_list_remove_ptr(szone, small_mag_ptr, previous_block, previous_msize); - last_block = (void *)((uintptr_t)last_block - SMALL_BYTES_FOR_MSIZE(previous_msize)); - last_msize += previous_msize; - } - } - - // splice last_block into the free list - small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize); - small_mag_ptr->mag_bytes_free_at_end = 0; - } - -#if ASLR_INTERNAL - if (small_mag_ptr->mag_bytes_free_at_start) { - last_block = SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region); - last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start); - - void *next_block = (void *) ((uintptr_t)last_block + small_mag_ptr->mag_bytes_free_at_start); - if (SMALL_PTR_IS_FREE(next_block)) { - msize_t next_msize = SMALL_PTR_SIZE(next_block); - - small_meta_header_set_middle(SMALL_META_HEADER_FOR_PTR(next_block), SMALL_META_INDEX_FOR_PTR(next_block)); - small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize); - last_msize += next_msize; - } - - // splice last_block into the free list - small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize); - small_mag_ptr->mag_bytes_free_at_start = 0; - } -#endif - - // TODO: Will we ever need to coalesce the blocks at the beginning and end when we finalize? - - small_mag_ptr->mag_last_region = NULL; -} - -static int -small_free_detach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r) { - unsigned char *ptr = SMALL_REGION_ADDRESS(r); - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); - int total_alloc = 0; - - while (current < limit) { - unsigned index = SMALL_META_INDEX_FOR_PTR(current); - msize_t msize_and_free = meta_headers[index]; - boolean_t is_free = msize_and_free & SMALL_IS_FREE; - msize_t msize = msize_and_free & ~ SMALL_IS_FREE; - - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** small_free_detach_region error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - small_free_list_remove_ptr(szone, small_mag_ptr, (void *)current, msize); - } else { - total_alloc++; - } - current += SMALL_BYTES_FOR_MSIZE(msize); - } - return total_alloc; -} - -static size_t -small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r) { - unsigned char *ptr = SMALL_REGION_ADDRESS(r); - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); - size_t total_alloc = 0; - - while (current < limit) { - unsigned index = SMALL_META_INDEX_FOR_PTR(current); - msize_t msize_and_free = meta_headers[index]; - boolean_t is_free = msize_and_free & SMALL_IS_FREE; - msize_t msize = msize_and_free & ~ SMALL_IS_FREE; - - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** small_free_reattach_region error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - small_free_list_add_ptr(szone, small_mag_ptr, (void *)current, msize); - } else { - total_alloc += SMALL_BYTES_FOR_MSIZE(msize); - } - current += SMALL_BYTES_FOR_MSIZE(msize); - } - return total_alloc; -} - -typedef struct { - uint16_t pnum, size; -} small_pg_pair_t; - -static void NOINLINE /* want private stack frame for automatic array */ -small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) { - uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); - uintptr_t current = start; - uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(start); - small_pg_pair_t advisory[((SMALL_REGION_PAYLOAD_BYTES + vm_page_quanta_size - 1) >> vm_page_quanta_shift) >> 1]; // 4096bytes stack allocated - int advisories = 0; - - // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list - // management data. - while (current < limit) { - unsigned index = SMALL_META_INDEX_FOR_PTR(current); - msize_t msize_and_free = meta_headers[index]; - boolean_t is_free = msize_and_free & SMALL_IS_FREE; - msize_t msize = msize_and_free & ~ SMALL_IS_FREE; - - if (is_free && !msize && (current == start)) { -#if DEBUG_MALLOC - // first block is all free - malloc_printf("*** small_free_scan_madvise_free first block is all free! %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - uintptr_t pgLo = round_page_quanta(start + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page_quanta(start + SMALL_REGION_SIZE - sizeof(msize_t)); - - if (pgLo < pgHi) { - advisory[advisories].pnum = (pgLo - start) >> vm_page_quanta_shift; - advisory[advisories].size = (pgHi - pgLo) >> vm_page_quanta_shift; - advisories++; - } - break; - } - if (!msize) { -#if DEBUG_MALLOC - malloc_printf("*** small_free_scan_madvise_free error with %p: msize=%d is_free =%d\n", - (void *)current, msize, is_free); -#endif - break; - } - if (is_free) { - uintptr_t pgLo = round_page_quanta(current + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page_quanta(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); - - if (pgLo < pgHi) { - advisory[advisories].pnum = (pgLo - start) >> vm_page_quanta_shift; - advisory[advisories].size = (pgHi - pgLo) >> vm_page_quanta_shift; - advisories++; + // deallocate the death-row cache outside the zone lock + size_t total = 0; + while (idx != idx_max) { + deallocate_pages(szone, (void *)local_entry_cache[idx].address, local_entry_cache[idx].size, 0); + total += local_entry_cache[idx].size; + if (++idx == LARGE_ENTRY_CACHE_SIZE) { + idx = 0; } } - current += SMALL_BYTES_FOR_MSIZE(msize); - } - - if (advisories > 0) { - int i; - - OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot)); - SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); - for (i = 0; i < advisories; ++i) { - uintptr_t addr = (advisory[i].pnum << vm_page_quanta_shift) + start; - size_t size = advisory[i].size << vm_page_quanta_shift; - - madvise_free_range(szone, r, addr, addr + size, NULL); - } - SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); - OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot)); - } -} - -static region_t -small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node) -{ - if (0 < node->bytes_used || - 0 < node->pinned_to_depot || - depot_ptr->recirculation_entries < (szone->num_small_magazines * 2)) { - return NULL; - } - - // disconnect first node from Depot - recirc_list_extract(szone, depot_ptr, node); - - // Iterate the region pulling its free entries off the (locked) Depot's free list - region_t sparse_region = SMALL_REGION_FOR_PTR(node); - int objects_in_use = small_free_detach_region(szone, depot_ptr, sparse_region); - - if (0 == objects_in_use) { - // Invalidate the hash table entry for this region with HASHRING_REGION_DEALLOCATED. - // Using HASHRING_REGION_DEALLOCATED preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not. - rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->small_region_generation->hashed_regions, - szone->small_region_generation->num_regions_allocated, - szone->small_region_generation->num_regions_allocated_shift, sparse_region); - if (NULL == pSlot) { - szone_error(szone, 1, "small_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region); - return NULL; - } - *pSlot = HASHRING_REGION_DEALLOCATED; - depot_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; - __sync_fetch_and_add( &(szone->num_small_regions_dealloc), 1); // Atomically increment num_small_regions_dealloc - - // Caller will transfer ownership of the region back to the OS with no locks held - MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, SMALL_REGION_SIZE); // DTrace USDT Probe - return sparse_region; - - } else { - szone_error(szone, 1, "small_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use); - return NULL; - } -} - -static boolean_t -small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index) -{ - // The entire magazine crossed the "emptiness threshold". Transfer a region - // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e - // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. - region_trailer_t *node = small_mag_ptr->firstNode; - - while (node && !node->recirc_suitable) { - node = node->next; - } - - if (NULL == node) { -#if DEBUG_MALLOC - malloc_printf("*** small_free_do_recirc_to_depot end of list\n"); -#endif - return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - } - - region_t sparse_region = SMALL_REGION_FOR_PTR(node); - - // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at start - if (sparse_region == small_mag_ptr->mag_last_region && (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start)) { - small_finalize_region(szone, small_mag_ptr); - } - - // disconnect "suitable" node from magazine - recirc_list_extract(szone, small_mag_ptr, node); - - // Iterate the region pulling its free entries off its (locked) magazine's free list - int objects_in_use = small_free_detach_region(szone, small_mag_ptr, sparse_region); - magazine_t *depot_ptr = &(szone->small_magazines[DEPOT_MAGAZINE_INDEX]); - - // hand over the region to the (locked) Depot - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - // this will cause small_free_list_add_ptr called by small_free_reattach_region to use - // the depot as its target magazine, rather than magazine formerly associated with sparse_region - MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX; - node->pinned_to_depot = 0; - - // Iterate the region putting its free entries on Depot's free list - size_t bytes_inplay = small_free_reattach_region(szone, depot_ptr, sparse_region); - - small_mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; - small_mag_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; - small_mag_ptr->mag_num_objects -= objects_in_use; - - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); // Unlock the originating magazine - - depot_ptr->mag_num_bytes_in_objects += bytes_inplay; - depot_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; - depot_ptr->mag_num_objects += objects_in_use; - - // connect to Depot as last node - recirc_list_splice_last(szone, depot_ptr, node); - - MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE, - (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe - - // Mark free'd dirty pages with MADV_FREE to reduce memory pressure - small_free_scan_madvise_free(szone, depot_ptr, sparse_region); - - // If the region is entirely empty vm_deallocate() it outside the depot lock - region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, depot_ptr, node); - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - if (r_dealloc) - deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0); - return FALSE; // Caller need not unlock the originating magazine -} - -static region_t -small_find_msize_region(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - free_list_t *ptr; - grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; - free_list_t **free_list = small_mag_ptr->mag_free_list; - free_list_t **the_slot = free_list + slot; - free_list_t **limit; - unsigned bitmap; - - // Assumes we've locked the magazine - CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); - - // Look for an exact match by checking the freelist for this msize. - ptr = *the_slot; - if (ptr) - return SMALL_REGION_FOR_PTR(ptr); - - // Mask off the bits representing slots holding free blocks smaller than - // the size we need. - if (szone->is_largemem) { - // BITMAPN_CTZ implementation - unsigned idx = slot >> 5; - bitmap = 0; - unsigned mask = ~ ((1 << (slot & 31)) - 1); - for ( ; idx < SMALL_BITMAP_WORDS; ++idx ) { - bitmap = small_mag_ptr->mag_bitmap[idx] & mask; - if (bitmap != 0) - break; - mask = ~0U; - } - // Check for fallthrough: No bits set in bitmap - if ((bitmap == 0) && (idx == SMALL_BITMAP_WORDS)) - return NULL; - - // Start looking at the first set bit, plus 32 bits for every word of - // zeroes or entries that were too small. - slot = BITMAP32_CTZ((&bitmap)) + (idx * 32); - } else { - bitmap = small_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1); - if (!bitmap) - return NULL; - - slot = BITMAP32_CTZ((&bitmap)); - } - limit = free_list + szone->num_small_slots - 1; - free_list += slot; - - if (free_list < limit) { - ptr = *free_list; - if (ptr) - return SMALL_REGION_FOR_PTR(ptr); - else { - /* Shouldn't happen. Fall through to look at last slot. */ -#if DEBUG_MALLOC - malloc_printf("in small_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n",slot); -#endif + if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) { + deallocate_pages(szone, (void *)local_entry_cache[idx].address, local_entry_cache[idx].size, 0); + total += local_entry_cache[idx].size; } } - - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than (num_small_slots - 1) * (small quantum size). - ptr = *limit; - if (ptr) - return SMALL_REGION_FOR_PTR(ptr); - - return NULL; -} - -static boolean_t -small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - magazine_t *depot_ptr = &(szone->small_magazines[DEPOT_MAGAZINE_INDEX]); - - /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ - if (szone->num_small_magazines == 1) // Uniprocessor, single magazine, so no recirculation necessary - return 0; - -#if DEBUG_MALLOC - if (DEPOT_MAGAZINE_INDEX == mag_index) { - szone_error(szone, 1, "small_get_region_from_depot called for magazine index -1", NULL, NULL); - return 0; - } #endif - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - - // Appropriate a Depot'd region that can satisfy requested msize. - region_trailer_t *node; - region_t sparse_region; - - while (1) { - sparse_region = small_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); - if (NULL == sparse_region) { // Depot empty? - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - return 0; - } - - node = REGION_TRAILER_FOR_SMALL_REGION(sparse_region); - if (0 >= node->pinned_to_depot) - break; - - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - yield(); - SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr); - } - - // disconnect node from Depot - recirc_list_extract(szone, depot_ptr, node); - - // Iterate the region pulling its free entries off the (locked) Depot's free list - int objects_in_use = small_free_detach_region(szone, depot_ptr, sparse_region); - - // Transfer ownership of the region - MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = mag_index; - node->pinned_to_depot = 0; - - // Iterate the region putting its free entries on its new (locked) magazine's free list - size_t bytes_inplay = small_free_reattach_region(szone, small_mag_ptr, sparse_region); - - depot_ptr->mag_num_bytes_in_objects -= bytes_inplay; - depot_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; - depot_ptr->mag_num_objects -= objects_in_use; - - small_mag_ptr->mag_num_bytes_in_objects += bytes_inplay; - small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; - small_mag_ptr->mag_num_objects += objects_in_use; - - // connect to magazine as first node - recirc_list_splice_first(szone, small_mag_ptr, node); - - SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr); - - // madvise() outside the Depot lock - (void)madvise_reuse_range(szone, sparse_region, sparse_region, sparse_region+SMALL_REGION_PAYLOAD_BYTES); - - MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE, - (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe - - return 1; -} - -#define K 1.5 // headroom measured in number of 8Mb regions -#define DENSITY_THRESHOLD(a) \ - ((a) - ((a) >> 2)) // "Emptiness" f = 0.25, so "Density" is (1 - f)*a. Generally: ((a) - ((a) >> -log2(f))) - -static INLINE boolean_t -small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize) -{ - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned index = SMALL_META_INDEX_FOR_PTR(ptr); - void *original_ptr = ptr; - size_t original_size = SMALL_BYTES_FOR_MSIZE(msize); - unsigned char *next_block = ((unsigned char *)ptr + original_size); - msize_t next_index = index + msize; - msize_t previous_msize, next_msize; - void *previous; - -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } - if (!msize) { - szone_error(szone, 1, "trying to free small block that is too small", ptr, - "in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); - } -#endif - - // We try to coalesce this block with the preceeding one - if (index && (SMALL_PREVIOUS_MSIZE(ptr) <= index)) { - previous_msize = SMALL_PREVIOUS_MSIZE(ptr); - if (meta_headers[index - previous_msize] == (previous_msize | SMALL_IS_FREE)) { - previous = (void *)((uintptr_t)ptr - SMALL_BYTES_FOR_MSIZE(previous_msize)); - // previous is really to be coalesced -#if DEBUG_MALLOC - if (LOG(szone, ptr) || LOG(szone,previous)) { - malloc_printf("in small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); - } -#endif - small_free_list_remove_ptr(szone, small_mag_ptr, previous, previous_msize); - small_meta_header_set_middle(meta_headers, index); - ptr = previous; - msize += previous_msize; - index -= previous_msize; - } - } - // We try to coalesce with the next block - if ((next_block < SMALL_REGION_END(region)) && (meta_headers[next_index] & SMALL_IS_FREE)) { - // next block is free, we coalesce - next_msize = meta_headers[next_index] & ~ SMALL_IS_FREE; -#if DEBUG_MALLOC - if (LOG(szone,ptr)) - malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n", - ptr, msize, next_block, next_msize); -#endif - small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize); - small_meta_header_set_middle(meta_headers, next_index); - msize += next_msize; - } - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) { - if (!msize) { - szone_error(szone, 1, "incorrect size information - block header was damaged", ptr, NULL); - } else { - memset(ptr, SCRABBLE_BYTE, SMALL_BYTES_FOR_MSIZE(msize)); - } - } - small_free_list_add_ptr(szone, small_mag_ptr, ptr, msize); - small_mag_ptr->mag_num_objects--; - // we use original_size and not msize to avoid double counting the coalesced blocks - small_mag_ptr->mag_num_bytes_in_objects -= original_size; - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(region); - size_t bytes_used = node->bytes_used - original_size; - node->bytes_used = bytes_used; - -#if !TARGET_OS_EMBEDDED // Always madvise for embedded platforms - /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ - if (szone->num_small_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary - /* NOTHING */ - } else if (DEPOT_MAGAZINE_INDEX != mag_index) { - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) { - /* Region has crossed threshold from density to sparsity. Mark it "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = TRUE; - } else { - /* After this free, we've found the region is still dense, so it must have been even more so before - the free. That implies the region is already correctly marked. Do nothing. */ - } - - // Has the entire magazine crossed the "emptiness threshold"? If so, transfer a region - // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e - // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. - - size_t a = small_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine - size_t u = small_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine - - if (a - u > ((3 * SMALL_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) { - return small_free_do_recirc_to_depot(szone, small_mag_ptr, mag_index); - } - - } else { -#endif - // Freed to Depot. N.B. Lock on small_magazines[DEPOT_MAGAZINE_INDEX] is already held - // Calcuate the first page in the coalesced block that would be safe to mark MADV_FREE - size_t free_header_size = sizeof(free_list_t) + sizeof(msize_t); - uintptr_t safe_ptr = (uintptr_t)ptr + free_header_size; - uintptr_t round_safe = round_page_quanta(safe_ptr); - - // Calcuate the last page in the coalesced block that would be safe to mark MADV_FREE - size_t free_tail_size = sizeof(msize_t); - uintptr_t safe_extent = (uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(msize) - free_tail_size; - uintptr_t trunc_extent = trunc_page_quanta(safe_extent); - - // The newly freed block may complete a span of bytes that cover one or more pages. Mark the span with MADV_FREE. - if (round_safe < trunc_extent) { // Coalesced area covers a page (perhaps many) - // Extend the freed block by the free region header and tail sizes to include pages - // we may have coalesced that no longer host free region tails and headers. - // This may extend over in-use ranges, but the MIN/MAX clamping below will fix that up. - uintptr_t lo = trunc_page_quanta((uintptr_t)original_ptr - free_tail_size); - uintptr_t hi = round_page_quanta((uintptr_t)original_ptr + original_size + free_header_size); - - uintptr_t free_lo = MAX(round_safe, lo); - uintptr_t free_hi = MIN(trunc_extent, hi); - - if (free_lo < free_hi) { - small_free_list_remove_ptr(szone, small_mag_ptr, ptr, msize); - small_meta_header_set_in_use(meta_headers, index, msize); - - OSAtomicIncrement32Barrier(&(node->pinned_to_depot)); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - madvise_free_range(szone, region, free_lo, free_hi, &szone->last_small_advise); - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - OSAtomicDecrement32Barrier(&(node->pinned_to_depot)); - - small_meta_header_set_is_free(meta_headers, index, msize); - small_free_list_add_ptr(szone, small_mag_ptr, ptr, msize); - } - } - -#if !TARGET_OS_EMBEDDED - if (0 < bytes_used || 0 < node->pinned_to_depot) { - /* Depot'd region is still live. Leave it in place on the Depot's recirculation list - so as to avoid thrashing between the Depot's free list and a magazines's free list - with detach_region/reattach_region */ - } else { - /* Depot'd region is just now empty. Consider return to OS. */ - region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, small_mag_ptr, node); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - if (r_dealloc) - deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0); - return FALSE; // Caller need not unlock - } - } -#endif - - return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr) -} - -// Allocates from the last region or a freshly allocated region -static void * -small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, - msize_t msize, void *aligned_address) -{ - void *ptr; - - // Before anything we transform the mag_bytes_free_at_end or mag_bytes_free_at_start - if any - to a regular free block - /* FIXME: last_block needs to be coalesced with previous entry if free, */ - if (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start) - small_finalize_region(szone, small_mag_ptr); - - // Here find the only place in smallville that (infrequently) takes the small_regions_lock. - // Only one thread at a time should be permitted to assess the density of the hash - // ring and adjust if needed. - // Only one thread at a time should be permitted to insert its new region on - // the hash ring. - // It is safe for all other threads to read the hash ring (hashed_regions) and - // the associated sizes (num_regions_allocated and num_small_regions). - - _malloc_lock_lock(&szone->small_regions_lock); - // Check to see if the hash ring of small regions needs to grow. Try to - // avoid the hash ring becoming too dense. - if (szone->small_region_generation->num_regions_allocated < (2 * szone->num_small_regions)) { - region_t *new_regions; - size_t new_size; - size_t new_shift = szone->small_region_generation->num_regions_allocated_shift; // In/Out parameter - new_regions = hash_regions_grow_no_lock(szone, szone->small_region_generation->hashed_regions, - szone->small_region_generation->num_regions_allocated, - &new_shift, - &new_size); - // Do not deallocate the current hashed_regions allocation since someone - // may be iterating it. Instead, just leak it. - - // Prepare to advance to the "next generation" of the hash ring. - szone->small_region_generation->nextgen->hashed_regions = new_regions; - szone->small_region_generation->nextgen->num_regions_allocated = new_size; - szone->small_region_generation->nextgen->num_regions_allocated_shift = new_shift; - - // Throw the switch to atomically advance to the next generation. - szone->small_region_generation = szone->small_region_generation->nextgen; - // Ensure everyone sees the advance. - OSMemoryBarrier(); - } - // Tag the region at "aligned_address" as belonging to us, - // and so put it under the protection of the magazine lock we are holding. - // Do this before advertising "aligned_address" on the hash ring(!) - MAGAZINE_INDEX_FOR_SMALL_REGION(aligned_address) = mag_index; - - // Insert the new region into the hash ring, and update malloc statistics - hash_region_insert_no_lock(szone->small_region_generation->hashed_regions, - szone->small_region_generation->num_regions_allocated, - szone->small_region_generation->num_regions_allocated_shift, - aligned_address); - - szone->num_small_regions++; - - _malloc_lock_unlock(&szone->small_regions_lock); - - small_mag_ptr->mag_last_region = aligned_address; - BYTES_USED_FOR_SMALL_REGION(aligned_address) = SMALL_BYTES_FOR_MSIZE(msize); -#if ASLR_INTERNAL - int offset_msize = malloc_entropy[1] & SMALL_ENTROPY_MASK; -#if DEBUG_MALLOC - if (getenv("MallocASLRForce")) offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & SMALL_ENTROPY_MASK; - if (getenv("MallocASLRPrint")) malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize); -#endif -#else - int offset_msize = 0; -#endif - ptr = (void *)((uintptr_t) aligned_address + SMALL_BYTES_FOR_MSIZE(offset_msize)); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize, msize); - small_mag_ptr->mag_num_objects++; - small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(msize); - small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; - - // add a big free block at the end - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize + msize, NUM_SMALL_BLOCKS - msize - offset_msize); - small_mag_ptr->mag_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(NUM_SMALL_BLOCKS - msize - offset_msize); - -#if ASLR_INTERNAL - // add a big free block at the start - small_mag_ptr->mag_bytes_free_at_start = SMALL_BYTES_FOR_MSIZE(offset_msize); - if (offset_msize) { - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, offset_msize); - } -#else - small_mag_ptr->mag_bytes_free_at_start = 0; -#endif - - // connect to magazine as last node - recirc_list_splice_last(szone, small_mag_ptr, REGION_TRAILER_FOR_SMALL_REGION(aligned_address)); - - return ptr; -} - -static INLINE void * -small_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) -{ - msize_t new_msize = SMALL_MSIZE_FOR_BYTES(new_good_size); - msize_t mshrinkage = SMALL_MSIZE_FOR_BYTES(old_size) - new_msize; - - if (mshrinkage) { - void *q = (void *)((uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(new_msize)); - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)), - MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr))); - - // Mark q as block header and in-use, thus creating two blocks. - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), new_msize); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), mshrinkage); - small_mag_ptr->mag_num_objects++; - - SZONE_MAGAZINE_PTR_UNLOCK(szone,small_mag_ptr); - szone_free(szone, q); // avoid inlining free_small(szone, q, ...); - } - - return ptr; -} - -static INLINE boolean_t -small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) -{ - // returns 1 on success - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned index; - msize_t old_msize, new_msize; - unsigned next_index; - void *next_block; - msize_t next_msize_and_free; - boolean_t is_free; - msize_t next_msize, leftover_msize; - void *leftover; - - index = SMALL_META_INDEX_FOR_PTR(ptr); - old_msize = SMALL_MSIZE_FOR_BYTES(old_size); - new_msize = SMALL_MSIZE_FOR_BYTES(new_size + SMALL_QUANTUM - 1); - next_index = index + old_msize; - - if (next_index >= NUM_SMALL_BLOCKS) { - return 0; - } - next_block = (char *)ptr + old_size; - -#if DEBUG_MALLOC - if ((uintptr_t)next_block & (SMALL_QUANTUM - 1)) { - szone_error(szone, 1, "internal invariant broken in realloc(next_block)", next_block, NULL); - } - if (meta_headers[index] != old_msize) - malloc_printf("*** small_try_realloc_in_place incorrect old %d %d\n", - meta_headers[index], old_msize); -#endif - - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)), - MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr))); - - /* - * Look for a free block immediately afterwards. If it's large enough, we can consume (part of) - * it. - */ - next_msize_and_free = meta_headers[next_index]; - is_free = next_msize_and_free & SMALL_IS_FREE; - if (!is_free) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; // next_block is in use; - } - next_msize = next_msize_and_free & ~ SMALL_IS_FREE; - if (old_msize + next_msize < new_msize) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; // even with next block, not enough - } - /* - * The following block is big enough; pull it from its freelist and chop off enough to satisfy - * our needs. - */ - small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize); - small_meta_header_set_middle(meta_headers, next_index); - leftover_msize = old_msize + next_msize - new_msize; - if (leftover_msize) { - /* there's some left, so put the remainder back */ - leftover = (unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(new_msize); - - small_free_list_add_ptr(szone, small_mag_ptr, leftover, leftover_msize); - } -#if DEBUG_MALLOC - if (SMALL_BYTES_FOR_MSIZE(new_msize) > szone->large_threshold) { - malloc_printf("*** realloc in place for %p exceeded msize=%d\n", new_msize); - } -#endif - small_meta_header_set_in_use(meta_headers, index, new_msize); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_try_realloc_in_place(), ptr=%p, msize=%d\n", ptr, *SMALL_METADATA_FOR_PTR(ptr)); - } -#endif - small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(new_msize - old_msize); - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - size_t bytes_used = node->bytes_used + SMALL_BYTES_FOR_MSIZE(new_msize - old_msize); - node->bytes_used = bytes_used; - - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) { - /* After this reallocation the region is still sparse, so it must have been even more so before - the reallocation. That implies the region is already correctly marked. Do nothing. */ - } else { - /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = FALSE; - } - - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return 1; -} - -static boolean_t -small_check_region(szone_t *szone, region_t region) -{ - unsigned char *ptr = SMALL_REGION_ADDRESS(region); - msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); - unsigned char *region_end = SMALL_REGION_END(region); - msize_t prev_free = 0; - unsigned index; - msize_t msize_and_free; - msize_t msize; - free_list_t *free_head; - void *previous, *next; - msize_t *follower; - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - // Assumes locked - CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); - - if (region == small_mag_ptr->mag_last_region) { - ptr += small_mag_ptr->mag_bytes_free_at_start; - region_end -= small_mag_ptr->mag_bytes_free_at_end; - } - - while (ptr < region_end) { - index = SMALL_META_INDEX_FOR_PTR(ptr); - msize_and_free = meta_headers[index]; - if (!(msize_and_free & SMALL_IS_FREE)) { - // block is in use - msize = msize_and_free; - if (!msize) { - malloc_printf("*** invariant broken: null msize ptr=%p num_small_regions=%d end=%p\n", - ptr, szone->num_small_regions, region_end); - return 0; - } -#if !RELAXED_INVARIANT_CHECKS - if (SMALL_BYTES_FOR_MSIZE(msize) > szone->large_threshold) { - malloc_printf("*** invariant broken for %p this small msize=%d - size is too large\n", - ptr, msize_and_free); - return 0; - } -#endif // RELAXED_INVARIANT_CHECKS - ptr += SMALL_BYTES_FOR_MSIZE(msize); - prev_free = 0; - } else { - // free pointer - msize = msize_and_free & ~ SMALL_IS_FREE; - free_head = (free_list_t *)ptr; - follower = (msize_t *)FOLLOWING_SMALL_PTR(ptr, msize); - if (!msize) { - malloc_printf("*** invariant broken for free block %p this msize=%d\n", ptr, msize); - return 0; - } -#if !RELAXED_INVARIANT_CHECKS - if (prev_free) { - malloc_printf("*** invariant broken for %p (2 free in a row)\n", ptr); - return 0; - } -#endif - previous = free_list_unchecksum_ptr(szone, &free_head->previous); - next = free_list_unchecksum_ptr(szone, &free_head->next); - if (previous && !SMALL_PTR_IS_FREE(previous)) { - malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", - ptr, free_head->previous); - return 0; - } - if (next && !SMALL_PTR_IS_FREE(next)) { - malloc_printf("*** invariant broken for %p (next is not a free pointer)\n", ptr); - return 0; - } - if (SMALL_PREVIOUS_MSIZE(follower) != msize) { - malloc_printf("*** invariant broken for small free %p followed by %p in region [%p-%p] " - "(end marker incorrect) should be %d; in fact %d\n", - ptr, follower, SMALL_REGION_ADDRESS(region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower)); - return 0; - } - ptr = (unsigned char *)follower; - prev_free = SMALL_IS_FREE; - } - } - return 1; -} - -static kern_return_t -small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, - memory_reader_t reader, vm_range_recorder_t recorder) -{ - size_t num_regions; - size_t index; - region_t *regions; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - kern_return_t err; - region_t region; - vm_range_t range; - vm_range_t admin_range; - vm_range_t ptr_range; - unsigned char *mapped_region; - msize_t *block_header; - unsigned block_index; - unsigned block_limit; - msize_t msize_and_free; - msize_t msize; - magazine_t *small_mag_base = NULL; - - region_hash_generation_t *srg_ptr; - err = reader(task, (vm_address_t)szone->small_region_generation, sizeof(region_hash_generation_t), (void **)&srg_ptr); - if (err) return err; - - num_regions = srg_ptr->num_regions_allocated; - err = reader(task, (vm_address_t)srg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions); - if (err) return err; - - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - // Map in all active magazines. Do this outside the iteration over regions. - err = reader(task, (vm_address_t)(szone->small_magazines), - szone->num_small_magazines*sizeof(magazine_t),(void **)&small_mag_base); - if (err) return err; - } - - for (index = 0; index < num_regions; ++index) { - region = regions[index]; - if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { - range.address = (vm_address_t)SMALL_REGION_ADDRESS(region); - range.size = SMALL_REGION_SIZE; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - admin_range.address = range.address + SMALL_METADATA_START; - admin_range.size = SMALL_METADATA_SIZE; - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); - } - if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { - ptr_range.address = range.address; - ptr_range.size = NUM_SMALL_BLOCKS * SMALL_QUANTUM; - recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); - } - if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { - void *mag_last_free; - vm_address_t mag_last_free_ptr = 0; - msize_t mag_last_free_msize = 0; - - err = reader(task, range.address, range.size, (void **)&mapped_region); - if (err) - return err; - - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(mapped_region); - magazine_t *small_mag_ptr = small_mag_base + mag_index; - - if (DEPOT_MAGAZINE_INDEX != mag_index) { - mag_last_free = small_mag_ptr->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(SMALL_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (SMALL_QUANTUM - 1); - } - } else { - for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { - if ((void *)range.address == (small_mag_base + mag_index)->mag_last_free_rgn) { - mag_last_free = (small_mag_base + mag_index)->mag_last_free; - if (mag_last_free) { - mag_last_free_ptr = (uintptr_t) mag_last_free & ~(SMALL_QUANTUM - 1); - mag_last_free_msize = (uintptr_t) mag_last_free & (SMALL_QUANTUM - 1); - } - } - } - } - - block_header = (msize_t *)(mapped_region + SMALL_METADATA_START + sizeof(region_trailer_t)); - block_index = 0; - block_limit = NUM_SMALL_BLOCKS; - if (region == small_mag_ptr->mag_last_region) { - block_index += SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start); - block_limit -= SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end); - } - while (block_index < block_limit) { - msize_and_free = block_header[block_index]; - msize = msize_and_free & ~ SMALL_IS_FREE; - if (! (msize_and_free & SMALL_IS_FREE) && - range.address + SMALL_BYTES_FOR_MSIZE(block_index) != mag_last_free_ptr) { - // Block in use - buffer[count].address = range.address + SMALL_BYTES_FOR_MSIZE(block_index); - buffer[count].size = SMALL_BYTES_FOR_MSIZE(msize); - count++; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } - - if (!msize) - return KERN_FAILURE; // Somethings amiss. Avoid looping at this block_index. - - block_index += msize; - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); - count = 0; - } - } - } - } - return 0; -} - -static void * -small_malloc_from_free_list(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) -{ - free_list_t *ptr; - msize_t this_msize; - grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; - free_list_t **free_list = small_mag_ptr->mag_free_list; - free_list_t **the_slot = free_list + slot; - free_list_t *next; - free_list_t **limit; - unsigned bitmap; - msize_t leftover_msize; - free_list_t *leftover_ptr; - - // Assumes we've locked the region - CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); - - // Look for an exact match by checking the freelist for this msize. - // - ptr = *the_slot; - if (ptr) { - next = free_list_unchecksum_ptr(szone, &ptr->next); - if (next) { - next->previous = ptr->previous; - } else { - BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot); - } - *the_slot = next; - this_msize = msize; - goto return_small_alloc; - } - - // Mask off the bits representing slots holding free blocks smaller than - // the size we need. If there are no larger free blocks, try allocating - // from the free space at the end of the small region. - if (szone->is_largemem) { - // BITMAPN_CTZ implementation - unsigned idx = slot >> 5; - bitmap = 0; - unsigned mask = ~ ((1 << (slot & 31)) - 1); - for ( ; idx < SMALL_BITMAP_WORDS; ++idx ) { - bitmap = small_mag_ptr->mag_bitmap[idx] & mask; - if (bitmap != 0) - break; - mask = ~0U; - } - // Check for fallthrough: No bits set in bitmap - if ((bitmap == 0) && (idx == SMALL_BITMAP_WORDS)) - goto try_small_from_end; - - // Start looking at the first set bit, plus 32 bits for every word of - // zeroes or entries that were too small. - slot = BITMAP32_CTZ((&bitmap)) + (idx * 32); - } else { - bitmap = small_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1); - if (!bitmap) - goto try_small_from_end; - - slot = BITMAP32_CTZ((&bitmap)); - } - // FIXME: Explain use of - 1 here, last slot has special meaning - limit = free_list + szone->num_small_slots - 1; - free_list += slot; - - if (free_list < limit) { - ptr = *free_list; - if (ptr) { - - next = free_list_unchecksum_ptr(szone, &ptr->next); - *free_list = next; - if (next) { - next->previous = ptr->previous; - } else { - BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot); - } - this_msize = SMALL_PTR_SIZE(ptr); - goto add_leftover_and_proceed; - } -#if DEBUG_MALLOC - malloc_printf("in small_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n",slot); -#endif - } - - // We are now looking at the last slot, which contains blocks equal to, or - // due to coalescing of free blocks, larger than (num_small_slots - 1) * (small quantum size). - // If the last freelist is not empty, and the head contains a block that is - // larger than our request, then the remainder is put back on the free list. - // - ptr = *limit; - if (ptr) { - this_msize = SMALL_PTR_SIZE(ptr); - next = free_list_unchecksum_ptr(szone, &ptr->next); - if (this_msize - msize >= szone->num_small_slots) { - // the leftover will go back to the free list, so we optimize by - // modifying the free list rather than a pop and push of the head - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)); - *limit = leftover_ptr; - if (next) { - next->previous.u = free_list_checksum_ptr(szone, leftover_ptr); - } - leftover_ptr->previous = ptr->previous; - leftover_ptr->next = ptr->next; - small_meta_header_set_is_free(SMALL_META_HEADER_FOR_PTR(leftover_ptr), - SMALL_META_INDEX_FOR_PTR(leftover_ptr), leftover_msize); - // Store msize at the end of the block denoted by "leftover_ptr" (i.e. at a negative offset from follower) - SMALL_PREVIOUS_MSIZE(FOLLOWING_SMALL_PTR(leftover_ptr, leftover_msize)) = leftover_msize; // Access is safe -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize); - } -#endif - this_msize = msize; - goto return_small_alloc; - } - if (next) { - next->previous = ptr->previous; - } - *limit = next; - goto add_leftover_and_proceed; - } - -try_small_from_end: - // Let's see if we can use small_mag_ptr->mag_bytes_free_at_end - if (small_mag_ptr->mag_bytes_free_at_end >= SMALL_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)(SMALL_REGION_END(small_mag_ptr->mag_last_region) - - small_mag_ptr->mag_bytes_free_at_end); - small_mag_ptr->mag_bytes_free_at_end -= SMALL_BYTES_FOR_MSIZE(msize); - if (small_mag_ptr->mag_bytes_free_at_end) { - // let's mark this block as in use to serve as boundary - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), - SMALL_META_INDEX_FOR_PTR((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)), - SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end)); - } - this_msize = msize; - goto return_small_alloc; - } -#if ASLR_INTERNAL - // Try from start if nothing left at end - if (small_mag_ptr->mag_bytes_free_at_start >= SMALL_BYTES_FOR_MSIZE(msize)) { - ptr = (free_list_t *)(SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region) + - small_mag_ptr->mag_bytes_free_at_start - SMALL_BYTES_FOR_MSIZE(msize)); - small_mag_ptr->mag_bytes_free_at_start -= SMALL_BYTES_FOR_MSIZE(msize); - if (small_mag_ptr->mag_bytes_free_at_start) { - // let's mark this block as in use to serve as boundary - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start)); - } - this_msize = msize; - goto return_small_alloc; - } -#endif - return NULL; - -add_leftover_and_proceed: - if (this_msize > msize) { - leftover_msize = this_msize - msize; - leftover_ptr = (free_list_t *)((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)); -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); - } -#endif - small_free_list_add_ptr(szone, small_mag_ptr, leftover_ptr, leftover_msize); - this_msize = msize; - } - -return_small_alloc: - small_mag_ptr->mag_num_objects++; - small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(this_msize); - - // Update this region's bytes in use count - region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - size_t bytes_used = node->bytes_used + SMALL_BYTES_FOR_MSIZE(this_msize); - node->bytes_used = bytes_used; - - // Emptiness discriminant - if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) { - /* After this allocation the region is still sparse, so it must have been even more so before - the allocation. That implies the region is already correctly marked. Do nothing. */ - } else { - /* Region has crossed threshold from sparsity to density. Mark in not "suitable" on the - recirculation candidates list. */ - node->recirc_suitable = FALSE; - } -#if DEBUG_MALLOC - if (LOG(szone,ptr)) { - malloc_printf("in small_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); - } -#endif - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), this_msize); - return ptr; -} -#undef DENSITY_THRESHOLD -#undef K - -static INLINE void * -small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) -{ - void *ptr; - mag_index_t mag_index = mag_get_thread_index(szone); - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - -#if SMALL_CACHE - ptr = (void *)small_mag_ptr->mag_last_free; - - if ((((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) == msize) { - // we have a winner - small_mag_ptr->mag_last_free = NULL; - small_mag_ptr->mag_last_free_rgn = NULL; - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - ptr = (void *)((uintptr_t)ptr & ~ (SMALL_QUANTUM - 1)); - if (cleared_requested) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } -#endif /* SMALL_CACHE */ - - while(1) { - ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - - if (small_get_region_from_depot(szone, small_mag_ptr, mag_index, msize)) { - ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize); - if (ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - if (cleared_requested) { - memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); - } - return ptr; - } - } - - // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc(). - // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first - // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section. - // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the - // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation, - // and retry-ing threads succeed in the code just above. - if (!small_mag_ptr->alloc_underway) { - void *fresh_region; - - // time to create a new region (do this outside the magazine lock) - small_mag_ptr->alloc_underway = TRUE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - fresh_region = allocate_pages_securely(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, VM_MEMORY_MALLOC_SMALL); - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - - MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, SMALL_REGION_SIZE); // DTrace USDT Probe - - if (!fresh_region) { // out of memory! - small_mag_ptr->alloc_underway = FALSE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return NULL; - } - - ptr = small_malloc_from_region_no_lock(szone, small_mag_ptr, mag_index, msize, fresh_region); - - // we don't clear because this freshly allocated space is pristine - small_mag_ptr->alloc_underway = FALSE; - OSMemoryBarrier(); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return ptr; - } else { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - yield(); - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - } - } - /* NOTREACHED */ -} - -static NOINLINE void -free_small_botch(szone_t *szone, free_list_t *ptr) -{ - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - szone_error(szone, 1, "double free", ptr, NULL); -} - -static INLINE void -free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size) -{ - msize_t msize; - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - // ptr is known to be in small_region - if (known_size) { - msize = SMALL_MSIZE_FOR_BYTES(known_size + SMALL_QUANTUM - 1); - } else { - msize = SMALL_PTR_SIZE(ptr); - if (SMALL_PTR_IS_FREE(ptr)) { - free_small_botch(szone, ptr); - return; - } - } - - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - -#if SMALL_CACHE - // Depot does not participate in SMALL_CACHE since it can't be directly malloc()'d - if (DEPOT_MAGAZINE_INDEX != mag_index) { - - void *ptr2 = small_mag_ptr->mag_last_free; // Might be NULL - region_t rgn2 = small_mag_ptr->mag_last_free_rgn; - - /* check that we don't already have this pointer in the cache */ - if (ptr == (void *)((uintptr_t)ptr2 & ~ (SMALL_QUANTUM - 1))) { - free_small_botch(szone, ptr); - return; - } - - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) - memset(ptr, SCRABBLE_BYTE, SMALL_BYTES_FOR_MSIZE(msize)); - - small_mag_ptr->mag_last_free = (void *)(((uintptr_t)ptr) | msize); - small_mag_ptr->mag_last_free_rgn = small_region; - - if (!ptr2) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - CHECK(szone, __PRETTY_FUNCTION__); - return; - } - - msize = (uintptr_t)ptr2 & (SMALL_QUANTUM - 1); - ptr = (void *)(((uintptr_t)ptr2) & ~(SMALL_QUANTUM - 1)); - small_region = rgn2; - } -#endif /* SMALL_CACHE */ - - // Now in the time it took to acquire the lock, the region may have migrated - // from one magazine to another. I.e. trailer->mag_index is volatile. - // In which case the magazine lock we obtained (namely magazines[mag_index].mag_lock) - // is stale. If so, keep on tryin' ... - region_trailer_t *trailer = REGION_TRAILER_FOR_SMALL_REGION(small_region); - mag_index_t refreshed_index; - - while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment - - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - - mag_index = refreshed_index; - small_mag_ptr = &(szone->small_magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - } - - if (small_free_no_lock(szone, small_mag_ptr, mag_index, small_region, ptr, msize)) - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - - CHECK(szone, __PRETTY_FUNCTION__); -} - -static void -print_small_free_list(szone_t *szone) -{ - free_list_t *ptr; - _SIMPLE_STRING b = _simple_salloc(); - mag_index_t mag_index; - - if (b) { - _simple_sappend(b, "small free sizes:\n"); - for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - grain_t slot = 0; - _simple_sprintf(b,"\tMagazine %d: ", mag_index); - while (slot < szone->num_small_slots) { - ptr = szone->small_magazines[mag_index].mag_free_list[slot]; - if (ptr) { - _simple_sprintf(b, "%s%y[%d]; ", (slot == szone->num_small_slots-1) ? ">=" : "", - (slot + 1) * SMALL_QUANTUM, free_list_count(szone, ptr)); - } - slot++; - } - _simple_sappend(b,"\n"); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static void -print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end) -{ - unsigned counts[1024]; - unsigned in_use = 0; - uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(region); - uintptr_t current = start + bytes_at_start; - uintptr_t limit = (uintptr_t)SMALL_REGION_END(region) - bytes_at_end; - msize_t msize_and_free; - msize_t msize; - unsigned ci; - _SIMPLE_STRING b; - uintptr_t pgTot = 0; - - if (region == HASHRING_REGION_DEALLOCATED) { - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Small region [unknown address] was returned to the OS\n"); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } - return; - } - - memset(counts, 0, sizeof(counts)); - while (current < limit) { - msize_and_free = *SMALL_METADATA_FOR_PTR(current); - msize = msize_and_free & ~ SMALL_IS_FREE; - if (!msize) { - malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize); - break; - } - if (!(msize_and_free & SMALL_IS_FREE)) { - // block in use - if (msize < 1024) - counts[msize]++; - in_use++; - } else { - uintptr_t pgLo = round_page_quanta(current + sizeof(free_list_t) + sizeof(msize_t)); - uintptr_t pgHi = trunc_page_quanta(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); - - if (pgLo < pgHi) { - pgTot += (pgHi - pgLo); - } - } - current += SMALL_BYTES_FOR_MSIZE(msize); - } - if ((b = _simple_salloc()) != NULL) { - _simple_sprintf(b, "Small region [%p-%p, %y] \t", (void *)start, SMALL_REGION_END(region), (int)SMALL_REGION_SIZE); - _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_SMALL_REGION(region)); - _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_SMALL_REGION(region)); - if (bytes_at_end || bytes_at_start) - _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start); - if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_SMALL_REGION(region)) { - _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot); - } else { - _simple_sprintf(b, "Fragments subject to reclamation=%ly", pgTot); - } - if (verbose && in_use) { - _simple_sappend(b, "\n\tSizes in use: "); - for (ci = 0; ci < 1024; ci++) - if (counts[ci]) - _simple_sprintf(b, "%d[%d] ", SMALL_BYTES_FOR_MSIZE(ci), counts[ci]); - } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} - -static boolean_t -small_free_list_check(szone_t *szone, grain_t slot) -{ - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); - - unsigned count = 0; - free_list_t *ptr = szone->small_magazines[mag_index].mag_free_list[slot]; - msize_t msize_and_free; - free_list_t *previous = NULL; - - while (ptr) { - msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); - if (!(msize_and_free & SMALL_IS_FREE)) { - malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; - } - if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { - malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; - } - if (!small_region_for_ptr_no_lock(szone, ptr)) { - malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; - } - if (free_list_unchecksum_ptr(szone, &ptr->previous) != previous) { - malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr); - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - return 0; - } - previous = ptr; - ptr = free_list_unchecksum_ptr(szone, &ptr->next); - count++; - } - - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - } - return 1; -} - -/******************************************************************************* - * Large allocator implementation - ******************************************************************************/ -#pragma mark large allocator - -#if DEBUG_MALLOC - -static void -large_debug_print(szone_t *szone) -{ - unsigned index; - large_entry_t *range; - _SIMPLE_STRING b = _simple_salloc(); - - if (b) { - for (index = 0, range = szone->large_entries; index < szone->num_large_entries; index++, range++) - if (range->address) - _simple_sprintf(b, "%d: %p(%y); ", index, range->address, range->size); - - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); - _simple_sfree(b); - } -} -#endif - -/* - * Scan the hash ring looking for an entry for the given pointer. - */ -static large_entry_t * -large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr) -{ - // result only valid with lock held - unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index; - unsigned index; - large_entry_t *range; - - if (!num_large_entries) - return NULL; - - hash_index = ((uintptr_t)ptr >> vm_page_quanta_shift) % num_large_entries; - index = hash_index; - - do { - range = szone->large_entries + index; - if (range->address == (vm_address_t)ptr) - return range; - if (0 == range->address) - return NULL; // end of chain - index++; - if (index == num_large_entries) - index = 0; - } while (index != hash_index); - - return NULL; -} - -static void -large_entry_insert_no_lock(szone_t *szone, large_entry_t range) -{ - unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index = (((uintptr_t)(range.address)) >> vm_page_quanta_shift) % num_large_entries; - unsigned index = hash_index; - large_entry_t *entry; - - // assert(szone->num_large_objects_in_use < szone->num_large_entries); /* must be called with room to spare */ - - do { - entry = szone->large_entries + index; - if (0 == entry->address) { - *entry = range; - return; // end of chain - } - index++; - if (index == num_large_entries) - index = 0; - } while (index != hash_index); - - // assert(0); /* must not fallthrough! */ -} - -// FIXME: can't we simply swap the (now empty) entry with the last entry on the collision chain for this hash slot? -static INLINE void -large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) -{ - unsigned num_large_entries = szone->num_large_entries; - unsigned hash_index = entry - szone->large_entries; - unsigned index = hash_index; - large_entry_t range; - - // assert(entry->address == 0) /* caller must have cleared *entry */ - - do { - index++; - if (index == num_large_entries) - index = 0; - range = szone->large_entries[index]; - if (0 == range.address) - return; - szone->large_entries[index].address = (vm_address_t)0; - szone->large_entries[index].size = 0; - szone->large_entries[index].did_madvise_reusable = FALSE; - large_entry_insert_no_lock(szone, range); // this will reinsert in the - // proper place - } while (index != hash_index); - - // assert(0); /* since entry->address == 0, must not fallthrough! */ -} - -// FIXME: num should probably be a size_t, since you can theoretically allocate -// more than 2^32-1 large_threshold objects in 64 bit. -static INLINE large_entry_t * -large_entries_alloc_no_lock(szone_t *szone, unsigned num) -{ - size_t size = num * sizeof(large_entry_t); - - // Note that we allocate memory (via a system call) under a spin lock - // That is certainly evil, however it's very rare in the lifetime of a process - // The alternative would slow down the normal case - return allocate_pages(szone, round_page_quanta(size), 0, 0, VM_MEMORY_MALLOC_LARGE); -} - -static void -large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate) -{ - size_t size = num * sizeof(large_entry_t); - - range_to_deallocate->address = (vm_address_t)entries; - range_to_deallocate->size = round_page_quanta(size); -} - -static large_entry_t * -large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) -{ - // sets range_to_deallocate - unsigned old_num_entries = szone->num_large_entries; - large_entry_t *old_entries = szone->large_entries; - // always an odd number for good hashing - unsigned new_num_entries = (old_num_entries) ? old_num_entries * 2 + 1 : - ((vm_page_quanta_size / sizeof(large_entry_t)) - 1); - large_entry_t *new_entries = large_entries_alloc_no_lock(szone, new_num_entries); - unsigned index = old_num_entries; - large_entry_t oldRange; - - // if the allocation of new entries failed, bail - if (new_entries == NULL) - return NULL; - - szone->num_large_entries = new_num_entries; - szone->large_entries = new_entries; - - /* rehash entries into the new list */ - while (index--) { - oldRange = old_entries[index]; - if (oldRange.address) { - large_entry_insert_no_lock(szone, oldRange); - } - } - - if (old_entries) { - large_entries_free_no_lock(szone, old_entries, old_num_entries, range_to_deallocate); - } else { - range_to_deallocate->address = (vm_address_t)0; - range_to_deallocate->size = 0; - } - - return new_entries; -} - -// frees the specific entry in the size table -// returns a range to truly deallocate -static vm_range_t -large_entry_free_no_lock(szone_t *szone, large_entry_t *entry) -{ - vm_range_t range; - - range.address = entry->address; - range.size = entry->size; - - if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) { - protect((void *)range.address, range.size, PROT_READ | PROT_WRITE, szone->debug_flags); - range.address -= vm_page_quanta_size; - range.size += 2 * vm_page_quanta_size; - } - - entry->address = 0; - entry->size = 0; - entry->did_madvise_reusable = FALSE; - large_entries_rehash_after_entry_no_lock(szone, entry); - -#if DEBUG_MALLOC - if (large_entry_for_pointer_no_lock(szone, (void *)range.address)) { - malloc_printf("*** freed entry %p still in use; num_large_entries=%d\n", - range.address, szone->num_large_entries); - large_debug_print(szone); - szone_sleep(); - } -#endif - return range; -} - -static NOINLINE kern_return_t -large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, - unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder) -{ - unsigned index = 0; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - unsigned count = 0; - large_entry_t *entries; - kern_return_t err; - vm_range_t range; - large_entry_t entry; - - err = reader(task, large_entries_address, sizeof(large_entry_t) * num_entries, (void **)&entries); - if (err) - return err; - - index = num_entries; - if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { - range.address = large_entries_address; - range.size = round_page_quanta(num_entries * sizeof(large_entry_t)); - recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &range, 1); - } - if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE)) { - while (index--) { - entry = entries[index]; - if (entry.address) { - range.address = entry.address; - range.size = entry.size; - buffer[count++] = range; - if (count >= MAX_RECORDER_BUFFER) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, - buffer, count); - count = 0; - } - } - } - } - if (count) { - recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, - buffer, count); - } - return 0; -} - -static void * -large_malloc(szone_t *szone, size_t num_kernel_pages, unsigned char alignment, - boolean_t cleared_requested) -{ - void *addr; - vm_range_t range_to_deallocate; - size_t size; - large_entry_t large_entry; - - if (!num_kernel_pages) - num_kernel_pages = 1; // minimal allocation size for this szone - size = (size_t)num_kernel_pages << vm_page_quanta_shift; - range_to_deallocate.size = 0; - range_to_deallocate.address = 0; - -#if LARGE_CACHE - if (size < LARGE_CACHE_SIZE_ENTRY_LIMIT) { // Look for a large_entry_t on the death-row cache? - SZONE_LOCK(szone); - - int i, best = -1, idx = szone->large_entry_cache_newest, stop_idx = szone->large_entry_cache_oldest; - size_t best_size = SIZE_T_MAX; - - while (1) { // Scan large_entry_cache for best fit, starting with most recent entry - size_t this_size = szone->large_entry_cache[idx].size; - addr = (void *)szone->large_entry_cache[idx].address; - - if (0 == alignment || 0 == (((uintptr_t) addr) & (((uintptr_t) 1 << alignment) - 1))) { - if (size == this_size) { // size match! - best = idx; - best_size = this_size; - break; - } - - if (size <= this_size && this_size < best_size) { // improved fit? - best = idx; - best_size = this_size; - } - } - - if (idx == stop_idx) // exhausted live ring? - break; - - if (idx) - idx--; // bump idx down - else - idx = LARGE_ENTRY_CACHE_SIZE - 1; // wrap idx - } - - if (best > -1 && (best_size - size) < size) { //limit fragmentation to 50% - addr = (void *)szone->large_entry_cache[best].address; - boolean_t was_madvised_reusable = szone->large_entry_cache[best].did_madvise_reusable; - - // Compact live ring to fill entry now vacated at large_entry_cache[best] - // while preserving time-order - if (szone->large_entry_cache_oldest < szone->large_entry_cache_newest) { - - // Ring hasn't wrapped. Fill in from right. - for (i = best; i < szone->large_entry_cache_newest; ++i) - szone->large_entry_cache[i] = szone->large_entry_cache[i + 1]; - - szone->large_entry_cache_newest--; // Pull in right endpoint. - - } else if (szone->large_entry_cache_newest < szone->large_entry_cache_oldest) { - - // Ring has wrapped. Arrange to fill in from the contiguous side. - if (best <= szone->large_entry_cache_newest) { - // Fill from right. - for (i = best; i < szone->large_entry_cache_newest; ++i) - szone->large_entry_cache[i] = szone->large_entry_cache[i + 1]; - - if (0 < szone->large_entry_cache_newest) - szone->large_entry_cache_newest--; - else - szone->large_entry_cache_newest = LARGE_ENTRY_CACHE_SIZE - 1; - } else { - // Fill from left. - for ( i = best; i > szone->large_entry_cache_oldest; --i) - szone->large_entry_cache[i] = szone->large_entry_cache[i - 1]; - - if (szone->large_entry_cache_oldest < LARGE_ENTRY_CACHE_SIZE - 1) - szone->large_entry_cache_oldest++; - else - szone->large_entry_cache_oldest = 0; - } - - } else { - // By trichotomy, large_entry_cache_newest == large_entry_cache_oldest. - // That implies best == large_entry_cache_newest == large_entry_cache_oldest - // and the ring is now empty. - szone->large_entry_cache[best].address = 0; - szone->large_entry_cache[best].size = 0; - szone->large_entry_cache[best].did_madvise_reusable = FALSE; - } - - if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) { - // density of hash table too high; grow table - // we do that under lock to avoid a race - large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate); - if (entries == NULL) { - SZONE_UNLOCK(szone); - return NULL; - } - } - - large_entry.address = (vm_address_t)addr; - large_entry.size = best_size; - large_entry.did_madvise_reusable = FALSE; - large_entry_insert_no_lock(szone, large_entry); - - szone->num_large_objects_in_use ++; - szone->num_bytes_in_large_objects += best_size; - if (!was_madvised_reusable) - szone->large_entry_cache_reserve_bytes -= best_size; - - szone->large_entry_cache_bytes -= best_size; - - if (szone->flotsam_enabled && szone->large_entry_cache_bytes < SZONE_FLOTSAM_THRESHOLD_LOW) { - szone->flotsam_enabled = FALSE; - } - - SZONE_UNLOCK(szone); - - if (range_to_deallocate.size) { - // we deallocate outside the lock - deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); - } - - // Perform the madvise() outside the lock. - // Typically the madvise() is successful and we'll quickly return from this routine. - // In the unusual case of failure, reacquire the lock to unwind. -#if TARGET_OS_EMBEDDED - // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large - // cache block twice without MADV_FREE_REUSE in between. -#endif - if (was_madvised_reusable && -1 == madvise(addr, size, MADV_FREE_REUSE)) { - /* -1 return: VM map entry change makes this unfit for reuse. */ -#if DEBUG_MADVISE - szone_error(szone, 0, "large_malloc madvise(..., MADV_FREE_REUSE) failed", - addr, "length=%d\n", size); -#endif - - SZONE_LOCK(szone); - szone->num_large_objects_in_use--; - szone->num_bytes_in_large_objects -= large_entry.size; - - // Re-acquire "entry" after interval just above where we let go the lock. - large_entry_t *entry = large_entry_for_pointer_no_lock(szone, addr); - if (NULL == entry) { - szone_error(szone, 1, "entry for pointer being discarded from death-row vanished", addr, NULL); - SZONE_UNLOCK(szone); - } else { - - range_to_deallocate = large_entry_free_no_lock(szone, entry); - SZONE_UNLOCK(szone); - - if (range_to_deallocate.size) { - // we deallocate outside the lock - deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); - } - } - /* Fall through to allocate_pages() afresh. */ - } else { - if (cleared_requested) { - memset(addr, 0, size); - } - - return addr; - } - } else { - SZONE_UNLOCK(szone); - } - } - - range_to_deallocate.size = 0; - range_to_deallocate.address = 0; -#endif /* LARGE_CACHE */ - - addr = allocate_pages(szone, size, alignment, szone->debug_flags, VM_MEMORY_MALLOC_LARGE); - if (addr == NULL) { - return NULL; - } - - SZONE_LOCK(szone); - if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) { - // density of hash table too high; grow table - // we do that under lock to avoid a race - large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate); - if (entries == NULL) { - SZONE_UNLOCK(szone); - return NULL; - } - } - - large_entry.address = (vm_address_t)addr; - large_entry.size = size; - large_entry.did_madvise_reusable = FALSE; - large_entry_insert_no_lock(szone, large_entry); - - szone->num_large_objects_in_use ++; - szone->num_bytes_in_large_objects += size; - SZONE_UNLOCK(szone); - - if (range_to_deallocate.size) { - // we deallocate outside the lock - deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); - } - return addr; -} - -static NOINLINE void -free_large(szone_t *szone, void *ptr) -{ - // We have established ptr is page-aligned and neither tiny nor small - large_entry_t *entry; - vm_range_t vm_range_to_deallocate; - - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (entry) { -#if LARGE_CACHE - if (entry->size < LARGE_CACHE_SIZE_ENTRY_LIMIT && - -1 != madvise((void *)(entry->address), entry->size, MADV_CAN_REUSE)) { // Put the large_entry_t on the death-row cache? - int idx = szone->large_entry_cache_newest, stop_idx = szone->large_entry_cache_oldest; - large_entry_t this_entry = *entry; // Make a local copy, "entry" is volatile when lock is let go. - boolean_t reusable = TRUE; - boolean_t should_madvise = szone->large_entry_cache_reserve_bytes + this_entry.size > szone->large_entry_cache_reserve_limit; - - // Already freed? - // [Note that repeated entries in death-row risk vending the same entry subsequently - // to two different malloc() calls. By checking here the (illegal) double free - // is accommodated, matching the behavior of the previous implementation.] - while (1) { // Scan large_entry_cache starting with most recent entry - if (szone->large_entry_cache[idx].address == entry->address) { - szone_error(szone, 1, "pointer being freed already on death-row", ptr, NULL); - SZONE_UNLOCK(szone); - return; - } - - if (idx == stop_idx) // exhausted live ring? - break; - - if (idx) - idx--; // bump idx down - else - idx = LARGE_ENTRY_CACHE_SIZE - 1; // wrap idx - } - - SZONE_UNLOCK(szone); - - if (szone->debug_flags & SCALABLE_MALLOC_PURGEABLE) { // Are we a purgable zone? - int state = VM_PURGABLE_NONVOLATILE; // restore to default condition - - if (KERN_SUCCESS != vm_purgable_control(mach_task_self(), this_entry.address, VM_PURGABLE_SET_STATE, &state)) { - malloc_printf("*** can't vm_purgable_control(..., VM_PURGABLE_SET_STATE) for large freed block at %p\n", - this_entry.address); - reusable = FALSE; - } - } - - if (szone->large_legacy_reset_mprotect) { // Linked for Leopard? - // Accomodate Leopard apps that (illegally) mprotect() their own guard pages on large malloc'd allocations - int err = mprotect((void *)(this_entry.address), this_entry.size, PROT_READ | PROT_WRITE); - if (err) { - malloc_printf("*** can't reset protection for large freed block at %p\n", this_entry.address); - reusable = FALSE; - } - } - - // madvise(..., MADV_REUSABLE) death-row arrivals if hoarding would exceed large_entry_cache_reserve_limit - if (should_madvise) { - // Issue madvise to avoid paging out the dirtied free()'d pages in "entry" - MAGMALLOC_MADVFREEREGION((void *)szone, (void *)0, (void *)(this_entry.address), this_entry.size); // DTrace USDT Probe - -#if TARGET_OS_EMBEDDED - // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large - // cache block twice without MADV_FREE_REUSE in between. -#endif - if (-1 == madvise((void *)(this_entry.address), this_entry.size, MADV_FREE_REUSABLE)) { - /* -1 return: VM map entry change makes this unfit for reuse. */ -#if DEBUG_MADVISE - szone_error(szone, 0, "free_large madvise(..., MADV_FREE_REUSABLE) failed", - (void *)this_entry.address, "length=%d\n", this_entry.size); -#endif - reusable = FALSE; - } - } - - SZONE_LOCK(szone); - - // Re-acquire "entry" after interval just above where we let go the lock. - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (NULL == entry) { - szone_error(szone, 1, "entry for pointer being freed from death-row vanished", ptr, NULL); - SZONE_UNLOCK(szone); - return; - } - - // Add "entry" to death-row ring - if (reusable) { - int idx = szone->large_entry_cache_newest; // Most recently occupied - vm_address_t addr; - size_t adjsize; - - if (szone->large_entry_cache_newest == szone->large_entry_cache_oldest && - 0 == szone->large_entry_cache[idx].address) { - // Ring is empty, idx is good as it stands - addr = 0; - adjsize = 0; - } else { - // Extend the queue to the "right" by bumping up large_entry_cache_newest - if (idx == LARGE_ENTRY_CACHE_SIZE - 1) - idx = 0; // Wrap index - else - idx++; // Bump index - - if (idx == szone->large_entry_cache_oldest) { // Fully occupied - // Drop this entry from the cache and deallocate the VM - addr = szone->large_entry_cache[idx].address; - adjsize = szone->large_entry_cache[idx].size; - szone->large_entry_cache_bytes -= adjsize; - if (!szone->large_entry_cache[idx].did_madvise_reusable) - szone->large_entry_cache_reserve_bytes -= adjsize; - } else { - // Using an unoccupied cache slot - addr = 0; - adjsize = 0; - } - } - - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE)) - memset((void *)(entry->address), should_madvise ? SCRUBBLE_BYTE : SCRABBLE_BYTE, entry->size); - - entry->did_madvise_reusable = should_madvise; // Was madvise()'d above? - if (!should_madvise) // Entered on death-row without madvise() => up the hoard total - szone->large_entry_cache_reserve_bytes += entry->size; - - szone->large_entry_cache_bytes += entry->size; - - if (!szone->flotsam_enabled && szone->large_entry_cache_bytes > SZONE_FLOTSAM_THRESHOLD_HIGH) { - szone->flotsam_enabled = TRUE; - } - - szone->large_entry_cache[idx] = *entry; - szone->large_entry_cache_newest = idx; - - szone->num_large_objects_in_use--; - szone->num_bytes_in_large_objects -= entry->size; - - (void)large_entry_free_no_lock(szone, entry); - - if (0 == addr) { - SZONE_UNLOCK(szone); - return; - } - - // Fall through to drop large_entry_cache_oldest from the cache, - // and then deallocate its pages. - - // Trim the queue on the "left" by bumping up large_entry_cache_oldest - if (szone->large_entry_cache_oldest == LARGE_ENTRY_CACHE_SIZE - 1) - szone->large_entry_cache_oldest = 0; - else - szone->large_entry_cache_oldest++; - - // we deallocate_pages, including guard pages, outside the lock - SZONE_UNLOCK(szone); - deallocate_pages(szone, (void *)addr, (size_t)adjsize, 0); - return; - } else { - /* fall through to discard an allocation that is not reusable */ - } - } -#endif /* LARGE_CACHE */ - - szone->num_large_objects_in_use--; - szone->num_bytes_in_large_objects -= entry->size; - - vm_range_to_deallocate = large_entry_free_no_lock(szone, entry); - } else { -#if DEBUG_MALLOC - large_debug_print(szone); -#endif - szone_error(szone, 1, "pointer being freed was not allocated", ptr, NULL); - SZONE_UNLOCK(szone); - return; - } - SZONE_UNLOCK(szone); // we release the lock asap - CHECK(szone, __PRETTY_FUNCTION__); - - // we deallocate_pages, including guard pages, outside the lock - if (vm_range_to_deallocate.address) { -#if DEBUG_MALLOC - // FIXME: large_entry_for_pointer_no_lock() needs the lock held ... - if (large_entry_for_pointer_no_lock(szone, (void *)vm_range_to_deallocate.address)) { - malloc_printf("*** invariant broken: %p still in use num_large_entries=%d\n", - vm_range_to_deallocate.address, szone->num_large_entries); - large_debug_print(szone); - szone_sleep(); - } -#endif - deallocate_pages(szone, (void *)vm_range_to_deallocate.address, (size_t)vm_range_to_deallocate.size, 0); - } -} - -static INLINE void * -large_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) -{ - size_t shrinkage = old_size - new_good_size; - - if (shrinkage) { - SZONE_LOCK(szone); - /* contract existing large entry */ - large_entry_t *large_entry = large_entry_for_pointer_no_lock(szone, ptr); - if (!large_entry) { - szone_error(szone, 1, "large entry reallocated is not properly in table", ptr, NULL); - SZONE_UNLOCK(szone); - return ptr; - } - - large_entry->address = (vm_address_t)ptr; - large_entry->size = new_good_size; - szone->num_bytes_in_large_objects -= shrinkage; - SZONE_UNLOCK(szone); // we release the lock asap - - deallocate_pages(szone, (void *)((uintptr_t)ptr + new_good_size), shrinkage, 0); - } - return ptr; -} - -static INLINE int -large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) -{ - vm_address_t addr = (vm_address_t)ptr + old_size; - large_entry_t *large_entry; - kern_return_t err; - - SZONE_LOCK(szone); - large_entry = large_entry_for_pointer_no_lock(szone, (void *)addr); - SZONE_UNLOCK(szone); - - if (large_entry) { // check if "addr = ptr + old_size" is already spoken for - return 0; // large pointer already exists in table - extension is not going to work - } - - new_size = round_page_quanta(new_size); - /* - * Ask for allocation at a specific address, and mark as realloc - * to request coalescing with previous realloc'ed extensions. - */ - err = vm_allocate(mach_task_self(), &addr, new_size - old_size, VM_MAKE_TAG(VM_MEMORY_REALLOC)); - if (err != KERN_SUCCESS) { - return 0; - } - - SZONE_LOCK(szone); - /* extend existing large entry */ - large_entry = large_entry_for_pointer_no_lock(szone, ptr); - if (!large_entry) { - szone_error(szone, 1, "large entry reallocated is not properly in table", ptr, NULL); - SZONE_UNLOCK(szone); - return 0; // Bail, leaking "addr" - } - - large_entry->address = (vm_address_t)ptr; - large_entry->size = new_size; - szone->num_bytes_in_large_objects += new_size - old_size; - SZONE_UNLOCK(szone); // we release the lock asap - - return 1; -} - -/********************* Zone call backs ************************/ -/* - * Mark these NOINLINE to avoid bloating the purgeable zone call backs - */ -static NOINLINE void -szone_free(szone_t *szone, void *ptr) -{ - region_t tiny_region; - region_t small_region; - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("in szone_free with %p\n", ptr); -#endif - if (!ptr) - return; - /* - * Try to free to a tiny region. - */ - if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) { - szone_error(szone, 1, "Non-aligned pointer being freed", ptr, NULL); - return; - } - if ((tiny_region = tiny_region_for_ptr_no_lock(szone, ptr)) != NULL) { - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { - szone_error(szone, 1, "Pointer to metadata being freed", ptr, NULL); - return; - } - free_tiny(szone, ptr, tiny_region, 0); - return; - } - - /* - * Try to free to a small region. - */ - if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) { - szone_error(szone, 1, "Non-aligned pointer being freed (2)", ptr, NULL); - return; - } - if ((small_region = small_region_for_ptr_no_lock(szone, ptr)) != NULL) { - if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { - szone_error(szone, 1, "Pointer to metadata being freed (2)", ptr, NULL); - return; - } - free_small(szone, ptr, small_region, 0); - return; - } - - /* check that it's a legal large allocation */ - if ((uintptr_t)ptr & (vm_page_quanta_size - 1)) { - szone_error(szone, 1, "non-page-aligned, non-allocated pointer being freed", ptr, NULL); - return; - } - free_large(szone, ptr); -} - -static NOINLINE void -szone_free_definite_size(szone_t *szone, void *ptr, size_t size) -{ -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("in szone_free_definite_size with %p\n", ptr); - - if (0 == size) { - szone_error(szone, 1, "pointer of size zero being freed", ptr, NULL); - return; - } - -#endif - if (!ptr) - return; - - /* - * Try to free to a tiny region. - */ - if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) { - szone_error(szone, 1, "Non-aligned pointer being freed", ptr, NULL); - return; - } - if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) { - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) { - szone_error(szone, 1, "Pointer to metadata being freed", ptr, NULL); - return; - } - free_tiny(szone, ptr, TINY_REGION_FOR_PTR(ptr), size); - return; - } - - /* - * Try to free to a small region. - */ - if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) { - szone_error(szone, 1, "Non-aligned pointer being freed (2)", ptr, NULL); - return; - } - if (size <= szone->large_threshold) { - if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) { - szone_error(szone, 1, "Pointer to metadata being freed (2)", ptr, NULL); - return; - } - free_small(szone, ptr, SMALL_REGION_FOR_PTR(ptr), size); - return; - } - - /* check that it's a legal large allocation */ - if ((uintptr_t)ptr & (vm_page_quanta_size - 1)) { - szone_error(szone, 1, "non-page-aligned, non-allocated pointer being freed", ptr, NULL); - return; - } - free_large(szone, ptr); -} - -static NOINLINE void * -szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested) -{ - void *ptr; - msize_t msize; - - if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) { - // think tiny - msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - if (!msize) - msize = 1; - ptr = tiny_malloc_should_clear(szone, msize, cleared_requested); - } else if (size <= szone->large_threshold) { - // think small - msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); - if (!msize) - msize = 1; - ptr = small_malloc_should_clear(szone, msize, cleared_requested); - } else { - // large - size_t num_kernel_pages = round_page_quanta(size) >> vm_page_quanta_shift; - if (num_kernel_pages == 0) /* Overflowed */ - ptr = 0; - else - ptr = large_malloc(szone, num_kernel_pages, 0, cleared_requested); - } -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("szone_malloc returned %p\n", ptr); -#endif - /* - * If requested, scribble on allocated memory. - */ - if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && ptr && !cleared_requested && size) - memset(ptr, SCRIBBLE_BYTE, szone_size(szone, ptr)); - - return ptr; -} - -static NOINLINE void * -szone_malloc(szone_t *szone, size_t size) { - return szone_malloc_should_clear(szone, size, 0); -} - -static NOINLINE void * -szone_calloc(szone_t *szone, size_t num_items, size_t size) -{ - size_t total_bytes = num_items * size; - - // Check for overflow of integer multiplication - if (num_items > 1) { -#if __LP64__ /* size_t is uint64_t */ - if ((num_items | size) & 0xffffffff00000000ul) { - // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic - __uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size); - if ((uint64_t)(product >> 64)) // compiles to test on upper register of register pair - return NULL; - } -#else /* size_t is uint32_t */ - if ((num_items | size) & 0xffff0000ul) { - // num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic - uint64_t product = ((uint64_t)num_items) * ((uint64_t)size); - if ((uint32_t)(product >> 32)) // compiles to test on upper register of register pair - return NULL; - } -#endif - } - - return szone_malloc_should_clear(szone, total_bytes, 1); -} - -static NOINLINE void * -szone_valloc(szone_t *szone, size_t size) -{ - void *ptr; - - if (size <= szone->large_threshold) { - ptr = szone_memalign(szone, vm_page_quanta_size, size); - } else { - size_t num_kernel_pages; - - num_kernel_pages = round_page_quanta(size) >> vm_page_quanta_shift; - ptr = large_malloc(szone, num_kernel_pages, 0, 0); - } - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("szone_valloc returned %p\n", ptr); -#endif - return ptr; -} - -/* Isolate PIC-base load here. */ -static NOINLINE size_t -szone_size_try_large(szone_t *szone, const void *ptr) -{ - size_t size = 0; - large_entry_t *entry; - - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - if (entry) { - size = entry->size; - } - SZONE_UNLOCK(szone); -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("szone_size for %p returned %d\n", ptr, (unsigned)size); - } -#endif - return size; -} - -static NOINLINE size_t -szone_size(szone_t *szone, const void *ptr) -{ - boolean_t is_free; - msize_t msize, msize_and_free; - - if (!ptr) - return 0; -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in szone_size for %p (szone=%p)\n", ptr, szone); - } -#endif - - /* - * Look for it in a tiny region. - */ - if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) - return 0; - if (tiny_region_for_ptr_no_lock(szone, ptr)) { - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) - return 0; - msize = get_tiny_meta_header(ptr, &is_free); - if (is_free) - return 0; -#if TINY_CACHE - { - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); - if (DEPOT_MAGAZINE_INDEX != mag_index) { - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~ (TINY_QUANTUM - 1))) - return 0; - } else { - for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~ (TINY_QUANTUM - 1))) - return 0; - } - } - } -#endif - return TINY_BYTES_FOR_MSIZE(msize); - } - - /* - * Look for it in a small region. - */ - if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) - return 0; - if (small_region_for_ptr_no_lock(szone, ptr)) { - if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) - return 0; - msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); - if (msize_and_free & SMALL_IS_FREE) - return 0; -#if SMALL_CACHE - { - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); - if (DEPOT_MAGAZINE_INDEX != mag_index) { - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~ (SMALL_QUANTUM - 1))) - return 0; - } else { - for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { - magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); - - if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~ (SMALL_QUANTUM - 1))) - return 0; - } - } - } -#endif - return SMALL_BYTES_FOR_MSIZE(msize_and_free); - } - - /* - * If not page-aligned, it cannot have come from a large allocation. - */ - if ((uintptr_t)ptr & (vm_page_quanta_size - 1)) - return 0; - - /* - * Look for it in a large entry. - */ - return szone_size_try_large(szone, ptr); -} - -static NOINLINE void * -szone_realloc(szone_t *szone, void *ptr, size_t new_size) -{ - size_t old_size, new_good_size, valid_size; - void *new_ptr; - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("in szone_realloc for %p, %d\n", ptr, (unsigned)new_size); - } -#endif - if (NULL == ptr) { - // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. - return szone_malloc(szone, new_size); - } else if (0 == new_size) { - // If size is 0 and ptr is not a null pointer, the object pointed to is freed. - szone_free(szone, ptr); - // If size is 0, either a null pointer or a unique pointer that can be successfully passed - // to free() shall be returned. - return szone_malloc(szone, 1); - } - - old_size = szone_size(szone, ptr); - if (!old_size) { - szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL); - return NULL; - } - - new_good_size = szone_good_size(szone, new_size); - if (new_good_size == old_size) { // Existing allocation is best fit evar? - return ptr; - } - - /* - * If the new size suits the tiny allocator and the pointer being resized - * belongs to a tiny region, try to reallocate in-place. - */ - if (new_good_size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { - if (old_size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { - if (new_good_size <= (old_size >> 1)) { - /* - * Serious shrinkage (more than half). free() the excess. - */ - return tiny_try_shrink_in_place(szone, ptr, old_size, new_good_size); - } else if (new_good_size <= old_size) { - /* - * new_good_size smaller than old_size but not by much (less than half). - * Avoid thrashing at the expense of some wasted storage. - */ - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) - memset(ptr + new_size, SCRIBBLE_BYTE, old_size - new_size); - return ptr; - } else if (tiny_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { // try to grow the allocation - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) - memset(ptr + old_size, SCRIBBLE_BYTE, new_good_size - old_size); - return ptr; - } - } - - /* - * Else if the new size suits the small allocator and the pointer being resized - * belongs to a small region, and we're not protecting the small allocations - * try to reallocate in-place. - */ - } else if (new_good_size <= szone->large_threshold) { - if ((NUM_TINY_SLOTS - 1) * TINY_QUANTUM < old_size && old_size <= szone->large_threshold) { - if (new_good_size <= (old_size >> 1)) { - return small_try_shrink_in_place(szone, ptr, old_size, new_good_size); - } else if (new_good_size <= old_size) { - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) - memset(ptr + new_size, SCRIBBLE_BYTE, old_size - new_size); - return ptr; - } else if (small_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) - memset(ptr + old_size, SCRIBBLE_BYTE, new_good_size - old_size); - return ptr; - } - } - /* - * Else if the allocation's a large allocation, try to reallocate in-place there. - */ - } else if (!(szone->debug_flags & SCALABLE_MALLOC_PURGEABLE) && // purgeable needs fresh allocation - (old_size > szone->large_threshold) && - (new_good_size > szone->large_threshold)) { - if (new_good_size <= (old_size >> 1)) { - return large_try_shrink_in_place(szone, ptr, old_size, new_good_size); - } else if (new_good_size <= old_size) { - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) - memset(ptr + new_size, SCRIBBLE_BYTE, old_size - new_size); - return ptr; - } else if (large_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) - memset(ptr + old_size, SCRIBBLE_BYTE, new_good_size - old_size); - return ptr; - } - } - - /* - * Can't reallocate in place for whatever reason; allocate a new buffer and copy. - */ - if (new_good_size <= (old_size >> 1)) { - /* Serious shrinkage (more than half). FALL THROUGH to alloc/copy/free. */ - } else if (new_good_size <= old_size) { - if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) - memset(ptr + new_size, SCRIBBLE_BYTE, old_size - new_size); - return ptr; - } - - new_ptr = szone_malloc(szone, new_size); - if (new_ptr == NULL) - return NULL; - - /* - * If the allocation's large enough, try to copy using VM. If that fails, or - * if it's too small, just copy by hand. - */ - valid_size = MIN(old_size, new_size); - if ((valid_size < szone->vm_copy_threshold) || - vm_copy(mach_task_self(), (vm_address_t)ptr, valid_size, (vm_address_t)new_ptr)) - memcpy(new_ptr, ptr, valid_size); - szone_free(szone, ptr); - -#if DEBUG_MALLOC - if (LOG(szone, ptr)) { - malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size); - } -#endif - return new_ptr; -} - -static NOINLINE void * -szone_memalign(szone_t *szone, size_t alignment, size_t size) -{ - if (size == 0) - size = 1; // Ensures we'll return an aligned free()-able pointer - - if ((size + alignment) < size) // size_t arithmetic wrapped! - return NULL; - - // alignment is gauranteed a power of 2 at least as large as sizeof(void *), hence non-zero. - // Since size + alignment didn't wrap, 0 <= size + alignment - 1 < size + alignment - size_t span = size + alignment - 1; - - if (alignment <= TINY_QUANTUM) { - return szone_malloc(szone, size); // Trivially satisfied by tiny, small, or large - - } else if (span <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) { - msize_t mspan = TINY_MSIZE_FOR_BYTES(span + TINY_QUANTUM - 1); - void *p = szone_malloc(szone, span); // avoids inlining tiny_malloc_should_clear(szone, mspan, 0); - - if (NULL == p) - return NULL; - - size_t offset = ((uintptr_t) p) & (alignment - 1); // p % alignment - size_t pad = (0 == offset) ? 0 : alignment - offset; // p + pad achieves desired alignment - - msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - msize_t mpad = TINY_MSIZE_FOR_BYTES(pad + TINY_QUANTUM - 1); - msize_t mwaste = mspan - msize - mpad; // excess blocks - - if (mpad > 0) { - void *q = (void *)(((uintptr_t) p) + pad); - - // Mark q as a block header and in-use, thus creating two blocks. - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)), - MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p))); - set_tiny_meta_header_in_use(q, msize); - tiny_mag_ptr->mag_num_objects++; - - // set_tiny_meta_header_in_use() "reaffirms" the block_header on the *following* block, so - // now set its in_use bit as well. But only if its within the original allocation made above. - if (mwaste > 0) - BITARRAY_SET(TINY_INUSE_FOR_HEADER(TINY_BLOCK_HEADER_FOR_PTR(q)), TINY_INDEX_FOR_PTR(q) + msize); - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - - // Give up mpad blocks beginning at p to the tiny free list - // region_t r = TINY_REGION_FOR_PTR(p); - szone_free(szone, p); // avoids inlining free_tiny(szone, p, &r); - - p = q; // advance p to the desired alignment - } - - if (mwaste > 0) { - void *q = (void *)(((uintptr_t) p) + TINY_BYTES_FOR_MSIZE(msize)); - // Mark q as block header and in-use, thus creating two blocks. - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)), - MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p))); - set_tiny_meta_header_in_use(q, mwaste); - tiny_mag_ptr->mag_num_objects++; - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - - // Give up mwaste blocks beginning at q to the tiny free list - // region_t r = TINY_REGION_FOR_PTR(q); - szone_free(szone, q); // avoids inlining free_tiny(szone, q, &r); - } - - return p; // p has the desired size and alignment, and can later be free()'d - - } else if ((NUM_TINY_SLOTS - 1)*TINY_QUANTUM < size && alignment <= SMALL_QUANTUM) { - return szone_malloc(szone, size); // Trivially satisfied by small or large - - } else if (span <= szone->large_threshold) { - - if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) { - size = (NUM_TINY_SLOTS - 1)*TINY_QUANTUM + TINY_QUANTUM; // ensure block allocated by small does not have a tiny-possible size - span = size + alignment - 1; - } - - msize_t mspan = SMALL_MSIZE_FOR_BYTES(span + SMALL_QUANTUM - 1); - void *p = szone_malloc(szone, span); // avoid inlining small_malloc_should_clear(szone, mspan, 0); - - if (NULL == p) - return NULL; - - size_t offset = ((uintptr_t) p) & (alignment - 1); // p % alignment - size_t pad = (0 == offset) ? 0 : alignment - offset; // p + pad achieves desired alignment - - msize_t msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); - msize_t mpad = SMALL_MSIZE_FOR_BYTES(pad + SMALL_QUANTUM - 1); - msize_t mwaste = mspan - msize - mpad; // excess blocks - - if (mpad > 0) { - void *q = (void *)(((uintptr_t) p) + pad); - - // Mark q as block header and in-use, thus creating two blocks. - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)), - MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p))); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(p), SMALL_META_INDEX_FOR_PTR(p), mpad); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), msize + mwaste); - small_mag_ptr->mag_num_objects++; - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - - // Give up mpad blocks beginning at p to the small free list - // region_t r = SMALL_REGION_FOR_PTR(p); - szone_free(szone, p); // avoid inlining free_small(szone, p, &r); - - p = q; // advance p to the desired alignment - } - if (mwaste > 0) { - void *q = (void *)(((uintptr_t) p) + SMALL_BYTES_FOR_MSIZE(msize)); - // Mark q as block header and in-use, thus creating two blocks. - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)), - MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p))); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(p), SMALL_META_INDEX_FOR_PTR(p), msize); - small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), mwaste); - small_mag_ptr->mag_num_objects++; - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - - // Give up mwaste blocks beginning at q to the small free list - // region_t r = SMALL_REGION_FOR_PTR(q); - szone_free(szone, q); // avoid inlining free_small(szone, q, &r); - } - - return p; // p has the desired size and alignment, and can later be free()'d - - } else if (szone->large_threshold < size && alignment <= vm_page_quanta_size) { - return szone_malloc(szone, size); // Trivially satisfied by large - - } else { - // ensure block allocated by large does not have a small-possible size - size_t num_kernel_pages = round_page_quanta(MAX(szone->large_threshold + 1, size)) >> vm_page_quanta_shift; - void *p; - - if (num_kernel_pages == 0) /* Overflowed */ - p = NULL; - else - p = large_malloc(szone, num_kernel_pages, MAX(vm_page_quanta_shift, __builtin_ctz(alignment)), 0); - - return p; - } - /* NOTREACHED */ -} - -// given a size, returns the number of pointers allocated capable of holding -// that size, up to the limit specified by the 'count' argument. These pointers -// are stored in the 'results' array, which must be allocated by the caller. -// may return zero, since this function is only a best attempt at allocating -// the pointers. clients should be prepared to call malloc for any additional -// blocks they need. -static NOINLINE unsigned -szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) -{ - msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - unsigned found = 0; - mag_index_t mag_index = mag_get_thread_index(szone); - magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); - - // only bother implementing this for tiny - if (size > (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) - return 0; - // make sure to return objects at least one quantum in size - if (!msize) - msize = 1; - - CHECK(szone, __PRETTY_FUNCTION__); - - // We must lock the zone now, since tiny_malloc_from_free_list assumes that - // the caller has done so. - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); - - // with the zone locked, allocate objects from the free list until all - // sufficiently large objects have been exhausted, or we have met our quota - // of objects to allocate. - while (found < count) { - void *ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); - if (!ptr) - break; - - *results++ = ptr; - found++; - } - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - return found; -} - -/* Try caching the tiny_region and checking if the next ptr hits there. */ -static NOINLINE void -szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) -{ - unsigned cc = 0; - void *ptr; - region_t tiny_region = NULL; - boolean_t is_free; - msize_t msize; - magazine_t *tiny_mag_ptr = NULL; - mag_index_t mag_index = -1; - - // frees all the pointers in to_be_freed - // note that to_be_freed may be overwritten during the process - if (!count) - return; - - CHECK(szone, __PRETTY_FUNCTION__); - while (cc < count) { - ptr = to_be_freed[cc]; - if (ptr) { - if (NULL == tiny_region || tiny_region != TINY_REGION_FOR_PTR(ptr)) { // region same as last iteration? - if (tiny_mag_ptr) { // non-NULL iff magazine lock taken - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - tiny_mag_ptr = NULL; - } - - tiny_region = tiny_region_for_ptr_no_lock(szone, ptr); - - if (tiny_region) { - tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(tiny_region), - MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region)); - mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region); - } - } - if (tiny_region) { - // this is a tiny pointer - if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) - break; // pointer to metadata; let the standard free deal with it - msize = get_tiny_meta_header(ptr, &is_free); - if (is_free) - break; // a double free; let the standard free deal with it - - if (!tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize)) { - // Arrange to re-acquire magazine lock - tiny_mag_ptr = NULL; - tiny_region = NULL; - } - to_be_freed[cc] = NULL; - } else { - // No region in this zone claims ptr; let the standard free deal with it - break; - } - } - cc++; - } - - if (tiny_mag_ptr) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - tiny_mag_ptr = NULL; - } - - CHECK(szone, __PRETTY_FUNCTION__); - while (count--) { - ptr = to_be_freed[count]; - if (ptr) - szone_free(szone, ptr); - } -} - -// FIXME: Suppose one of the locks is held? -static void -szone_destroy(szone_t *szone) -{ - size_t index; - large_entry_t *large; - vm_range_t range_to_deallocate; - -#if LARGE_CACHE - SZONE_LOCK(szone); - - /* disable any memory pressure responder */ - szone->flotsam_enabled = FALSE; - - // stack allocated copy of the death-row cache - int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest; - large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE]; - - memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache)); - - szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0; - szone->large_entry_cache[0].address = 0x0; - szone->large_entry_cache[0].size = 0; - szone->large_entry_cache_bytes = 0; - szone->large_entry_cache_reserve_bytes = 0; - - SZONE_UNLOCK(szone); - - // deallocate the death-row cache outside the zone lock - while (idx != idx_max) { - deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); - if (++idx == LARGE_ENTRY_CACHE_SIZE) idx = 0; - } - if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) { - deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); - } -#endif - - /* destroy large entries */ - index = szone->num_large_entries; - while (index--) { - large = szone->large_entries + index; - if (large->address) { - // we deallocate_pages, including guard pages - deallocate_pages(szone, (void *)(large->address), large->size, szone->debug_flags); - } - } - large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate); - if (range_to_deallocate.size) - deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0); - - /* destroy tiny regions */ - for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) - if ((HASHRING_OPEN_ENTRY != szone->tiny_region_generation->hashed_regions[index]) && - (HASHRING_REGION_DEALLOCATED != szone->tiny_region_generation->hashed_regions[index])) - deallocate_pages(szone, szone->tiny_region_generation->hashed_regions[index], TINY_REGION_SIZE, 0); - - /* destroy small regions */ - for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) - if ((HASHRING_OPEN_ENTRY != szone->small_region_generation->hashed_regions[index]) && - (HASHRING_REGION_DEALLOCATED != szone->small_region_generation->hashed_regions[index])) - deallocate_pages(szone, szone->small_region_generation->hashed_regions[index], SMALL_REGION_SIZE, 0); - - /* destroy region hash rings, if any */ - if (szone->tiny_region_generation->hashed_regions != szone->initial_tiny_regions) { - size_t size = round_page_quanta(szone->tiny_region_generation->num_regions_allocated * sizeof(region_t)); - deallocate_pages(szone, szone->tiny_region_generation->hashed_regions, size, 0); - } - if (szone->small_region_generation->hashed_regions != szone->initial_small_regions) { - size_t size = round_page_quanta(szone->small_region_generation->num_regions_allocated * sizeof(region_t)); - deallocate_pages(szone, szone->small_region_generation->hashed_regions, size, 0); - } - - /* Now destroy the separate szone region */ - deallocate_pages(szone, (void *)&(szone->tiny_magazines[-1]), TINY_MAGAZINE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); - deallocate_pages(szone, (void *)&(szone->small_magazines[-1]), SMALL_MAGAZINE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES); - deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0); -} - -static NOINLINE size_t -szone_good_size(szone_t *szone, size_t size) -{ - msize_t msize; - - // Find a good size for this tiny allocation. - if (size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) { - msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); - if (!msize) - msize = 1; - return TINY_BYTES_FOR_MSIZE(msize); - } - - // Find a good size for this small allocation. - if (size <= szone->large_threshold) { - msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); - if (!msize) - msize = 1; - return SMALL_BYTES_FOR_MSIZE(msize); - } - - // Check for integer overflow on the size, since unlike the two cases above, - // there is no upper bound on allocation size at this point. - if (size > round_page_quanta(size)) - return (size_t)(-1LL); - -#if DEBUG_MALLOC - // It is not acceptable to see a size of zero here, since that means we - // failed to catch a request for zero bytes in the tiny check, or the size - // overflowed to zero during some arithmetic. - if (size == 0) - malloc_printf("szone_good_size() invariant broken %y\n", size); -#endif - return round_page_quanta(size); -} - -unsigned szone_check_counter = 0; -unsigned szone_check_start = 0; -unsigned szone_check_modulo = 1; - -static NOINLINE boolean_t -szone_check_all(szone_t *szone, const char *function) -{ - size_t index; - - /* check tiny regions - chould check region count */ - for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) { - region_t tiny = szone->tiny_region_generation->hashed_regions[index]; - - if (HASHRING_REGION_DEALLOCATED == tiny) - continue; - - if (tiny) { - magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, - REGION_TRAILER_FOR_TINY_REGION(tiny), MAGAZINE_INDEX_FOR_TINY_REGION(tiny)); - - if (!tiny_check_region(szone, tiny)) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, 1, "check: tiny region incorrect", NULL, - "*** tiny region %ld incorrect szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); - } - } - /* check tiny free lists */ - for (index = 0; index < NUM_TINY_SLOTS; ++index) { - if (!tiny_free_list_check(szone, index)) { - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, 1, "check: tiny free list incorrect", NULL, - "*** tiny free list incorrect (slot=%ld) szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - } - - /* check small regions - could check region count */ - for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) { - region_t small = szone->small_region_generation->hashed_regions[index]; - - if (HASHRING_REGION_DEALLOCATED == small) - continue; - - if (small) { - magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, - REGION_TRAILER_FOR_SMALL_REGION(small), MAGAZINE_INDEX_FOR_SMALL_REGION(small)); - - if (!small_check_region(szone, small)) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, 1, "check: small region incorrect", NULL, - "*** small region %ld incorrect szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); - } - } - /* check small free lists */ - for (index = 0; index < szone->num_small_slots; ++index) { - if (!small_free_list_check(szone, index)) { - szone->debug_flags &= ~ CHECK_REGIONS; - szone_error(szone, 1, "check: small free list incorrect", NULL, - "*** small free list incorrect (slot=%ld) szone_check_all(%s) counter=%d\n", - index, function, szone_check_counter); - return 0; - } - } - - return 1; -} - -static boolean_t -szone_check(szone_t *szone) -{ - if ((++szone_check_counter % 10000) == 0) - _malloc_printf(ASL_LEVEL_NOTICE, "at szone_check counter=%d\n", szone_check_counter); - - if (szone_check_counter < szone_check_start) - return 1; - - if (szone_check_counter % szone_check_modulo) - return 1; - - return szone_check_all(szone, ""); -} - -static kern_return_t -szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, vm_range_recorder_t recorder) -{ - szone_t *szone; - kern_return_t err; - - if (!reader) reader = _szone_default_reader; - - err = reader(task, zone_address, sizeof(szone_t), (void **)&szone); - if (err) return err; - - err = tiny_in_use_enumerator(task, context, type_mask, szone, reader, recorder); - if (err) return err; - - err = small_in_use_enumerator(task, context, type_mask, szone, reader, recorder); - if (err) return err; - - err = large_in_use_enumerator(task, context, type_mask, - (vm_address_t)szone->large_entries, szone->num_large_entries, reader, recorder); - return err; -} - -// Following method is deprecated: use scalable_zone_statistics instead -void -scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) -{ - szone_t *szone = (void *)zone; - unsigned info[13]; - - // We do not lock to facilitate debug - - size_t s = 0; - unsigned t = 0; - size_t u = 0; - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; - t += szone->tiny_magazines[mag_index].mag_num_objects; - u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; - } - - info[4] = t; - info[5] = u; - - for (t = 0, u = 0, mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - s += szone->small_magazines[mag_index].mag_bytes_free_at_start; - s += szone->small_magazines[mag_index].mag_bytes_free_at_end; - t += szone->small_magazines[mag_index].mag_num_objects; - u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; - } - - info[6] = t; - info[7] = u; - - info[8] = szone->num_large_objects_in_use; - info[9] = szone->num_bytes_in_large_objects; - - info[10] = 0; // DEPRECATED szone->num_huge_entries; - info[11] = 0; // DEPRECATED szone->num_bytes_in_huge_objects; - - info[12] = szone->debug_flags; - - info[0] = info[4] + info[6] + info[8] + info[10]; - info[1] = info[5] + info[7] + info[9] + info[11]; - - info[3] = (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE + - (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE + info[9] + info[11]; - - info[2] = info[3] - s; - memcpy(info_to_fill, info, sizeof(unsigned)*count); -} - -// FIXME: consistent picture requires locking! -static NOINLINE void -szone_print(szone_t *szone, boolean_t verbose) -{ - unsigned info[13]; - size_t index; - region_t region; - - scalable_zone_info((void *)szone, info, 13); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "Scalable zone %p: inUse=%u(%y) touched=%y allocated=%y flags=%d\n", - szone, info[0], info[1], info[2], info[3], info[12]); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "\ttiny=%u(%y) small=%u(%y) large=%u(%y) huge=%u(%y)\n", - info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11]); - // tiny - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "%lu tiny regions:\n", szone->num_tiny_regions); - if (szone->num_tiny_regions_dealloc) - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "[%lu tiny regions have been vm_deallocate'd]\n", szone->num_tiny_regions_dealloc); - for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) { - region = szone->tiny_region_generation->hashed_regions[index]; - if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { - mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(region); - print_tiny_region(verbose, region, - (region == szone->tiny_magazines[mag_index].mag_last_region) ? - szone->tiny_magazines[mag_index].mag_bytes_free_at_start : 0, - (region == szone->tiny_magazines[mag_index].mag_last_region) ? - szone->tiny_magazines[mag_index].mag_bytes_free_at_end : 0); - } - } - if (verbose) - print_tiny_free_list(szone); - // small - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "%lu small regions:\n", szone->num_small_regions); - if (szone->num_small_regions_dealloc) - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "[%lu small regions have been vm_deallocate'd]\n", szone->num_small_regions_dealloc); - for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) { - region = szone->small_region_generation->hashed_regions[index]; - if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { - mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(region); - print_small_region(szone, verbose, region, - (region == szone->small_magazines[mag_index].mag_last_region) ? - szone->small_magazines[mag_index].mag_bytes_free_at_start : 0, - (region == szone->small_magazines[mag_index].mag_last_region) ? - szone->small_magazines[mag_index].mag_bytes_free_at_end : 0); - } - } - if (verbose) - print_small_free_list(szone); -} - -static void -szone_log(malloc_zone_t *zone, void *log_address) -{ - szone_t *szone = (szone_t *)zone; - - szone->log_address = log_address; -} - -// -// When forcing the lock on the entire zone, make sure we are out of the critical section in each magazine -static INLINE void -szone_force_lock_magazine(szone_t *szone, magazine_t *mag) -{ - while (1) { - SZONE_MAGAZINE_PTR_LOCK(szone, mag); - if (!mag->alloc_underway) - return; - - SZONE_MAGAZINE_PTR_UNLOCK(szone, mag); - yield(); - } -} - -static void -szone_force_lock(szone_t *szone) -{ - mag_index_t i; - - for (i = 0; i < szone->num_tiny_magazines; ++i) { - szone_force_lock_magazine(szone, &szone->tiny_magazines[i]); - } - szone_force_lock_magazine(szone, &szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); - - for (i = 0; i < szone->num_small_magazines; ++i) { - szone_force_lock_magazine(szone, &szone->small_magazines[i]); - } - szone_force_lock_magazine(szone, &szone->small_magazines[DEPOT_MAGAZINE_INDEX]); - - SZONE_LOCK(szone); -} - -static void -szone_force_unlock(szone_t *szone) -{ - mag_index_t i; - - SZONE_UNLOCK(szone); - - for (i = -1; i < szone->num_small_magazines; ++i) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->small_magazines[i]))); - } - - for (i = -1; i < szone->num_tiny_magazines; ++i) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->tiny_magazines[i]))); - } -} - -static boolean_t -szone_locked(szone_t *szone) -{ - mag_index_t i; - int tookLock; - - tookLock = SZONE_TRY_LOCK(szone); - if (tookLock == 0) - return 1; - SZONE_UNLOCK(szone); - - for (i = -1; i < szone->num_small_magazines; ++i) { - tookLock = SZONE_MAGAZINE_PTR_TRY_LOCK(szone, (&(szone->small_magazines[i]))); - if (tookLock == 0) - return 1; - SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->small_magazines[i]))); - } - - for (i = -1; i < szone->num_tiny_magazines; ++i) { - tookLock = SZONE_MAGAZINE_PTR_TRY_LOCK(szone, (&(szone->tiny_magazines[i]))); - if (tookLock == 0) - return 1; - SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->tiny_magazines[i]))); - } - return 0; -} - -static size_t -szone_pressure_relief(szone_t *szone, size_t goal) -{ - size_t total = 0; - -#if MADVISE_PRESSURE_RELIEF - mag_index_t mag_index; - - magazine_t *tiny_depot_ptr = (&szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); - magazine_t *small_depot_ptr = (&szone->small_magazines[DEPOT_MAGAZINE_INDEX]); - - for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { - size_t index; - for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) { - SZONE_LOCK(szone); - - region_t tiny = szone->tiny_region_generation->hashed_regions[index]; - if (!tiny || tiny == HASHRING_REGION_DEALLOCATED) { - SZONE_UNLOCK(szone); - continue; - } - - magazine_t *mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, REGION_TRAILER_FOR_TINY_REGION(tiny), MAGAZINE_INDEX_FOR_TINY_REGION(tiny)); - SZONE_UNLOCK(szone); - - /* Ordering is important here, the magazine of a region may potentially change - * during mag_lock_zine_for_region_trailer, so src_mag_index must be taken - * after we've obtained the lock. - */ - mag_index_t src_mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny); - - /* We can (and must) ignore magazines that are already in the recirc depot. */ - if (src_mag_index == DEPOT_MAGAZINE_INDEX) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); - continue; - } - - if (tiny == mag_ptr->mag_last_region && (mag_ptr->mag_bytes_free_at_end || mag_ptr->mag_bytes_free_at_start)) { - tiny_finalize_region(szone, mag_ptr); - } - - /* Because this region is currently in use, we can't safely madvise it while - * it's attached to the magazine. For this operation we have to remove it from - * the current mag, attach it to the depot and then madvise. - */ - - recirc_list_extract(szone, mag_ptr, REGION_TRAILER_FOR_TINY_REGION(tiny)); - int objects_in_use = tiny_free_detach_region(szone, mag_ptr, tiny); - - SZONE_MAGAZINE_PTR_LOCK(szone, tiny_depot_ptr); - MAGAZINE_INDEX_FOR_TINY_REGION(tiny) = DEPOT_MAGAZINE_INDEX; - REGION_TRAILER_FOR_TINY_REGION(tiny)->pinned_to_depot = 0; - - size_t bytes_inplay = tiny_free_reattach_region(szone, tiny_depot_ptr, tiny); - - /* Fix up the metadata of the target magazine while the region is in the depot. */ - mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; - mag_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; - mag_ptr->mag_num_objects -= objects_in_use; - - /* Now we can drop the magazine lock of the source mag. */ - SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); - - tiny_depot_ptr->mag_num_bytes_in_objects += bytes_inplay; - tiny_depot_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; - tiny_depot_ptr->mag_num_objects -= objects_in_use; - - recirc_list_splice_last(szone, tiny_depot_ptr, REGION_TRAILER_FOR_TINY_REGION(tiny)); - - /* Actually do the scan, done holding the depot lock, the call will drop the lock - * around the actual madvise syscalls. - */ - tiny_free_scan_madvise_free(szone, tiny_depot_ptr, tiny); - - /* Now the region is in the recirc depot, the next allocations to require more - * blocks will come along and take one of these regions back out of the depot. - * As OS X madvise's reuse on an per-region basis, we leave as many of these - * regions in the depot as possible after memory pressure. - */ - SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_depot_ptr); - } - } - - for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { - size_t index; - for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) { - SZONE_LOCK(szone); - - region_t small = szone->small_region_generation->hashed_regions[index]; - if (!small || small == HASHRING_REGION_DEALLOCATED) { - SZONE_UNLOCK(szone); - continue; - } - - magazine_t *mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, REGION_TRAILER_FOR_SMALL_REGION(small), MAGAZINE_INDEX_FOR_SMALL_REGION(small)); - SZONE_UNLOCK(szone); - - /* Ordering is important here, the magazine of a region may potentially change - * during mag_lock_zine_for_region_trailer, so src_mag_index must be taken - * after we've obtained the lock. - */ - mag_index_t src_mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(small); - - /* We can (and must) ignore magazines that are already in the recirc depot. */ - if (src_mag_index == DEPOT_MAGAZINE_INDEX) { - SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); - continue; - } - - if (small == mag_ptr->mag_last_region && (mag_ptr->mag_bytes_free_at_end || mag_ptr->mag_bytes_free_at_start)) { - small_finalize_region(szone, mag_ptr); - } - - /* Because this region is currently in use, we can't safely madvise it while - * it's attached to the magazine. For this operation we have to remove it from - * the current mag, attach it to the depot and then madvise. - */ - - recirc_list_extract(szone, mag_ptr, REGION_TRAILER_FOR_SMALL_REGION(small)); - int objects_in_use = small_free_detach_region(szone, mag_ptr, small); - - SZONE_MAGAZINE_PTR_LOCK(szone, small_depot_ptr); - MAGAZINE_INDEX_FOR_SMALL_REGION(small) = DEPOT_MAGAZINE_INDEX; - REGION_TRAILER_FOR_SMALL_REGION(small)->pinned_to_depot = 0; - - size_t bytes_inplay = small_free_reattach_region(szone, small_depot_ptr, small); - - /* Fix up the metadata of the target magazine while the region is in the depot. */ - mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; - mag_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; - mag_ptr->mag_num_objects -= objects_in_use; - - /* Now we can drop the magazine lock of the source mag. */ - SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr); - - small_depot_ptr->mag_num_bytes_in_objects += bytes_inplay; - small_depot_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; - small_depot_ptr->mag_num_objects -= objects_in_use; - - recirc_list_splice_last(szone, small_depot_ptr, REGION_TRAILER_FOR_SMALL_REGION(small)); - - /* Actually do the scan, done holding the depot lock, the call will drop the lock - * around the actual madvise syscalls. - */ - small_free_scan_madvise_free(szone, small_depot_ptr, small); - - /* Now the region is in the recirc depot, the next allocations to require more - * blocks will come along and take one of these regions back out of the depot. - * As OS X madvise's reuse on an per-region basis, we leave as many of these - * regions in the depot as possible after memory pressure. - */ - SZONE_MAGAZINE_PTR_UNLOCK(szone, small_depot_ptr); - } - } -#endif - -#if LARGE_CACHE - if (szone->flotsam_enabled) { - SZONE_LOCK(szone); - - // stack allocated copy of the death-row cache - int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest; - large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE]; - - memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache)); - - szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0; - szone->large_entry_cache[0].address = 0x0; - szone->large_entry_cache[0].size = 0; - szone->large_entry_cache_bytes = 0; - szone->large_entry_cache_reserve_bytes = 0; - - szone->flotsam_enabled = FALSE; - - SZONE_UNLOCK(szone); - - // deallocate the death-row cache outside the zone lock - size_t total = 0; - while (idx != idx_max) { - deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); - total += local_entry_cache[idx].size; - if (++idx == LARGE_ENTRY_CACHE_SIZE) idx = 0; - } - if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) { - deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0); - total += local_entry_cache[idx].size; - } - } -#endif - - MAGMALLOC_PRESSURERELIEF((void *)szone, goal, total); // DTrace USDT Probe - return total; -} - -boolean_t -scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone) -{ - szone_t *szone = (szone_t *)zone; - - switch (subzone) { - case 0: - { - size_t s = 0; - unsigned t = 0; - size_t u = 0; - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; - t += szone->tiny_magazines[mag_index].mag_num_objects; - u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; - } - - stats->blocks_in_use = t; - stats->size_in_use = u; - stats->size_allocated = (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE; - stats->max_size_in_use = stats->size_allocated - s; - return 1; - } - case 1: - { - size_t s = 0; - unsigned t = 0; - size_t u = 0; - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - s += szone->small_magazines[mag_index].mag_bytes_free_at_start; - s += szone->small_magazines[mag_index].mag_bytes_free_at_end; - t += szone->small_magazines[mag_index].mag_num_objects; - u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; - } - - stats->blocks_in_use = t; - stats->size_in_use = u; - stats->size_allocated = (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE; - stats->max_size_in_use = stats->size_allocated - s; - return 1; - } - case 2: - stats->blocks_in_use = szone->num_large_objects_in_use; - stats->size_in_use = szone->num_bytes_in_large_objects; - stats->max_size_in_use = stats->size_allocated = stats->size_in_use; - return 1; - case 3: - stats->blocks_in_use = 0; // DEPRECATED szone->num_huge_entries; - stats->size_in_use = 0; // DEPRECATED szone->num_bytes_in_huge_objects; - stats->max_size_in_use = stats->size_allocated = 0; - return 1; - } - return 0; -} - -static void -szone_statistics(szone_t *szone, malloc_statistics_t *stats) -{ - size_t large; - - size_t s = 0; - unsigned t = 0; - size_t u = 0; - mag_index_t mag_index; - - for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; - s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; - t += szone->tiny_magazines[mag_index].mag_num_objects; - u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; - } - - for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { - s += szone->small_magazines[mag_index].mag_bytes_free_at_start; - s += szone->small_magazines[mag_index].mag_bytes_free_at_end; - t += szone->small_magazines[mag_index].mag_num_objects; - u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; - } - - large = szone->num_bytes_in_large_objects + 0; // DEPRECATED szone->num_bytes_in_huge_objects; - - stats->blocks_in_use = t + szone->num_large_objects_in_use + 0; // DEPRECATED szone->num_huge_entries; - stats->size_in_use = u + large; - stats->max_size_in_use = stats->size_allocated = - (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE + - (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE + large; - // Now we account for the untouched areas - stats->max_size_in_use -= s; -} - -static void * -legacy_zeroing_large_malloc(szone_t *szone, size_t size) { - if (size > LARGE_THRESHOLD) // Leopard and earlier returned a ZFOD range, so ... - return szone_calloc(szone, 1, size); // Clear to zero always, ham-handedly touching in each page - else - return szone_malloc(szone, size); -} - -static void * -legacy_zeroing_large_valloc(szone_t *szone, size_t size) { - void *p = szone_valloc(szone, size); - - // Leopard and earlier returned a ZFOD range, so ... - memset(p, 0, size); // Clear to zero always, ham-handedly touching in each page - return p; -} - -void zeroify_scalable_zone(malloc_zone_t *zone) -{ - szone_t *szone = (szone_t *)zone; - - if (szone) { - mprotect(szone, sizeof(szone->basic_zone), PROT_READ | PROT_WRITE); - szone->basic_zone.malloc = (void *)legacy_zeroing_large_malloc; - szone->basic_zone.valloc = (void *)legacy_zeroing_large_valloc; - mprotect(szone, sizeof(szone->basic_zone), PROT_READ); - } -} - -static const struct malloc_introspection_t szone_introspect = { - (void *)szone_ptr_in_use_enumerator, - (void *)szone_good_size, - (void *)szone_check, - (void *)szone_print, - szone_log, - (void *)szone_force_lock, - (void *)szone_force_unlock, - (void *)szone_statistics, - (void *)szone_locked, - NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */ -}; // marked as const to spare the DATA section - -malloc_zone_t * -create_scalable_zone(size_t initial_size, unsigned debug_flags) -{ - szone_t *szone; - uint64_t hw_memsize = 0; - -#if defined(__i386__) || defined(__x86_64__) - if (_COMM_PAGE_VERSION_REQD > (*((uint16_t *)_COMM_PAGE_VERSION))) { - malloc_printf("*** ERROR - comm page version mismatch.\n"); - exit(-1); - } -#endif - - /* get memory for the zone. */ - szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC); - if (!szone) - return NULL; - - /* set up the szone structure */ -#if 0 -#warning CHECK_REGIONS enabled - debug_flags |= CHECK_REGIONS; -#endif -#if 0 -#warning LOG enabled - szone->log_address = ~0; -#endif - szone->trg[0].nextgen = &(szone->trg[1]); - szone->trg[1].nextgen = &(szone->trg[0]); - szone->tiny_region_generation = &(szone->trg[0]); - - szone->tiny_region_generation->hashed_regions = szone->initial_tiny_regions; - szone->tiny_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS; - szone->tiny_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT; - - szone->srg[0].nextgen = &(szone->srg[1]); - szone->srg[1].nextgen = &(szone->srg[0]); - szone->small_region_generation = &(szone->srg[0]); - - szone->small_region_generation->hashed_regions = szone->initial_small_regions; - szone->small_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS; - szone->small_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT; - - - /* - * Initialize variables that size the free list for SMALL allocations based - * upon the amount of memory in the system. Switch to a larger number of - * free list entries at 1GB. - */ -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__) - if ((hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE) >= (1ULL << 30)) -#else - size_t uint64_t_size = sizeof(hw_memsize); - - if (0 == sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0) && - hw_memsize >= (1ULL << 30)) -#endif - { - szone->is_largemem = 1; - szone->num_small_slots = NUM_SMALL_SLOTS_LARGEMEM; - szone->large_threshold = LARGE_THRESHOLD_LARGEMEM; - szone->vm_copy_threshold = VM_COPY_THRESHOLD_LARGEMEM; - } else { - szone->is_largemem = 0; - szone->num_small_slots = NUM_SMALL_SLOTS; - szone->large_threshold = LARGE_THRESHOLD; - szone->vm_copy_threshold = VM_COPY_THRESHOLD; - } -#if LARGE_CACHE - szone->large_entry_cache_reserve_limit = - hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%] - - /* Reset protection when returning a previous large allocation? */ - int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System"); - if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 112) /* CFSystemVersionSnowLeopard */) - szone->large_legacy_reset_mprotect = TRUE; - else - szone->large_legacy_reset_mprotect = FALSE; -#endif - - // Prepare ASLR -#if __i386__ || __x86_64__ || __arm64__ || TARGET_OS_EMBEDDED -#if __i386__ - uintptr_t stackbase = 0x8fe00000; - int entropic_bits = 3; -#elif __x86_64__ - uintptr_t stackbase = USRSTACK64; - int entropic_bits = 16; -#elif __arm64__ - uintptr_t stackbase = USRSTACK64; - int entropic_bits = 7; -#else - uintptr_t stackbase = USRSTACK; - int entropic_bits = 3; -#endif - - // assert(((1 << entropic_bits) - 1) << SMALL_BLOCKS_ALIGN < (stackbase - MAXSSIZ - ENTROPIC_KABILLION)); - - if (0 != _dyld_get_image_slide((const struct mach_header*)_NSGetMachExecuteHeader())) { - if (0 == entropic_address) { - uintptr_t t = stackbase - MAXSSIZ - ((uintptr_t) (malloc_entropy[1] & ((1 << entropic_bits) - 1)) << SMALL_BLOCKS_ALIGN); - (void)__sync_bool_compare_and_swap(&entropic_limit, 0, t); // Just one initialization please - (void)__sync_bool_compare_and_swap(&entropic_address, 0, t - ENTROPIC_KABILLION); // Just one initialization please - } - debug_flags &= ~DISABLE_ASLR; - } else { - // zero slide when ASLR has been disabled by boot-arg. Eliminate cloaking. - malloc_entropy[0] = 0; - malloc_entropy[1] = 0; - debug_flags |= DISABLE_ASLR; - } - -#else - malloc_entropy[0] = 0; - malloc_entropy[1] = 0; - debug_flags |= DISABLE_ASLR; -#endif - - // Initialize the security token. - szone->cookie = (uintptr_t)malloc_entropy[0]; - - szone->basic_zone.version = 8; - szone->basic_zone.size = (void *)szone_size; - szone->basic_zone.malloc = (void *)szone_malloc; - szone->basic_zone.calloc = (void *)szone_calloc; - szone->basic_zone.valloc = (void *)szone_valloc; - szone->basic_zone.free = (void *)szone_free; - szone->basic_zone.realloc = (void *)szone_realloc; - szone->basic_zone.destroy = (void *)szone_destroy; - szone->basic_zone.batch_malloc = (void *)szone_batch_malloc; - szone->basic_zone.batch_free = (void *)szone_batch_free; - szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; - szone->basic_zone.memalign = (void *)szone_memalign; - szone->basic_zone.free_definite_size = (void *)szone_free_definite_size; - szone->basic_zone.pressure_relief = (void *)szone_pressure_relief; - - szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */ - szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */ - mprotect(szone, sizeof(szone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */ - - szone->debug_flags = debug_flags; - _malloc_lock_init(&szone->large_szone_lock); - -#if defined(__ppc__) || defined(__ppc64__) - /* - * In the interest of compatibility for PPC applications executing via Rosetta, - * arrange to zero-fill allocations as occurred by side effect in Leopard and earlier. - */ - zeroify_scalable_zone((malloc_zone_t *)szone); -#endif - - szone->cpu_id_key = -1UL; // Unused. - - // Query the number of configured processors. - // Uniprocessor case gets just one tiny and one small magazine (whose index is zero). This gives - // the same behavior as the original scalable malloc. MP gets per-CPU magazines - // that scale (way) better. -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__) - int nproc = *(uint8_t *)(uintptr_t)_COMM_PAGE_NCPUS; -#else - int nproc = sysconf(_SC_NPROCESSORS_CONF); -#endif - szone->num_tiny_magazines = (nproc > 1) ? MIN(nproc, TINY_MAX_MAGAZINES) : 1; - - // FIXME vm_allocate() based on number of configured CPUs - magazine_t *tiny_magazines = allocate_pages(NULL, TINY_MAGAZINE_PAGED_SIZE, 0, - SCALABLE_MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC); - if (NULL == tiny_magazines) - return NULL; - - szone->tiny_magazines = &(tiny_magazines[1]); // szone->tiny_magazines[-1] is the Depot - - // The magazines are indexed in [0 .. (num_tiny_magazines - 1)] - // Find the smallest power of 2 that exceeds (num_tiny_magazines - 1) - szone->num_tiny_magazines_mask_shift = 0; - int i = 1; - while( i <= (szone->num_tiny_magazines - 1) ) { - szone->num_tiny_magazines_mask_shift++; - i <<= 1; - } - - // Now if i <= TINY_MAX_MAGAZINES we'll never access tiny_magazines[] out of bounds. - if (i > TINY_MAX_MAGAZINES) { - malloc_printf("*** FATAL ERROR - magazine mask exceeds allocated magazines.\n"); - exit(-1); - } - - // Reduce i by 1 to obtain a mask covering [0 .. (num_tiny_magazines - 1)] - szone->num_tiny_magazines_mask = i - 1; // A mask used for hashing to a magazine index (and a safety aid) - szone->last_tiny_advise = 0; - - // Init the tiny_magazine locks - _malloc_lock_init(&szone->tiny_regions_lock); - _malloc_lock_init(&szone->tiny_magazines[DEPOT_MAGAZINE_INDEX].magazine_lock); - for (i = 0; i < szone->num_tiny_magazines; ++i) { - _malloc_lock_init(&szone->tiny_magazines[i].magazine_lock); - } - - szone->num_small_magazines = (nproc > 1) ? MIN(nproc, SMALL_MAX_MAGAZINES) : 1; - - // FIXME vm_allocate() based on number of configured CPUs - magazine_t *small_magazines = allocate_pages(NULL, SMALL_MAGAZINE_PAGED_SIZE, 0, - SCALABLE_MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC); - if (NULL == small_magazines) - return NULL; - - szone->small_magazines = &(small_magazines[1]); // szone->small_magazines[-1] is the Depot - - // The magazines are indexed in [0 .. (num_small_magazines - 1)] - // Find the smallest power of 2 that exceeds (num_small_magazines - 1) - szone->num_small_magazines_mask_shift = 0; - while( i <= (szone->num_small_magazines - 1) ) { - szone->num_small_magazines_mask_shift++; - i <<= 1; - } - - // Now if i <= SMALL_MAX_MAGAZINES we'll never access small_magazines[] out of bounds. - if (i > SMALL_MAX_MAGAZINES) { - malloc_printf("*** FATAL ERROR - magazine mask exceeds allocated magazines.\n"); - exit(-1); - } - - // Reduce i by 1 to obtain a mask covering [0 .. (num_small_magazines - 1)] - szone->num_small_magazines_mask = i - 1; // A mask used for hashing to a magazine index (and a safety aid) - szone->last_small_advise = 0; - - // Init the small_magazine locks - _malloc_lock_init(&szone->small_regions_lock); - _malloc_lock_init(&szone->small_magazines[DEPOT_MAGAZINE_INDEX].magazine_lock); - for (i = 0; i < szone->num_small_magazines; ++i) { - _malloc_lock_init(&szone->small_magazines[i].magazine_lock); - } - - CHECK(szone, __PRETTY_FUNCTION__); - return (malloc_zone_t *)szone; -} - -// -// purgeable zones have their own "large" allocation pool, but share "tiny" and "large" -// heaps with a helper_zone identified in the call to create_purgeable_zone() -// -static size_t -purgeable_size(szone_t *szone, const void *ptr) -{ - // Only claim our large allocations, leave the shared tiny/small for the helper zone to claim. - return szone_size_try_large(szone, ptr); -} - -static void * -purgeable_malloc(szone_t *szone, size_t size) { - if (size <= szone->large_threshold) - return szone_malloc(szone->helper_zone, size); - else - return szone_malloc(szone, size); -} - -static void * -purgeable_calloc(szone_t *szone, size_t num_items, size_t size) -{ - size_t total_bytes = num_items * size; - - // Check for overflow of integer multiplication - if (num_items > 1) { -#if __LP64__ /* size_t is uint64_t */ - if ((num_items | size) & 0xffffffff00000000ul) { - // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic - __uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size); - if ((uint64_t)(product >> 64)) // compiles to test on upper register of register pair - return NULL; - } -#else /* size_t is uint32_t */ - if ((num_items | size) & 0xffff0000ul) { - // num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic - uint64_t product = ((uint64_t)num_items) * ((uint64_t)size); - if ((uint32_t)(product >> 32)) // compiles to test on upper register of register pair - return NULL; - } -#endif - } - - if (total_bytes <= szone->large_threshold) - return szone_calloc(szone->helper_zone, 1, total_bytes); - else - return szone_calloc(szone, 1, total_bytes); -} - -static void * -purgeable_valloc(szone_t *szone, size_t size) -{ - if (size <= szone->large_threshold) - return szone_valloc(szone->helper_zone, size); - else - return szone_valloc(szone, size); -} - -static void -purgeable_free(szone_t *szone, void *ptr) -{ - large_entry_t *entry; - - SZONE_LOCK(szone); - entry = large_entry_for_pointer_no_lock(szone, ptr); - SZONE_UNLOCK(szone); - if (entry) { - return free_large(szone, ptr); - } else { - return szone_free(szone->helper_zone, ptr); - } -} - -static void -purgeable_free_definite_size(szone_t *szone, void *ptr, size_t size) -{ - if (size <= szone->large_threshold) - return szone_free_definite_size(szone->helper_zone, ptr, size); - else - return szone_free_definite_size(szone, ptr, size); -} - -static void * -purgeable_realloc(szone_t *szone, void *ptr, size_t new_size) -{ - size_t old_size; - - if (NULL == ptr) { - // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. - return purgeable_malloc(szone, new_size); - } else if (0 == new_size) { - // If size is 0 and ptr is not a null pointer, the object pointed to is freed. - purgeable_free(szone, ptr); - // If size is 0, either a null pointer or a unique pointer that can be successfully passed - // to free() shall be returned. - return purgeable_malloc(szone, 1); - } - - old_size = purgeable_size(szone, ptr); // Now ptr can be safely size()'d - if (!old_size) - old_size = szone_size(szone->helper_zone, ptr); - - if (!old_size) { - szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL); - return NULL; - } - - // Distinguish 4 cases: {oldsize, newsize} x { <= , > large_threshold } - // and deal with the allocation crossing from the purgeable zone to the helper zone and vice versa. - if (old_size <= szone->large_threshold) { - if (new_size <= szone->large_threshold) - return szone_realloc(szone->helper_zone, ptr, new_size); - else { - // allocation crosses from helper to purgeable zone - void * new_ptr = purgeable_malloc(szone, new_size); - if (new_ptr) { - memcpy(new_ptr, ptr, old_size); - szone_free_definite_size(szone->helper_zone, ptr, old_size); - } - return new_ptr; // in state VM_PURGABLE_NONVOLATILE - } - } else { - if (new_size <= szone->large_threshold) { - // allocation crosses from purgeable to helper zone - void * new_ptr = szone_malloc(szone->helper_zone, new_size); - if (new_ptr) { - memcpy(new_ptr, ptr, new_size); - purgeable_free_definite_size(szone, ptr, old_size); - } - return new_ptr; - } else { - void * new_ptr = purgeable_malloc(szone, new_size); - if (new_ptr) { - memcpy(new_ptr, ptr, MIN(old_size, new_size)); - purgeable_free_definite_size(szone, ptr, old_size); - } - return new_ptr; // in state VM_PURGABLE_NONVOLATILE - } - } - /* NOTREACHED */ -} - -static void -purgeable_destroy(szone_t *szone) -{ - /* destroy large entries */ - size_t index = szone->num_large_entries; - large_entry_t *large; - vm_range_t range_to_deallocate; - - while (index--) { - large = szone->large_entries + index; - if (large->address) { - // we deallocate_pages, including guard pages - deallocate_pages(szone, (void *)(large->address), large->size, szone->debug_flags); - } - } - large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate); - if (range_to_deallocate.size) - deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0); - - /* Now destroy the separate szone region */ - deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0); -} - -static unsigned -purgeable_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) -{ - return szone_batch_malloc(szone->helper_zone, size, results, count); -} - -static void -purgeable_batch_free(szone_t *szone, void **to_be_freed, unsigned count) -{ - return szone_batch_free(szone->helper_zone, to_be_freed, count); -} - -static void * -purgeable_memalign(szone_t *szone, size_t alignment, size_t size) -{ - if (size <= szone->large_threshold) - return szone_memalign(szone->helper_zone, alignment, size); - else - return szone_memalign(szone, alignment, size); + MAGMALLOC_PRESSURERELIEF((void *)szone, (int)goal, (int)total); // DTrace USDT Probe + return total; } -static kern_return_t -purgeable_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, vm_range_recorder_t recorder) +boolean_t +scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone) { - szone_t *szone; - kern_return_t err; - - if (!reader) reader = _szone_default_reader; - - err = reader(task, zone_address, sizeof(szone_t), (void **)&szone); - if (err) return err; - - err = large_in_use_enumerator(task, context, type_mask, - (vm_address_t)szone->large_entries, szone->num_large_entries, reader, recorder); - return err; -} + szone_t *szone = (szone_t *)zone; -static size_t -purgeable_good_size(szone_t *szone, size_t size) -{ - if (size <= szone->large_threshold) - return szone_good_size(szone->helper_zone, size); - else - return szone_good_size(szone, size); -} + switch (subzone) { + case 0: { + size_t s = 0; + unsigned t = 0; + size_t u = 0; + mag_index_t mag_index; -static boolean_t -purgeable_check(szone_t *szone) -{ - return 1; -} + for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { + s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; + s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; + t += szone->tiny_magazines[mag_index].mag_num_objects; + u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; + } -static void -purgeable_print(szone_t *szone, boolean_t verbose) -{ - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "Scalable zone %p: inUse=%u(%y) flags=%d\n", - szone, szone->num_large_objects_in_use, szone->num_bytes_in_large_objects, szone->debug_flags); + stats->blocks_in_use = t; + stats->size_in_use = u; + stats->size_allocated = (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE; + stats->max_size_in_use = stats->size_allocated - s; + return 1; + } + case 1: { + size_t s = 0; + unsigned t = 0; + size_t u = 0; + mag_index_t mag_index; + + for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { + s += szone->small_magazines[mag_index].mag_bytes_free_at_start; + s += szone->small_magazines[mag_index].mag_bytes_free_at_end; + t += szone->small_magazines[mag_index].mag_num_objects; + u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; + } + + stats->blocks_in_use = t; + stats->size_in_use = u; + stats->size_allocated = (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE; + stats->max_size_in_use = stats->size_allocated - s; + return 1; + } + case 2: + stats->blocks_in_use = szone->num_large_objects_in_use; + stats->size_in_use = szone->num_bytes_in_large_objects; + stats->max_size_in_use = stats->size_allocated = stats->size_in_use; + return 1; + case 3: + stats->blocks_in_use = 0; // DEPRECATED szone->num_huge_entries; + stats->size_in_use = 0; // DEPRECATED szone->num_bytes_in_huge_objects; + stats->max_size_in_use = stats->size_allocated = 0; + return 1; + } + return 0; } static void -purgeable_log(malloc_zone_t *zone, void *log_address) +szone_statistics(szone_t *szone, malloc_statistics_t *stats) { - szone_t *szone = (szone_t *)zone; - - szone->log_address = log_address; -} + size_t large; -static void -purgeable_force_lock(szone_t *szone) -{ - SZONE_LOCK(szone); -} + size_t s = 0; + unsigned t = 0; + size_t u = 0; + mag_index_t mag_index; -static void -purgeable_force_unlock(szone_t *szone) -{ - SZONE_UNLOCK(szone); -} + for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { + s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start; + s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end; + t += szone->tiny_magazines[mag_index].mag_num_objects; + u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects; + } -static void -purgeable_statistics(szone_t *szone, malloc_statistics_t *stats) -{ - stats->blocks_in_use = szone->num_large_objects_in_use; - stats->size_in_use = stats->max_size_in_use = stats->size_allocated = szone->num_bytes_in_large_objects; -} + for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { + s += szone->small_magazines[mag_index].mag_bytes_free_at_start; + s += szone->small_magazines[mag_index].mag_bytes_free_at_end; + t += szone->small_magazines[mag_index].mag_num_objects; + u += szone->small_magazines[mag_index].mag_num_bytes_in_objects; + } -static boolean_t -purgeable_locked(szone_t *szone) -{ - int tookLock; - - tookLock = SZONE_TRY_LOCK(szone); - if (tookLock == 0) - return 1; - SZONE_UNLOCK(szone); - return 0; -} + large = szone->num_bytes_in_large_objects + 0; // DEPRECATED szone->num_bytes_in_huge_objects; -static size_t -purgeable_pressure_relief(szone_t *szone, size_t goal) -{ - return szone_pressure_relief(szone, goal) + szone_pressure_relief(szone->helper_zone, goal); + stats->blocks_in_use = t + szone->num_large_objects_in_use + 0; // DEPRECATED szone->num_huge_entries; + stats->size_in_use = u + large; + stats->max_size_in_use = stats->size_allocated = + (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE + + (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE + large; + // Now we account for the untouched areas + stats->max_size_in_use -= s; } -static const struct malloc_introspection_t purgeable_introspect = { - (void *)purgeable_ptr_in_use_enumerator, - (void *)purgeable_good_size, - (void *)purgeable_check, - (void *)purgeable_print, - purgeable_log, - (void *)purgeable_force_lock, - (void *)purgeable_force_unlock, - (void *)purgeable_statistics, - (void *)purgeable_locked, - NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */ +const struct malloc_introspection_t szone_introspect = { + (void *)szone_ptr_in_use_enumerator, (void *)szone_good_size, (void *)szone_check, (void *)szone_print, szone_log, + (void *)szone_force_lock, (void *)szone_force_unlock, (void *)szone_statistics, (void *)szone_locked, NULL, NULL, NULL, + NULL, /* Zone enumeration version 7 and forward. */ + (void *)szone_reinit_lock, // reinit_lock version 9 and foward }; // marked as const to spare the DATA section -__attribute__((visibility("hidden"))) -malloc_zone_t * -create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags) +szone_t * +create_scalable_szone(size_t initial_size, unsigned debug_flags) { - szone_t *szone; - uint64_t hw_memsize = 0; - + szone_t *szone; + +#if defined(__i386__) || defined(__x86_64__) + if (_COMM_PAGE_VERSION_REQD > (*((uint16_t *)_COMM_PAGE_VERSION))) { + MALLOC_PRINTF_FATAL_ERROR((*((uint16_t *)_COMM_PAGE_VERSION)), "comm page version mismatch"); + } +#endif + /* get memory for the zone. */ szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC); - if (!szone) + if (!szone) { return NULL; - - /* set up the szone structure */ + } + +/* set up the szone structure */ +#if 0 +#warning CHECK_REGIONS enabled + debug_flags |= CHECK_REGIONS; +#endif #if 0 #warning LOG enabled szone->log_address = ~0; #endif - -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__) - hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE; -#else - size_t uint64_t_size = sizeof(hw_memsize); - - sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0); -#endif - szone->trg[0].nextgen = &(szone->trg[1]); szone->trg[1].nextgen = &(szone->trg[0]); szone->tiny_region_generation = &(szone->trg[0]); @@ -8137,252 +1799,193 @@ create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, u szone->small_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS; szone->small_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT; - /* Purgeable zone does not participate in the adaptive "largemem" sizing. */ +#if CONFIG_SMALL_CUTTOFF_127KB + szone->is_largemem = 1; + szone->num_small_slots = NUM_SMALL_SLOTS_LARGEMEM; + szone->large_threshold = LARGE_THRESHOLD_LARGEMEM; + szone->vm_copy_threshold = VM_COPY_THRESHOLD_LARGEMEM; +#else // CONFIG_SMALL_CUTTOFF_127KB szone->is_largemem = 0; + szone->num_small_slots = NUM_SMALL_SLOTS; szone->large_threshold = LARGE_THRESHOLD; szone->vm_copy_threshold = VM_COPY_THRESHOLD; - -#if LARGE_CACHE - szone->large_entry_cache_reserve_limit = - hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%] - +#endif // CONFIG_SMALL_CUTTOFF_127KB + +#if CONFIG_LARGE_CACHE + uint64_t hw_memsize = 0; + +#if CONFIG_HAS_COMMPAGE_MEMSIZE + hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE; +#else + size_t uint64_t_size = sizeof(hw_memsize); + // hw_memsize was always 0 if sysctlbyname failed, so preserve that behaviour + (void)sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0); +#endif + + // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%] + szone->large_entry_cache_reserve_limit = hw_memsize >> 10; + /* Reset protection when returning a previous large allocation? */ - int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System"); - if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 112) /* CFSystemVersionSnowLeopard */) + int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System"); + if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 112) /* CFSystemVersionSnowLeopard */) { szone->large_legacy_reset_mprotect = TRUE; - else + } else { szone->large_legacy_reset_mprotect = FALSE; + } +#endif + +// Prepare ASLR +#if __i386__ || __x86_64__ || __arm64__ || TARGET_OS_EMBEDDED +#if __i386__ + uintptr_t stackbase = 0x8fe00000; + int entropic_bits = 3; +#elif __x86_64__ + uintptr_t stackbase = USRSTACK64; + int entropic_bits = 16; +#elif __arm64__ + uintptr_t stackbase = USRSTACK64; + int entropic_bits = 7; +#else + uintptr_t stackbase = USRSTACK; + int entropic_bits = 3; +#endif + + // assert(((1 << entropic_bits) - 1) << SMALL_BLOCKS_ALIGN < (stackbase - MAXSSIZ - ENTROPIC_KABILLION)); + + if (0 != _dyld_get_image_slide((const struct mach_header *)_NSGetMachExecuteHeader())) { + if (0 == entropic_address) { + uintptr_t t = stackbase - MAXSSIZ - ((uintptr_t)(malloc_entropy[1] & ((1 << entropic_bits) - 1)) << ENTROPIC_SHIFT); + (void)__sync_bool_compare_and_swap(&entropic_limit, 0, t); // Just one initialization please + (void)__sync_bool_compare_and_swap(&entropic_address, 0, t - ENTROPIC_KABILLION); // Just one initialization please + } + debug_flags &= ~DISABLE_ASLR; + } else { + // zero slide when ASLR has been disabled by boot-arg. Eliminate cloaking. + malloc_entropy[0] = 0; + malloc_entropy[1] = 0; + debug_flags |= DISABLE_ASLR; + } + +#else + malloc_entropy[0] = 0; + malloc_entropy[1] = 0; + debug_flags |= DISABLE_ASLR; #endif - - szone->basic_zone.version = 8; - szone->basic_zone.size = (void *)purgeable_size; - szone->basic_zone.malloc = (void *)purgeable_malloc; - szone->basic_zone.calloc = (void *)purgeable_calloc; - szone->basic_zone.valloc = (void *)purgeable_valloc; - szone->basic_zone.free = (void *)purgeable_free; - szone->basic_zone.realloc = (void *)purgeable_realloc; - szone->basic_zone.destroy = (void *)purgeable_destroy; - szone->basic_zone.batch_malloc = (void *)purgeable_batch_malloc; - szone->basic_zone.batch_free = (void *)purgeable_batch_free; - szone->basic_zone.introspect = (struct malloc_introspection_t *)&purgeable_introspect; - szone->basic_zone.memalign = (void *)purgeable_memalign; - szone->basic_zone.free_definite_size = (void *)purgeable_free_definite_size; - szone->basic_zone.pressure_relief = (void *)purgeable_pressure_relief; - - szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */ - szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */ + + // Initialize the security token. + szone->cookie = (uintptr_t)malloc_entropy[0]; + + szone->basic_zone.version = 9; + szone->basic_zone.size = (void *)szone_size; + szone->basic_zone.malloc = (void *)szone_malloc; + szone->basic_zone.calloc = (void *)szone_calloc; + szone->basic_zone.valloc = (void *)szone_valloc; + szone->basic_zone.free = (void *)szone_free; + szone->basic_zone.realloc = (void *)szone_realloc; + szone->basic_zone.destroy = (void *)szone_destroy; + szone->basic_zone.batch_malloc = (void *)szone_batch_malloc; + szone->basic_zone.batch_free = (void *)szone_batch_free; + szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; + szone->basic_zone.memalign = (void *)szone_memalign; + szone->basic_zone.free_definite_size = (void *)szone_free_definite_size; + szone->basic_zone.pressure_relief = (void *)szone_pressure_relief; + + szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */ + szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */ mprotect(szone, sizeof(szone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */ - - szone->debug_flags = debug_flags | SCALABLE_MALLOC_PURGEABLE; - - /* Purgeable zone does not support SCALABLE_MALLOC_ADD_GUARD_PAGES. */ - if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) { - _malloc_printf(ASL_LEVEL_INFO, "purgeable zone does not support guard pages\n"); - szone->debug_flags &= ~SCALABLE_MALLOC_ADD_GUARD_PAGES; - } - + + szone->debug_flags = debug_flags; _malloc_lock_init(&szone->large_szone_lock); - - szone->helper_zone = (struct szone_s *)malloc_default_zone; - - CHECK(szone, __PRETTY_FUNCTION__); - return (malloc_zone_t *)szone; -} -/* - * For use by CheckFix: create a new zone whose behavior is, apart from - * the use of death-row and per-CPU magazines, that of Leopard. - */ -static NOINLINE void * -legacy_valloc(szone_t *szone, size_t size) -{ - void *ptr; - size_t num_kernel_pages; - - num_kernel_pages = round_page_quanta(size) >> vm_page_quanta_shift; - ptr = large_malloc(szone, num_kernel_pages, 0, TRUE); -#if DEBUG_MALLOC - if (LOG(szone, ptr)) - malloc_printf("legacy_valloc returned %p\n", ptr); + szone->cpu_id_key = -1UL; // Unused. + +// Query the number of configured processors. +// Uniprocessor case gets just one tiny and one small magazine (whose index is zero). This gives +// the same behavior as the original scalable malloc. MP gets per-CPU magazines +// that scale (way) better. +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__) + int nproc = *(uint8_t *)(uintptr_t)_COMM_PAGE_NCPUS; +#else + int nproc = sysconf(_SC_NPROCESSORS_CONF); #endif - return ptr; -} + szone->num_tiny_magazines = (nproc > 1) ? MIN(nproc, TINY_MAX_MAGAZINES) : 1; -__attribute__((visibility("hidden"))) -malloc_zone_t * -create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags) -{ - malloc_zone_t *mzone = create_scalable_zone(initial_size, debug_flags); - szone_t *szone = (szone_t *)mzone; - - if (!szone) + // FIXME vm_allocate() based on number of configured CPUs + magazine_t *tiny_magazines = + allocate_pages(NULL, TINY_MAGAZINE_PAGED_SIZE, 0, MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC); + if (NULL == tiny_magazines) { return NULL; - - szone->is_largemem = 0; - szone->num_small_slots = NUM_SMALL_SLOTS; - szone->large_threshold = LARGE_THRESHOLD; - szone->vm_copy_threshold = VM_COPY_THRESHOLD; - - mprotect(szone, sizeof(szone->basic_zone), PROT_READ | PROT_WRITE); - szone->basic_zone.valloc = (void *)legacy_valloc; - szone->basic_zone.free_definite_size = NULL; - mprotect(szone, sizeof(szone->basic_zone), PROT_READ); - - return mzone; -} + } -/********* Support code for emacs unexec ************/ + szone->tiny_magazines = &(tiny_magazines[1]); // szone->tiny_magazines[-1] is the Depot -/* History of freezedry version numbers: - * - * 1) Old malloc (before the scalable malloc implementation in this file - * existed). - * 2) Original freezedrying code for scalable malloc. This code was apparently - * based on the old freezedrying code and was fundamentally flawed in its - * assumption that tracking allocated memory regions was adequate to fake - * operations on freezedried memory. This doesn't work, since scalable - * malloc does not store flags in front of large page-aligned allocations. - * 3) Original szone-based freezedrying code. - * 4) Fresher malloc with tiny zone - * 5) 32/64bit compatible malloc - * 6) Metadata within 1MB and 8MB region for tiny and small - * - * No version backward compatibility is provided, but the version number does - * make it possible for malloc_jumpstart() to return an error if the application - * was freezedried with an older version of malloc. - */ -#define MALLOC_FREEZEDRY_VERSION 6 + // The magazines are indexed in [0 .. (num_tiny_magazines - 1)] + // Find the smallest power of 2 that exceeds (num_tiny_magazines - 1) + szone->num_tiny_magazines_mask_shift = 0; + int i = 1; + while (i <= (szone->num_tiny_magazines - 1)) { + szone->num_tiny_magazines_mask_shift++; + i <<= 1; + } -typedef struct { - unsigned version; - unsigned nszones; - szone_t *szones; -} malloc_frozen; + // Now if i <= TINY_MAX_MAGAZINES we'll never access tiny_magazines[] out of bounds. + if (i > TINY_MAX_MAGAZINES) { + MALLOC_PRINTF_FATAL_ERROR(i, "magazine mask exceeds allocated magazines"); + } -static void * -frozen_malloc(szone_t *zone, size_t new_size) -{ - return malloc(new_size); -} + // Reduce i by 1 to obtain a mask covering [0 .. (num_tiny_magazines - 1)] + szone->num_tiny_magazines_mask = i - 1; // A mask used for hashing to a magazine index (and a safety aid) + szone->last_tiny_advise = 0; -static void * -frozen_calloc(szone_t *zone, size_t num_items, size_t size) -{ - return calloc(num_items, size); -} + // Init the tiny_magazine locks + _malloc_lock_init(&szone->tiny_regions_lock); + _malloc_lock_init(&szone->tiny_magazines[DEPOT_MAGAZINE_INDEX].magazine_lock); + for (i = 0; i < szone->num_tiny_magazines; ++i) { + _malloc_lock_init(&szone->tiny_magazines[i].magazine_lock); + } -static void * -frozen_valloc(szone_t *zone, size_t new_size) -{ - return valloc(new_size); -} + szone->num_small_magazines = (nproc > 1) ? MIN(nproc, SMALL_MAX_MAGAZINES) : 1; -static void * -frozen_realloc(szone_t *zone, void *ptr, size_t new_size) -{ - size_t old_size = szone_size(zone, ptr); - void *new_ptr; - - if (new_size <= old_size) { - return ptr; - } - new_ptr = malloc(new_size); - if (old_size > 0) { - memcpy(new_ptr, ptr, old_size); + // FIXME vm_allocate() based on number of configured CPUs + magazine_t *small_magazines = + allocate_pages(NULL, SMALL_MAGAZINE_PAGED_SIZE, 0, MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC); + if (NULL == small_magazines) { + return NULL; } - return new_ptr; -} -static void -frozen_free(szone_t *zone, void *ptr) -{ -} + szone->small_magazines = &(small_magazines[1]); // szone->small_magazines[-1] is the Depot -static void -frozen_destroy(szone_t *zone) -{ -} + // The magazines are indexed in [0 .. (num_small_magazines - 1)] + // Find the smallest power of 2 that exceeds (num_small_magazines - 1) + szone->num_small_magazines_mask_shift = 0; + while (i <= (szone->num_small_magazines - 1)) { + szone->num_small_magazines_mask_shift++; + i <<= 1; + } -/********* Pseudo-private API for emacs unexec ************/ + // Now if i <= SMALL_MAX_MAGAZINES we'll never access small_magazines[] out of bounds. + if (i > SMALL_MAX_MAGAZINES) { + MALLOC_PRINTF_FATAL_ERROR(i, "magazine mask exceeds allocated magazines"); + } -/* - * malloc_freezedry() records all of the szones in use, so that they can be - * partially reconstituted by malloc_jumpstart(). Due to the differences - * between reconstituted memory regions and those created by the szone code, - * care is taken not to reallocate from the freezedried memory, except in the - * case of a non-growing realloc(). - * - * Due to the flexibility provided by the zone registration mechanism, it is - * impossible to implement generic freezedrying for any zone type. This code - * only handles applications that use the szone allocator, so malloc_freezedry() - * returns 0 (error) if any non-szone zones are encountered. - */ + // Reduce i by 1 to obtain a mask covering [0 .. (num_small_magazines - 1)] + szone->num_small_magazines_mask = i - 1; // A mask used for hashing to a magazine index (and a safety aid) + szone->last_small_advise = 0; -uintptr_t -malloc_freezedry(void) -{ - extern unsigned malloc_num_zones; - extern malloc_zone_t **malloc_zones; - malloc_frozen *data; - unsigned i; - - /* Allocate space in which to store the freezedry state. */ - data = (malloc_frozen *) malloc(sizeof(malloc_frozen)); - - /* Set freezedry version number so that malloc_jumpstart() can check for compatibility. */ - data->version = MALLOC_FREEZEDRY_VERSION; - - /* Allocate the array of szone pointers. */ - data->nszones = malloc_num_zones; - data->szones = (szone_t *) calloc(malloc_num_zones, sizeof(szone_t)); - - /* - * Fill in the array of szone structures. They are copied rather than - * referenced, since the originals are likely to be clobbered during malloc - * initialization. - */ - for (i = 0; i < malloc_num_zones; i++) { - if (strcmp(malloc_zones[i]->zone_name, "DefaultMallocZone")) { - /* Unknown zone type. */ - free(data->szones); - free(data); - return 0; - } - memcpy(&data->szones[i], malloc_zones[i], sizeof(szone_t)); + // Init the small_magazine locks + _malloc_lock_init(&szone->small_regions_lock); + _malloc_lock_init(&szone->small_magazines[DEPOT_MAGAZINE_INDEX].magazine_lock); + for (i = 0; i < szone->num_small_magazines; ++i) { + _malloc_lock_init(&szone->small_magazines[i].magazine_lock); } - - return((uintptr_t)data); + + CHECK(szone, __PRETTY_FUNCTION__); + return szone; } -int -malloc_jumpstart(uintptr_t cookie) -{ - malloc_frozen *data = (malloc_frozen *)cookie; - unsigned i; - - if (data->version != MALLOC_FREEZEDRY_VERSION) { - /* Unsupported freezedry version. */ - return 1; - } - - for (i = 0; i < data->nszones; i++) { - /* Set function pointers. Even the functions that stay the same must be - * set, since there are no guarantees that they will be mapped to the - * same addresses. */ - data->szones[i].basic_zone.size = (void *) szone_size; - data->szones[i].basic_zone.malloc = (void *) frozen_malloc; - data->szones[i].basic_zone.calloc = (void *) frozen_calloc; - data->szones[i].basic_zone.valloc = (void *) frozen_valloc; - data->szones[i].basic_zone.free = (void *) frozen_free; - data->szones[i].basic_zone.realloc = (void *) frozen_realloc; - data->szones[i].basic_zone.destroy = (void *) frozen_destroy; - data->szones[i].basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect; - - /* Register the freezedried zone. */ - malloc_zone_register(&data->szones[i].basic_zone); - } - - return 0; +malloc_zone_t * +create_scalable_zone(size_t initial_size, unsigned debug_flags) { + return (malloc_zone_t *) create_scalable_szone(initial_size, debug_flags); } /* vim: set noet:ts=4:sw=4:cindent: */ diff --git a/src/libmalloc/src/magazine_malloc.h b/src/libmalloc/src/magazine_malloc.h new file mode 100644 index 000000000..6ac8b1dd4 --- /dev/null +++ b/src/libmalloc/src/magazine_malloc.h @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __MAGAZINE_MALLOC_H +#define __MAGAZINE_MALLOC_H + +// MARK: magazine_malloc + +MALLOC_NOEXPORT +malloc_zone_t * +create_scalable_zone(size_t initial_size, unsigned debug_flags); + +MALLOC_NOEXPORT +szone_t * +create_scalable_szone(size_t initial_size, unsigned debug_flags); + +MALLOC_EXPORT +boolean_t +scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone); + +MALLOC_NOINLINE __printflike(5, 6) +void +szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...); + +// MARK: magazine_malloc utility functions + +MALLOC_NOEXPORT +extern const +struct malloc_introspection_t szone_introspect; + +MALLOC_NOEXPORT +void * +allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label); + +MALLOC_NOEXPORT +void * +allocate_pages_securely(szone_t *szone, size_t size, unsigned char align, int vm_page_label); + +MALLOC_NOEXPORT +void +deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags); + +MALLOC_NOEXPORT +int +madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi, uintptr_t *last); + +MALLOC_NOEXPORT +int +madvise_reuse_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t phHi); + +MALLOC_NOEXPORT +void +protect(void *address, size_t size, unsigned protection, unsigned debug_flags); + +MALLOC_NOEXPORT +void +szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count); + +MALLOC_NOEXPORT +unsigned +szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count); + +MALLOC_NOEXPORT +void * +szone_calloc(szone_t *szone, size_t num_items, size_t size); + +MALLOC_NOEXPORT +void +szone_free(szone_t *szone, void *ptr); + +MALLOC_NOEXPORT +void +szone_free_definite_size(szone_t *szone, void *ptr, size_t size); + +MALLOC_NOEXPORT +size_t +szone_good_size(szone_t *szone, size_t size); + +MALLOC_NOEXPORT +void * +szone_malloc(szone_t *szone, size_t size); + +MALLOC_NOEXPORT +void * +szone_memalign(szone_t *szone, size_t alignment, size_t size); + +MALLOC_NOEXPORT +size_t +szone_pressure_relief(szone_t *szone, size_t goal); + +MALLOC_NOEXPORT +void * +szone_realloc(szone_t *szone, void *ptr, size_t new_size); + +MALLOC_NOEXPORT +size_t +szone_size(szone_t *szone, const void *ptr); + +MALLOC_NOEXPORT +size_t +szone_size_try_large(szone_t *szone, const void *ptr); + +MALLOC_NOEXPORT +void * +szone_valloc(szone_t *szone, size_t size); + +// MARK: tiny region allocator functions + +MALLOC_NOEXPORT +boolean_t +tiny_check_region(szone_t *szone, region_t region); + +MALLOC_NOEXPORT +void +tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr); + +MALLOC_NOEXPORT +int +tiny_free_detach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r); + +MALLOC_NOEXPORT +boolean_t +tiny_free_list_check(szone_t *szone, grain_t slot); + +MALLOC_NOEXPORT +boolean_t +tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize); + +MALLOC_NOEXPORT +size_t +tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r); + +MALLOC_NOEXPORT +void +tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r); + +MALLOC_NOEXPORT +kern_return_t +tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, + vm_range_recorder_t recorder); + +MALLOC_NOEXPORT +void * +tiny_malloc_from_free_list(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize); + +MALLOC_NOEXPORT +void * +tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested); + +MALLOC_NOEXPORT +void * +tiny_memalign(szone_t *szone, size_t alignment, size_t size, size_t span); + +MALLOC_NOEXPORT +void * +tiny_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size); + +MALLOC_NOEXPORT +boolean_t +tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size); + +MALLOC_NOEXPORT +void +free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size); + +MALLOC_NOEXPORT +void +print_tiny_free_list(szone_t *szone); + +MALLOC_NOEXPORT +void +print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end); + +// MARK: small region allocation functions + +MALLOC_NOEXPORT +boolean_t +small_check_region(szone_t *szone, region_t region); + +MALLOC_NOEXPORT +void +small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr); + +MALLOC_NOEXPORT +int +small_free_detach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r); + +MALLOC_NOEXPORT +boolean_t +small_free_list_check(szone_t *szone, grain_t slot); + +MALLOC_NOEXPORT +size_t +small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r); + +MALLOC_NOEXPORT +void +small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r); + +MALLOC_NOEXPORT +kern_return_t +small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, + vm_range_recorder_t recorder); + +MALLOC_NOEXPORT +void * +small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested); + +MALLOC_NOEXPORT +void * +small_memalign(szone_t *szone, size_t alignment, size_t size, size_t span); + +MALLOC_NOEXPORT +void * +small_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size); + +MALLOC_NOEXPORT +boolean_t +small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size); + +MALLOC_NOEXPORT +void +free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size); + +MALLOC_NOEXPORT +void +print_small_free_list(szone_t *szone); + +MALLOC_NOEXPORT +void +print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end); + +// MARK: large region allocator functions + +MALLOC_NOEXPORT +void +free_large(szone_t *szone, void *ptr); + +MALLOC_NOEXPORT +void +large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate); + +MALLOC_NOEXPORT +large_entry_t * +large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr); + +MALLOC_NOEXPORT +kern_return_t +large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, unsigned num_entries, + memory_reader_t reader, vm_range_recorder_t recorder); + +MALLOC_NOEXPORT +int +large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size); + +MALLOC_NOEXPORT +void * +large_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size); + +MALLOC_NOEXPORT +void * +large_malloc(szone_t *szone, size_t num_kernel_pages, unsigned char alignment, boolean_t cleared_requested); + +MALLOC_NOEXPORT +void * +szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested); + +// MARK: stack logging lite functionality + +#define MALLOC_STOCK_LOGGING_LITE_ZONE_NAME "MallocStackLoggingLiteZone" + +MALLOC_NOEXPORT +void +enable_stack_logging_lite(); + +MALLOC_NOEXPORT +void +disable_stack_logging_lite(); + +MALLOC_NOEXPORT +malloc_zone_t * +create_stack_logging_lite_zone(size_t initial_size, malloc_zone_t *helper_zone, unsigned debug_flags); + +#endif // __MAGAZINE_MALLOC_H diff --git a/src/libmalloc/src/magazine_small.c b/src/libmalloc/src/magazine_small.c new file mode 100644 index 000000000..820a6cf9c --- /dev/null +++ b/src/libmalloc/src/magazine_small.c @@ -0,0 +1,2116 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "internal.h" + +/********************* SMALL FREE LIST UTILITIES ************************/ + +#pragma mark meta header helpers + +/* + * Mark a block as free. Only the first quantum of a block is marked thusly, + * the remainder are marked "middle". + */ +static MALLOC_INLINE void +small_meta_header_set_is_free(msize_t *meta_headers, msize_t index, msize_t msize) +{ + meta_headers[index] = msize | SMALL_IS_FREE; +} + +/* + * Mark a block as in use. Only the first quantum of a block is marked thusly, + * the remainder are marked "middle". + */ +static MALLOC_INLINE void +small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) +{ + meta_headers[index] = msize; +} + +/* + * Mark a quantum as being the second or later in a block. + */ +static MALLOC_INLINE void +small_meta_header_set_middle(msize_t *meta_headers, msize_t index) +{ + meta_headers[index] = 0; +} + +#pragma mark in-place free list + +static MALLOC_INLINE void +small_inplace_checksum_ptr(szone_t *szone, inplace_linkage_s *linkage, void *ptr) +{ + uintptr_t checksum = free_list_gen_checksum((uintptr_t)ptr ^ szone->cookie ^ (uintptr_t)szone); + linkage->checksum = checksum; + linkage->ptr = ptr; +} + +static MALLOC_INLINE free_list_t +small_inplace_unchecksum_ptr(szone_t *szone, inplace_linkage_s *linkage) +{ + if (linkage->checksum != free_list_gen_checksum((uintptr_t)linkage->ptr ^ szone->cookie ^ (uintptr_t)szone)) { + free_list_checksum_botch(szone, linkage); + __builtin_trap(); + } + + return (free_list_t){ .p = linkage->ptr }; +} + +static MALLOC_INLINE free_list_t +small_inplace_free_entry_get_previous(szone_t *szone, small_inplace_free_entry_t ptr) +{ + return small_inplace_unchecksum_ptr(szone, &ptr->previous); +} + +static MALLOC_INLINE void +small_inplace_free_entry_set_previous(szone_t *szone, small_inplace_free_entry_t entry, free_list_t previous) +{ + small_inplace_checksum_ptr(szone, &entry->previous, previous.p); +} + +static MALLOC_INLINE free_list_t +small_inplace_free_entry_get_next(szone_t *szone, small_inplace_free_entry_t ptr) +{ + return small_inplace_unchecksum_ptr(szone, &ptr->next); +} + +static MALLOC_INLINE void +small_inplace_free_entry_set_next(szone_t *szone, small_inplace_free_entry_t entry, free_list_t next) +{ + small_inplace_checksum_ptr(szone, &entry->next, next.p); +} + +#pragma mark OOB free list + +// Returns true if the address and size of the free list entry would result +// in the free entry being the only data on a given page. +static MALLOC_INLINE boolean_t +small_needs_oob_free_entry(void *ptr, msize_t msize) +{ + return ((trunc_page_quanta((uintptr_t)ptr) == (uintptr_t)ptr) && (SMALL_BYTES_FOR_MSIZE(msize) >= vm_kernel_page_size)); +} + +// Returns true if the address given lies within the region's OOB free +// list entries, rather than a free_list_t in the region's heap space. +static MALLOC_INLINE boolean_t +small_is_oob_free_entry(free_list_t ptr) +{ + small_region_t region = SMALL_REGION_FOR_PTR(ptr.p); + return (((uintptr_t)ptr.p >= (uintptr_t)®ion->small_oob_free_entries[0]) && + ((uintptr_t)ptr.p < (uintptr_t)®ion->small_oob_free_entries[SMALL_OOB_COUNT])); +} + +static MALLOC_INLINE void +small_oob_free_entry_set_previous(oob_free_entry_t oobe, free_list_t previous) +{ + oobe->prev = (uintptr_t)previous.p; +} + +static MALLOC_INLINE free_list_t +small_oob_free_entry_get_previous(oob_free_entry_t oobe) +{ + return (free_list_t){ .p = (void *)oobe->prev }; +} + +static MALLOC_INLINE void +small_oob_free_entry_set_next(oob_free_entry_t oobe, free_list_t next) +{ + oobe->next = (uintptr_t)next.p; +} + +static MALLOC_INLINE free_list_t +small_oob_free_entry_get_next(oob_free_entry_t oobe) +{ + return (free_list_t){ .p = (void *)oobe->next }; +} + +static MALLOC_INLINE void * +small_oob_free_entry_get_ptr(oob_free_entry_t oobe) +{ + small_region_t region = SMALL_REGION_FOR_PTR(oobe); + uint16_t block = oobe->ptr & ~SMALL_IS_OOB; + return (void *)((uintptr_t)region + (block << SHIFT_SMALL_QUANTUM)); +} + +static MALLOC_INLINE void * +small_oob_free_entry_set_ptr(oob_free_entry_t oobe, void *ptr) +{ + oobe->ptr = SMALL_IS_OOB | (SMALL_OFFSET_FOR_PTR(ptr) >> SHIFT_SMALL_QUANTUM); +} + +static MALLOC_INLINE void * +small_oob_free_entry_set_free(oob_free_entry_t oobe) +{ + oobe->prev = ~0; + oobe->next = ~0; + oobe->ptr = 0; +} + +// Finds the first unused OOB free list entry in the pointer's region. +// Returns NULL if all of the OOB entries are used. +static MALLOC_INLINE oob_free_entry_t +small_oob_free_find_empty(void *ptr, msize_t msize) +{ + small_region_t region = SMALL_REGION_FOR_PTR(ptr); + + // There are 61 of these entries at the end of a small region. + // If this changes, then a linear search through the list may + // become an unsuitable choice. + for (int i=0; i < SMALL_OOB_COUNT; i++) { + if (region->small_oob_free_entries[i].ptr == 0) { + return ®ion->small_oob_free_entries[i]; + } + } + +#if DEBUG_MALLOC + malloc_printf("used all slots of OOB entries\n"); +#endif + return NULL; +} + +static MALLOC_INLINE oob_free_entry_t +small_oob_free_find_ptr(void *ptr, msize_t msize) +{ + small_region_t region = SMALL_REGION_FOR_PTR(ptr); + + // There are 61 of these entries at the end of a small region. + // If this changes, then a linear search through the list may + // become an unsuitable choice. + for (int i=0; i < SMALL_OOB_COUNT; i++) { + if (small_oob_free_entry_get_ptr(®ion->small_oob_free_entries[i]) == ptr) { + return ®ion->small_oob_free_entries[i]; + } + } + + return NULL; +} + +#pragma mark generic free list + +static MALLOC_INLINE void +small_free_list_set_previous(szone_t *szone, free_list_t entry, free_list_t previous) +{ + if (small_is_oob_free_entry(entry)) { + small_oob_free_entry_set_previous(entry.oob, previous); + } else { + small_inplace_free_entry_set_previous(szone, entry.small_inplace, previous); + } +} + +static MALLOC_INLINE free_list_t +small_free_list_get_previous(szone_t *szone, free_list_t ptr) +{ + MALLOC_ASSERT(ptr.p); + if (small_is_oob_free_entry(ptr)) { + return small_oob_free_entry_get_previous(ptr.oob); + } else { + return small_inplace_free_entry_get_previous(szone, ptr.small_inplace); + } +} + +static MALLOC_INLINE void +small_free_list_set_next(szone_t *szone, free_list_t entry, free_list_t next) +{ + if (small_is_oob_free_entry(entry)) { + small_oob_free_entry_set_next(entry.oob, next); + } else { + small_inplace_free_entry_set_next(szone, entry.small_inplace, next); + } +} + +static MALLOC_INLINE free_list_t +small_free_list_get_next(szone_t *szone, free_list_t ptr) +{ + MALLOC_ASSERT(ptr.p); + if (small_is_oob_free_entry(ptr)) { + return small_oob_free_entry_get_next(ptr.oob); + } else { + return small_inplace_free_entry_get_next(szone, ptr.small_inplace); + } +} + +static MALLOC_INLINE void * +small_free_list_get_ptr(szone_t *szone, free_list_t ptr) +{ + if (!ptr.p) { + return NULL; + } else if (small_is_oob_free_entry(ptr)) { + return small_oob_free_entry_get_ptr(ptr.oob); + } else { + return (void *)ptr.p; + } +} + +// Returns a free_list_t that is either inline or not based on the +// pointer and msize. +static MALLOC_INLINE free_list_t +small_free_list_from_ptr(szone_t *szone, void *ptr, msize_t msize) +{ + MALLOC_ASSERT(msize); + + // The default is to put the free_list_t in the memory that + // the pointer leads to. + free_list_t entry; + entry.p = ptr; + + // If the pointer is page aligned, and the msize is greater + // than a whole page, then we try and put the entry in + // the out-of-band area instead. + if (small_needs_oob_free_entry(ptr, msize)) { + oob_free_entry_t oobe = small_oob_free_find_empty(ptr, msize); + if (oobe) { + small_oob_free_entry_set_ptr(oobe, ptr); + entry.oob = oobe; + } + } + + return entry; +} + +static MALLOC_INLINE void +small_free_mark_free(szone_t *szone, free_list_t entry, msize_t msize) +{ + // Marks both the start and end block of a free-list entry as free. + void *ptr = small_free_list_get_ptr(szone, entry); + msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); + uintptr_t start_index = SMALL_META_INDEX_FOR_PTR(ptr); + uintptr_t end_index = SMALL_META_INDEX_FOR_PTR(ptr + SMALL_BYTES_FOR_MSIZE(msize) - 1); + MALLOC_ASSERT(start_index <= end_index); + + small_meta_header_set_is_free(meta_headers, start_index, msize); + small_meta_header_set_is_free(meta_headers, end_index, msize); +} + +static MALLOC_INLINE void +small_free_mark_unfree(szone_t *szone, free_list_t entry, msize_t msize) +{ + // Marks both the start and end block of a free-list entry as "middle" (unfree). + void *ptr = small_free_list_get_ptr(szone, entry); + msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); + uintptr_t start_index = SMALL_META_INDEX_FOR_PTR(ptr); + uintptr_t end_index = SMALL_META_INDEX_FOR_PTR(ptr + SMALL_BYTES_FOR_MSIZE(msize) - 1); + MALLOC_ASSERT(start_index <= end_index); + + small_meta_header_set_middle(meta_headers, start_index); + small_meta_header_set_middle(meta_headers, end_index); +} + +static MALLOC_INLINE unsigned int +small_free_list_count(szone_t *szone, free_list_t ptr) +{ + unsigned int count = 0; + while (ptr.p) { + count++; + ptr = small_free_list_get_next(szone, ptr); + } + return count; +} + +/* + * Adds an item to the proper free list, and also marks the meta-header of the + * block properly. + * Assumes szone has been locked + */ +static free_list_t +small_free_list_add_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize) +{ + grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; + free_list_t free_head = small_mag_ptr->mag_free_list[slot]; + + // This will either return the free_list_t for the current pointer, or attempt + // to reserve an OOB entry for us. + free_list_t free_ptr = small_free_list_from_ptr(szone, ptr, msize); + +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); + } + if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { + szone_error(szone, 1, "small_free_list_add_ptr: Unaligned ptr", ptr, NULL); + } +#endif + + small_free_list_set_previous(szone, free_ptr, (free_list_t){ .p = NULL }); + small_free_list_set_next(szone, free_ptr, free_head); + + // Set the start and end blocks of the meta header as "free". Marking the last block + // allows coalescing the regions when we free adjacent regions. + small_free_mark_free(szone, free_ptr, msize); + + if (small_free_list_get_ptr(szone, free_head)) { +#if DEBUG_MALLOC + if (small_free_list_get_previous(szone, free_head)) { + szone_error(szone, 1, "small_free_list_add_ptr: Internal invariant broken (free_head->previous != NULL)", ptr, + "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, (void *)free_head, free_head->previous.p); + } + if (!SMALL_PTR_IS_FREE(small_free_list_get_ptr(szone, free_head))) { + szone_error(szone, 1, "small_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, + "ptr=%p slot=%d free_head=%p\n", ptr, slot, (void *)small_free_list_get_ptr(szone, free_head)); + } +#endif + small_free_list_set_previous(szone, free_head, free_ptr); + } else { + BITMAPN_SET(small_mag_ptr->mag_bitmap, slot); + } + + small_mag_ptr->mag_free_list[slot] = free_ptr; + return free_ptr; +} + +/* + * Removes the item pointed to by ptr in the proper free list. + * Assumes szone has been locked + */ +static void +small_free_list_remove_ptr_no_clear(szone_t *szone, magazine_t *small_mag_ptr, free_list_t entry, msize_t msize) +{ + grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; + free_list_t next, previous; + +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); + } +#endif + + previous = small_free_list_get_previous(szone, entry); + next = small_free_list_get_next(szone, entry); + + if (!small_free_list_get_ptr(szone, previous)) { + // The block to remove is the head of the free list +#if DEBUG_MALLOC + if (small_mag_ptr->mag_free_list[slot] != ptr) { + szone_error(szone, 1, "small_free_list_remove_ptr: Internal invariant broken (small_mag_ptr->mag_free_list[slot])", ptr, + "ptr=%p slot=%d msize=%d small_mag_ptr->mag_free_list[slot]=%p\n", ptr, slot, msize, + (void *)small_mag_ptr->mag_free_list[slot]); + return; + } +#endif + small_mag_ptr->mag_free_list[slot] = next; + if (!small_free_list_get_ptr(szone, next)) { + BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot); + } + } else { + small_free_list_set_next(szone, previous, next); + } + + if (small_free_list_get_ptr(szone, next)) { + small_free_list_set_previous(szone, next, previous); + } + + if (small_is_oob_free_entry(entry)) { + small_oob_free_entry_set_free(entry.oob); + } +} + +static void +small_free_list_remove_ptr(szone_t *szone, magazine_t *small_mag_ptr, free_list_t entry, msize_t msize) +{ + // In the general case we want to ensure we marked these entries as "middle" + // while we are in this function. However, when we're moving free list entries + // from/to the recirc depot we rely on the metadata bits being intact to + // reconstruct the free list. In that case we have to be able to skip this + // metadata manipulation. + small_free_mark_unfree(szone, entry, msize); + small_free_list_remove_ptr_no_clear(szone, small_mag_ptr, entry, msize); +} + +// Find a free list entry by its pointer address. This should only really be used +// by small_finalize_region, or similar, where the free_list_t entry of a known +// pointer is desired. Otherwise it is cheaper to always pull off the free lists. +static free_list_t +small_free_list_find_by_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize) +{ + if (*SMALL_METADATA_FOR_PTR(ptr) == (SMALL_IS_FREE | msize)) { + // If the block is marked free, and of size `msize`, then we first must check + // if the alignment+size is such that we could have use an OOB-entry. + if (small_needs_oob_free_entry(ptr, msize)) { + // Scan the OOB entries looking for this address. + small_region_t region = SMALL_REGION_FOR_PTR(ptr); + for (int i=0; ismall_oob_free_entries[i].ptr) { + continue; + } + if (small_oob_free_entry_get_ptr(®ion->small_oob_free_entries[i]) == ptr) { + return (free_list_t){ .oob = ®ion->small_oob_free_entries[i] }; + } + } + } + + // Otherwise, the freed pointer will be in place. + return (free_list_t){ .p = ptr }; + } + + szone_error(szone, 1, "small_free_list_find_by_ptr: ptr is not free (ptr metadata !SMALL_IS_FREE)", ptr, + "ptr=%p msize=%d metadata=0x%x", ptr, msize, *SMALL_METADATA_FOR_PTR(ptr)); +} + +void +small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr) +{ + void *last_block, *previous_block; + msize_t last_msize, previous_msize, last_index; + free_list_t previous; + + // It is possible that the block prior to the last block in the region has + // been free'd, but was not coalesced with the free bytes at the end of the + // block, since we treat the bytes at the end of the region as "in use" in + // the meta headers. Attempt to coalesce the last block with the previous + // block, so we don't violate the "no consecutive free blocks" invariant. + // + // FIXME: If we could calculate the previous small free size in the same + // manner as tiny_previous_preceding_free, it would eliminate the + // index & previous msize checks, which are a guard against reading + // bogus data out of in-use or written-on-freed memory. + // + // FIXME: Need to investigate how much work would be required to increase + // 'mag_bytes_free_at_end' when freeing the preceding block, rather + // than performing this workaround. + // + if (small_mag_ptr->mag_bytes_free_at_end) { + last_block = SMALL_REGION_END(small_mag_ptr->mag_last_region) - small_mag_ptr->mag_bytes_free_at_end; + last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end); + + last_index = SMALL_META_INDEX_FOR_PTR(last_block); + previous_msize = SMALL_PREVIOUS_MSIZE(last_block); + + if (last_index && (previous_msize <= last_index)) { + previous_block = (void *)((uintptr_t)last_block - SMALL_BYTES_FOR_MSIZE(previous_msize)); + + if (SMALL_PTR_IS_FREE(previous_block)) { + previous = small_free_list_find_by_ptr(szone, small_mag_ptr, previous_block, previous_msize); + small_free_list_remove_ptr(szone, small_mag_ptr, previous, previous_msize); + last_block = previous_block; + last_msize += previous_msize; + } + } + + // splice last_block into the free list + small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize); + small_mag_ptr->mag_bytes_free_at_end = 0; + } + +#if CONFIG_ASLR_INTERNAL + free_list_t next; + + if (small_mag_ptr->mag_bytes_free_at_start) { + last_block = SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region); + last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start); + + void *next_block = (void *)((uintptr_t)last_block + small_mag_ptr->mag_bytes_free_at_start); + if (SMALL_PTR_IS_FREE(next_block)) { + msize_t next_msize = SMALL_PTR_SIZE(next_block); + next = small_free_list_find_by_ptr(szone, small_mag_ptr, next_block, next_msize); + small_free_list_remove_ptr(szone, small_mag_ptr, next, next_msize); + last_msize += next_msize; + } + + // splice last_block into the free list + small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize); + small_mag_ptr->mag_bytes_free_at_start = 0; + } +#endif + + // TODO: Will we ever need to coalesce the blocks at the beginning and end when we finalize? + small_mag_ptr->mag_last_region = NULL; +} + +int +small_free_detach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r) +{ + unsigned char *ptr = SMALL_REGION_ADDRESS(r); + msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); + uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); + uintptr_t current = start; + uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); + int total_alloc = 0; + + while (current < limit) { + unsigned index = SMALL_META_INDEX_FOR_PTR(current); + msize_t msize_and_free = meta_headers[index]; + boolean_t is_free = msize_and_free & SMALL_IS_FREE; + msize_t msize = msize_and_free & ~SMALL_IS_FREE; + + if (!msize) { +#if DEBUG_MALLOC + boolean_t is_free = msize_and_free & SMALL_IS_FREE; + malloc_printf("*** small_free_detach_region error with %p: msize=%d is_free =%d\n", (void *)current, msize, is_free); +#endif + break; + } + + if (is_free) { + free_list_t entry = small_free_list_find_by_ptr(szone, small_mag_ptr, (void *)current, msize); + small_free_list_remove_ptr_no_clear(szone, small_mag_ptr, entry, msize); + } else { + total_alloc++; + } + current += SMALL_BYTES_FOR_MSIZE(msize); + } + return total_alloc; +} + +size_t +small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r) +{ + unsigned char *ptr = SMALL_REGION_ADDRESS(r); + msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); + uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); + uintptr_t current = start; + uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); + size_t total_alloc = 0; + + while (current < limit) { + unsigned index = SMALL_META_INDEX_FOR_PTR(current); + msize_t msize_and_free = meta_headers[index]; + boolean_t is_free = msize_and_free & SMALL_IS_FREE; + msize_t msize = msize_and_free & ~SMALL_IS_FREE; + + if (!msize) { +#if DEBUG_MALLOC + malloc_printf("*** small_free_reattach_region error with %p: msize=%d is_free =%d\n", (void *)current, msize, is_free); +#endif + break; + } + if (is_free) { + small_free_list_add_ptr(szone, small_mag_ptr, (void *)current, msize); + } else { + total_alloc += SMALL_BYTES_FOR_MSIZE(msize); + } + current += SMALL_BYTES_FOR_MSIZE(msize); + } + return total_alloc; +} + +typedef struct { + uint16_t pnum, size; +} small_pg_pair_t; + +void +small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) +{ + uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r); + uintptr_t current = start; + uintptr_t limit = (uintptr_t)SMALL_REGION_END(r); + msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(start); + small_pg_pair_t advisory[((SMALL_REGION_PAYLOAD_BYTES + vm_kernel_page_size - 1) >> vm_kernel_page_shift) >> + 1]; // 4096bytes stack allocated + int advisories = 0; + + // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list + // management data. + while (current < limit) { + unsigned index = SMALL_META_INDEX_FOR_PTR(current); + msize_t msize_and_free = meta_headers[index]; + boolean_t is_free = msize_and_free & SMALL_IS_FREE; + msize_t msize = msize_and_free & ~SMALL_IS_FREE; + + if (is_free && !msize && (current == start)) { +#if DEBUG_MALLOC + // first block is all free + malloc_printf("*** small_free_scan_madvise_free first block is all free! %p: msize=%d is_free =%d\n", (void *)current, + msize, is_free); +#endif + uintptr_t pgLo = round_page_kernel(start + sizeof(free_list_t) + sizeof(msize_t)); + uintptr_t pgHi = trunc_page_kernel(start + SMALL_REGION_SIZE - sizeof(msize_t)); + + if (pgLo < pgHi) { + advisory[advisories].pnum = (pgLo - start) >> vm_kernel_page_shift; + advisory[advisories].size = (pgHi - pgLo) >> vm_kernel_page_shift; + advisories++; + } + break; + } + if (!msize) { +#if DEBUG_MALLOC + malloc_printf( + "*** small_free_scan_madvise_free error with %p: msize=%d is_free =%d\n", (void *)current, msize, is_free); +#endif + break; + } + if (is_free) { + uintptr_t pgLo = round_page_kernel(current + sizeof(free_list_t) + sizeof(msize_t)); + uintptr_t pgHi = trunc_page_kernel(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); + + if (pgLo < pgHi) { + advisory[advisories].pnum = (pgLo - start) >> vm_kernel_page_shift; + advisory[advisories].size = (pgHi - pgLo) >> vm_kernel_page_shift; + advisories++; + } + } + current += SMALL_BYTES_FOR_MSIZE(msize); + } + + if (advisories > 0) { + int i; + + OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot)); + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + for (i = 0; i < advisories; ++i) { + uintptr_t addr = (advisory[i].pnum << vm_page_quanta_shift) + start; + size_t size = advisory[i].size << vm_page_quanta_shift; + + madvise_free_range(szone, r, addr, addr + size, NULL); + } + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot)); + } +} + +static region_t +small_find_msize_region(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) +{ + void *ptr; + grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; + free_list_t *free_list = small_mag_ptr->mag_free_list; + free_list_t *the_slot = free_list + slot; + free_list_t *limit; + unsigned bitmap; + + // Assumes we've locked the magazine + CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); + + // Look for an exact match by checking the freelist for this msize. + ptr = small_free_list_get_ptr(szone, *the_slot); + if (ptr) { + return SMALL_REGION_FOR_PTR(ptr); + } + + // Mask off the bits representing slots holding free blocks smaller than + // the size we need. + if (szone->is_largemem) { + // BITMAPN_CTZ implementation + unsigned idx = slot >> 5; + bitmap = 0; + unsigned mask = ~((1 << (slot & 31)) - 1); + for (; idx < SMALL_BITMAP_WORDS; ++idx) { + bitmap = small_mag_ptr->mag_bitmap[idx] & mask; + if (bitmap != 0) { + break; + } + mask = ~0U; + } + // Check for fallthrough: No bits set in bitmap + if ((bitmap == 0) && (idx == SMALL_BITMAP_WORDS)) { + return NULL; + } + + // Start looking at the first set bit, plus 32 bits for every word of + // zeroes or entries that were too small. + slot = BITMAP32_CTZ((&bitmap)) + (idx * 32); + } else { + bitmap = small_mag_ptr->mag_bitmap[0] & ~((1 << slot) - 1); + if (!bitmap) { + return NULL; + } + + slot = BITMAP32_CTZ((&bitmap)); + } + limit = free_list + szone->num_small_slots - 1; + free_list += slot; + + if (free_list < limit) { + ptr = small_free_list_get_ptr(szone, *free_list); + if (ptr) { + return SMALL_REGION_FOR_PTR(ptr); + } else { + /* Shouldn't happen. Fall through to look at last slot. */ +#if DEBUG_MALLOC + malloc_printf("in small_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n", slot); +#endif + } + } + + // We are now looking at the last slot, which contains blocks equal to, or + // due to coalescing of free blocks, larger than (num_small_slots - 1) * (small quantum size). + ptr = small_free_list_get_ptr(szone, *limit); + if (ptr) { + return SMALL_REGION_FOR_PTR(ptr); + } + + return NULL; +} + +static boolean_t +small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) +{ + magazine_t *depot_ptr = &(szone->small_magazines[DEPOT_MAGAZINE_INDEX]); + + /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ + if (szone->num_small_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary + return 0; + } + +#if DEBUG_MALLOC + if (DEPOT_MAGAZINE_INDEX == mag_index) { + szone_error(szone, 1, "small_get_region_from_depot called for magazine index -1", NULL, NULL); + return 0; + } +#endif + + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + + // Appropriate a Depot'd region that can satisfy requested msize. + region_trailer_t *node; + region_t sparse_region; + + while (1) { + sparse_region = small_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); + if (NULL == sparse_region) { // Depot empty? + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + return 0; + } + + node = REGION_TRAILER_FOR_SMALL_REGION(sparse_region); + if (0 >= node->pinned_to_depot) { + break; + } + + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + yield(); + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + } + + // disconnect node from Depot + recirc_list_extract(szone, depot_ptr, node); + + // Iterate the region pulling its free entries off the (locked) Depot's free list + int objects_in_use = small_free_detach_region(szone, depot_ptr, sparse_region); + + // Transfer ownership of the region + MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = mag_index; + node->pinned_to_depot = 0; + + // Iterate the region putting its free entries on its new (locked) magazine's free list + size_t bytes_inplay = small_free_reattach_region(szone, small_mag_ptr, sparse_region); + + depot_ptr->mag_num_bytes_in_objects -= bytes_inplay; + depot_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; + depot_ptr->mag_num_objects -= objects_in_use; + + small_mag_ptr->mag_num_bytes_in_objects += bytes_inplay; + small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; + small_mag_ptr->mag_num_objects += objects_in_use; + + // connect to magazine as first node + recirc_list_splice_first(szone, small_mag_ptr, node); + + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + + // madvise() outside the Depot lock + (void)madvise_reuse_range( + szone, sparse_region, (uintptr_t)sparse_region, (uintptr_t)sparse_region + SMALL_REGION_PAYLOAD_BYTES); + + MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE, + (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe + + return 1; +} + +#if CONFIG_AGGRESSIVE_MADVISE || CONFIG_RECIRC_DEPOT +static MALLOC_INLINE void +small_madvise_free_range_no_lock(szone_t *szone, + magazine_t *small_mag_ptr, + region_t region, + free_list_t freee, + msize_t fmsize, + void *headptr, + size_t headsize) +{ + void *ptr = small_free_list_get_ptr(szone, freee); + region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(region); + + // Lock on small_magazines[mag_index] is already held here. + // Calculate the first page in the coalesced block that would be safe to mark MADV_FREE + size_t free_header_size = sizeof(free_list_t) + sizeof(msize_t); + + // If the free_list_t entry is out-of-line then we don't need to reserve any space + // at the start of the region. + if (small_is_oob_free_entry(freee)) { + free_header_size = 0; + } + + uintptr_t safe_ptr = (uintptr_t)ptr + free_header_size; + uintptr_t round_safe = round_page_kernel(safe_ptr); + + // Calculate the last page in the coalesced block that would be safe to mark MADV_FREE + uintptr_t safe_extent = (uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(fmsize); + uintptr_t trunc_extent = trunc_page_kernel(safe_extent); + + // The newly freed block may complete a span of bytes that cover one or more pages. Mark the span with MADV_FREE. + if (round_safe < trunc_extent) { // Coalesced area covers a page (perhaps many) + // Extend the freed block by the free region header and tail sizes to include pages + // we may have coalesced that no longer host free region tails and headers. + // This may extend over in-use ranges, but the MIN/MAX clamping below will fix that up. + uintptr_t lo = trunc_page_kernel((uintptr_t)headptr); + uintptr_t hi = round_page_kernel((uintptr_t)headptr + headsize + free_header_size); + + uintptr_t free_lo = MAX(round_safe, lo); + uintptr_t free_hi = MIN(trunc_extent, hi); + + if (free_lo < free_hi) { + small_free_list_remove_ptr(szone, small_mag_ptr, freee, fmsize); + OSAtomicIncrement32Barrier(&(node->pinned_to_depot)); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + madvise_free_range(szone, region, free_lo, free_hi, &szone->last_small_advise); + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + OSAtomicDecrement32Barrier(&(node->pinned_to_depot)); + small_free_list_add_ptr(szone, small_mag_ptr, ptr, fmsize); + } + } +} +#endif // CONFIG_AGGRESSIVE_MADVISE || CONFIG_RECIRC_DEPOT + +#if CONFIG_RECIRC_DEPOT +static region_t +small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node) +{ + if (0 < node->bytes_used || 0 < node->pinned_to_depot || depot_ptr->recirculation_entries < (szone->num_small_magazines * 2)) { + return NULL; + } + + // disconnect first node from Depot + recirc_list_extract(szone, depot_ptr, node); + + // Iterate the region pulling its free entries off the (locked) Depot's free list + region_t sparse_region = SMALL_REGION_FOR_PTR(node); + int objects_in_use = small_free_detach_region(szone, depot_ptr, sparse_region); + + if (0 == objects_in_use) { + // Invalidate the hash table entry for this region with HASHRING_REGION_DEALLOCATED. + // Using HASHRING_REGION_DEALLOCATED preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not. + rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->small_region_generation->hashed_regions, + szone->small_region_generation->num_regions_allocated, szone->small_region_generation->num_regions_allocated_shift, + sparse_region); + if (NULL == pSlot) { + szone_error(szone, 1, "small_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region); + return NULL; + } + *pSlot = HASHRING_REGION_DEALLOCATED; + depot_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; + __sync_fetch_and_add(&(szone->num_small_regions_dealloc), 1); // Atomically increment num_small_regions_dealloc + + // Caller will transfer ownership of the region back to the OS with no locks held + MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, SMALL_REGION_SIZE); // DTrace USDT Probe + return sparse_region; + + } else { + szone_error(szone, 1, "small_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use); + return NULL; + } +} + +static boolean_t +small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index) +{ + // The entire magazine crossed the "emptiness threshold". Transfer a region + // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e + // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. + region_trailer_t *node = small_mag_ptr->firstNode; + + while (node && !node->recirc_suitable) { + node = node->next; + } + + if (NULL == node) { +#if DEBUG_MALLOC + malloc_printf("*** small_free_do_recirc_to_depot end of list\n"); +#endif + return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + } + + region_t sparse_region = SMALL_REGION_FOR_PTR(node); + + // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at start + if (sparse_region == small_mag_ptr->mag_last_region && + (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start)) { + small_finalize_region(szone, small_mag_ptr); + } + + // disconnect "suitable" node from magazine + recirc_list_extract(szone, small_mag_ptr, node); + + // Iterate the region pulling its free entries off its (locked) magazine's free list + int objects_in_use = small_free_detach_region(szone, small_mag_ptr, sparse_region); + magazine_t *depot_ptr = &(szone->small_magazines[DEPOT_MAGAZINE_INDEX]); + + // hand over the region to the (locked) Depot + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + // this will cause small_free_list_add_ptr called by small_free_reattach_region to use + // the depot as its target magazine, rather than magazine formerly associated with sparse_region + MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX; + node->pinned_to_depot = 0; + + // Iterate the region putting its free entries on Depot's free list + size_t bytes_inplay = small_free_reattach_region(szone, depot_ptr, sparse_region); + + small_mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; + small_mag_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES; + small_mag_ptr->mag_num_objects -= objects_in_use; + + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); // Unlock the originating magazine + + depot_ptr->mag_num_bytes_in_objects += bytes_inplay; + depot_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; + depot_ptr->mag_num_objects += objects_in_use; + + // connect to Depot as last node + recirc_list_splice_last(szone, depot_ptr, node); + + MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE, + (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe + +#if !CONFIG_AGGRESSIVE_MADVISE + // Mark free'd dirty pages with MADV_FREE to reduce memory pressure + small_free_scan_madvise_free(szone, depot_ptr, sparse_region); +#endif + + // If the region is entirely empty vm_deallocate() it outside the depot lock + region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, depot_ptr, node); + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + if (r_dealloc) { + deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0); + } + return FALSE; // Caller need not unlock the originating magazine +} + +static MALLOC_INLINE boolean_t +small_free_try_recirc_to_depot(szone_t *szone, + magazine_t *small_mag_ptr, + mag_index_t mag_index, + region_t region, + free_list_t freee, + msize_t msize, + void *headptr, + size_t headsize) +{ + region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(region); + size_t bytes_used = node->bytes_used; + + /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ + if (szone->num_small_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary + /* NOTHING */ + return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr) + } else if (DEPOT_MAGAZINE_INDEX != mag_index) { + // Emptiness discriminant + if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) { + /* Region has crossed threshold from density to sparsity. Mark it "suitable" on the + * recirculation candidates list. */ + node->recirc_suitable = TRUE; + } else { + /* After this free, we've found the region is still dense, so it must have been even more so before + * the free. That implies the region is already correctly marked. Do nothing. */ + } + + // Has the entire magazine crossed the "emptiness threshold"? If so, transfer a region + // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e + // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. + + size_t a = small_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine + size_t u = small_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine + + if (a - u > ((3 * SMALL_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) { + return small_free_do_recirc_to_depot(szone, small_mag_ptr, mag_index); + } + + } else { +#if !CONFIG_AGGRESSIVE_MADVISE + // We are free'ing into the depot, so madvise as we do so unless we were madvising every incoming + // allocation anyway. + small_madvise_free_range_no_lock(szone, small_mag_ptr, region, freee, msize, headptr, headsize); +#endif + + if (0 < bytes_used || 0 < node->pinned_to_depot) { + /* Depot'd region is still live. Leave it in place on the Depot's recirculation list + * so as to avoid thrashing between the Depot's free list and a magazines's free list + * with detach_region/reattach_region */ + } else { + /* Depot'd region is just now empty. Consider return to OS. */ + region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, small_mag_ptr, node); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + if (r_dealloc) { + deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0); + } + return FALSE; // Caller need not unlock + } + } + return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr) +} +#endif // CONFIG_RECIRC_DEPOT + +static MALLOC_INLINE boolean_t +small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize) +{ + msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); + unsigned index = SMALL_META_INDEX_FOR_PTR(ptr); + size_t original_size = SMALL_BYTES_FOR_MSIZE(msize); + unsigned char *next_block = ((unsigned char *)ptr + original_size); + msize_t next_index = index + msize; + + MALLOC_TRACE(TRACE_small_free, (uintptr_t)szone, (uintptr_t)small_mag_ptr, (uintptr_t)ptr, SMALL_BYTES_FOR_MSIZE(msize)); + +#if CONFIG_AGGRESSIVE_MADVISE || CONFIG_RECIRC_DEPOT + void *original_ptr = ptr; +#endif + +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); + } + if (!msize) { + szone_error(szone, 1, "trying to free small block that is too small", ptr, "in small_free_no_lock(), ptr=%p, msize=%d\n", + ptr, msize); + } +#endif + + // We try to coalesce this block with the preceeding one + if (index > 0 && (meta_headers[index - 1] & SMALL_IS_FREE)) { + msize_t previous_msize = meta_headers[index - 1] & ~SMALL_IS_FREE; + grain_t previous_index = index - previous_msize; + + // Check if the metadata for the start of the region is also free. + if (meta_headers[previous_index] == (previous_msize | SMALL_IS_FREE)) { + void *previous_ptr = (void *)((uintptr_t)ptr - SMALL_BYTES_FOR_MSIZE(previous_msize)); + free_list_t previous = small_free_list_find_by_ptr(szone, small_mag_ptr, previous_ptr, previous_msize); + small_free_list_remove_ptr(szone, small_mag_ptr, previous, previous_msize); + ptr = previous_ptr; + msize += previous_msize; + index -= previous_msize; + } else { + _os_set_crash_log_message("small free list metadata inconsistency (headers[previous] != previous size)"); + __builtin_trap(); + } + } + + // Try to coalesce with this block with the next block + if ((next_block < SMALL_REGION_END(region)) && (meta_headers[next_index] & SMALL_IS_FREE)) { + msize_t next_msize = meta_headers[next_index] & ~SMALL_IS_FREE; + free_list_t next = small_free_list_find_by_ptr(szone, small_mag_ptr, next_block, next_msize); + small_free_list_remove_ptr(szone, small_mag_ptr, next, next_msize); + msize += next_msize; + } + + if (szone->debug_flags & MALLOC_DO_SCRIBBLE) { + if (!msize) { + szone_error(szone, 1, "incorrect size information - block header was damaged", ptr, NULL); + } else { + memset(ptr, SCRABBLE_BYTE, SMALL_BYTES_FOR_MSIZE(msize)); + } + } + + free_list_t freee = small_free_list_add_ptr(szone, small_mag_ptr, ptr, msize); + + // use original_size and not msize to avoid double counting the coalesced blocks + small_mag_ptr->mag_num_bytes_in_objects -= original_size; + small_mag_ptr->mag_num_objects--; + + // Update this region's bytes in use count + region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(region); + size_t bytes_used = node->bytes_used - original_size; + node->bytes_used = (unsigned int)bytes_used; + +#if CONFIG_AGGRESSIVE_MADVISE + small_madvise_free_range_no_lock(szone, small_mag_ptr, region, freee, msize, original_ptr, original_size); +#endif + + // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr) if this function + // returns TRUE. + boolean_t needs_unlock = TRUE; + +#if CONFIG_RECIRC_DEPOT + needs_unlock = small_free_try_recirc_to_depot(szone, small_mag_ptr, mag_index, region, freee, msize, original_ptr, original_size); +#endif + return needs_unlock; +} + +// Allocates from the last region or a freshly allocated region +static void * +small_malloc_from_region_no_lock(szone_t *szone, + magazine_t *small_mag_ptr, + mag_index_t mag_index, + msize_t msize, + void *aligned_address) +{ + void *ptr; + + // Before anything we transform the mag_bytes_free_at_end or mag_bytes_free_at_start - if any - to a regular free block + /* FIXME: last_block needs to be coalesced with previous entry if free, */ + if (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start) { + small_finalize_region(szone, small_mag_ptr); + } + + // Here find the only place in smallville that (infrequently) takes the small_regions_lock. + // Only one thread at a time should be permitted to assess the density of the hash + // ring and adjust if needed. + // Only one thread at a time should be permitted to insert its new region on + // the hash ring. + // It is safe for all other threads to read the hash ring (hashed_regions) and + // the associated sizes (num_regions_allocated and num_small_regions). + + _malloc_lock_lock(&szone->small_regions_lock); + // Check to see if the hash ring of small regions needs to grow. Try to + // avoid the hash ring becoming too dense. + if (szone->small_region_generation->num_regions_allocated < (2 * szone->num_small_regions)) { + region_t *new_regions; + size_t new_size; + size_t new_shift = szone->small_region_generation->num_regions_allocated_shift; // In/Out parameter + new_regions = hash_regions_grow_no_lock(szone, szone->small_region_generation->hashed_regions, + szone->small_region_generation->num_regions_allocated, &new_shift, &new_size); + // Do not deallocate the current hashed_regions allocation since someone + // may be iterating it. Instead, just leak it. + + // Prepare to advance to the "next generation" of the hash ring. + szone->small_region_generation->nextgen->hashed_regions = new_regions; + szone->small_region_generation->nextgen->num_regions_allocated = new_size; + szone->small_region_generation->nextgen->num_regions_allocated_shift = new_shift; + + // Throw the switch to atomically advance to the next generation. + szone->small_region_generation = szone->small_region_generation->nextgen; + // Ensure everyone sees the advance. + OSMemoryBarrier(); + } + // Tag the region at "aligned_address" as belonging to us, + // and so put it under the protection of the magazine lock we are holding. + // Do this before advertising "aligned_address" on the hash ring(!) + MAGAZINE_INDEX_FOR_SMALL_REGION(aligned_address) = mag_index; + + // Insert the new region into the hash ring, and update malloc statistics + hash_region_insert_no_lock(szone->small_region_generation->hashed_regions, + szone->small_region_generation->num_regions_allocated, szone->small_region_generation->num_regions_allocated_shift, + aligned_address); + + szone->num_small_regions++; + + _malloc_lock_unlock(&szone->small_regions_lock); + + small_mag_ptr->mag_last_region = aligned_address; + BYTES_USED_FOR_SMALL_REGION(aligned_address) = SMALL_BYTES_FOR_MSIZE(msize); +#if CONFIG_ASLR_INTERNAL + int offset_msize = malloc_entropy[1] & SMALL_ENTROPY_MASK; +#if DEBUG_MALLOC + if (getenv("MallocASLRForce")) { + offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & SMALL_ENTROPY_MASK; + } + if (getenv("MallocASLRPrint")) { + malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize); + } +#endif +#else + int offset_msize = 0; +#endif + ptr = (void *)((uintptr_t)aligned_address + SMALL_BYTES_FOR_MSIZE(offset_msize)); + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize, msize); + small_mag_ptr->mag_num_objects++; + small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(msize); + small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES; + + // add a big free block at the end + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize + msize, NUM_SMALL_BLOCKS - msize - offset_msize); + small_mag_ptr->mag_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(NUM_SMALL_BLOCKS - msize - offset_msize); + +#if CONFIG_ASLR_INTERNAL + // add a big free block at the start + small_mag_ptr->mag_bytes_free_at_start = SMALL_BYTES_FOR_MSIZE(offset_msize); + if (offset_msize) { + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, offset_msize); + } +#else + small_mag_ptr->mag_bytes_free_at_start = 0; +#endif + + // connect to magazine as last node + recirc_list_splice_last(szone, small_mag_ptr, REGION_TRAILER_FOR_SMALL_REGION(aligned_address)); + + return ptr; +} + +void * +small_memalign(szone_t *szone, size_t alignment, size_t size, size_t span) +{ + if (size <= SMALL_THRESHOLD) { + // ensure block allocated by small does not have a tiny-possible size + size = SMALL_THRESHOLD + TINY_QUANTUM; + span = size + alignment - 1; + } + + msize_t mspan = SMALL_MSIZE_FOR_BYTES(span + SMALL_QUANTUM - 1); + void *p = szone_malloc(szone, span); // avoid inlining small_malloc_should_clear(szone, mspan, 0); + + if (NULL == p) { + return NULL; + } + + size_t offset = ((uintptr_t)p) & (alignment - 1); // p % alignment + size_t pad = (0 == offset) ? 0 : alignment - offset; // p + pad achieves desired alignment + + msize_t msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1); + msize_t mpad = SMALL_MSIZE_FOR_BYTES(pad + SMALL_QUANTUM - 1); + msize_t mwaste = mspan - msize - mpad; // excess blocks + + if (mpad > 0) { + void *q = (void *)(((uintptr_t)p) + pad); + + // Mark q as block header and in-use, thus creating two blocks. + magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, + REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)), + MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p))); + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(p), SMALL_META_INDEX_FOR_PTR(p), mpad); + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), msize + mwaste); + small_mag_ptr->mag_num_objects++; + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + + // Give up mpad blocks beginning at p to the small free list + // region_t r = SMALL_REGION_FOR_PTR(p); + szone_free(szone, p); // avoid inlining free_small(szone, p, &r); + + p = q; // advance p to the desired alignment + } + if (mwaste > 0) { + void *q = (void *)(((uintptr_t)p) + SMALL_BYTES_FOR_MSIZE(msize)); + // Mark q as block header and in-use, thus creating two blocks. + magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, + REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)), + MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p))); + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(p), SMALL_META_INDEX_FOR_PTR(p), msize); + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), mwaste); + small_mag_ptr->mag_num_objects++; + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + + // Give up mwaste blocks beginning at q to the small free list + // region_t r = SMALL_REGION_FOR_PTR(q); + szone_free(szone, q); // avoid inlining free_small(szone, q, &r); + } + + return p; // p has the desired size and alignment, and can later be free()'d +} + +void * +small_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) +{ + msize_t new_msize = SMALL_MSIZE_FOR_BYTES(new_good_size); + msize_t mshrinkage = SMALL_MSIZE_FOR_BYTES(old_size) - new_msize; + + if (mshrinkage) { + void *q = (void *)((uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(new_msize)); + magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, + REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)), + MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr))); + + // Mark q as block header and in-use, thus creating two blocks. + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), new_msize); + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), mshrinkage); + small_mag_ptr->mag_num_objects++; + + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + szone_free(szone, q); // avoid inlining free_small(szone, q, ...); + } + + return ptr; +} + +boolean_t +small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) +{ + // returns 1 on success + msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); + unsigned index; + msize_t old_msize, new_msize; + unsigned next_index; + void *next_block; + msize_t next_msize_and_free; + boolean_t is_free; + msize_t next_msize, leftover_msize; + void *leftover; + + index = SMALL_META_INDEX_FOR_PTR(ptr); + old_msize = SMALL_MSIZE_FOR_BYTES(old_size); + new_msize = SMALL_MSIZE_FOR_BYTES(new_size + SMALL_QUANTUM - 1); + next_index = index + old_msize; + + if (next_index >= NUM_SMALL_BLOCKS) { + return 0; + } + next_block = (char *)ptr + old_size; + +#if DEBUG_MALLOC + if ((uintptr_t)next_block & (SMALL_QUANTUM - 1)) { + szone_error(szone, 1, "internal invariant broken in realloc(next_block)", next_block, NULL); + } + if (meta_headers[index] != old_msize) { + malloc_printf("*** small_try_realloc_in_place incorrect old %d %d\n", meta_headers[index], old_msize); + } +#endif + + magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines, + REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)), MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr))); + if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr))) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + return 0; + } + + /* + * Look for a free block immediately afterwards. If it's large enough, we can consume (part of) + * it. + */ + next_msize_and_free = meta_headers[next_index]; + is_free = next_msize_and_free & SMALL_IS_FREE; + if (!is_free) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + return 0; // next_block is in use; + } + + next_msize = next_msize_and_free & ~SMALL_IS_FREE; + if (old_msize + next_msize < new_msize) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + return 0; // even with next block, not enough + } + + // The following block is big enough; pull it from its freelist and chop off enough to satisfy + // our needs. + free_list_t freee = small_free_list_find_by_ptr(szone, small_mag_ptr, next_block, next_msize); + small_free_list_remove_ptr(szone, small_mag_ptr, freee, next_msize); + small_meta_header_set_middle(meta_headers, next_index); + leftover_msize = old_msize + next_msize - new_msize; + if (leftover_msize) { + /* there's some left, so put the remainder back */ + leftover = (unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(new_msize); + + small_free_list_add_ptr(szone, small_mag_ptr, leftover, leftover_msize); + } +#if DEBUG_MALLOC + if (SMALL_BYTES_FOR_MSIZE(new_msize) > szone->large_threshold) { + malloc_printf("*** realloc in place for %p exceeded msize=%d\n", new_msize); + } +#endif + small_meta_header_set_in_use(meta_headers, index, new_msize); +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in small_try_realloc_in_place(), ptr=%p, msize=%d\n", ptr, *SMALL_METADATA_FOR_PTR(ptr)); + } +#endif + small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(new_msize - old_msize); + + // Update this region's bytes in use count + region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); + size_t bytes_used = node->bytes_used + SMALL_BYTES_FOR_MSIZE(new_msize - old_msize); + node->bytes_used = (unsigned int)bytes_used; + + // Emptiness discriminant + if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) { + /* After this reallocation the region is still sparse, so it must have been even more so before + * the reallocation. That implies the region is already correctly marked. Do nothing. */ + } else { + /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the + * recirculation candidates list. */ + node->recirc_suitable = FALSE; + } + + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + return 1; +} + +boolean_t +small_check_region(szone_t *szone, region_t region) +{ + unsigned char *ptr = SMALL_REGION_ADDRESS(region); + msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr); + unsigned char *region_end = SMALL_REGION_END(region); + msize_t prev_free = 0; + unsigned index; + msize_t msize_and_free; + msize_t msize; + free_list_t free_head, previous, next; + msize_t *follower; + mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); + magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); + + // Assumes locked + CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); + + if (region == small_mag_ptr->mag_last_region) { + ptr += small_mag_ptr->mag_bytes_free_at_start; + region_end -= small_mag_ptr->mag_bytes_free_at_end; + } + + while (ptr < region_end) { + index = SMALL_META_INDEX_FOR_PTR(ptr); + msize_and_free = meta_headers[index]; + if (!(msize_and_free & SMALL_IS_FREE)) { + // block is in use + msize = msize_and_free; + if (!msize) { + malloc_printf("*** invariant broken: null msize ptr=%p num_small_regions=%d end=%p\n", ptr, + szone->num_small_regions, region_end); + return 0; + } +#if !CONFIG_RELAXED_INVARIANT_CHECKS + if (SMALL_BYTES_FOR_MSIZE(msize) > szone->large_threshold) { + malloc_printf("*** invariant broken for %p this small msize=%d - size is too large\n", ptr, msize_and_free); + return 0; + } +#endif // CONFIG_RELAXED_INVARIANT_CHECKS + ptr += SMALL_BYTES_FOR_MSIZE(msize); + prev_free = 0; + } else { + // free pointer + msize = msize_and_free & ~SMALL_IS_FREE; + free_head = (free_list_t){ .p = ptr }; + follower = (msize_t *)FOLLOWING_SMALL_PTR(ptr, msize); + if (!msize) { + malloc_printf("*** invariant broken for free block %p this msize=%d\n", ptr, msize); + return 0; + } +#if !CONFIG_RELAXED_INVARIANT_CHECKS + if (prev_free) { + malloc_printf("*** invariant broken for %p (2 free in a row)\n", ptr); + return 0; + } +#endif + + // check for possible OOB entry if needed + if (small_needs_oob_free_entry(ptr, msize)) { + oob_free_entry_t oob = small_oob_free_find_ptr(ptr, msize); + if (oob) { + free_head.oob = oob; + } + } + + previous = small_free_list_get_previous(szone, free_head); + next = small_free_list_get_next(szone, free_head); + if (previous.p && !SMALL_PTR_IS_FREE(small_free_list_get_ptr(szone, previous))) { + malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", ptr, small_free_list_get_ptr(szone, previous)); + return 0; + } + if (next.p && !SMALL_PTR_IS_FREE(small_free_list_get_ptr(szone, next))) { + malloc_printf("*** invariant broken for %p (next %p is not a free pointer)\n", ptr, small_free_list_get_ptr(szone, next)); + return 0; + } + if (SMALL_PREVIOUS_MSIZE(follower) != msize) { + malloc_printf( + "*** invariant broken for small free %p followed by %p in region [%p-%p] " + "(end marker incorrect) should be %d; in fact %d\n", + ptr, follower, SMALL_REGION_ADDRESS(region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower)); + return 0; + } + ptr = (unsigned char *)follower; + prev_free = SMALL_IS_FREE; + } + } + return 1; +} + +kern_return_t +small_in_use_enumerator(task_t task, + void *context, + unsigned type_mask, + szone_t *szone, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + size_t num_regions; + size_t index; + region_t *regions; + vm_range_t buffer[MAX_RECORDER_BUFFER]; + unsigned count = 0; + kern_return_t err; + region_t region; + vm_range_t range; + vm_range_t admin_range; + vm_range_t ptr_range; + unsigned char *mapped_region; + msize_t *block_header; + unsigned block_index; + unsigned block_limit; + msize_t msize_and_free; + msize_t msize; + magazine_t *small_mag_base = NULL; + + region_hash_generation_t *srg_ptr; + err = reader(task, (vm_address_t)szone->small_region_generation, sizeof(region_hash_generation_t), (void **)&srg_ptr); + if (err) { + return err; + } + + num_regions = srg_ptr->num_regions_allocated; + err = reader(task, (vm_address_t)srg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions); + if (err) { + return err; + } + + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + // Map in all active magazines. Do this outside the iteration over regions. + err = reader(task, (vm_address_t)(szone->small_magazines), szone->num_small_magazines * sizeof(magazine_t), + (void **)&small_mag_base); + if (err) { + return err; + } + } + + for (index = 0; index < num_regions; ++index) { + region = regions[index]; + if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { + range.address = (vm_address_t)SMALL_REGION_ADDRESS(region); + range.size = SMALL_REGION_SIZE; + if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { + admin_range.address = range.address + SMALL_METADATA_START; + admin_range.size = SMALL_METADATA_SIZE; + recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); + } + if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { + ptr_range.address = range.address; + ptr_range.size = NUM_SMALL_BLOCKS * SMALL_QUANTUM; + recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); + } + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + void *mag_last_free; + vm_address_t mag_last_free_ptr = 0; + msize_t mag_last_free_msize = 0; + + err = reader(task, range.address, range.size, (void **)&mapped_region); + if (err) { + return err; + } + + mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(mapped_region); + magazine_t *small_mag_ptr = small_mag_base + mag_index; + + if (DEPOT_MAGAZINE_INDEX != mag_index) { + mag_last_free = small_mag_ptr->mag_last_free; + if (mag_last_free) { + mag_last_free_ptr = (uintptr_t)mag_last_free & ~(SMALL_QUANTUM - 1); + mag_last_free_msize = (uintptr_t)mag_last_free & (SMALL_QUANTUM - 1); + } + } else { + for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) { + if ((void *)range.address == (small_mag_base + mag_index)->mag_last_free_rgn) { + mag_last_free = (small_mag_base + mag_index)->mag_last_free; + if (mag_last_free) { + mag_last_free_ptr = (uintptr_t)mag_last_free & ~(SMALL_QUANTUM - 1); + mag_last_free_msize = (uintptr_t)mag_last_free & (SMALL_QUANTUM - 1); + } + } + } + } + + block_header = (msize_t *)(mapped_region + SMALL_METADATA_START + sizeof(region_trailer_t)); + block_index = 0; + block_limit = NUM_SMALL_BLOCKS; + if (region == small_mag_ptr->mag_last_region) { + block_index += SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start); + block_limit -= SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end); + } + while (block_index < block_limit) { + msize_and_free = block_header[block_index]; + msize = msize_and_free & ~SMALL_IS_FREE; + if (!(msize_and_free & SMALL_IS_FREE) && + range.address + SMALL_BYTES_FOR_MSIZE(block_index) != mag_last_free_ptr) { + // Block in use + buffer[count].address = range.address + SMALL_BYTES_FOR_MSIZE(block_index); + buffer[count].size = SMALL_BYTES_FOR_MSIZE(msize); + count++; + if (count >= MAX_RECORDER_BUFFER) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + count = 0; + } + } + + if (!msize) { + return KERN_FAILURE; // Somethings amiss. Avoid looping at this block_index. + } + block_index += msize; + } + if (count) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + count = 0; + } + } + } + } + return 0; +} + +static void * +small_malloc_from_free_list(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize) +{ + msize_t this_msize; + grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1; + free_list_t *free_list = small_mag_ptr->mag_free_list; + free_list_t *the_slot = free_list + slot; + free_list_t *limit; + unsigned bitmap; + msize_t leftover_msize; + void *leftover_ptr; + void *ptr; + + // Assumes we've locked the region + CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__); + + // Look for an exact match by checking the freelist for this msize. + // + if (small_free_list_get_ptr(szone, *the_slot)) { + ptr = small_free_list_get_ptr(szone, *the_slot); + this_msize = msize; + small_free_list_remove_ptr(szone, small_mag_ptr, *the_slot, msize); + goto return_small_alloc; + } + + // Mask off the bits representing slots holding free blocks smaller than + // the size we need. If there are no larger free blocks, try allocating + // from the free space at the end of the small region. + if (szone->is_largemem) { + // BITMAPN_CTZ implementation + unsigned idx = slot >> 5; + bitmap = 0; + unsigned mask = ~((1 << (slot & 31)) - 1); + for (; idx < SMALL_BITMAP_WORDS; ++idx) { + bitmap = small_mag_ptr->mag_bitmap[idx] & mask; + if (bitmap != 0) { + break; + } + mask = ~0U; + } + // Check for fallthrough: No bits set in bitmap + if ((bitmap == 0) && (idx == SMALL_BITMAP_WORDS)) { + goto try_small_from_end; + } + + // Start looking at the first set bit, plus 32 bits for every word of + // zeroes or entries that were too small. + slot = BITMAP32_CTZ((&bitmap)) + (idx * 32); + } else { + bitmap = small_mag_ptr->mag_bitmap[0] & ~((1 << slot) - 1); + if (!bitmap) { + goto try_small_from_end; + } + + slot = BITMAP32_CTZ((&bitmap)); + } + // FIXME: Explain use of - 1 here, last slot has special meaning + limit = free_list + szone->num_small_slots - 1; + free_list += slot; + + // Attempt to pull off the free_list slot that we now think is full. + if ((ptr = small_free_list_get_ptr(szone, *free_list))) { + this_msize = SMALL_PTR_SIZE(ptr); + small_free_list_remove_ptr(szone, small_mag_ptr, *free_list, this_msize); + goto add_leftover_and_proceed; + } + +#if DEBUG_MALLOC + malloc_printf("in small_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n", slot); +#endif + +try_small_from_end: + // Let's see if we can use small_mag_ptr->mag_bytes_free_at_end + if (small_mag_ptr->mag_bytes_free_at_end >= SMALL_BYTES_FOR_MSIZE(msize)) { + ptr = SMALL_REGION_END(small_mag_ptr->mag_last_region) - small_mag_ptr->mag_bytes_free_at_end; + small_mag_ptr->mag_bytes_free_at_end -= SMALL_BYTES_FOR_MSIZE(msize); + if (small_mag_ptr->mag_bytes_free_at_end) { + // let's mark this block as in use to serve as boundary + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), + SMALL_META_INDEX_FOR_PTR((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)), + SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end)); + } + this_msize = msize; + goto return_small_alloc; + } +#if CONFIG_ASLR_INTERNAL + // Try from start if nothing left at end + if (small_mag_ptr->mag_bytes_free_at_start >= SMALL_BYTES_FOR_MSIZE(msize)) { + ptr = SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region) + small_mag_ptr->mag_bytes_free_at_start - + SMALL_BYTES_FOR_MSIZE(msize); + small_mag_ptr->mag_bytes_free_at_start -= SMALL_BYTES_FOR_MSIZE(msize); + if (small_mag_ptr->mag_bytes_free_at_start) { + // let's mark this block as in use to serve as boundary + small_meta_header_set_in_use( + SMALL_META_HEADER_FOR_PTR(ptr), 0, SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start)); + } + this_msize = msize; + goto return_small_alloc; + } +#endif + return NULL; + +add_leftover_and_proceed: + if (this_msize > msize) { + leftover_msize = this_msize - msize; + leftover_ptr = (unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize); +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); + } +#endif + small_free_list_add_ptr(szone, small_mag_ptr, leftover_ptr, leftover_msize); + this_msize = msize; + } + +return_small_alloc: + small_mag_ptr->mag_num_objects++; + small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(this_msize); + + // Update this region's bytes in use count + region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); + size_t bytes_used = node->bytes_used + SMALL_BYTES_FOR_MSIZE(this_msize); + node->bytes_used = (unsigned int)bytes_used; + + // Emptiness discriminant + if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) { + /* After this allocation the region is still sparse, so it must have been even more so before + * the allocation. That implies the region is already correctly marked. Do nothing. */ + } else { + /* Region has crossed threshold from sparsity to density. Mark in not "suitable" on the + * recirculation candidates list. */ + node->recirc_suitable = FALSE; + } +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in small_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); + } +#endif + small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), this_msize); + return ptr; +} + +void * +small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) +{ + void *ptr; + mag_index_t mag_index = mag_get_thread_index(szone); + magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); + + MALLOC_TRACE(TRACE_small_malloc, (uintptr_t)szone, SMALL_BYTES_FOR_MSIZE(msize), (uintptr_t)small_mag_ptr, cleared_requested); + + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + +#if CONFIG_SMALL_CACHE + ptr = (void *)small_mag_ptr->mag_last_free; + + if ((((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) == msize) { + // we have a winner + small_mag_ptr->mag_last_free = NULL; + small_mag_ptr->mag_last_free_rgn = NULL; + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + ptr = (void *)((uintptr_t)ptr & ~(SMALL_QUANTUM - 1)); + if (cleared_requested) { + memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); + } + return ptr; + } +#endif /* CONFIG_SMALL_CACHE */ + + while (1) { + ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize); + if (ptr) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + if (cleared_requested) { + memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); + } + return ptr; + } + + if (small_get_region_from_depot(szone, small_mag_ptr, mag_index, msize)) { + ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize); + if (ptr) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + if (cleared_requested) { + memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize)); + } + return ptr; + } + } + + // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc(). + // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first + // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section. + // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the + // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation, + // and retry-ing threads succeed in the code just above. + if (!small_mag_ptr->alloc_underway) { + void *fresh_region; + + // time to create a new region (do this outside the magazine lock) + small_mag_ptr->alloc_underway = TRUE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + fresh_region = allocate_pages_securely(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, VM_MEMORY_MALLOC_SMALL); + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + + MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, SMALL_REGION_SIZE); // DTrace USDT Probe + + if (!fresh_region) { // out of memory! + small_mag_ptr->alloc_underway = FALSE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + return NULL; + } + + ptr = small_malloc_from_region_no_lock(szone, small_mag_ptr, mag_index, msize, fresh_region); + + // we don't clear because this freshly allocated space is pristine + small_mag_ptr->alloc_underway = FALSE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + return ptr; + } else { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + yield(); + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + } + } + /* NOTREACHED */ +} + +static MALLOC_NOINLINE void +free_small_botch(szone_t *szone, void *ptr) +{ + mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); + magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + szone_error(szone, 1, "double free", ptr, NULL); +} + +void +free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size) +{ + msize_t msize; + mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)); + magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); + + // ptr is known to be in small_region + if (known_size) { + msize = SMALL_MSIZE_FOR_BYTES(known_size + SMALL_QUANTUM - 1); + } else { + msize = SMALL_PTR_SIZE(ptr); + if (SMALL_PTR_IS_FREE(ptr)) { + free_small_botch(szone, ptr); + return; + } + } + + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + +#if CONFIG_SMALL_CACHE + // Depot does not participate in CONFIG_SMALL_CACHE since it can't be directly malloc()'d + if (DEPOT_MAGAZINE_INDEX != mag_index) { + void *ptr2 = small_mag_ptr->mag_last_free; // Might be NULL + region_t rgn2 = small_mag_ptr->mag_last_free_rgn; + + /* check that we don't already have this pointer in the cache */ + if (ptr == (void *)((uintptr_t)ptr2 & ~(SMALL_QUANTUM - 1))) { + free_small_botch(szone, ptr); + return; + } + + if ((szone->debug_flags & MALLOC_DO_SCRIBBLE) && msize) { + memset(ptr, SCRABBLE_BYTE, SMALL_BYTES_FOR_MSIZE(msize)); + } + + small_mag_ptr->mag_last_free = (void *)(((uintptr_t)ptr) | msize); + small_mag_ptr->mag_last_free_rgn = small_region; + + if (!ptr2) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + return; + } + + msize = (uintptr_t)ptr2 & (SMALL_QUANTUM - 1); + ptr = (void *)(((uintptr_t)ptr2) & ~(SMALL_QUANTUM - 1)); + small_region = rgn2; + } +#endif /* CONFIG_SMALL_CACHE */ + + // Now in the time it took to acquire the lock, the region may have migrated + // from one magazine to another. I.e. trailer->mag_index is volatile. + // In which case the magazine lock we obtained (namely magazines[mag_index].mag_lock) + // is stale. If so, keep on tryin' ... + region_trailer_t *trailer = REGION_TRAILER_FOR_SMALL_REGION(small_region); + mag_index_t refreshed_index; + + while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment + + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + + mag_index = refreshed_index; + small_mag_ptr = &(szone->small_magazines[mag_index]); + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + } + + if (small_free_no_lock(szone, small_mag_ptr, mag_index, small_region, ptr, msize)) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + } + + CHECK(szone, __PRETTY_FUNCTION__); +} + +void +print_small_free_list(szone_t *szone) +{ + free_list_t ptr; + _SIMPLE_STRING b = _simple_salloc(); + mag_index_t mag_index; + + if (b) { + _simple_sappend(b, "small free sizes:\n"); + for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { + grain_t slot = 0; + _simple_sprintf(b, "\tMagazine %d: ", mag_index); + while (slot < szone->num_small_slots) { + ptr = szone->small_magazines[mag_index].mag_free_list[slot]; + if (small_free_list_get_ptr(szone, ptr)) { + _simple_sprintf(b, "%s%y[%d]; ", (slot == szone->num_small_slots - 1) ? ">=" : "", (slot + 1) * SMALL_QUANTUM, + small_free_list_count(szone, ptr)); + } + slot++; + } + _simple_sappend(b, "\n"); + } + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); + } +} + +void +print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end) +{ + unsigned counts[1024]; + unsigned in_use = 0; + uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(region); + uintptr_t current = start + bytes_at_start; + uintptr_t limit = (uintptr_t)SMALL_REGION_END(region) - bytes_at_end; + msize_t msize_and_free; + msize_t msize; + unsigned ci; + _SIMPLE_STRING b; + uintptr_t pgTot = 0; + + if (region == HASHRING_REGION_DEALLOCATED) { + if ((b = _simple_salloc()) != NULL) { + _simple_sprintf(b, "Small region [unknown address] was returned to the OS\n"); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); + } + return; + } + + memset(counts, 0, sizeof(counts)); + while (current < limit) { + msize_and_free = *SMALL_METADATA_FOR_PTR(current); + msize = msize_and_free & ~SMALL_IS_FREE; + if (!msize) { + malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize); + break; + } + if (!(msize_and_free & SMALL_IS_FREE)) { + // block in use + if (msize < 1024) { + counts[msize]++; + } + in_use++; + } else { + uintptr_t pgLo = round_page_quanta(current + sizeof(free_list_t) + sizeof(msize_t)); + uintptr_t pgHi = trunc_page_quanta(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); + + if (pgLo < pgHi) { + pgTot += (pgHi - pgLo); + } + } + current += SMALL_BYTES_FOR_MSIZE(msize); + } + if ((b = _simple_salloc()) != NULL) { + _simple_sprintf(b, "Small region [%p-%p, %y] \t", (void *)start, SMALL_REGION_END(region), (int)SMALL_REGION_SIZE); + _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_SMALL_REGION(region)); + _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_SMALL_REGION(region)); + if (bytes_at_end || bytes_at_start) { + _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start); + } + if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_SMALL_REGION(region)) { + _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot); + } else { + _simple_sprintf(b, "Fragments subject to reclamation=%ly", pgTot); + } + if (verbose && in_use) { + _simple_sappend(b, "\n\tSizes in use: "); + for (ci = 0; ci < 1024; ci++) { + if (counts[ci]) { + _simple_sprintf(b, "%d[%d] ", SMALL_BYTES_FOR_MSIZE(ci), counts[ci]); + } + } + } + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); + } +} + +boolean_t +small_free_list_check(szone_t *szone, grain_t slot) +{ + mag_index_t mag_index; + + for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) { + magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]); + SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr); + + unsigned count = 0; + free_list_t current = szone->small_magazines[mag_index].mag_free_list[slot]; + free_list_t previous = (free_list_t){ .p = NULL }; + msize_t msize_and_free; + void *ptr = NULL; + + while ((ptr = small_free_list_get_ptr(szone, current))) { + msize_and_free = *SMALL_METADATA_FOR_PTR(ptr); + if (!(msize_and_free & SMALL_IS_FREE)) { + malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + return 0; + } + if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) { + malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + return 0; + } + if (!small_region_for_ptr_no_lock(szone, ptr)) { + malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + return 0; + } + if (small_free_list_get_previous(szone, current).p != previous.p) { + malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr); + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + return 0; + } + previous = current; + current = small_free_list_get_next(szone, current); + count++; + } + + SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); + } + return 1; +} diff --git a/src/libmalloc/src/magazine_tiny.c b/src/libmalloc/src/magazine_tiny.c new file mode 100644 index 000000000..18f0d3b5a --- /dev/null +++ b/src/libmalloc/src/magazine_tiny.c @@ -0,0 +1,2158 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "internal.h" + +/* + * Get the size of the previous free block, which is stored in the last two + * bytes of the block. If the previous block is not free, then the result is + * undefined. + */ +static msize_t +get_tiny_previous_free_msize(const void *ptr) +{ + // check whether the previous block is in the tiny region and a block header + // if so, then the size of the previous block is one, and there is no stored + // size. + if (ptr != TINY_REGION_FOR_PTR(ptr)) { + void *prev_block = (void *)((uintptr_t)ptr - TINY_QUANTUM); + uint32_t *prev_header = TINY_BLOCK_HEADER_FOR_PTR(prev_block); + msize_t prev_index = TINY_INDEX_FOR_PTR(prev_block); + if (BITARRAY_BIT(prev_header, prev_index)) { + return 1; + } + return TINY_PREVIOUS_MSIZE(ptr); + } + // don't read possibly unmapped memory before the beginning of the region + return 0; +} + +static MALLOC_INLINE void +set_tiny_meta_header_in_use(const void *ptr, msize_t msize) +{ + uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); + msize_t index = TINY_INDEX_FOR_PTR(ptr); + msize_t clr_msize = msize - 1; + msize_t midx = (index >> 5) << 1; + uint32_t val = (1 << (index & 31)); + +#if DEBUG_MALLOC + if (msize >= NUM_TINY_SLOTS) { + malloc_printf("set_tiny_meta_header_in_use() invariant broken %p %d\n", ptr, msize); + } + if ((unsigned)index + (unsigned)msize > 0x10000) { + malloc_printf("set_tiny_meta_header_in_use() invariant broken (2) %p %d\n", ptr, msize); + } +#endif + + block_header[midx] |= val; // BITARRAY_SET(block_header, index); + block_header[midx + 1] |= val; // BITARRAY_SET(in_use, index); + + // bitarray_mclr(block_header, index, end_bit); + // bitarray_mclr(in_use, index, end_bit); + + index++; + midx = (index >> 5) << 1; + + unsigned start = index & 31; + unsigned end = start + clr_msize; + +#if defined(__LP64__) + if (end > 63) { + unsigned mask0 = (0xFFFFFFFFU >> (31 - start)) >> 1; + unsigned mask1 = (0xFFFFFFFFU << (end - 64)); + block_header[midx + 0] &= mask0; // clear header + block_header[midx + 1] &= mask0; // clear in_use + block_header[midx + 2] = 0; // clear header + block_header[midx + 3] = 0; // clear in_use + block_header[midx + 4] &= mask1; // clear header + block_header[midx + 5] &= mask1; // clear in_use + } else +#endif + if (end > 31) { + unsigned mask0 = (0xFFFFFFFFU >> (31 - start)) >> 1; + unsigned mask1 = (0xFFFFFFFFU << (end - 32)); + block_header[midx + 0] &= mask0; + block_header[midx + 1] &= mask0; + block_header[midx + 2] &= mask1; + block_header[midx + 3] &= mask1; + } else { + unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1; + mask |= (0xFFFFFFFFU << end); + block_header[midx + 0] &= mask; + block_header[midx + 1] &= mask; + } + + // we set the block_header bit for the following block to reaffirm next block is a block + index += clr_msize; + midx = (index >> 5) << 1; + val = (1 << (index & 31)); + block_header[midx] |= val; // BITARRAY_SET(block_header, (index+clr_msize)); +#if DEBUG_MALLOC + { + boolean_t ff; + msize_t mf; + + mf = get_tiny_meta_header(ptr, &ff); + if (msize != mf) { + malloc_printf("setting header for tiny in_use %p : %d\n", ptr, msize); + malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff); + } + } +#endif +} + +static MALLOC_INLINE void set_tiny_meta_header_in_use_1(const void *ptr) // As above with msize == 1 +{ + uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); + msize_t index = TINY_INDEX_FOR_PTR(ptr); + msize_t midx = (index >> 5) << 1; + uint32_t val = (1 << (index & 31)); + + block_header[midx] |= val; // BITARRAY_SET(block_header, index); + block_header[midx + 1] |= val; // BITARRAY_SET(in_use, index); + + index++; + midx = (index >> 5) << 1; + val = (1 << (index & 31)); + + block_header[midx] |= val; // BITARRAY_SET(block_header, (index+clr_msize)) +} + +static MALLOC_INLINE void +set_tiny_meta_header_middle(const void *ptr) +{ + // indicates this block is in the middle of an in use block + uint32_t *block_header; + uint32_t *in_use; + msize_t index; + + block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); + in_use = TINY_INUSE_FOR_HEADER(block_header); + index = TINY_INDEX_FOR_PTR(ptr); + + BITARRAY_CLR(block_header, index); + BITARRAY_CLR(in_use, index); +} + +static MALLOC_INLINE void +set_tiny_meta_header_free(const void *ptr, msize_t msize) +{ + // !msize is acceptable and means 65536 + uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); + msize_t index = TINY_INDEX_FOR_PTR(ptr); + msize_t midx = (index >> 5) << 1; + uint32_t val = (1 << (index & 31)); + +#if DEBUG_MALLOC + if ((unsigned)index + (unsigned)msize > 0x10000) { + malloc_printf("setting header for tiny free %p msize too large: %d\n", ptr, msize); + } +#endif + + block_header[midx] |= val; // BITARRAY_SET(block_header, index); + block_header[midx + 1] &= ~val; // BITARRAY_CLR(in_use, index); + + // mark the end of this block if msize is > 1. For msize == 0, the whole + // region is free, so there is no following block. For msize == 1, there is + // no space to write the size on 64 bit systems. The size for 1 quantum + // blocks is computed from the metadata bitmaps. + if (msize > 1) { + void *follower = FOLLOWING_TINY_PTR(ptr, msize); + TINY_PREVIOUS_MSIZE(follower) = msize; + TINY_FREE_SIZE(ptr) = msize; + } + if (msize == 0) { + TINY_FREE_SIZE(ptr) = msize; + } +#if DEBUG_MALLOC + boolean_t ff; + msize_t mf = get_tiny_meta_header(ptr, &ff); + if ((msize != mf) || !ff) { + malloc_printf("setting header for tiny free %p : %u\n", ptr, msize); + malloc_printf("reading header for tiny %p : %u %u\n", ptr, mf, ff); + } +#endif +} + +static MALLOC_INLINE boolean_t +tiny_meta_header_is_free(const void *ptr) +{ + uint32_t *block_header; + uint32_t *in_use; + msize_t index; + + block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); + in_use = TINY_INUSE_FOR_HEADER(block_header); + index = TINY_INDEX_FOR_PTR(ptr); + if (!BITARRAY_BIT(block_header, index)) { + return 0; + } + return !BITARRAY_BIT(in_use, index); +} + +static MALLOC_INLINE void * +tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) +{ + // returns the previous block, assuming and verifying it's free + uint32_t *block_header; + uint32_t *in_use; + msize_t index; + msize_t previous_msize; + msize_t previous_index; + void *previous_ptr; + + block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr); + in_use = TINY_INUSE_FOR_HEADER(block_header); + index = TINY_INDEX_FOR_PTR(ptr); + + if (!index) { + return NULL; + } + if ((previous_msize = get_tiny_previous_free_msize(ptr)) > index) { + return NULL; + } + + previous_index = index - previous_msize; + previous_ptr = (void *)((uintptr_t)TINY_REGION_FOR_PTR(ptr) + TINY_BYTES_FOR_MSIZE(previous_index)); + if (!BITARRAY_BIT(block_header, previous_index)) { + return NULL; + } + if (BITARRAY_BIT(in_use, previous_index)) { + return NULL; + } + if (get_tiny_free_size(previous_ptr) != previous_msize) { + return NULL; + } + + // conservative check did match true check + *prev_msize = previous_msize; + return previous_ptr; +} + +/* + * Adds an item to the proper free list, and also marks the meta-header of the + * block properly. + * Assumes szone has been locked + */ +static void +tiny_free_list_add_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize) +{ + grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; + tiny_free_list_t *free_ptr = ptr; + tiny_free_list_t *free_head = tiny_mag_ptr->mag_free_list[slot].p; + +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); + } + if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { + szone_error(szone, 1, "tiny_free_list_add_ptr: Unaligned ptr", ptr, NULL); + } +#endif + set_tiny_meta_header_free(ptr, msize); + if (free_head) { +#if DEBUG_MALLOC + if (free_list_unchecksum_ptr(szone, &free_head->previous)) { + szone_error(szone, 1, "tiny_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr, + "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, (void *)free_head, free_head->previous.p); + } + if (!tiny_meta_header_is_free(free_head)) { + szone_error(szone, 1, "tiny_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr, + "ptr=%p slot=%d free_head=%p\n", ptr, slot, (void *)free_head); + } +#endif + free_head->previous.u = free_list_checksum_ptr(szone, free_ptr); + } else { + BITMAPV_SET(tiny_mag_ptr->mag_bitmap, slot); + } + free_ptr->previous.u = free_list_checksum_ptr(szone, NULL); + free_ptr->next.u = free_list_checksum_ptr(szone, free_head); + + tiny_mag_ptr->mag_free_list[slot].p = free_ptr; +} + +/* + * Removes the item pointed to by ptr in the proper free list. + * Assumes szone has been locked + */ +static void +tiny_free_list_remove_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize) +{ + grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1; + tiny_free_list_t *free_ptr = ptr, *next, *previous; + + next = free_list_unchecksum_ptr(szone, &free_ptr->next); + previous = free_list_unchecksum_ptr(szone, &free_ptr->previous); + +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize); + } +#endif + if (!previous) { + // The block to remove is the head of the free list +#if DEBUG_MALLOC + if (tiny_mag_ptr->mag_free_list[slot] != ptr) { + szone_error(szone, 1, "tiny_free_list_remove_ptr: Internal invariant broken (tiny_mag_ptr->mag_free_list[slot])", ptr, + "ptr=%p slot=%d msize=%d tiny_mag_ptr->mag_free_list[slot]=%p\n", ptr, slot, msize, + (void *)tiny_mag_ptr->mag_free_list[slot]); + return; + } +#endif + tiny_mag_ptr->mag_free_list[slot].p = next; + if (!next) { + BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot); + } + } else { + // We know free_ptr is already checksummed, so we don't need to do it + // again. + previous->next = free_ptr->next; + } + if (next) { + // We know free_ptr is already checksummed, so we don't need to do it + // again. + next->previous = free_ptr->previous; + } +} + +void +tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr) +{ + void *last_block, *previous_block; + uint32_t *last_header; + msize_t last_msize, previous_msize, last_index; + + // It is possible that the block prior to the last block in the region has + // been free'd, but was not coalesced with the free bytes at the end of the + // block, since we treat the bytes at the end of the region as "in use" in + // the meta headers. Attempt to coalesce the last block with the previous + // block, so we don't violate the "no consecutive free blocks" invariant. + // + // FIXME: Need to investigate how much work would be required to increase + // 'mag_bytes_free_at_end' when freeing the preceding block, rather + // than performing this workaround. + // + + if (tiny_mag_ptr->mag_bytes_free_at_end) { + last_block = (void *)((uintptr_t)TINY_REGION_END(tiny_mag_ptr->mag_last_region) - tiny_mag_ptr->mag_bytes_free_at_end); + last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end); + last_header = TINY_BLOCK_HEADER_FOR_PTR(last_block); + last_index = TINY_INDEX_FOR_PTR(last_block); + + // Before anything we transform any remaining mag_bytes_free_at_end into a + // regular free block. We take special care here to update the bitfield + // information, since we are bypassing the normal free codepath. If there + // is more than one quanta worth of memory in mag_bytes_free_at_end, then + // there will be two block headers: + // 1) header for the free space at end, msize = 1 + // 2) header inserted by set_tiny_meta_header_in_use after block + // We must clear the second one so that when the free block's size is + // queried, we do not think the block is only 1 quantum in size because + // of the second set header bit. + if (last_index != (NUM_TINY_BLOCKS - 1)) { + BITARRAY_CLR(last_header, (last_index + 1)); + } + + previous_block = tiny_previous_preceding_free(last_block, &previous_msize); + if (previous_block) { + set_tiny_meta_header_middle(last_block); + tiny_free_list_remove_ptr(szone, tiny_mag_ptr, previous_block, previous_msize); + last_block = previous_block; + last_msize += previous_msize; + } + + // splice last_block into the free list + tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize); + tiny_mag_ptr->mag_bytes_free_at_end = 0; + } + +#if CONFIG_ASLR_INTERNAL + // Coalesce the big free block at start with any following free blocks + if (tiny_mag_ptr->mag_bytes_free_at_start) { + last_block = TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region); + last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start); + + void *next_block = (void *)((uintptr_t)last_block + tiny_mag_ptr->mag_bytes_free_at_start); + + // clear the in use bit we were using to mark the end of the big start block + set_tiny_meta_header_middle((void *)((uintptr_t)next_block - TINY_QUANTUM)); + + // Coalesce the big start block with any following free blocks + if (tiny_meta_header_is_free(next_block)) { + msize_t next_msize = get_tiny_free_size(next_block); + set_tiny_meta_header_middle(next_block); + tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); + last_msize += next_msize; + } + + // splice last_block into the free list + tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize); + tiny_mag_ptr->mag_bytes_free_at_start = 0; + } +#endif + + tiny_mag_ptr->mag_last_region = NULL; +} + +int +tiny_free_detach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r) +{ + uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); + uintptr_t current = start; + uintptr_t limit = (uintptr_t)TINY_REGION_END(r); + boolean_t is_free; + msize_t msize; + int total_alloc = 0; + + while (current < limit) { + msize = get_tiny_meta_header((void *)current, &is_free); + if (is_free && !msize && (current == start)) { + // first block is all free + break; + } + if (!msize) { +#if DEBUG_MALLOC + malloc_printf("*** tiny_free_detach_region error with %p: msize=%d is_free =%d\n", (void *)current, msize, is_free); +#endif + break; + } + if (is_free) { + tiny_free_list_remove_ptr(szone, tiny_mag_ptr, (void *)current, msize); + } else { + total_alloc++; + } + current += TINY_BYTES_FOR_MSIZE(msize); + } + return total_alloc; +} + +size_t +tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r) +{ + uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); + uintptr_t current = start; + uintptr_t limit = (uintptr_t)TINY_REGION_END(r); + boolean_t is_free; + msize_t msize; + size_t total_alloc = 0; + + while (current < limit) { + msize = get_tiny_meta_header((void *)current, &is_free); + if (is_free && !msize && (current == start)) { + // first block is all free + break; + } + if (!msize) { +#if DEBUG_MALLOC + malloc_printf("*** tiny_free_reattach_region error with %p: msize=%d is_free =%d\n", (void *)current, msize, is_free); +#endif + break; + } + if (is_free) { + tiny_free_list_add_ptr(szone, tiny_mag_ptr, (void *)current, msize); + } else { + total_alloc += TINY_BYTES_FOR_MSIZE(msize); + } + current += TINY_BYTES_FOR_MSIZE(msize); + } + return total_alloc; +} + +typedef struct { + uint8_t pnum, size; +} tiny_pg_pair_t; + +void +tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) +{ + uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r); + uintptr_t current = start; + uintptr_t limit = (uintptr_t)TINY_REGION_END(r); + boolean_t is_free; + msize_t msize; + tiny_pg_pair_t advisory[((TINY_REGION_PAYLOAD_BYTES + vm_page_quanta_size - 1) >> vm_page_quanta_shift) >> + 1]; // 256bytes stack allocated + int advisories = 0; + + // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list + // management data. + while (current < limit) { + msize = get_tiny_meta_header((void *)current, &is_free); + if (is_free && !msize && (current == start)) { + // first block is all free +#if DEBUG_MALLOC + malloc_printf("*** tiny_free_scan_madvise_free first block is all free! %p: msize=%d is_free =%d\n", (void *)current, + msize, is_free); +#endif + uintptr_t pgLo = round_page_kernel(start + sizeof(tiny_free_list_t) + sizeof(msize_t)); + uintptr_t pgHi = trunc_page_kernel(start + TINY_REGION_SIZE - sizeof(msize_t)); + + if (pgLo < pgHi) { + advisory[advisories].pnum = (pgLo - start) >> vm_kernel_page_shift; + advisory[advisories].size = (pgHi - pgLo) >> vm_kernel_page_shift; + advisories++; + } + break; + } + if (!msize) { +#if DEBUG_MALLOC + malloc_printf("*** tiny_free_scan_madvise_free error with %p: msize=%d is_free =%d\n", (void *)current, msize, is_free); +#endif + break; + } + if (is_free) { + uintptr_t pgLo = round_page_kernel(current + sizeof(tiny_free_list_t) + sizeof(msize_t)); + uintptr_t pgHi = trunc_page_kernel(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); + + if (pgLo < pgHi) { + advisory[advisories].pnum = (pgLo - start) >> vm_kernel_page_shift; + advisory[advisories].size = (pgHi - pgLo) >> vm_kernel_page_shift; + advisories++; + } + } + current += TINY_BYTES_FOR_MSIZE(msize); + } + + if (advisories > 0) { + int i; + + // So long as the following hold for this region: + // (1) No malloc()'s are ever performed from the depot (hence free pages remain free,) + // (2) The region is not handed over to a per-CPU magazine (where malloc()'s could be performed), + // (3) The entire region is not mumap()'d (so the madvise's are applied to the intended addresses), + // then the madvise opportunities collected just above can be applied outside all locks. + // (1) is ensured by design, (2) and (3) are ensured by bumping the globally visible counter node->pinned_to_depot. + + OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot)); + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + for (i = 0; i < advisories; ++i) { + uintptr_t addr = (advisory[i].pnum << vm_kernel_page_shift) + start; + size_t size = advisory[i].size << vm_kernel_page_shift; + + madvise_free_range(szone, r, addr, addr + size, NULL); + } + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot)); + } +} + +static region_t +tiny_find_msize_region(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) +{ + tiny_free_list_t *ptr; + grain_t slot = msize - 1; + free_list_t *free_list = tiny_mag_ptr->mag_free_list; + free_list_t *the_slot = free_list + slot; + free_list_t *limit; +#if defined(__LP64__) + uint64_t bitmap; +#else + uint32_t bitmap; +#endif + // Assumes we've locked the magazine + CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__); + + // Look for an exact match by checking the freelist for this msize. + ptr = the_slot->p; + if (ptr) { + return TINY_REGION_FOR_PTR(ptr); + } + + // Mask off the bits representing slots holding free blocks smaller than the + // size we need. If there are no larger free blocks, try allocating from + // the free space at the end of the tiny region. +#if defined(__LP64__) + bitmap = ((uint64_t *)(tiny_mag_ptr->mag_bitmap))[0] & ~((1ULL << slot) - 1); +#else + bitmap = tiny_mag_ptr->mag_bitmap[0] & ~((1 << slot) - 1); +#endif + if (!bitmap) { + return NULL; + } + + slot = BITMAPV_CTZ(bitmap); + limit = free_list + NUM_TINY_SLOTS - 1; + free_list += slot; + + if (free_list < limit) { + ptr = free_list->p; + if (ptr) { + return TINY_REGION_FOR_PTR(ptr); + } else { + /* Shouldn't happen. Fall through to look at last slot. */ +#if DEBUG_MALLOC + malloc_printf("in tiny_find_msize_region(), mag_bitmap out of sync, slot=%d\n", slot); +#endif + } + } + + // We are now looking at the last slot, which contains blocks equal to, or + // due to coalescing of free blocks, larger than (NUM_TINY_SLOTS - 1) * tiny quantum size. + ptr = limit->p; + if (ptr) { + return TINY_REGION_FOR_PTR(ptr); + } + + return NULL; +} + +static MALLOC_INLINE void +tiny_madvise_free_range_no_lock(szone_t *szone, + magazine_t *tiny_mag_ptr, + region_t region, + void *headptr, + size_t headsize, + void *ptr, + msize_t msize) +{ + region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(region); + + // Lock on tiny_magazines[mag_index] is already held here + // Calculate the first page in the coalesced block that would be safe to mark MADV_FREE + size_t free_header_size = sizeof(tiny_free_list_t) + sizeof(msize_t); + uintptr_t safe_ptr = (uintptr_t)ptr + free_header_size; + uintptr_t round_safe = round_page_kernel(safe_ptr); + + // Calculate the last page in the coalesced block that would be safe to mark MADV_FREE + size_t free_tail_size = sizeof(msize_t); + uintptr_t safe_extent = (uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize) - free_tail_size; + uintptr_t trunc_extent = trunc_page_kernel(safe_extent); + + // The newly freed block may complete a span of bytes that cover a page. Mark it with MADV_FREE. + if (round_safe < trunc_extent) { // Coalesced area covers a page (perhaps many) + // Extend the freed block by the free region header and tail sizes to include pages + // we may have coalesced that no longer host free region tails and headers. + // This may extend over in-use ranges, but the MIN/MAX clamping below will fix that up. + uintptr_t lo = trunc_page_kernel((uintptr_t)headptr - free_tail_size); + uintptr_t hi = round_page_kernel((uintptr_t)headptr + headsize + free_header_size); + + uintptr_t free_lo = MAX(round_safe, lo); + uintptr_t free_hi = MIN(trunc_extent, hi); + + if (free_lo < free_hi) { + tiny_free_list_remove_ptr(szone, tiny_mag_ptr, ptr, msize); + set_tiny_meta_header_in_use(ptr, msize); + + OSAtomicIncrement32Barrier(&(node->pinned_to_depot)); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + madvise_free_range(szone, region, free_lo, free_hi, &szone->last_tiny_advise); + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + OSAtomicDecrement32Barrier(&(node->pinned_to_depot)); + + set_tiny_meta_header_free(ptr, msize); + tiny_free_list_add_ptr(szone, tiny_mag_ptr, ptr, msize); + } + } +} + +static boolean_t +tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) +{ + magazine_t *depot_ptr = &(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); + + /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ + if (szone->num_tiny_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary + return 0; + } + +#if DEBUG_MALLOC + if (DEPOT_MAGAZINE_INDEX == mag_index) { + szone_error(szone, 1, "tiny_get_region_from_depot called for magazine index -1", NULL, NULL); + return 0; + } +#endif + + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + + // Appropriate a Depot'd region that can satisfy requested msize. + region_trailer_t *node; + region_t sparse_region; + + while (1) { + sparse_region = tiny_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize); + if (NULL == sparse_region) { // Depot empty? + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + return 0; + } + + node = REGION_TRAILER_FOR_TINY_REGION(sparse_region); + if (0 >= node->pinned_to_depot) { + break; + } + + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + yield(); + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + } + + // disconnect node from Depot + recirc_list_extract(szone, depot_ptr, node); + + // Iterate the region pulling its free entries off the (locked) Depot's free list + int objects_in_use = tiny_free_detach_region(szone, depot_ptr, sparse_region); + + // Transfer ownership of the region + MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = mag_index; + node->pinned_to_depot = 0; + + // Iterate the region putting its free entries on its new (locked) magazine's free list + size_t bytes_inplay = tiny_free_reattach_region(szone, tiny_mag_ptr, sparse_region); + + depot_ptr->mag_num_bytes_in_objects -= bytes_inplay; + depot_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; + depot_ptr->mag_num_objects -= objects_in_use; + + tiny_mag_ptr->mag_num_bytes_in_objects += bytes_inplay; + tiny_mag_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; + tiny_mag_ptr->mag_num_objects += objects_in_use; + + // connect to magazine as first node + recirc_list_splice_first(szone, tiny_mag_ptr, node); + + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + + // madvise() outside the Depot lock + (void)madvise_reuse_range(szone, sparse_region, (uintptr_t)sparse_region, (uintptr_t)sparse_region + TINY_REGION_PAYLOAD_BYTES); + + MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE, + (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe + + return 1; +} + +#if CONFIG_RECIRC_DEPOT +static region_t +tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node) +{ + if (0 < node->bytes_used || 0 < node->pinned_to_depot || depot_ptr->recirculation_entries < (szone->num_tiny_magazines * 2)) { + return NULL; + } + + // disconnect node from Depot + recirc_list_extract(szone, depot_ptr, node); + + // Iterate the region pulling its free entries off the (locked) Depot's free list + region_t sparse_region = TINY_REGION_FOR_PTR(node); + int objects_in_use = tiny_free_detach_region(szone, depot_ptr, sparse_region); + + if (0 == objects_in_use) { + // Invalidate the hash table entry for this region with HASHRING_REGION_DEALLOCATED. + // Using HASHRING_REGION_DEALLOCATED preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not. + rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->tiny_region_generation->hashed_regions, + szone->tiny_region_generation->num_regions_allocated, szone->tiny_region_generation->num_regions_allocated_shift, + sparse_region); + if (NULL == pSlot) { + szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region); + return NULL; + } + *pSlot = HASHRING_REGION_DEALLOCATED; + depot_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; + __sync_fetch_and_add(&(szone->num_tiny_regions_dealloc), 1); // Atomically increment num_tiny_regions_dealloc + + // Caller will transfer ownership of the region back to the OS with no locks held + MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, TINY_REGION_SIZE); // DTrace USDT Probe + return sparse_region; + } else { + szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use); + return NULL; + } +} + +static boolean_t +tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index) +{ + // The entire magazine crossed the "emptiness threshold". Transfer a region + // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e + // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. + region_trailer_t *node = tiny_mag_ptr->firstNode; + + while (node && !node->recirc_suitable) { + node = node->next; + } + + if (NULL == node) { +#if DEBUG_MALLOC + malloc_printf("*** tiny_free_do_recirc_to_depot end of list\n"); +#endif + return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + } + + region_t sparse_region = TINY_REGION_FOR_PTR(node); + + // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start + if (sparse_region == tiny_mag_ptr->mag_last_region && + (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start)) { + tiny_finalize_region(szone, tiny_mag_ptr); + } + + // disconnect "suitable" node from magazine + recirc_list_extract(szone, tiny_mag_ptr, node); + + // Iterate the region pulling its free entries off its (locked) magazine's free list + int objects_in_use = tiny_free_detach_region(szone, tiny_mag_ptr, sparse_region); + magazine_t *depot_ptr = &(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]); + + // hand over the region to the (locked) Depot + SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr); + // this will cause tiny_free_list_add_ptr called by tiny_free_reattach_region to use + // the depot as its target magazine, rather than magazine formerly associated with sparse_region + MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX; + node->pinned_to_depot = 0; + + // Iterate the region putting its free entries on Depot's free list + size_t bytes_inplay = tiny_free_reattach_region(szone, depot_ptr, sparse_region); + + tiny_mag_ptr->mag_num_bytes_in_objects -= bytes_inplay; + tiny_mag_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES; + tiny_mag_ptr->mag_num_objects -= objects_in_use; + + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); // Unlock the originating magazine + + depot_ptr->mag_num_bytes_in_objects += bytes_inplay; + depot_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; + depot_ptr->mag_num_objects += objects_in_use; + + // connect to Depot as last node + recirc_list_splice_last(szone, depot_ptr, node); + + MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE, + (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe + +#if !CONFIG_AGGRESSIVE_MADVISE + // Mark free'd dirty pages with MADV_FREE to reduce memory pressure + tiny_free_scan_madvise_free(szone, depot_ptr, sparse_region); +#endif + + // If the region is entirely empty vm_deallocate() it outside the depot lock + region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, depot_ptr, node); + SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr); + if (r_dealloc) { + deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0); + } + return FALSE; // Caller need not unlock the originating magazine +} + +static MALLOC_INLINE boolean_t +tiny_free_try_recirc_to_depot(szone_t *szone, + magazine_t *tiny_mag_ptr, + mag_index_t mag_index, + region_t region, + void *headptr, + size_t headsize, + void *ptr, + msize_t msize) +{ + region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(region); + size_t bytes_used = node->bytes_used; + + /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */ + if (szone->num_tiny_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary + /* NOTHING */ + return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr) + } else if (DEPOT_MAGAZINE_INDEX != mag_index) { + // Emptiness discriminant + if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) { + /* Region has crossed threshold from density to sparsity. Mark it "suitable" on the + * recirculation candidates list. */ + node->recirc_suitable = TRUE; + } else { + /* After this free, we've found the region is still dense, so it must have been even more so before + * the free. That implies the region is already correctly marked. Do nothing. */ + } + + // Has the entire magazine crossed the "emptiness threshold"? If so, transfer a region + // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e + // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list. + size_t a = tiny_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine + size_t u = tiny_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine + + if (a - u > ((3 * TINY_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) { + return tiny_free_do_recirc_to_depot(szone, tiny_mag_ptr, mag_index); + } + } else { +#if !CONFIG_AGGRESSIVE_MADVISE + // We are free'ing into the depot, so madvise as we do so unless we were madvising every incoming + // allocation anyway. + tiny_madvise_free_range_no_lock(szone, tiny_mag_ptr, region, headptr, headsize, ptr, msize); +#endif + + if (0 < bytes_used || 0 < node->pinned_to_depot) { + /* Depot'd region is still live. Leave it in place on the Depot's recirculation list + * so as to avoid thrashing between the Depot's free list and a magazines's free list + * with detach_region/reattach_region */ + } else { + /* Depot'd region is just now empty. Consider return to OS. */ + region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, tiny_mag_ptr, node); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + if (r_dealloc) { + deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0); + } + return FALSE; // Caller need not unlock + } + } + return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr) +} +#endif // CONFIG_RECIRC_DEPOT + +boolean_t +tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize) +{ + void *original_ptr = ptr; + size_t original_size = TINY_BYTES_FOR_MSIZE(msize); + void *next_block = ((unsigned char *)ptr + original_size); + msize_t previous_msize, next_msize; + void *previous; + tiny_free_list_t *big_free_block; + tiny_free_list_t *after_next_block; + tiny_free_list_t *before_next_block; + +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize); + } + if (!msize) { + szone_error(szone, 1, "trying to free tiny block that is too small", ptr, "in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, + msize); + } +#endif + + // We try to coalesce this block with the preceeding one + previous = tiny_previous_preceding_free(ptr, &previous_msize); + if (previous) { +#if DEBUG_MALLOC + if (LOG(szone, ptr) || LOG(szone, previous)) { + malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous); + } +#endif + + // clear the meta_header since this is no longer the start of a block + set_tiny_meta_header_middle(ptr); + tiny_free_list_remove_ptr(szone, tiny_mag_ptr, previous, previous_msize); + ptr = previous; + msize += previous_msize; + } + // We try to coalesce with the next block + if ((next_block < TINY_REGION_END(region)) && tiny_meta_header_is_free(next_block)) { + next_msize = get_tiny_free_size(next_block); +#if DEBUG_MALLOC + if (LOG(szone, ptr) || LOG(szone, next_block)) { + malloc_printf("in tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n", ptr, msize, + next_block, next_msize); + } +#endif + // If we are coalescing with the next block, and the next block is in + // the last slot of the free list, then we optimize this case here to + // avoid removing next_block from the slot (NUM_TINY_SLOTS - 1) and then adding ptr back + // to slot (NUM_TINY_SLOTS - 1). + if (next_msize >= NUM_TINY_SLOTS) { + msize += next_msize; + + big_free_block = (tiny_free_list_t *)next_block; + after_next_block = free_list_unchecksum_ptr(szone, &big_free_block->next); + before_next_block = free_list_unchecksum_ptr(szone, &big_free_block->previous); + + if (!before_next_block) { + tiny_mag_ptr->mag_free_list[NUM_TINY_SLOTS - 1].p = ptr; + } else { + before_next_block->next.u = free_list_checksum_ptr(szone, ptr); + } + + if (after_next_block) { + after_next_block->previous.u = free_list_checksum_ptr(szone, ptr); + } + + // we don't need to checksum these since they are already checksummed + ((tiny_free_list_t *)ptr)->previous = big_free_block->previous; + ((tiny_free_list_t *)ptr)->next = big_free_block->next; + + // clear the meta_header to enable coalescing backwards + set_tiny_meta_header_middle(big_free_block); + set_tiny_meta_header_free(ptr, msize); + + goto tiny_free_ending; + } + tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); + set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards + msize += next_msize; + } + + // The tiny cache already scribbles free blocks as they go through the + // cache whenever msize < TINY_QUANTUM , so we do not need to do it here. + if ((szone->debug_flags & MALLOC_DO_SCRIBBLE) && msize && (msize >= TINY_QUANTUM)) { + memset(ptr, SCRABBLE_BYTE, TINY_BYTES_FOR_MSIZE(msize)); + } + + tiny_free_list_add_ptr(szone, tiny_mag_ptr, ptr, msize); + +tiny_free_ending: + + tiny_mag_ptr->mag_num_objects--; + // we use original_size and not msize to avoid double counting the coalesced blocks + tiny_mag_ptr->mag_num_bytes_in_objects -= original_size; + + // Update this region's bytes in use count + region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(region); + size_t bytes_used = node->bytes_used - original_size; + node->bytes_used = (unsigned int)bytes_used; + +#if CONFIG_AGGRESSIVE_MADVISE + // Platforms that want to madvise every freed allocation do so here, even if we continue + // on to use the recirc depot after. + tiny_madvise_free_range_no_lock(szone, tiny_mag_ptr, region, original_ptr, original_size, ptr, msize); +#endif + + // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr) if this function + // returns TRUE. + boolean_t needs_unlock = TRUE; + +#if CONFIG_RECIRC_DEPOT + needs_unlock = tiny_free_try_recirc_to_depot(szone, tiny_mag_ptr, mag_index, region, original_ptr, original_size, ptr, msize); +#endif + return needs_unlock; +} + +// Allocates from the last region or a freshly allocated region +static void * +tiny_malloc_from_region_no_lock(szone_t *szone, + magazine_t *tiny_mag_ptr, + mag_index_t mag_index, + msize_t msize, + void *aligned_address) +{ + void *ptr; + + // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start + if (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start) { + tiny_finalize_region(szone, tiny_mag_ptr); + } + + // We set the unused bits of the header in the last pair to be all ones, and those of the inuse to zeroes. + ((tiny_region_t)aligned_address)->pairs[CEIL_NUM_TINY_BLOCKS_WORDS - 1].header = + (NUM_TINY_BLOCKS & 31) ? (0xFFFFFFFFU << (NUM_TINY_BLOCKS & 31)) : 0; + ((tiny_region_t)aligned_address)->pairs[CEIL_NUM_TINY_BLOCKS_WORDS - 1].inuse = 0; + + // Here find the only place in tinyland that (infrequently) takes the tiny_regions_lock. + // Only one thread at a time should be permitted to assess the density of the hash + // ring and adjust if needed. + // Only one thread at a time should be permitted to insert its new region on + // the hash ring. + // It is safe for all other threads to read the hash ring (hashed_regions) and + // the associated sizes (num_regions_allocated and num_tiny_regions). + + _malloc_lock_lock(&szone->tiny_regions_lock); + + // Check to see if the hash ring of tiny regions needs to grow. Try to + // avoid the hash ring becoming too dense. + if (szone->tiny_region_generation->num_regions_allocated < (2 * szone->num_tiny_regions)) { + region_t *new_regions; + size_t new_size; + size_t new_shift = szone->tiny_region_generation->num_regions_allocated_shift; // In/Out parameter + new_regions = hash_regions_grow_no_lock(szone, szone->tiny_region_generation->hashed_regions, + szone->tiny_region_generation->num_regions_allocated, &new_shift, &new_size); + // Do not deallocate the current hashed_regions allocation since someone may + // be iterating it. Instead, just leak it. + + // Prepare to advance to the "next generation" of the hash ring. + szone->tiny_region_generation->nextgen->hashed_regions = new_regions; + szone->tiny_region_generation->nextgen->num_regions_allocated = new_size; + szone->tiny_region_generation->nextgen->num_regions_allocated_shift = new_shift; + + // Throw the switch to atomically advance to the next generation. + szone->tiny_region_generation = szone->tiny_region_generation->nextgen; + // Ensure everyone sees the advance. + OSMemoryBarrier(); + } + // Tag the region at "aligned_address" as belonging to us, + // and so put it under the protection of the magazine lock we are holding. + // Do this before advertising "aligned_address" on the hash ring(!) + MAGAZINE_INDEX_FOR_TINY_REGION(aligned_address) = mag_index; + + // Insert the new region into the hash ring, and update malloc statistics + hash_region_insert_no_lock(szone->tiny_region_generation->hashed_regions, szone->tiny_region_generation->num_regions_allocated, + szone->tiny_region_generation->num_regions_allocated_shift, aligned_address); + + szone->num_tiny_regions++; + _malloc_lock_unlock(&szone->tiny_regions_lock); + + tiny_mag_ptr->mag_last_region = aligned_address; + BYTES_USED_FOR_TINY_REGION(aligned_address) = TINY_BYTES_FOR_MSIZE(msize); +#if CONFIG_ASLR_INTERNAL + int offset_msize = malloc_entropy[0] & TINY_ENTROPY_MASK; +#if DEBUG_MALLOC + if (getenv("MallocASLRForce")) { + offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & TINY_ENTROPY_MASK; + } + if (getenv("MallocASLRPrint")) { + malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize); + } +#endif +#else + int offset_msize = 0; +#endif + ptr = (void *)((uintptr_t)aligned_address + TINY_BYTES_FOR_MSIZE(offset_msize)); + set_tiny_meta_header_in_use(ptr, msize); + tiny_mag_ptr->mag_num_objects++; + tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(msize); + tiny_mag_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES; + + // We put a header on the last block so that it appears in use (for coalescing, etc...) + set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize))); + tiny_mag_ptr->mag_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize - offset_msize); + +#if CONFIG_ASLR_INTERNAL + // Put a header on the previous block for same reason + tiny_mag_ptr->mag_bytes_free_at_start = TINY_BYTES_FOR_MSIZE(offset_msize); + if (offset_msize) { + set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr - TINY_QUANTUM)); + } +#else + tiny_mag_ptr->mag_bytes_free_at_start = 0; +#endif + + // connect to magazine as last node + recirc_list_splice_last(szone, tiny_mag_ptr, REGION_TRAILER_FOR_TINY_REGION(aligned_address)); + +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_from_region_no_lock(), ptr=%p, msize=%d\n", ptr, msize); + } +#endif + return ptr; +} + +void * +tiny_memalign(szone_t *szone, size_t alignment, size_t size, size_t span) +{ + msize_t mspan = TINY_MSIZE_FOR_BYTES(span + TINY_QUANTUM - 1); + void *p = szone_malloc(szone, span); // avoids inlining tiny_malloc_should_clear(szone, mspan, 0); + + if (NULL == p) { + return NULL; + } + + size_t offset = ((uintptr_t)p) & (alignment - 1); // p % alignment + size_t pad = (0 == offset) ? 0 : alignment - offset; // p + pad achieves desired alignment + + msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1); + msize_t mpad = TINY_MSIZE_FOR_BYTES(pad + TINY_QUANTUM - 1); + msize_t mwaste = mspan - msize - mpad; // excess blocks + + if (mpad > 0) { + void *q = (void *)(((uintptr_t)p) + pad); + + // Mark q as a block header and in-use, thus creating two blocks. + magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, + REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)), MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p))); + set_tiny_meta_header_in_use(q, msize); + tiny_mag_ptr->mag_num_objects++; + + // set_tiny_meta_header_in_use() "reaffirms" the block_header on the *following* block, so + // now set its in_use bit as well. But only if its within the original allocation made above. + if (mwaste > 0) { + BITARRAY_SET(TINY_INUSE_FOR_HEADER(TINY_BLOCK_HEADER_FOR_PTR(q)), TINY_INDEX_FOR_PTR(q) + msize); + } + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + + // Give up mpad blocks beginning at p to the tiny free list + // region_t r = TINY_REGION_FOR_PTR(p); + szone_free(szone, p); // avoids inlining free_tiny(szone, p, &r); + + p = q; // advance p to the desired alignment + } + + if (mwaste > 0) { + void *q = (void *)(((uintptr_t)p) + TINY_BYTES_FOR_MSIZE(msize)); + // Mark q as block header and in-use, thus creating two blocks. + magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, + REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)), MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p))); + set_tiny_meta_header_in_use(q, mwaste); + tiny_mag_ptr->mag_num_objects++; + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + + // Give up mwaste blocks beginning at q to the tiny free list + // region_t r = TINY_REGION_FOR_PTR(q); + szone_free(szone, q); // avoids inlining free_tiny(szone, q, &r); + } + + return p; // p has the desired size and alignment, and can later be free()'d +} + +void * +tiny_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size) +{ + msize_t new_msize = TINY_MSIZE_FOR_BYTES(new_good_size); + msize_t mshrinkage = TINY_MSIZE_FOR_BYTES(old_size) - new_msize; + + if (mshrinkage) { + void *q = (void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(new_msize)); + magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, + REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)), MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr))); + + // Mark q as block header and in-use, thus creating two blocks. + set_tiny_meta_header_in_use(q, mshrinkage); + tiny_mag_ptr->mag_num_objects++; + + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + szone_free(szone, q); // avoid inlining free_tiny(szone, q, ...); + } + return ptr; +} + +boolean_t +tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) +{ + // returns 1 on success + msize_t index; + msize_t old_msize; + unsigned next_index; + void *next_block; + boolean_t is_free; + msize_t next_msize, coalesced_msize, leftover_msize; + void *leftover; + + index = TINY_INDEX_FOR_PTR(ptr); + old_msize = TINY_MSIZE_FOR_BYTES(old_size); + next_index = index + old_msize; + + if (next_index >= NUM_TINY_BLOCKS) { + return 0; + } + next_block = (char *)ptr + old_size; + + magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines, + REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)), MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr))); + + if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr))) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return 0; + } + + /* + * Look for a free block immediately afterwards. If it's large enough, we can consume (part of) + * it. + */ + is_free = tiny_meta_header_is_free(next_block); + if (!is_free) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return 0; // next_block is in use; + } + next_msize = get_tiny_free_size(next_block); + if (old_size + TINY_BYTES_FOR_MSIZE(next_msize) < new_size) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return 0; // even with next block, not enough + } + /* + * The following block is big enough; pull it from its freelist and chop off enough to satisfy + * our needs. + */ + tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize); + set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards + coalesced_msize = TINY_MSIZE_FOR_BYTES(new_size - old_size + TINY_QUANTUM - 1); + leftover_msize = next_msize - coalesced_msize; + if (leftover_msize) { + /* there's some left, so put the remainder back */ + leftover = (void *)((uintptr_t)next_block + TINY_BYTES_FOR_MSIZE(coalesced_msize)); + + tiny_free_list_add_ptr(szone, tiny_mag_ptr, leftover, leftover_msize); + } + set_tiny_meta_header_in_use(ptr, old_msize + coalesced_msize); +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_try_realloc_in_place(), ptr=%p, msize=%d\n", ptr, old_msize + coalesced_msize); + } +#endif + tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(coalesced_msize); + + // Update this region's bytes in use count + region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); + size_t bytes_used = node->bytes_used + TINY_BYTES_FOR_MSIZE(coalesced_msize); + node->bytes_used = (unsigned int)bytes_used; + + // Emptiness discriminant + if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) { + /* After this reallocation the region is still sparse, so it must have been even more so before + * the reallocation. That implies the region is already correctly marked. Do nothing. */ + } else { + /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the + * recirculation candidates list. */ + node->recirc_suitable = FALSE; + } + + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + return 1; +} + +boolean_t +tiny_check_region(szone_t *szone, region_t region) +{ + uintptr_t start, ptr, region_end; + boolean_t prev_free = 0; + boolean_t is_free; + msize_t msize; + tiny_free_list_t *free_head; + void *follower, *previous, *next; + mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(region); + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); + + // Assumes locked + CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__); + + /* establish region limits */ + start = (uintptr_t)TINY_REGION_ADDRESS(region); + ptr = start; + if (region == tiny_mag_ptr->mag_last_region) { + ptr += tiny_mag_ptr->mag_bytes_free_at_start; + + /* + * Check the leading block's integrity here also. + */ + if (tiny_mag_ptr->mag_bytes_free_at_start) { + msize = get_tiny_meta_header((void *)(ptr - TINY_QUANTUM), &is_free); + if (is_free || (msize != 1)) { + malloc_printf("*** invariant broken for leader block %p - %d %d\n", ptr - TINY_QUANTUM, msize, is_free); + } + } + } + region_end = (uintptr_t)TINY_REGION_END(region); + + /* + * The last region may have a trailing chunk which has not been converted into inuse/freelist + * blocks yet. + */ + if (region == tiny_mag_ptr->mag_last_region) { + region_end -= tiny_mag_ptr->mag_bytes_free_at_end; + } + + /* + * Scan blocks within the region. + */ + while (ptr < region_end) { + /* + * If the first block is free, and its size is 65536 (msize = 0) then the entire region is + * free. + */ + msize = get_tiny_meta_header((void *)ptr, &is_free); + if (is_free && !msize && (ptr == start)) { + return 1; + } + + /* + * If the block's size is 65536 (msize = 0) then since we're not the first entry the size is + * corrupt. + */ + if (!msize) { + malloc_printf("*** invariant broken for tiny block %p this msize=%d - size is too small\n", ptr, msize); + return 0; + } + + if (!is_free) { + /* + * In use blocks cannot be more than (NUM_TINY_SLOTS - 1) quanta large. + */ + prev_free = 0; + if (msize > (NUM_TINY_SLOTS - 1)) { + malloc_printf("*** invariant broken for %p this tiny msize=%d - size is too large\n", ptr, msize); + return 0; + } + /* move to next block */ + ptr += TINY_BYTES_FOR_MSIZE(msize); + } else { +#if !CONFIG_RELAXED_INVARIANT_CHECKS + /* + * Free blocks must have been coalesced, we cannot have a free block following another + * free block. + */ + if (prev_free) { + malloc_printf("*** invariant broken for free block %p this tiny msize=%d: two free blocks in a row\n", ptr, msize); + return 0; + } +#endif // CONFIG_RELAXED_INVARIANT_CHECKS + prev_free = 1; + /* + * Check the integrity of this block's entry in its freelist. + */ + free_head = (tiny_free_list_t *)ptr; + previous = free_list_unchecksum_ptr(szone, &free_head->previous); + next = free_list_unchecksum_ptr(szone, &free_head->next); + if (previous && !tiny_meta_header_is_free(previous)) { + malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n", ptr, previous); + return 0; + } + if (next && !tiny_meta_header_is_free(next)) { + malloc_printf("*** invariant broken for %p (next in free list %p is not a free pointer)\n", ptr, next); + return 0; + } + /* + * Check the free block's trailing size value. + */ + follower = FOLLOWING_TINY_PTR(ptr, msize); + if (((uintptr_t)follower != region_end) && (get_tiny_previous_free_msize(follower) != msize)) { + malloc_printf( + "*** invariant broken for tiny free %p followed by %p in region [%p-%p] " + "(end marker incorrect) should be %d; in fact %d\n", + ptr, follower, TINY_REGION_ADDRESS(region), region_end, msize, get_tiny_previous_free_msize(follower)); + return 0; + } + /* move to next block */ + ptr = (uintptr_t)follower; + } + } + /* + * Ensure that we scanned the entire region + */ + if (ptr != region_end) { + malloc_printf("*** invariant broken for region end %p - %p\n", ptr, region_end); + return 0; + } + /* + * Check the trailing block's integrity. + */ + if (region == tiny_mag_ptr->mag_last_region) { + if (tiny_mag_ptr->mag_bytes_free_at_end) { + msize = get_tiny_meta_header((void *)ptr, &is_free); + if (is_free || (msize != 1)) { + malloc_printf("*** invariant broken for blocker block %p - %d %d\n", ptr, msize, is_free); + } + } + } + return 1; +} + +kern_return_t +tiny_in_use_enumerator(task_t task, + void *context, + unsigned type_mask, + szone_t *szone, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + size_t num_regions; + size_t index; + region_t *regions; + vm_range_t buffer[MAX_RECORDER_BUFFER]; + unsigned count = 0; + kern_return_t err; + region_t region; + vm_range_t range; + vm_range_t admin_range; + vm_range_t ptr_range; + unsigned char *mapped_region; + uint32_t *block_header; + uint32_t *in_use; + unsigned block_index; + unsigned block_limit; + boolean_t is_free; + msize_t msize; + void *mapped_ptr; + unsigned bit; + magazine_t *tiny_mag_base = NULL; + + region_hash_generation_t *trg_ptr; + err = reader(task, (vm_address_t)szone->tiny_region_generation, sizeof(region_hash_generation_t), (void **)&trg_ptr); + if (err) { + return err; + } + + num_regions = trg_ptr->num_regions_allocated; + err = reader(task, (vm_address_t)trg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions); + if (err) { + return err; + } + + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + // Map in all active magazines. Do this outside the iteration over regions. + err = reader(task, (vm_address_t)(szone->tiny_magazines), szone->num_tiny_magazines * sizeof(magazine_t), + (void **)&tiny_mag_base); + if (err) { + return err; + } + } + + for (index = 0; index < num_regions; ++index) { + region = regions[index]; + if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) { + range.address = (vm_address_t)TINY_REGION_ADDRESS(region); + range.size = (vm_size_t)TINY_REGION_SIZE; + if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { + admin_range.address = range.address + TINY_METADATA_START; + admin_range.size = TINY_METADATA_SIZE; + recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1); + } + if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { + ptr_range.address = range.address; + ptr_range.size = NUM_TINY_BLOCKS * TINY_QUANTUM; + recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1); + } + if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { + void *mag_last_free; + vm_address_t mag_last_free_ptr = 0; + msize_t mag_last_free_msize = 0; + + err = reader(task, range.address, range.size, (void **)&mapped_region); + if (err) { + return err; + } + + mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(mapped_region); + magazine_t *tiny_mag_ptr = tiny_mag_base + mag_index; + + if (DEPOT_MAGAZINE_INDEX != mag_index) { + mag_last_free = tiny_mag_ptr->mag_last_free; + if (mag_last_free) { + mag_last_free_ptr = (uintptr_t)mag_last_free & ~(TINY_QUANTUM - 1); + mag_last_free_msize = (uintptr_t)mag_last_free & (TINY_QUANTUM - 1); + } + } else { + for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) { + if ((void *)range.address == (tiny_mag_base + mag_index)->mag_last_free_rgn) { + mag_last_free = (tiny_mag_base + mag_index)->mag_last_free; + if (mag_last_free) { + mag_last_free_ptr = (uintptr_t)mag_last_free & ~(TINY_QUANTUM - 1); + mag_last_free_msize = (uintptr_t)mag_last_free & (TINY_QUANTUM - 1); + } + } + } + } + + block_header = (uint32_t *)(mapped_region + TINY_METADATA_START + sizeof(region_trailer_t)); + in_use = TINY_INUSE_FOR_HEADER(block_header); + block_index = 0; + block_limit = NUM_TINY_BLOCKS; + if (region == tiny_mag_ptr->mag_last_region) { + block_index += TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start); + block_limit -= TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end); + } + + while (block_index < block_limit) { + vm_size_t block_offset = TINY_BYTES_FOR_MSIZE(block_index); + is_free = !BITARRAY_BIT(in_use, block_index); + if (is_free) { + mapped_ptr = mapped_region + block_offset; + + // mapped_region, the address at which 'range' in 'task' has been + // mapped into our process, is not necessarily aligned to + // TINY_BLOCKS_ALIGN. + // + // Since the code in get_tiny_free_size() assumes the pointer came + // from a properly aligned tiny region, and mapped_region is not + // necessarily aligned, then do the size calculation directly. + // If the next bit is set in the header bitmap, then the size is one + // quantum. Otherwise, read the size field. + if (!BITARRAY_BIT(block_header, (block_index + 1))) { + msize = TINY_FREE_SIZE(mapped_ptr); + } else { + msize = 1; + } + + } else if (range.address + block_offset != mag_last_free_ptr) { + msize = 1; + bit = block_index + 1; + while (!BITARRAY_BIT(block_header, bit)) { + bit++; + msize++; + } + buffer[count].address = range.address + block_offset; + buffer[count].size = TINY_BYTES_FOR_MSIZE(msize); + count++; + if (count >= MAX_RECORDER_BUFFER) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + count = 0; + } + } else { + // Block is not free but it matches mag_last_free_ptr so even + // though it is not marked free in the bitmap, we treat it as if + // it is and move on + msize = mag_last_free_msize; + } + + if (!msize) { + return KERN_FAILURE; // Somethings amiss. Avoid looping at this block_index. + } + block_index += msize; + } + if (count) { + recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count); + count = 0; + } + } + } + } + return 0; +} + +void * +tiny_malloc_from_free_list(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize) +{ + tiny_free_list_t *ptr; + msize_t this_msize; + grain_t slot = msize - 1; + free_list_t *free_list = tiny_mag_ptr->mag_free_list; + free_list_t *the_slot = free_list + slot; + tiny_free_list_t *next; + free_list_t *limit; +#if defined(__LP64__) + uint64_t bitmap; +#else + uint32_t bitmap; +#endif + msize_t leftover_msize; + tiny_free_list_t *leftover_ptr; + + // Assumes we've locked the region + CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__); + + // Look for an exact match by checking the freelist for this msize. + // + ptr = the_slot->p; + if (ptr) { + next = free_list_unchecksum_ptr(szone, &ptr->next); + if (next) { + next->previous = ptr->previous; + } else { + BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot); + } + the_slot->p = next; + this_msize = msize; +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize); + } +#endif + goto return_tiny_alloc; + } + + // Mask off the bits representing slots holding free blocks smaller than the + // size we need. If there are no larger free blocks, try allocating from + // the free space at the end of the tiny region. +#if defined(__LP64__) + bitmap = ((uint64_t *)(tiny_mag_ptr->mag_bitmap))[0] & ~((1ULL << slot) - 1); +#else + bitmap = tiny_mag_ptr->mag_bitmap[0] & ~((1 << slot) - 1); +#endif + if (!bitmap) { + goto try_tiny_malloc_from_end; + } + + slot = BITMAPV_CTZ(bitmap); + limit = free_list + NUM_TINY_SLOTS - 1; + free_list += slot; + + if (free_list < limit) { + ptr = free_list->p; + if (ptr) { + next = free_list_unchecksum_ptr(szone, &ptr->next); + free_list->p = next; + if (next) { + next->previous = ptr->previous; + } else { + BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot); + } + this_msize = get_tiny_free_size(ptr); + goto add_leftover_and_proceed; + } +#if DEBUG_MALLOC + malloc_printf("in tiny_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n", slot); +#endif + } + + // We are now looking at the last slot, which contains blocks equal to, or + // due to coalescing of free blocks, larger than (NUM_TINY_SLOTS - 1) * tiny quantum size. + // If the last freelist is not empty, and the head contains a block that is + // larger than our request, then the remainder is put back on the free list. + ptr = limit->p; + if (ptr) { + this_msize = get_tiny_free_size(ptr); + next = free_list_unchecksum_ptr(szone, &ptr->next); + if (this_msize - msize >= NUM_TINY_SLOTS) { + // the leftover will go back to the free list, so we optimize by + // modifying the free list rather than a pop and push of the head + leftover_msize = this_msize - msize; + leftover_ptr = (tiny_free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); + limit->p = leftover_ptr; + if (next) { + next->previous.u = free_list_checksum_ptr(szone, leftover_ptr); + } + leftover_ptr->previous = ptr->previous; + leftover_ptr->next = ptr->next; + set_tiny_meta_header_free(leftover_ptr, leftover_msize); +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf( + "in tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize); + } +#endif + this_msize = msize; + goto return_tiny_alloc; + } + if (next) { + next->previous = ptr->previous; + } + limit->p = next; + goto add_leftover_and_proceed; + /* NOTREACHED */ + } + +try_tiny_malloc_from_end: + // Let's see if we can use tiny_mag_ptr->mag_bytes_free_at_end + if (tiny_mag_ptr->mag_bytes_free_at_end >= TINY_BYTES_FOR_MSIZE(msize)) { + ptr = (tiny_free_list_t *)((uintptr_t)TINY_REGION_END(tiny_mag_ptr->mag_last_region) - tiny_mag_ptr->mag_bytes_free_at_end); + tiny_mag_ptr->mag_bytes_free_at_end -= TINY_BYTES_FOR_MSIZE(msize); + if (tiny_mag_ptr->mag_bytes_free_at_end) { + // let's add an in use block after ptr to serve as boundary + set_tiny_meta_header_in_use_1((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); + } + this_msize = msize; +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize); + } +#endif + goto return_tiny_alloc; + } +#if CONFIG_ASLR_INTERNAL + // Try from start if nothing left at end + if (tiny_mag_ptr->mag_bytes_free_at_start >= TINY_BYTES_FOR_MSIZE(msize)) { + ptr = (tiny_free_list_t *)(TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region) + tiny_mag_ptr->mag_bytes_free_at_start - + TINY_BYTES_FOR_MSIZE(msize)); + tiny_mag_ptr->mag_bytes_free_at_start -= TINY_BYTES_FOR_MSIZE(msize); + if (tiny_mag_ptr->mag_bytes_free_at_start) { + // let's add an in use block before ptr to serve as boundary + set_tiny_meta_header_in_use_1((unsigned char *)ptr - TINY_QUANTUM); + } + this_msize = msize; +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), from start ptr=%p, msize=%d\n", ptr, msize); + } +#endif + goto return_tiny_alloc; + } +#endif + return NULL; + +add_leftover_and_proceed: + if (!this_msize || (this_msize > msize)) { + leftover_msize = this_msize - msize; + leftover_ptr = (tiny_free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize)); +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize); + } +#endif + tiny_free_list_add_ptr(szone, tiny_mag_ptr, leftover_ptr, leftover_msize); + this_msize = msize; + } + +return_tiny_alloc: + tiny_mag_ptr->mag_num_objects++; + tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(this_msize); + + // Update this region's bytes in use count + region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); + size_t bytes_used = node->bytes_used + TINY_BYTES_FOR_MSIZE(this_msize); + node->bytes_used = (unsigned int)bytes_used; + + // Emptiness discriminant + if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) { + /* After this allocation the region is still sparse, so it must have been even more so before + * the allocation. That implies the region is already correctly marked. Do nothing. */ + } else { + /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the + * recirculation candidates list. */ + node->recirc_suitable = FALSE; + } +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize); + } +#endif + if (this_msize > 1) { + set_tiny_meta_header_in_use(ptr, this_msize); + } else { + set_tiny_meta_header_in_use_1(ptr); + } + return ptr; +} + +void * +tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) +{ + void *ptr; + mag_index_t mag_index = mag_get_thread_index(szone); + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); + + MALLOC_TRACE(TRACE_tiny_malloc, (uintptr_t)szone, TINY_BYTES_FOR_MSIZE(msize), (uintptr_t)tiny_mag_ptr, cleared_requested); + +#if DEBUG_MALLOC + if (DEPOT_MAGAZINE_INDEX == mag_index) { + szone_error(szone, 1, "malloc called for magazine index -1", NULL, NULL); + return (NULL); + } + + if (!msize) { + szone_error(szone, 1, "invariant broken (!msize) in allocation (region)", NULL, NULL); + return (NULL); + } +#endif + + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + +#if CONFIG_TINY_CACHE + ptr = tiny_mag_ptr->mag_last_free; + + if ((((uintptr_t)ptr) & (TINY_QUANTUM - 1)) == msize) { + // we have a winner + tiny_mag_ptr->mag_last_free = NULL; + tiny_mag_ptr->mag_last_free_rgn = NULL; + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + ptr = (void *)((uintptr_t)ptr & ~(TINY_QUANTUM - 1)); + if (cleared_requested) { + memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); + } +#if DEBUG_MALLOC + if (LOG(szone, ptr)) { + malloc_printf("in tiny_malloc_should_clear(), tiny cache ptr=%p, msize=%d\n", ptr, msize); + } +#endif + return ptr; + } +#endif /* CONFIG_TINY_CACHE */ + + while (1) { + ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); + if (ptr) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + if (cleared_requested) { + memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); + } + return ptr; + } + + if (tiny_get_region_from_depot(szone, tiny_mag_ptr, mag_index, msize)) { + ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize); + if (ptr) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + if (cleared_requested) { + memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize)); + } + return ptr; + } + } + + // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc(). + // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first + // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section. + // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the + // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation, + // and retry-ing threads succeed in the code just above. + if (!tiny_mag_ptr->alloc_underway) { + void *fresh_region; + + // time to create a new region (do this outside the magazine lock) + tiny_mag_ptr->alloc_underway = TRUE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + fresh_region = allocate_pages_securely(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, VM_MEMORY_MALLOC_TINY); + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + + MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, TINY_REGION_SIZE); // DTrace USDT Probe + + if (!fresh_region) { // out of memory! + tiny_mag_ptr->alloc_underway = FALSE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return NULL; + } + + ptr = tiny_malloc_from_region_no_lock(szone, tiny_mag_ptr, mag_index, msize, fresh_region); + + // we don't clear because this freshly allocated space is pristine + tiny_mag_ptr->alloc_underway = FALSE; + OSMemoryBarrier(); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + return ptr; + } else { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + yield(); + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + } + } + /* NOTREACHED */ +} + +static MALLOC_NOINLINE void +free_tiny_botch(szone_t *szone, tiny_free_list_t *ptr) +{ + mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)); + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + szone_error(szone, 1, "double free", ptr, NULL); +} + +void +free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size) +{ + msize_t msize; + boolean_t is_free; + mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region); + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); + + MALLOC_TRACE(TRACE_tiny_free, (uintptr_t)szone, (uintptr_t)ptr, (uintptr_t)tiny_mag_ptr, known_size); + + // ptr is known to be in tiny_region + if (known_size) { + msize = TINY_MSIZE_FOR_BYTES(known_size + TINY_QUANTUM - 1); + } else { + msize = get_tiny_meta_header(ptr, &is_free); + if (is_free) { + free_tiny_botch(szone, ptr); + return; + } + } +#if DEBUG_MALLOC + if (!msize) { + malloc_printf("*** free_tiny() block in use is too large: %p\n", ptr); + return; + } +#endif + + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + +#if CONFIG_TINY_CACHE + // Depot does not participate in CONFIG_TINY_CACHE since it can't be directly malloc()'d + if (DEPOT_MAGAZINE_INDEX != mag_index) { + if (msize < TINY_QUANTUM) { // to see if the bits fit in the last 4 bits + void *ptr2 = tiny_mag_ptr->mag_last_free; // Might be NULL + region_t rgn2 = tiny_mag_ptr->mag_last_free_rgn; + + /* check that we don't already have this pointer in the cache */ + if (ptr == (void *)((uintptr_t)ptr2 & ~(TINY_QUANTUM - 1))) { + free_tiny_botch(szone, ptr); + return; + } + + if ((szone->debug_flags & MALLOC_DO_SCRIBBLE) && msize) { + memset(ptr, SCRABBLE_BYTE, TINY_BYTES_FOR_MSIZE(msize)); + } + + tiny_mag_ptr->mag_last_free = (void *)(((uintptr_t)ptr) | msize); + tiny_mag_ptr->mag_last_free_rgn = tiny_region; + + if (!ptr2) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + CHECK(szone, __PRETTY_FUNCTION__); + return; + } + + msize = (uintptr_t)ptr2 & (TINY_QUANTUM - 1); + ptr = (void *)(((uintptr_t)ptr2) & ~(TINY_QUANTUM - 1)); + tiny_region = rgn2; + } + } +#endif /* CONFIG_TINY_CACHE */ + + // Now in the time it took to acquire the lock, the region may have migrated + // from one magazine to another. I.e. trailer->mag_index is volatile. + // In which case the magazine lock we obtained (namely magazines[mag_index].mag_lock) + // is stale. If so, keep on tryin' ... + region_trailer_t *trailer = REGION_TRAILER_FOR_TINY_REGION(tiny_region); + mag_index_t refreshed_index; + + while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment + + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + + mag_index = refreshed_index; + tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + } + + if (tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize)) { + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + } + + CHECK(szone, __PRETTY_FUNCTION__); +} + +void +print_tiny_free_list(szone_t *szone) +{ + tiny_free_list_t *ptr; + _SIMPLE_STRING b = _simple_salloc(); + mag_index_t mag_index; + + if (b) { + _simple_sappend(b, "tiny free sizes:\n"); + for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { + grain_t slot = 0; + _simple_sprintf(b, "\tMagazine %d: ", mag_index); + while (slot < NUM_TINY_SLOTS) { + ptr = szone->tiny_magazines[mag_index].mag_free_list[slot].p; + if (ptr) { + _simple_sprintf(b, "%s%y[%d]; ", (slot == NUM_TINY_SLOTS - 1) ? ">=" : "", (slot + 1) * TINY_QUANTUM, + free_list_count(szone, (free_list_t){ .p = ptr })); + } + slot++; + } + _simple_sappend(b, "\n"); + } + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); + } +} + +void +print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end) +{ + unsigned counts[1024]; + unsigned in_use = 0; + uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(region); + uintptr_t current = start + bytes_at_start; + uintptr_t limit = (uintptr_t)TINY_REGION_END(region) - bytes_at_end; + boolean_t is_free; + msize_t msize; + unsigned ci; + _SIMPLE_STRING b; + uintptr_t pgTot = 0; + + if (region == HASHRING_REGION_DEALLOCATED) { + if ((b = _simple_salloc()) != NULL) { + _simple_sprintf(b, "Tiny region [unknown address] was returned to the OS\n"); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); + } + return; + } + + memset(counts, 0, sizeof(counts)); + while (current < limit) { + msize = get_tiny_meta_header((void *)current, &is_free); + if (is_free && !msize && (current == start)) { + // first block is all free + uintptr_t pgLo = round_page_quanta(start + sizeof(tiny_free_list_t) + sizeof(msize_t)); + uintptr_t pgHi = trunc_page_quanta(start + TINY_REGION_SIZE - sizeof(msize_t)); + + if (pgLo < pgHi) { + pgTot += (pgHi - pgLo); + } + break; + } + if (!msize) { + malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize); + break; + } + if (!is_free) { + // block in use + if (msize > NUM_TINY_SLOTS) { + malloc_printf("*** error at %p msize for in_use is %d\n", (void *)current, msize); + } + if (msize < 1024) { + counts[msize]++; + } + in_use++; + } else { + uintptr_t pgLo = round_page_quanta(current + sizeof(tiny_free_list_t) + sizeof(msize_t)); + uintptr_t pgHi = trunc_page_quanta(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t)); + + if (pgLo < pgHi) { + pgTot += (pgHi - pgLo); + } + } + current += TINY_BYTES_FOR_MSIZE(msize); + } + if ((b = _simple_salloc()) != NULL) { + _simple_sprintf(b, "Tiny region [%p-%p, %y] \t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE); + _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_TINY_REGION(region)); + _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_TINY_REGION(region)); + if (bytes_at_end || bytes_at_start) { + _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start); + } + if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_TINY_REGION(region)) { + _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot); + } else { + _simple_sprintf(b, "Fragments subject to reclamation=%ly", pgTot); + } + if (verbose && in_use) { + _simple_sappend(b, "\n\tSizes in use: "); + for (ci = 0; ci < 1024; ci++) { + if (counts[ci]) { + _simple_sprintf(b, "%d[%d] ", TINY_BYTES_FOR_MSIZE(ci), counts[ci]); + } + } + } + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b)); + _simple_sfree(b); + } +} + +boolean_t +tiny_free_list_check(szone_t *szone, grain_t slot) +{ + mag_index_t mag_index; + + for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) { + magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]); + SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr); + + unsigned count = 0; + tiny_free_list_t *ptr = szone->tiny_magazines[mag_index].mag_free_list[slot].p; + boolean_t is_free; + tiny_free_list_t *previous = NULL; + + while (ptr) { + is_free = tiny_meta_header_is_free(ptr); + if (!is_free) { + malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return 0; + } + if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) { + malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return 0; + } + if (!tiny_region_for_ptr_no_lock(szone, ptr)) { + malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return 0; + } + if (free_list_unchecksum_ptr(szone, &ptr->previous) != previous) { + malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr); + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + return 0; + } + previous = ptr; + ptr = free_list_unchecksum_ptr(szone, &ptr->next); + count++; + } + + SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); + } + return 1; +} diff --git a/src/libmalloc/src/magazine_zone.h b/src/libmalloc/src/magazine_zone.h new file mode 100644 index 000000000..40f30021e --- /dev/null +++ b/src/libmalloc/src/magazine_zone.h @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __MAGAZINE_ZONE_H +#define __MAGAZINE_ZONE_H + +/********************* DEFINITIONS ************************/ + +// Out-of-band free list entry. Out-of-band free list entries are used +// in specific cases where a free-list entry is the *only* data on a given page, +// and the presence of that entry causes the page to stay dirty. +// +// `ptr` is all 16-bit quantum-sized index and packed, as that references a +// block address inside the current region. `next` and `prev` have to be pointer +// sized references, as these values can point to entries outside the current +// region, so it's not safe to compact them. +typedef struct { + uintptr_t prev; + uintptr_t next; + uint16_t ptr; +} MALLOC_PACKED oob_free_entry_s, *oob_free_entry_t; + +// In-place free list entry. Unlike the out-of-band entry, the in-place entries +// are stored at the start of the range that has been freed. +typedef struct _inplace_free_entry_s *inplace_free_entry_t; + +typedef struct { + void *ptr; + uint8_t checksum; +} inplace_linkage_s; + +typedef union { + inplace_free_entry_t p; + uintptr_t u; +} inplace_union; + +typedef struct _inplace_free_entry_s { + inplace_union previous; + inplace_union next; +} inplace_free_entry_s, *inplace_free_entry_t; + +#ifdef __LP64__ +MALLOC_STATIC_ASSERT(sizeof(inplace_free_entry_s) == 16, "inplace free list must be 16-bytes long"); +#else +MALLOC_STATIC_ASSERT(sizeof(inplace_free_entry_s) == 8, "inplace free list must be 8-bytes long"); +#endif + +typedef struct _small_inplace_free_entry_s { + inplace_linkage_s previous; + inplace_linkage_s next; +} small_inplace_free_entry_s, *small_inplace_free_entry_t; + +typedef union { + small_inplace_free_entry_t small_inplace; + inplace_free_entry_t inplace; + oob_free_entry_t oob; + void *p; +} free_list_t; + +typedef struct { + inplace_union previous; + inplace_union next; +} tiny_free_list_t; + +typedef unsigned int grain_t; // N.B. wide enough to index all free slots + +typedef int mag_index_t; + +#define CHECK_REGIONS (1 << 31) +#define DISABLE_ASLR (1 << 30) + +#define MAX_RECORDER_BUFFER 256 + +/********************* DEFINITIONS for tiny ************************/ + +/* + * Memory in the Tiny range is allocated from regions (heaps) pointed to by the + * szone's hashed_regions pointer. + * + * Each region is laid out as a heap, followed by a header block, all within + * a 1MB (2^20) block. This means there are 64520 16-byte blocks and the header + * is 16138 bytes, making the total 1048458 bytes, leaving 118 bytes unused. + * + * The header block is arranged as in struct tiny_region defined just below, and + * consists of two bitfields (or bit arrays) interleaved 32 bits by 32 bits. + * + * Each bitfield comprises NUM_TINY_BLOCKS bits, and refers to the corresponding + * TINY_QUANTUM block within the heap. + * + * The bitfields are used to encode the state of memory within the heap. The header bit indicates + * that the corresponding quantum is the first quantum in a block (either in use or free). The + * in-use bit is set for the header if the block has been handed out (allocated). If the header + * bit is not set, the in-use bit is invalid. + * + * The szone maintains an array of NUM_TINY_SLOTS freelists, each of which is used to hold + * free objects of the corresponding quantum size. + * + * A free block is laid out depending on its size, in order to fit all free + * blocks in 16 bytes, on both 32 and 64 bit platforms. One quantum blocks do + * not store their size in the block, instead relying on the header information + * to determine their size. Blocks of two or more quanta have room to store + * their size in the block, and store it both after the 'next' pointer, and in + * the last 2 bytes of the block. + * + * 1-quantum block + * Offset (32-bit mode) (64-bit mode) + * 0x0 0x0 : previous + * 0x4 0x08 : next + * end end + * + * >1-quantum block + * Offset (32-bit mode) (64-bit mode) + * 0x0 0x0 : previous + * 0x4 0x08 : next + * 0x8 0x10 : size (in quantum counts) + * end - 2 end - 2 : size (in quantum counts) + * end end + * + * All fields are pointer-sized, except for the size which is an unsigned short. + * + */ + +#define FOLLOWING_TINY_PTR(ptr, msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM)) + +#define TINY_BLOCKS_ALIGN (SHIFT_TINY_CEIL_BLOCKS + SHIFT_TINY_QUANTUM) // 20 + +#define TINY_ENTROPY_BITS 15 +#define TINY_ENTROPY_MASK ((1 << TINY_ENTROPY_BITS) - 1) + +/* + * Avoid having so much entropy that the end of a valid tiny allocation + * might overrun the end of the tiny region. + */ +#if TINY_ENTROPY_MASK + NUM_TINY_SLOTS > NUM_TINY_BLOCKS +#error Too many entropy bits for tiny region requested +#endif + +/* + * Enough room for the data, followed by the bit arrays (2-bits per block) + * plus rounding to the nearest page. + */ +#define CEIL_NUM_TINY_BLOCKS_WORDS (((NUM_TINY_BLOCKS + 31) & ~31) >> 5) +#define TINY_METADATA_SIZE (sizeof(region_trailer_t) + sizeof(tiny_header_inuse_pair_t) * CEIL_NUM_TINY_BLOCKS_WORDS) +#define TINY_REGION_SIZE ((NUM_TINY_BLOCKS * TINY_QUANTUM + TINY_METADATA_SIZE + PAGE_MAX_SIZE - 1) & ~(PAGE_MAX_SIZE - 1)) + +#define TINY_METADATA_START (NUM_TINY_BLOCKS * TINY_QUANTUM) + +/* + * Beginning and end pointers for a region's heap. + */ +#define TINY_REGION_ADDRESS(region) ((void *)(region)) +#define TINY_REGION_END(region) ((void *)(((uintptr_t)(region)) + (NUM_TINY_BLOCKS * TINY_QUANTUM))) + +/* + * Locate the heap base for a pointer known to be within a tiny region. + */ +#define TINY_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << TINY_BLOCKS_ALIGN) - 1))) + +/* + * Convert between byte and msize units. + */ +#define TINY_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_TINY_QUANTUM) +#define TINY_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_TINY_QUANTUM) + +#if MALLOC_TARGET_64BIT +#define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[8]) +#else // MALLOC_TARGET_64BIT +#define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[4]) +#endif // MALLOC_TARGET_64BIT +#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1] + +/* + * Layout of a tiny region + */ +typedef uint32_t tiny_block_t[4]; // assert(TINY_QUANTUM == sizeof(tiny_block_t)) + +typedef struct tiny_header_inuse_pair { + uint32_t header; + uint32_t inuse; +} tiny_header_inuse_pair_t; + +typedef struct region_trailer { + struct region_trailer *prev; + struct region_trailer *next; + boolean_t recirc_suitable; + volatile int pinned_to_depot; + unsigned bytes_used; + mag_index_t mag_index; +} region_trailer_t; + +typedef struct tiny_region { + tiny_block_t blocks[NUM_TINY_BLOCKS]; + + region_trailer_t trailer; + + // The interleaved bit arrays comprising the header and inuse bitfields. + // The unused bits of each component in the last pair will be initialized to sentinel values. + tiny_header_inuse_pair_t pairs[CEIL_NUM_TINY_BLOCKS_WORDS]; + + uint8_t pad[TINY_REGION_SIZE - (NUM_TINY_BLOCKS * sizeof(tiny_block_t)) - TINY_METADATA_SIZE]; +} * tiny_region_t; + +/* + * Per-region meta data for tiny allocator + */ +#define REGION_TRAILER_FOR_TINY_REGION(r) (&(((tiny_region_t)(r))->trailer)) +#define MAGAZINE_INDEX_FOR_TINY_REGION(r) (REGION_TRAILER_FOR_TINY_REGION(r)->mag_index) +#define BYTES_USED_FOR_TINY_REGION(r) (REGION_TRAILER_FOR_TINY_REGION(r)->bytes_used) + +/* + * Locate the block header for a pointer known to be within a tiny region. + */ +#define TINY_BLOCK_HEADER_FOR_PTR(_p) ((void *)&(((tiny_region_t)TINY_REGION_FOR_PTR(_p))->pairs)) + +/* + * Locate the inuse map for a given block header pointer. + */ +#define TINY_INUSE_FOR_HEADER(_h) ((void *)&(((tiny_header_inuse_pair_t *)(_h))->inuse)) + +/* + * Compute the bitmap index for a pointer known to be within a tiny region. + */ +#define TINY_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_CEIL_BLOCKS - 1)) + +#if !CONFIG_TINY_CACHE +#warning CONFIG_TINY_CACHE turned off +#endif + +#define TINY_REGION_PAYLOAD_BYTES (NUM_TINY_BLOCKS * TINY_QUANTUM) + +/********************* DEFINITIONS for small ************************/ + +/* + * Memory in the Small range is allocated from regions (heaps) pointed to by the szone's hashed_regions + * pointer. + * + * Each region is laid out as a heap, followed by the metadata array, all within an 8MB (2^23) block. + * The array is arranged as an array of shorts, one for each SMALL_QUANTUM in the heap. There are + * 16319 512-blocks and the array is 16319*2 bytes, which totals 8387966, leaving 642 bytes unused. + * Once the region trailer is accounted for, there is room for 61 out-of-band free list entries in + * the remaining padding (or 6, if the region was split into 16320 blocks, not 16319). + * + * The 16-bit shorts in the region are used for allocation metadata. The MSB bit marks a block as + * either free, or not. The remaining 15-bits give the size of the allocation, defined in "msize", the + * quantum-shifted size of the allocation. + * + * The metadata table either: + * + * 1. Stores the allocation size in the first short for the block, with the MSB cleared to indicate + * that the block is allocated and in-use, or, + * + * 2. Stores the free-allocation size in the first and last shorts for the block, with the MSB set + * in both places to indicate that the block is freed. (Storing the range in last block allows + * for coalescing of adjacent free entries). + * + * 3. Zero, or "middle", meaning that this block in the region is not the start or end of an + * allocated block. + * + * The small zone represents the free list in one of two ways: + * + * 1. In-line free list entries. These are stored at the starting address of the just-freed memory + * and both the previous and next pointer are checksummed to attempt to detect use-after-free + * writes. + * + * An in-line free list entry is laid out as: + * |prev (uintptr_t)|checksum (uint8_t)|next (uintptr_t)|checksum (uint8_t) + * + * 2. Out-of-band free list entries. These utilitise the remaining padding in the 8mb region that + * follows the blocks, metadata and region trailer. Out-of-band entries are used *iff* the + * freed address lies on a page boundary and the freed region spans more than a page. If we were + * to store the free list entry in-line in that memory, it would keep the entire page dirty, + * so an out-of-band entry is used. + * + * An out-of-band free list entry is laid out as: + * |prev (uintptr_t)|next (uintptr_t)|ptr (uint16_t)| + * + * The szone maintains an array of 32 freelists, each of which is used to hold free objects + * of the corresponding quantum size. + */ + +#define SMALL_IS_FREE (1 << 15) +#define FOLLOWING_SMALL_PTR(ptr, msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_SMALL_QUANTUM)) + +/* + * SMALL_IS_OOB is used mark to the MSB of OOB free list entries to show that they are in use, and + * distinguish them from their initial, empty, state. + */ +#define SMALL_IS_OOB (1 << 15) + +#define SMALL_ENTROPY_BITS 13 +#define SMALL_ENTROPY_MASK ((1 << SMALL_ENTROPY_BITS) - 1) + +/* + * Avoid having so much entropy that the end of a valid small allocation + * might overrun the end of the small region. + */ +#if SMALL_ENTROPY_MASK + NUM_SMALL_SLOTS > NUM_SMALL_BLOCKS +#error Too many entropy bits for small region requested +#endif + +#define SMALL_METADATA_SIZE (sizeof(region_trailer_t) + NUM_SMALL_BLOCKS * sizeof(msize_t)) +#define SMALL_REGION_SIZE ((NUM_SMALL_BLOCKS * SMALL_QUANTUM + SMALL_METADATA_SIZE + PAGE_MAX_SIZE - 1) & ~(PAGE_MAX_SIZE - 1)) + +#define SMALL_METADATA_START (NUM_SMALL_BLOCKS * SMALL_QUANTUM) + +/* + * Beginning and end pointers for a region's heap. + */ +#define SMALL_REGION_ADDRESS(region) ((unsigned char *)region) +#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region) + (NUM_SMALL_BLOCKS * SMALL_QUANTUM)) + +/* + * Locate the heap base for a pointer known to be within a small region. + */ +#define SMALL_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << SMALL_BLOCKS_ALIGN) - 1))) +#define SMALL_OFFSET_FOR_PTR(_p) ((uintptr_t)(_p) & ((1 << SMALL_BLOCKS_ALIGN) - 1)) + +/* + * Convert between byte and msize units. + */ +#define SMALL_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_SMALL_QUANTUM) +#define SMALL_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_SMALL_QUANTUM) + +#define SMALL_PREVIOUS_MSIZE(ptr) (*SMALL_METADATA_FOR_PTR(ptr - 1) & ~SMALL_IS_FREE) + +/* + * Layout of a small region + */ +typedef uint32_t small_block_t[SMALL_QUANTUM / sizeof(uint32_t)]; +#define SMALL_HEAP_SIZE (NUM_SMALL_BLOCKS * sizeof(small_block_t)) +#define SMALL_OOB_COUNT ((SMALL_REGION_SIZE - SMALL_HEAP_SIZE - SMALL_METADATA_SIZE) / sizeof(oob_free_entry_s)) +#define SMALL_OOB_SIZE (SMALL_OOB_COUNT * sizeof(oob_free_entry_s)) +#define SMALL_REGION_PAD (SMALL_REGION_SIZE - SMALL_HEAP_SIZE - SMALL_METADATA_SIZE - SMALL_OOB_SIZE) + +typedef struct small_region { + small_block_t blocks[NUM_SMALL_BLOCKS]; + region_trailer_t trailer; + msize_t small_meta_words[NUM_SMALL_BLOCKS]; + oob_free_entry_s small_oob_free_entries[SMALL_OOB_COUNT]; + uint8_t pad[SMALL_REGION_PAD]; +} * small_region_t; + +// The layout described above should result in a small_region_t being 8MB. +MALLOC_STATIC_ASSERT(sizeof(struct small_region) == 8388608, "incorrect small_region_size"); + +/* + * Per-region meta data for small allocator + */ +#define REGION_TRAILER_FOR_SMALL_REGION(r) (&(((small_region_t)(r))->trailer)) +#define MAGAZINE_INDEX_FOR_SMALL_REGION(r) (REGION_TRAILER_FOR_SMALL_REGION(r)->mag_index) +#define BYTES_USED_FOR_SMALL_REGION(r) (REGION_TRAILER_FOR_SMALL_REGION(r)->bytes_used) + +/* + * Locate the metadata base for a pointer known to be within a small region. + */ +#define SMALL_META_HEADER_FOR_PTR(_p) (((small_region_t)SMALL_REGION_FOR_PTR(_p))->small_meta_words) + +/* + * Compute the metadata index for a pointer known to be within a small region. + */ +#define SMALL_META_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_CEIL_BLOCKS - 1)) + +/* + * Find the metadata word for a pointer known to be within a small region. + */ +#define SMALL_METADATA_FOR_PTR(_p) (SMALL_META_HEADER_FOR_PTR(_p) + SMALL_META_INDEX_FOR_PTR(_p)) + +/* + * Determine whether a pointer known to be within a small region points to memory which is free. + */ +#define SMALL_PTR_IS_FREE(_p) (*SMALL_METADATA_FOR_PTR(_p) & SMALL_IS_FREE) + +/* + * Extract the msize value for a pointer known to be within a small region. + */ +#define SMALL_PTR_SIZE(_p) (*SMALL_METADATA_FOR_PTR(_p) & ~SMALL_IS_FREE) + +#if !CONFIG_SMALL_CACHE +#warning CONFIG_SMALL_CACHE turned off +#endif + +#define SMALL_REGION_PAYLOAD_BYTES (NUM_SMALL_BLOCKS * SMALL_QUANTUM) + +/************************* DEFINITIONS for large ****************************/ + + +typedef struct large_entry_s { + vm_address_t address; + vm_size_t size; + boolean_t did_madvise_reusable; +} large_entry_t; + +#if !CONFIG_LARGE_CACHE && DEBUG_MALLOC +#warning CONFIG_LARGE_CACHE turned off +#endif + + +/******************************************************************************* + * Definitions for region hash + ******************************************************************************/ + +typedef void *region_t; +typedef region_t *rgnhdl_t; /* A pointer into hashed_regions array. */ + +#define INITIAL_NUM_REGIONS_SHIFT 6 // log2(INITIAL_NUM_REGIONS) +#define INITIAL_NUM_REGIONS (1 << INITIAL_NUM_REGIONS_SHIFT) // Must be a power of 2! +#define HASHRING_OPEN_ENTRY ((region_t)0) // Initial value and sentinel marking end of collision chain +#define HASHRING_REGION_DEALLOCATED ((region_t)-1) // Region at this slot reclaimed by OS +#define HASH_BLOCKS_ALIGN TINY_BLOCKS_ALIGN // MIN( TINY_BLOCKS_ALIGN, SMALL_BLOCKS_ALIGN, ... ) + +typedef struct region_hash_generation { + size_t num_regions_allocated; + size_t num_regions_allocated_shift; // log2(num_regions_allocated) + region_t *hashed_regions; // hashed by location + struct region_hash_generation *nextgen; +} region_hash_generation_t; + +/******************************************************************************* + * Per-processor magazine for tiny and small allocators + ******************************************************************************/ + +typedef struct magazine_s { // vm_allocate()'d, so the array of magazines is page-aligned to begin with. + // Take magazine_lock first, Depot lock when needed for recirc, then szone->{tiny,small}_regions_lock when needed for alloc + _malloc_lock_s magazine_lock MALLOC_CACHE_ALIGN; + // Protection for the crtical section that does allocate_pages outside the magazine_lock + volatile boolean_t alloc_underway; + + // One element deep "death row", optimizes malloc/free/malloc for identical size. + void *mag_last_free; // low SHIFT_{TINY,SMALL}_QUANTUM bits indicate the msize + region_t mag_last_free_rgn; // holds the region for mag_last_free + + free_list_t mag_free_list[256]; // assert( 256 >= MAX( NUM_TINY_SLOTS, NUM_SMALL_SLOTS_LARGEMEM )) + unsigned mag_bitmap[8]; // assert( sizeof(mag_bitmap) << 3 >= sizeof(mag_free_list)/sizeof(free_list_t) ) + + // the first and last free region in the last block are treated as big blocks in use that are not accounted for + size_t mag_bytes_free_at_end; + size_t mag_bytes_free_at_start; + region_t mag_last_region; // Valid iff mag_bytes_free_at_end || mag_bytes_free_at_start > 0 + + // bean counting ... + unsigned mag_num_objects; + size_t mag_num_bytes_in_objects; + size_t num_bytes_in_magazine; + + // recirculation list -- invariant: all regions owned by this magazine that meet the emptiness criteria + // are located nearer to the head of the list than any region that doesn't satisfy that criteria. + // Doubly linked list for efficient extraction. + unsigned recirculation_entries; + region_trailer_t *firstNode; + region_trailer_t *lastNode; + + uintptr_t pad[50 - MALLOC_CACHE_LINE / sizeof(uintptr_t)]; +} magazine_t; + +#if MALLOC_TARGET_64BIT +MALLOC_STATIC_ASSERT(sizeof(magazine_t) == 2560, "Incorrect padding in magazine_t"); +#else +MALLOC_STATIC_ASSERT(sizeof(magazine_t) == 1280, "Incorrect padding in magazine_t"); +#endif + +#define TINY_MAX_MAGAZINES 32 /* MUST BE A POWER OF 2! */ +#define TINY_MAGAZINE_PAGED_SIZE \ + (((sizeof(magazine_t) * (TINY_MAX_MAGAZINES + 1)) + vm_page_quanta_size - 1) & \ + ~(vm_page_quanta_size - 1)) /* + 1 for the Depot */ + +#define SMALL_MAX_MAGAZINES 32 /* MUST BE A POWER OF 2! */ +#define SMALL_MAGAZINE_PAGED_SIZE \ + (((sizeof(magazine_t) * (SMALL_MAX_MAGAZINES + 1)) + vm_page_quanta_size - 1) & \ + ~(vm_page_quanta_size - 1)) /* + 1 for the Depot */ + +#define DEPOT_MAGAZINE_INDEX -1 + +/****************************** zone itself ***********************************/ + +/* + * Note that objects whose adddress are held in pointers here must be pursued + * individually in the {tiny,small}_in_use_enumeration() routines. See for + * example the treatment of region_hash_generation and tiny_magazines below. + */ + +typedef struct szone_s { // vm_allocate()'d, so page-aligned to begin with. + malloc_zone_t basic_zone; // first page will be given read-only protection + uint8_t pad[PAGE_MAX_SIZE - sizeof(malloc_zone_t)]; + + unsigned long cpu_id_key; // unused + // remainder of structure is R/W (contains no function pointers) + unsigned debug_flags; + void *log_address; + + /* Regions for tiny objects */ + _malloc_lock_s tiny_regions_lock MALLOC_CACHE_ALIGN; + size_t num_tiny_regions; + size_t num_tiny_regions_dealloc; + region_hash_generation_t *tiny_region_generation; + region_hash_generation_t trg[2]; + + int num_tiny_magazines; + unsigned num_tiny_magazines_mask; + int num_tiny_magazines_mask_shift; + magazine_t *tiny_magazines; // array of per-processor magazines + + uintptr_t last_tiny_advise; + + /* Regions for small objects */ + _malloc_lock_s small_regions_lock MALLOC_CACHE_ALIGN; + size_t num_small_regions; + size_t num_small_regions_dealloc; + region_hash_generation_t *small_region_generation; + region_hash_generation_t srg[2]; + + unsigned num_small_slots; // determined by physmem size + + int num_small_magazines; + unsigned num_small_magazines_mask; + int num_small_magazines_mask_shift; + magazine_t *small_magazines; // array of per-processor magazines + + uintptr_t last_small_advise; + + /* large objects: all the rest */ + _malloc_lock_s large_szone_lock MALLOC_CACHE_ALIGN; // One customer at a time for large + unsigned num_large_objects_in_use; + unsigned num_large_entries; + large_entry_t *large_entries; // hashed by location; null entries don't count + size_t num_bytes_in_large_objects; + +#if CONFIG_LARGE_CACHE + int large_entry_cache_oldest; + int large_entry_cache_newest; + large_entry_t large_entry_cache[LARGE_ENTRY_CACHE_SIZE]; // "death row" for large malloc/free + boolean_t large_legacy_reset_mprotect; + size_t large_entry_cache_reserve_bytes; + size_t large_entry_cache_reserve_limit; + size_t large_entry_cache_bytes; // total size of death row, bytes +#endif + + /* flag and limits pertaining to altered malloc behavior for systems with + * large amounts of physical memory */ + unsigned is_largemem; + unsigned large_threshold; + unsigned vm_copy_threshold; + + /* security cookie */ + uintptr_t cookie; + + /* Initial region list */ + region_t initial_tiny_regions[INITIAL_NUM_REGIONS]; + region_t initial_small_regions[INITIAL_NUM_REGIONS]; + + /* The purgeable zone constructed by create_purgeable_zone() would like to hand off tiny and small + * allocations to the default scalable zone. Record the latter as the "helper" zone here. */ + struct szone_s *helper_zone; + + boolean_t flotsam_enabled; +} szone_t; + +#define SZONE_PAGED_SIZE round_page_quanta((sizeof(szone_t))) + +#endif // __MAGAZINE_ZONE_H diff --git a/src/libmalloc/src/malloc.c b/src/libmalloc/src/malloc.c index 462e011d7..1d03905f4 100644 --- a/src/libmalloc/src/malloc.c +++ b/src/libmalloc/src/malloc.c @@ -21,34 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include "magmallocProvider.h" - -#include <_simple.h> -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "malloc.h" -#include "malloc_printf.h" -#include "scalable_malloc.h" -#include "malloc_internal.h" -#include "stack_logging.h" +#include "internal.h" #if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR // _malloc_printf(ASL_LEVEL_INFO...) on iOS doesn't show up in the Xcode Console log of the device, @@ -57,14 +30,6 @@ #define ASL_LEVEL_INFO ASL_LEVEL_NOTICE #endif -#include - -#ifdef __LP64__ -#define CONFIG_NANOZONE 1 -#else -#define CONFIG_NANOZONE 0 -#endif - /* * MALLOC_ABSOLUTE_MAX_SIZE - There are many instances of addition to a * user-specified size_t, which can cause overflow (and subsequent crashes) @@ -76,23 +41,35 @@ * seems to be PAGE_SIZE (in the macro round_page()), so to be safe, we set * the maximum to be 2 * PAGE_SIZE less than SIZE_T_MAX. */ -#define MALLOC_ABSOLUTE_MAX_SIZE (SIZE_T_MAX - (2 * PAGE_SIZE)) +#define MALLOC_ABSOLUTE_MAX_SIZE (SIZE_T_MAX - (2 * PAGE_SIZE)) -#define USE_SLEEP_RATHER_THAN_ABORT 0 +#define USE_SLEEP_RATHER_THAN_ABORT 0 -typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip); +/* + MAX_LITE_MALLOCS + + If msl lite is turned on due to a memory resource exception use this value as the maximum + number of allocations allowed before msl lite is turned off. This prevents msl lite from being + enabled indefinitely if the process never reaches 100% of its jetsam limit. + See rdar://problem/25950426 for a discussion of how this number was determined. + */ -extern malloc_logger_t *__syscall_logger; // use this to set up syscall logging (e.g., vm_allocate, vm_deallocate, mmap, munmap) +#define MAX_LITE_MALLOCS 100000000 -extern void __prepare_to_log_stacks(void); +typedef void(malloc_logger_t)(uint32_t type, + uintptr_t arg1, + uintptr_t arg2, + uintptr_t arg3, + uintptr_t result, + uint32_t num_hot_frames_to_skip); -static _malloc_lock_s _malloc_lock = _MALLOC_LOCK_INIT; -#define MALLOC_LOCK() _malloc_lock_lock(&_malloc_lock) -#define MALLOC_UNLOCK() _malloc_lock_unlock(&_malloc_lock) +extern malloc_logger_t *__syscall_logger; // use this to set up syscall logging (e.g., vm_allocate, vm_deallocate, mmap, munmap) -static inline void yield(void) { - thread_switch(MACH_PORT_NULL, SWITCH_OPTION_DEPRESS, 1); -} +static _malloc_lock_s _malloc_lock = _MALLOC_LOCK_INIT; +#define MALLOC_LOCK() _malloc_lock_lock(&_malloc_lock) +#define MALLOC_TRY_LOCK() _malloc_lock_trylock(&_malloc_lock) +#define MALLOC_UNLOCK() _malloc_lock_unlock(&_malloc_lock) +#define MALLOC_REINIT_LOCK() _malloc_lock_init(&_malloc_lock) /* The following variables are exported for the benefit of performance tools * @@ -101,12 +78,14 @@ static inline void yield(void) { * provided that when malloc_destroy_zone is called all prior operations on that * zone are complete and no further calls referencing that zone can be made. */ -unsigned malloc_num_zones = 0; -unsigned malloc_num_zones_allocated = 0; +int32_t malloc_num_zones = 0; +int32_t malloc_num_zones_allocated = 0; malloc_zone_t **malloc_zones = 0; malloc_logger_t *malloc_logger = NULL; +static malloc_zone_t *initial_default_zone = NULL; unsigned malloc_debug_flags = 0; +boolean_t malloc_tracing_enabled = false; unsigned malloc_check_start = 0; // 0 means don't check unsigned malloc_check_counter = 0; @@ -116,10 +95,10 @@ unsigned malloc_check_each = 1000; int _malloc_no_asl_log = 0; static int malloc_check_sleep = 100; // default 100 second sleep -static int malloc_check_abort = 0; // default is to sleep, not abort +static int malloc_check_abort = 0; // default is to sleep, not abort static int malloc_debug_file = STDERR_FILENO; -static boolean_t _malloc_is_initialized = FALSE; +static os_once_t _malloc_initialize_pred; static const char Malloc_Facility[] = "com.apple.Libsystem.malloc"; @@ -128,26 +107,26 @@ static const char Malloc_Facility[] = "com.apple.Libsystem.malloc"; * find_registered_zone (here abbreviated as FRZ). */ static int counterAlice = 0, counterBob = 0; -static int *pFRZCounterLive= &counterAlice, *pFRZCounterDrain = &counterBob; +static int *pFRZCounterLive = &counterAlice, *pFRZCounterDrain = &counterBob; + +static inline malloc_zone_t *inline_malloc_default_zone(void) __attribute__((always_inline)); -#define MALLOC_LOG_TYPE_ALLOCATE stack_logging_type_alloc -#define MALLOC_LOG_TYPE_DEALLOCATE stack_logging_type_dealloc -#define MALLOC_LOG_TYPE_HAS_ZONE stack_logging_flag_zone -#define MALLOC_LOG_TYPE_CLEARED stack_logging_flag_cleared +#define MALLOC_LOG_TYPE_ALLOCATE stack_logging_type_alloc +#define MALLOC_LOG_TYPE_DEALLOCATE stack_logging_type_dealloc +#define MALLOC_LOG_TYPE_HAS_ZONE stack_logging_flag_zone +#define MALLOC_LOG_TYPE_CLEARED stack_logging_flag_cleared #define DEFAULT_MALLOC_ZONE_STRING "DefaultMallocZone" #define DEFAULT_PUREGEABLE_ZONE_STRING "DefaultPurgeableMallocZone" boolean_t malloc_engaged_nano(void); #if CONFIG_NANOZONE -extern boolean_t _malloc_engaged_nano; -malloc_zone_t *create_nano_zone(size_t initial_size, malloc_zone_t *helper_zone, unsigned debug_flags); -void nano_forked_zone(malloc_zone_t *zone); -#define MALLOC_HELPER_ZONE_STRING "MallocHelperZone" +boolean_t _malloc_engaged_nano; #endif /********* Utilities ************/ __attribute__((visibility("hidden"))) uint64_t malloc_entropy[2] = {0, 0}; +static bool _malloc_entropy_initialized; void __malloc_init(const char *apple[]); @@ -160,29 +139,27 @@ __entropy_from_kernel(const char *str) /* Skip over key to the first value */ str = strchr(str, '='); - if (str == NULL) + if (str == NULL) { return 0; + } str++; - while (str && idx < sizeof(malloc_entropy)/sizeof(malloc_entropy[0])) { + while (str && idx < sizeof(malloc_entropy) / sizeof(malloc_entropy[0])) { strlcpy(tmp, str, 20); p = strchr(tmp, ','); - if (p) *p = '\0'; + if (p) { + *p = '\0'; + } val = strtoull_l(tmp, NULL, 0, NULL); malloc_entropy[idx] = (uint64_t)val; idx++; - if ((str = strchr(str, ',')) != NULL) + if ((str = strchr(str, ',')) != NULL) { str++; + } } return idx; } -/* TODO: Remove __malloc_entropy_setup, it was left to avoid rev-lock */ -void -__malloc_entropy_setup(const char *apple[]) { - __malloc_init(apple); -} - /* TODO: Investigate adding _malloc_initialize() into this libSystem initializer */ void __malloc_init(const char *apple[]) @@ -202,63 +179,354 @@ __malloc_init(const char *apple[]) for (p = apple; p && *p; p++) { if (strstr(*p, "malloc_entropy") == *p) { int count = __entropy_from_kernel(*p); - bzero((void*)*p, strlen(*p)); + bzero((void *)*p, strlen(*p)); - if (sizeof(malloc_entropy)/sizeof(malloc_entropy[0]) == count) { - return; + if (sizeof(malloc_entropy) / sizeof(malloc_entropy[0]) == count) { + _malloc_entropy_initialized = true; } break; } } + if (!_malloc_entropy_initialized) { + getentropy((void*)malloc_entropy, sizeof(malloc_entropy)); + _malloc_entropy_initialized = true; + } +} - malloc_entropy[0] = ((uint64_t)arc4random()) << 32 | ((uint64_t)arc4random()); - malloc_entropy[1] = ((uint64_t)arc4random()) << 32 | ((uint64_t)arc4random()); - return; +static malloc_zone_t* lite_zone = NULL; + +MALLOC_ALWAYS_INLINE +static inline malloc_zone_t * +runtime_default_zone() { + return (lite_zone) ? lite_zone : inline_malloc_default_zone(); +} + +static size_t +default_zone_size(malloc_zone_t *zone, const void *ptr) +{ + zone = runtime_default_zone(); + + return zone->size(zone, ptr); +} + +static void * +default_zone_malloc(malloc_zone_t *zone, size_t size) +{ + zone = runtime_default_zone(); + + return zone->malloc(zone, size); +} + +static void * +default_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) +{ + zone = runtime_default_zone(); + + return zone->calloc(zone, num_items, size); +} + +static void * +default_zone_valloc(malloc_zone_t *zone, size_t size) +{ + zone = runtime_default_zone(); + + return zone->valloc(zone, size); +} + +static void +default_zone_free(malloc_zone_t *zone, void *ptr) +{ + zone = runtime_default_zone(); + + return zone->free(zone, ptr); +} + +static void * +default_zone_realloc(malloc_zone_t *zone, void *ptr, size_t new_size) +{ + zone = runtime_default_zone(); + + return zone->realloc(zone, ptr, new_size); +} + +static void +default_zone_destroy(malloc_zone_t *zone) +{ + zone = runtime_default_zone(); + + return zone->destroy(zone); +} + +static unsigned +default_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned count) +{ + zone = runtime_default_zone(); + + return zone->batch_malloc(zone, size, results, count); +} + +static void +default_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned count) +{ + zone = runtime_default_zone(); + + return zone->batch_free(zone, to_be_freed, count); +} + +static void * +default_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) +{ + zone = runtime_default_zone(); + + return zone->memalign(zone, alignment, size); +} + +static void +default_zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size) +{ + zone = runtime_default_zone(); + + return zone->free_definite_size(zone, ptr, size); +} + +static size_t +default_zone_pressure_relief(malloc_zone_t *zone, size_t goal) +{ + zone = runtime_default_zone(); + + return zone->pressure_relief(zone, goal); +} + +static kern_return_t +default_zone_ptr_in_use_enumerator(task_t task, + void *context, + unsigned type_mask, + vm_address_t zone_address, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + malloc_zone_t *zone = runtime_default_zone(); + + return zone->introspect->enumerator(task, context, type_mask, (vm_address_t) zone, reader, recorder); +} + +static size_t +default_zone_good_size(malloc_zone_t *zone, size_t size) +{ + zone = runtime_default_zone(); + + return zone->introspect->good_size(zone, size); +} + +static boolean_t +default_zone_check(malloc_zone_t *zone) +{ + zone = runtime_default_zone(); + + return zone->introspect->check(zone); +} + +static void +default_zone_print(malloc_zone_t *zone, boolean_t verbose) +{ + zone = runtime_default_zone(); + + zone->introspect->check(zone); +} + +static void +default_zone_log(malloc_zone_t *zone, void *log_address) +{ + zone = runtime_default_zone(); + + zone->introspect->log(zone, log_address); +} + +static void +default_zone_force_lock(malloc_zone_t *zone) +{ + zone = runtime_default_zone(); + + zone->introspect->force_lock(zone); +} + +static void +default_zone_force_unlock(malloc_zone_t *zone) +{ + zone = runtime_default_zone(); + + zone->introspect->force_unlock(zone); } -static inline malloc_zone_t * find_registered_zone(const void *, size_t *) __attribute__((always_inline)); +static void +default_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) +{ + zone = runtime_default_zone(); + + zone->introspect->statistics(zone, stats); +} + +static boolean_t +default_zone_locked(malloc_zone_t *zone) +{ + zone = runtime_default_zone(); + + zone->introspect->zone_locked(zone); +} + +static void +default_zone_reinit_lock(malloc_zone_t *zone) +{ + zone = runtime_default_zone(); + + zone->introspect->reinit_lock(zone); +} + +static struct malloc_introspection_t default_zone_introspect = { + default_zone_ptr_in_use_enumerator, + default_zone_good_size, + default_zone_check, + default_zone_print, + default_zone_log, + default_zone_force_lock, + default_zone_force_unlock, + default_zone_statistics, + default_zone_locked, + NULL, + NULL, + NULL, + NULL, + default_zone_reinit_lock +}; + +typedef struct { + malloc_zone_t malloc_zone; + uint8_t pad[PAGE_MAX_SIZE - sizeof(malloc_zone_t)]; +} virtual_default_zone_t; + +static virtual_default_zone_t virtual_default_zone +__attribute__((section("__DATA,__v_zone"))) +__attribute__((aligned(PAGE_MAX_SIZE))) = { + NULL, + NULL, + default_zone_size, + default_zone_malloc, + default_zone_calloc, + default_zone_valloc, + default_zone_free, + default_zone_realloc, + default_zone_destroy, + DEFAULT_MALLOC_ZONE_STRING, + default_zone_batch_malloc, + default_zone_batch_free, + &default_zone_introspect, + 9, + default_zone_memalign, + default_zone_free_definite_size, + default_zone_pressure_relief +}; + +static malloc_zone_t *default_zone = &virtual_default_zone.malloc_zone; + +static boolean_t +has_default_zone0(void) +{ + if (!malloc_zones) { + return false; + } + + return initial_default_zone == malloc_zones[0]; +} + +static inline malloc_zone_t *find_registered_zone(const void *, size_t *) __attribute__((always_inline)); static inline malloc_zone_t * -find_registered_zone(const void *ptr, size_t *returned_size) { +find_registered_zone(const void *ptr, size_t *returned_size) +{ // Returns a zone which contains ptr, else NULL if (0 == malloc_num_zones) { - if (returned_size) *returned_size = 0; + if (returned_size) { + *returned_size = 0; + } return NULL; } + // first look in the lite zone + if (lite_zone) { + malloc_zone_t *zone = lite_zone; + size_t size = zone->size(zone, ptr); + if (size) { // Claimed by this zone? + if (returned_size) { + *returned_size = size; + } + // Return the virtual default zone instead of the lite zone - see + return default_zone; + } + } + // The default zone is registered in malloc_zones[0]. There's no danger that it will ever be unregistered. // So don't advance the FRZ counter yet. malloc_zone_t *zone = malloc_zones[0]; size_t size = zone->size(zone, ptr); if (size) { // Claimed by this zone? - if (returned_size) *returned_size = size; - return zone; + if (returned_size) { + *returned_size = size; + } + + // Asan and others replace the zone at position 0 with their own zone. + // In that case just return that zone as they need this information. + // Otherwise return the virtual default zone, not the actual zone in position 0. + if (!has_default_zone0()) { + return zone; + } else { + return default_zone; + } } - int *pFRZCounter = pFRZCounterLive; // Capture pointer to the counter of the moment + int *pFRZCounter = pFRZCounterLive; // Capture pointer to the counter of the moment __sync_fetch_and_add(pFRZCounter, 1); // Advance this counter -- our thread is in FRZ - unsigned index; - unsigned limit = malloc_num_zones; - malloc_zone_t **zones = &malloc_zones[1]; + unsigned index; + int32_t limit = *(volatile int32_t *)&malloc_num_zones; + malloc_zone_t **zones = &malloc_zones[1]; + + // From this point on, FRZ is accessing the malloc_zones[] array without locking + // in order to avoid contention on common operations (such as non-default-zone free()). + // In order to ensure that this is actually safe to do, register/unregister take care + // to: + // + // 1. Register ensures that newly inserted pointers in malloc_zones[] are visible + // when malloc_num_zones is incremented. At the moment, we're relying on that store + // ordering to work without taking additional steps here to ensure load memory + // ordering. + // + // 2. Unregister waits for all readers in FRZ to complete their iteration before it + // returns from the unregister call (during which, even unregistered zone pointers + // are still valid). It also ensures that all the pointers in the zones array are + // valid until it returns, so that a stale value in limit is not dangerous. for (index = 1; index < limit; ++index, ++zones) { zone = *zones; size = zone->size(zone, ptr); if (size) { // Claimed by this zone? - if (returned_size) *returned_size = size; + if (returned_size) { + *returned_size = size; + } __sync_fetch_and_sub(pFRZCounter, 1); // our thread is leaving FRZ return zone; } } // Unclaimed by any zone. - if (returned_size) *returned_size = 0; + if (returned_size) { + *returned_size = 0; + } __sync_fetch_and_sub(pFRZCounter, 1); // our thread is leaving FRZ return NULL; } -__attribute__((visibility("hidden"))) __attribute__((noinline)) void -malloc_error_break(void) { +void +malloc_error_break(void) +{ // Provides a non-inlined place for various malloc error procedures to call // that will be called after an error message appears. It does not make // sense for developers to call this function, so it is marked @@ -266,10 +534,9 @@ malloc_error_break(void) { MAGMALLOC_MALLOCERRORBREAK(); // DTrace USDT probe } -extern boolean_t __stack_logging_locked(); - -__attribute__((visibility("hidden"))) __attribute__((noinline)) __attribute__((used)) int -malloc_gdb_po_unsafe(void) { +int +malloc_gdb_po_unsafe(void) +{ // In order to implement "po" other data formatters in gdb, the debugger // calls functions that call malloc. The debugger will only run one thread // of the program in this case, so if another thread is holding a zone lock, @@ -279,8 +546,9 @@ malloc_gdb_po_unsafe(void) { // lock. If trylock succeeds, unlock it, otherwise return "locked". Returns // 0 == safe, 1 == locked/unsafe. - if (__stack_logging_locked()) + if (__stack_logging_locked()) { return 1; + } malloc_zone_t **zones = malloc_zones; unsigned i, e = malloc_num_zones; @@ -289,11 +557,13 @@ malloc_gdb_po_unsafe(void) { malloc_zone_t *zone = zones[i]; // Version must be >= 5 to look at the new introspection field. - if (zone->version < 5) + if (zone->version < 5) { continue; + } - if (zone->introspect->zone_locked && zone->introspect->zone_locked(zone)) + if (zone->introspect->zone_locked && zone->introspect->zone_locked(zone)) { return 1; + } } return 0; } @@ -303,17 +573,19 @@ malloc_gdb_po_unsafe(void) { static void set_flags_from_environment(void); static void -malloc_zone_register_while_locked(malloc_zone_t *zone) { +malloc_zone_register_while_locked(malloc_zone_t *zone) +{ size_t protect_size; unsigned i; /* scan the list of zones, to see if this zone is already registered. If * so, print an error message and return. */ - for (i = 0; i != malloc_num_zones; ++i) + for (i = 0; i != malloc_num_zones; ++i) { if (zone == malloc_zones[i]) { _malloc_printf(ASL_LEVEL_ERR, "Attempted to register zone more than once: %p\n", zone); return; } + } if (malloc_num_zones == malloc_num_zones_allocated) { size_t malloc_zones_size = malloc_num_zones * sizeof(malloc_zone_t *); @@ -328,12 +600,12 @@ malloc_zone_register_while_locked(malloc_zone_t *zone) { return; } - malloc_zone_t **new_zones = (uintptr_t)vm_addr; + malloc_zone_t **new_zones = (malloc_zone_t **)vm_addr; /* If there were previously allocated malloc zones, we need to copy them * out of the previous array and into the new zones array */ if (malloc_zones) { memcpy(new_zones, malloc_zones, malloc_zones_size); - vm_addr = malloc_zones; + vm_addr = (mach_vm_address_t)malloc_zones; mach_vm_size_t dealloc_size = round_page(malloc_zones_size); mach_vm_deallocate(mach_task_self(), vm_addr, dealloc_size); } @@ -342,101 +614,288 @@ malloc_zone_register_while_locked(malloc_zone_t *zone) { * allocated, and the number of zones allocated */ protect_size = alloc_size; malloc_zones = new_zones; - malloc_num_zones_allocated = alloc_size / sizeof(malloc_zone_t *); + malloc_num_zones_allocated = (int32_t)(alloc_size / sizeof(malloc_zone_t *)); } else { /* If we don't need to reallocate zones, we need to briefly change the * page protection the malloc zones to allow writes */ protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); } - malloc_zones[malloc_num_zones++] = zone; + + /* This store-increment needs to be visible in the correct + * order to any threads in find_registered_zone, such that if the incremented value + * in malloc_num_zones is visible then the pointer write before it must also be visible. + * + * While we could be slightly more efficent here with atomic ops the cleanest way to + * ensure the proper store-release operation is performed is to use __sync... to update + * malloc_num_zones. + */ + malloc_zones[malloc_num_zones] = zone; + __sync_fetch_and_add(&malloc_num_zones, 1); /* Finally, now that the zone is registered, disallow write access to the * malloc_zones array */ mprotect(malloc_zones, protect_size, PROT_READ); - //_malloc_printf(ASL_LEVEL_INFO, "Registered malloc_zone %p in malloc_zones %p [%u zones, %u bytes]\n", zone, malloc_zones, malloc_num_zones, protect_size); + //_malloc_printf(ASL_LEVEL_INFO, "Registered malloc_zone %p in malloc_zones %p [%u zones, %u bytes]\n", zone, malloc_zones, + // malloc_num_zones, protect_size); +} + +static void +create_and_insert_lite_zone_while_locked() +{ + malloc_zone_t *zone0 = malloc_zones[0]; + + malloc_zone_t *stack_logging_lite_zone = create_stack_logging_lite_zone(0, zone0, malloc_debug_flags); + malloc_zone_register_while_locked(stack_logging_lite_zone); + malloc_set_zone_name(stack_logging_lite_zone, MALLOC_STOCK_LOGGING_LITE_ZONE_NAME); + lite_zone = stack_logging_lite_zone; +} + +boolean_t +turn_on_stack_logging(stack_logging_mode_type mode) +{ + boolean_t ret = false; + + MALLOC_LOCK(); + + if (!stack_logging_enable_logging) { + if (__uniquing_table_memory_was_deleted()) { + // It would great to be able re-enable even if the uniquing table has been deleted + // malloc stack logging should be able to recreate the uniquing table if needed + } else { + switch (mode) { + case stack_logging_mode_all: + __prepare_to_log_stacks(false); + malloc_logger = __disk_stack_logging_log_stack; + __syscall_logger = __disk_stack_logging_log_stack; + stack_logging_mode = mode; + stack_logging_enable_logging = 1; + ret = true; + + malloc_printf("recording malloc and VM allocation stacks to disk using standard recorder\n"); + break; + + case stack_logging_mode_malloc: + __prepare_to_log_stacks(false); + malloc_logger = __disk_stack_logging_log_stack; + stack_logging_mode = mode; + stack_logging_enable_logging = 1; + ret = true; + + malloc_printf("recording malloc (but not VM allocation) stacks to disk using standard recorder\n"); + break; + + case stack_logging_mode_vm: + __prepare_to_log_stacks(false); + __syscall_logger = __disk_stack_logging_log_stack; + stack_logging_mode = mode; + stack_logging_enable_logging = 1; + ret = true; + + malloc_printf("recording VM allocation (but not malloc) stacks to disk using standard recorder\n"); + break; + + case stack_logging_mode_lite: + if (!has_default_zone0()) { + malloc_printf("zone[0] is not the normal default zone so can't turn on lite mode.\n", mode); + ret = false; + } else { + malloc_printf("recording malloc (but not VM allocation) stacks using lite mode\n"); + + if (lite_zone) { + enable_stack_logging_lite(); + } else { + if (__prepare_to_log_stacks(true)) { + stack_logging_mode = stack_logging_mode_lite; + stack_logging_enable_logging = 1; + __prepare_to_log_stacks_stage2(); + create_and_insert_lite_zone_while_locked(); + enable_stack_logging_lite(); + } + } + ret = true; + } + break; + + default: + malloc_printf("invalid mode %d passed to turn_on_stack_logging\n", mode); + break; + } + } + } else { + malloc_printf("malloc stack logging already enabled.\n"); + } + + MALLOC_UNLOCK(); + + return ret; } +void +turn_off_stack_logging() +{ + MALLOC_LOCK(); + + if (stack_logging_enable_logging) { + switch (stack_logging_mode) { + case stack_logging_mode_all: + malloc_logger = NULL; + __syscall_logger = NULL; + stack_logging_enable_logging = 0; + malloc_printf("turning off recording malloc and VM allocation stacks to disk using standard recorder\n"); + break; + + case stack_logging_mode_malloc: + malloc_logger = NULL; + stack_logging_enable_logging = 0; + malloc_printf("turnning off recording malloc (but not VM allocation) stacks to disk using standard recorder\n"); + break; + + case stack_logging_mode_vm: + __syscall_logger = NULL; + stack_logging_enable_logging = 0; + malloc_printf("turning off recording VM allocation (but not malloc) stacks to disk using standard recorder\n"); + break; + + case stack_logging_mode_lite: + malloc_printf("turning off recording malloc (but not VM allocation) stacks using lite mode\n"); + + disable_stack_logging_lite(); + stack_logging_enable_logging = 0; + break; + + default: + malloc_printf("invalid stack_logging_mode %d in turn_off_stack_logging\n", stack_logging_mode); + break; + } + } else { + malloc_printf("malloc stack logging not enabled.\n"); + } + + MALLOC_UNLOCK(); +} + +// To be used in _malloc_initialize_once() only, call that function instead. static void -_malloc_initialize(void) { +_malloc_initialize(void *context __unused) +{ MALLOC_LOCK(); - if (!_malloc_is_initialized) { - unsigned n; - malloc_zone_t *zone; + unsigned n; + malloc_zone_t *zone; - _malloc_is_initialized = TRUE; + if (!_malloc_entropy_initialized) { + // Lazy initialization may occur before __malloc_init (rdar://27075409) + // TODO: make this a fatal error + malloc_printf("*** malloc was initialized without entropy\n"); + } - set_flags_from_environment(); // will only set flags up to two times - n = malloc_num_zones; + set_flags_from_environment(); // will only set flags up to two times + n = malloc_num_zones; #if CONFIG_NANOZONE - malloc_zone_t *helper_zone = create_scalable_zone(0, malloc_debug_flags); - zone = create_nano_zone(0, helper_zone, malloc_debug_flags); + malloc_zone_t *helper_zone = create_scalable_zone(0, malloc_debug_flags); + zone = create_nano_zone(0, helper_zone, malloc_debug_flags); - if (zone) { - malloc_zone_register_while_locked(zone); - malloc_zone_register_while_locked(helper_zone); + if (zone) { + malloc_zone_register_while_locked(zone); + malloc_zone_register_while_locked(helper_zone); - // Must call malloc_set_zone_name() *after* helper and nano are hooked together. - malloc_set_zone_name(zone, DEFAULT_MALLOC_ZONE_STRING); - malloc_set_zone_name(helper_zone, MALLOC_HELPER_ZONE_STRING); - } else { - zone = helper_zone; - malloc_zone_register_while_locked(zone); - malloc_set_zone_name(zone, DEFAULT_MALLOC_ZONE_STRING); - } -#else - zone = create_scalable_zone(0, malloc_debug_flags); + // Must call malloc_set_zone_name() *after* helper and nano are hooked together. + malloc_set_zone_name(zone, DEFAULT_MALLOC_ZONE_STRING); + malloc_set_zone_name(helper_zone, MALLOC_HELPER_ZONE_STRING); + } else { + zone = helper_zone; malloc_zone_register_while_locked(zone); malloc_set_zone_name(zone, DEFAULT_MALLOC_ZONE_STRING); + } +#else + zone = create_scalable_zone(0, malloc_debug_flags); + malloc_zone_register_while_locked(zone); + malloc_set_zone_name(zone, DEFAULT_MALLOC_ZONE_STRING); #endif - if (n != 0) { // make the default first, for efficiency - unsigned protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); - malloc_zone_t *hold = malloc_zones[0]; + initial_default_zone = zone; - if(hold->zone_name && strcmp(hold->zone_name, DEFAULT_MALLOC_ZONE_STRING) == 0) { - malloc_set_zone_name(hold, NULL); - } + if (n != 0) { // make the default first, for efficiency + unsigned protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *); + malloc_zone_t *hold = malloc_zones[0]; - mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); - malloc_zones[0] = malloc_zones[n]; - malloc_zones[n] = hold; - mprotect(malloc_zones, protect_size, PROT_READ); + if (hold->zone_name && strcmp(hold->zone_name, DEFAULT_MALLOC_ZONE_STRING) == 0) { + malloc_set_zone_name(hold, NULL); + } + + mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE); + malloc_zones[0] = malloc_zones[n]; + malloc_zones[n] = hold; + mprotect(malloc_zones, protect_size, PROT_READ); + } + + // Only setup stack logging hooks once lazy initialization is complete, the + // malloc_zone calls above would otherwise initialize malloc stack logging, + // which calls into malloc re-entrantly from Libc upcalls and so deadlocks + // in the lazy initialization os_once(). rdar://13046853 + if (stack_logging_enable_logging) { + switch (stack_logging_mode) { + case stack_logging_mode_malloc: + malloc_logger = __disk_stack_logging_log_stack; + break; + case stack_logging_mode_vm: + __syscall_logger = __disk_stack_logging_log_stack; + break; + case stack_logging_mode_all: + malloc_logger = __disk_stack_logging_log_stack; + __syscall_logger = __disk_stack_logging_log_stack; + break; + case stack_logging_mode_lite: + create_and_insert_lite_zone_while_locked(); + enable_stack_logging_lite(); + break; } - // _malloc_printf(ASL_LEVEL_INFO, "%d registered zones\n", malloc_num_zones); - // _malloc_printf(ASL_LEVEL_INFO, "malloc_zones is at %p; malloc_num_zones is at %p\n", (unsigned)&malloc_zones, (unsigned)&malloc_num_zones); } + + // _malloc_printf(ASL_LEVEL_INFO, "%d registered zones\n", malloc_num_zones); + // _malloc_printf(ASL_LEVEL_INFO, "malloc_zones is at %p; malloc_num_zones is at %p\n", (unsigned)&malloc_zones, + // (unsigned)&malloc_num_zones); MALLOC_UNLOCK(); } -static inline malloc_zone_t *inline_malloc_default_zone(void) __attribute__((always_inline)); +MALLOC_ALWAYS_INLINE +static inline void +_malloc_initialize_once(void) +{ + os_once(&_malloc_initialize_pred, NULL, _malloc_initialize); +} + static inline malloc_zone_t * -inline_malloc_default_zone(void) { - if (!_malloc_is_initialized) _malloc_initialize(); +inline_malloc_default_zone(void) +{ + _malloc_initialize_once(); // _malloc_printf(ASL_LEVEL_INFO, "In inline_malloc_default_zone with %d %d\n", malloc_num_zones, malloc_has_debug_zone); return malloc_zones[0]; } malloc_zone_t * -malloc_default_zone(void) { - return inline_malloc_default_zone(); +malloc_default_zone(void) +{ + return default_zone; } static inline malloc_zone_t *inline_malloc_default_scalable_zone(void) __attribute__((always_inline)); static inline malloc_zone_t * -inline_malloc_default_scalable_zone(void) { +inline_malloc_default_scalable_zone(void) +{ unsigned index; - if (!_malloc_is_initialized) _malloc_initialize(); - // _malloc_printf(ASL_LEVEL_INFO, "In inline_malloc_default_scalable_zone with %d %d\n", malloc_num_zones, malloc_has_debug_zone); + _malloc_initialize_once(); + // _malloc_printf(ASL_LEVEL_INFO, "In inline_malloc_default_scalable_zone with %d %d\n", malloc_num_zones, + // malloc_has_debug_zone); MALLOC_LOCK(); #if CONFIG_NANOZONE for (index = 0; index < malloc_num_zones; ++index) { malloc_zone_t *z = malloc_zones[index]; - if(z->zone_name && strcmp(z->zone_name, MALLOC_HELPER_ZONE_STRING) == 0) { + if (z->zone_name && strcmp(z->zone_name, MALLOC_HELPER_ZONE_STRING) == 0) { MALLOC_UNLOCK(); return z; } @@ -445,7 +904,7 @@ inline_malloc_default_scalable_zone(void) { for (index = 0; index < malloc_num_zones; ++index) { malloc_zone_t *z = malloc_zones[index]; - if(z->zone_name && strcmp(z->zone_name, DEFAULT_MALLOC_ZONE_STRING) == 0) { + if (z->zone_name && strcmp(z->zone_name, DEFAULT_MALLOC_ZONE_STRING) == 0) { MALLOC_UNLOCK(); return z; } @@ -456,10 +915,46 @@ inline_malloc_default_scalable_zone(void) { return NULL; // FIXME: abort() instead? } +static void * +legacy_zeroing_large_malloc(malloc_zone_t *zone, size_t size) +{ + if (size > LARGE_THRESHOLD) { // Leopard and earlier returned a ZFOD range, so ... + return default_zone_calloc(zone, 1, size); // Clear to zero always, ham-handedly touching in each page + } else { + return default_zone_malloc(zone, size); + } +} + +static void * +legacy_zeroing_large_valloc(malloc_zone_t *zone, size_t size) +{ + void *p = default_zone_valloc(zone, size); + + // Leopard and earlier returned a ZFOD range, so ... + memset(p, 0, size); // Clear to zero always, ham-handedly touching in each page + return p; +} + +void +zeroify_scalable_zone(malloc_zone_t *zone) +{ + // this checkfix should replace the default zone's + // allocation routines with the zeroing versions. Instead of getting in hot + // water with the wrong zone, ensure that we're mutating the zone we expect. + // + // Additionally, the default_zone is no longer PROT_READ, so the two mprotect + // calls that were here are no longer needed. + if (zone == default_zone) { + zone->malloc = (void *)legacy_zeroing_large_malloc; + zone->valloc = (void *)legacy_zeroing_large_valloc; + } +} + /* * malloc_engaged_nano() is for the benefit of libdispatch, which calls here just once. */ -boolean_t malloc_engaged_nano(void) +boolean_t +malloc_engaged_nano(void) { #if CONFIG_NANOZONE return _malloc_engaged_nano; @@ -469,7 +964,8 @@ boolean_t malloc_engaged_nano(void) } malloc_zone_t * -malloc_default_purgeable_zone(void) { +malloc_default_purgeable_zone(void) +{ static malloc_zone_t *dpz; if (!dpz) { @@ -480,32 +976,36 @@ malloc_default_purgeable_zone(void) { malloc_zone_t *tmp = create_purgeable_zone(0, inline_malloc_default_scalable_zone(), malloc_debug_flags); malloc_zone_register(tmp); malloc_set_zone_name(tmp, DEFAULT_PUREGEABLE_ZONE_STRING); - if (!__sync_bool_compare_and_swap(&dpz, NULL, tmp)) + if (!__sync_bool_compare_and_swap(&dpz, NULL, tmp)) { malloc_destroy_zone(tmp); + } } return dpz; } static void -set_flags_from_environment(void) { - const char *flag; - int fd; - char **env = * _NSGetEnviron(); - char **p; - char *c; +set_flags_from_environment(void) +{ + const char *flag; + int fd; + char **env = *_NSGetEnviron(); + char **p; + char *c; + bool restricted = 0; if (malloc_debug_file != STDERR_FILENO) { close(malloc_debug_file); malloc_debug_file = STDERR_FILENO; } #if __LP64__ - malloc_debug_flags = SCALABLE_MALLOC_ABORT_ON_CORRUPTION; // Set always on 64-bit processes + malloc_debug_flags = MALLOC_ABORT_ON_CORRUPTION; // Set always on 64-bit processes #else - int libSystemVersion = NSVersionOfLinkTimeLibrary("System"); - if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 126) /* Lion or greater */) + int libSystemVersion = NSVersionOfLinkTimeLibrary("System"); + if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 126) /* Lion or greater */) { malloc_debug_flags = 0; - else - malloc_debug_flags = SCALABLE_MALLOC_ABORT_ON_CORRUPTION; + } else { + malloc_debug_flags = MALLOC_ABORT_ON_CORRUPTION; + } #endif stack_logging_enable_logging = 0; stack_logging_dontcompact = 0; @@ -522,32 +1022,44 @@ set_flags_from_environment(void) { */ for (p = env; (c = *p) != NULL; ++p) { if (!strncmp(c, "Malloc", 6)) { - if (issetugid()) + if (issetugid()) { return; + } break; } } - if (c == NULL) + + /* + * Deny certain flags for entitled processes rdar://problem/13521742 + * MallocLogFile & MallocCorruptionAbort + * as these provide the ability to turn *off* aborting in error cases. + */ + restricted = dyld_process_is_restricted(); + + if (c == NULL) { return; - flag = getenv("MallocLogFile"); - if (flag) { - fd = open(flag, O_WRONLY|O_APPEND|O_CREAT, 0644); - if (fd >= 0) { - malloc_debug_file = fd; - fcntl(fd, F_SETFD, 0); // clear close-on-exec flag XXX why? - } else { - malloc_printf("Could not open %s, using stderr\n", flag); + } + if (!restricted) { + flag = getenv("MallocLogFile"); + if (flag) { + fd = open(flag, O_WRONLY | O_APPEND | O_CREAT, 0644); + if (fd >= 0) { + malloc_debug_file = fd; + fcntl(fd, F_SETFD, 0); // clear close-on-exec flag XXX why? + } else { + malloc_printf("Could not open %s, using stderr\n", flag); + } } } if (getenv("MallocGuardEdges")) { - malloc_debug_flags |= SCALABLE_MALLOC_ADD_GUARD_PAGES; + malloc_debug_flags |= MALLOC_ADD_GUARD_PAGES; _malloc_printf(ASL_LEVEL_INFO, "protecting edges\n"); if (getenv("MallocDoNotProtectPrelude")) { - malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_PRELUDE; + malloc_debug_flags |= MALLOC_DONT_PROTECT_PRELUDE; _malloc_printf(ASL_LEVEL_INFO, "... but not protecting prelude guard page\n"); } if (getenv("MallocDoNotProtectPostlude")) { - malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE; + malloc_debug_flags |= MALLOC_DONT_PROTECT_POSTLUDE; _malloc_printf(ASL_LEVEL_INFO, "... but not protecting postlude guard page\n"); } } @@ -561,35 +1073,44 @@ set_flags_from_environment(void) { // including those from _malloc_printf and malloc zone setup. Make sure to set // __syscall_logger after this, because prepare_to_log_stacks() itself makes VM // allocations that we aren't prepared to log yet. - __prepare_to_log_stacks(); - if (strcmp(flag,"malloc") == 0) { - malloc_logger = __disk_stack_logging_log_stack; + boolean_t lite_mode = strcmp(flag, "lite") == 0; + + __prepare_to_log_stacks(lite_mode); + + if (strcmp(flag, "lite") == 0) { + stack_logging_mode = stack_logging_mode_lite; + _malloc_printf(ASL_LEVEL_INFO, "recording malloc (but not VM allocation) stacks using lite mode\n"); + } else if (strcmp(flag,"malloc") == 0) { + stack_logging_mode = stack_logging_mode_malloc; _malloc_printf(ASL_LEVEL_INFO, "recording malloc (but not VM allocation) stacks to disk using standard recorder\n"); - } else if (strcmp(flag,"vm") == 0) { - __syscall_logger = __disk_stack_logging_log_stack; + } else if (strcmp(flag, "vm") == 0) { + stack_logging_mode = stack_logging_mode_vm; _malloc_printf(ASL_LEVEL_INFO, "recording VM allocation (but not malloc) stacks to disk using standard recorder\n"); } else { - malloc_logger = __disk_stack_logging_log_stack; - __syscall_logger = __disk_stack_logging_log_stack; + stack_logging_mode = stack_logging_mode_all; _malloc_printf(ASL_LEVEL_INFO, "recording malloc and VM allocation stacks to disk using standard recorder\n"); } stack_logging_enable_logging = 1; if (stack_logging_dontcompact) { - if (malloc_logger == __disk_stack_logging_log_stack) { - _malloc_printf(ASL_LEVEL_INFO, "stack logging compaction turned off; size of log files on disk can increase rapidly\n"); + if (stack_logging_mode == stack_logging_mode_all || stack_logging_mode == stack_logging_mode_malloc) { + _malloc_printf( + ASL_LEVEL_INFO, "stack logging compaction turned off; size of log files on disk can increase rapidly\n"); } else { _malloc_printf(ASL_LEVEL_INFO, "stack logging compaction turned off; VM can increase rapidly\n"); } } } if (getenv("MallocScribble")) { - malloc_debug_flags |= SCALABLE_MALLOC_DO_SCRIBBLE; + malloc_debug_flags |= MALLOC_DO_SCRIBBLE; _malloc_printf(ASL_LEVEL_INFO, "enabling scribbling to detect mods to free blocks\n"); } if (getenv("MallocErrorAbort")) { - malloc_debug_flags |= SCALABLE_MALLOC_ABORT_ON_ERROR; + malloc_debug_flags |= MALLOC_ABORT_ON_ERROR; _malloc_printf(ASL_LEVEL_INFO, "enabling abort() on bad malloc or free\n"); } + if (getenv("MallocTracing")) { + malloc_tracing_enabled = true; + } #if CONFIG_NANOZONE /* Explicit overrides from the environment */ if ((flag = getenv("MallocNanoZone"))) { @@ -602,77 +1123,90 @@ set_flags_from_environment(void) { #endif /* CONFIG_NANOZONE */ #if __LP64__ - /* initialization above forces SCALABLE_MALLOC_ABORT_ON_CORRUPTION of 64-bit processes */ +/* initialization above forces MALLOC_ABORT_ON_CORRUPTION of 64-bit processes */ #else flag = getenv("MallocCorruptionAbort"); - if (flag && (flag[0] == '0')) { // Set from an environment variable in 32-bit processes - malloc_debug_flags &= ~SCALABLE_MALLOC_ABORT_ON_CORRUPTION; + if (!restricted && flag && (flag[0] == '0')) { // Set from an environment variable in 32-bit processes + malloc_debug_flags &= ~MALLOC_ABORT_ON_CORRUPTION; } else if (flag) { - malloc_debug_flags |= SCALABLE_MALLOC_ABORT_ON_CORRUPTION; + malloc_debug_flags |= MALLOC_ABORT_ON_CORRUPTION; } #endif flag = getenv("MallocCheckHeapStart"); if (flag) { - malloc_check_start = strtoul(flag, NULL, 0); - if (malloc_check_start == 0) malloc_check_start = 1; - if (malloc_check_start == -1) malloc_check_start = 1; + malloc_check_start = (unsigned)strtoul(flag, NULL, 0); + if (malloc_check_start == 0) { + malloc_check_start = 1; + } + if (malloc_check_start == -1) { + malloc_check_start = 1; + } flag = getenv("MallocCheckHeapEach"); if (flag) { - malloc_check_each = strtoul(flag, NULL, 0); - if (malloc_check_each == 0) malloc_check_each = 1; - if (malloc_check_each == -1) malloc_check_each = 1; + malloc_check_each = (unsigned)strtoul(flag, NULL, 0); + if (malloc_check_each == 0) { + malloc_check_each = 1; + } + if (malloc_check_each == -1) { + malloc_check_each = 1; + } } - _malloc_printf(ASL_LEVEL_INFO, "checks heap after %dth operation and each %d operations\n", malloc_check_start, malloc_check_each); + _malloc_printf( + ASL_LEVEL_INFO, "checks heap after %dth operation and each %d operations\n", malloc_check_start, malloc_check_each); flag = getenv("MallocCheckHeapAbort"); - if (flag) - malloc_check_abort = strtol(flag, NULL, 0); - if (malloc_check_abort) + if (flag) { + malloc_check_abort = (unsigned)strtol(flag, NULL, 0); + } + if (malloc_check_abort) { _malloc_printf(ASL_LEVEL_INFO, "will abort on heap corruption\n"); - else { + } else { flag = getenv("MallocCheckHeapSleep"); - if (flag) - malloc_check_sleep = strtol(flag, NULL, 0); - if (malloc_check_sleep > 0) + if (flag) { + malloc_check_sleep = (unsigned)strtol(flag, NULL, 0); + } + if (malloc_check_sleep > 0) { _malloc_printf(ASL_LEVEL_INFO, "will sleep for %d seconds on heap corruption\n", malloc_check_sleep); - else if (malloc_check_sleep < 0) + } else if (malloc_check_sleep < 0) { _malloc_printf(ASL_LEVEL_INFO, "will sleep once for %d seconds on heap corruption\n", -malloc_check_sleep); - else + } else { _malloc_printf(ASL_LEVEL_INFO, "no sleep on heap corruption\n"); + } } } if (getenv("MallocHelp")) { _malloc_printf(ASL_LEVEL_INFO, - "environment variables that can be set for debug:\n" - "- MallocLogFile to create/append messages to file instead of stderr\n" - "- MallocGuardEdges to add 2 guard pages for each large block\n" - "- MallocDoNotProtectPrelude to disable protection (when previous flag set)\n" - "- MallocDoNotProtectPostlude to disable protection (when previous flag set)\n" - "- MallocStackLogging to record all stacks. Tools like leaks can then be applied\n" - "- MallocStackLoggingNoCompact to record all stacks. Needed for malloc_history\n" - "- MallocStackLoggingDirectory to set location of stack logs, which can grow large; default is /tmp\n" - "- MallocScribble to detect writing on free blocks and missing initializers:\n" - " 0x55 is written upon free and 0xaa is written on allocation\n" - "- MallocCheckHeapStart to start checking the heap after operations\n" - "- MallocCheckHeapEach to repeat the checking of the heap after operations\n" - "- MallocCheckHeapSleep to sleep seconds on heap corruption\n" - "- MallocCheckHeapAbort to abort on heap corruption if is non-zero\n" - "- MallocCorruptionAbort to abort on malloc errors, but not on out of memory for 32-bit processes\n" - " MallocCorruptionAbort is always set on 64-bit processes\n" - "- MallocErrorAbort to abort on any malloc error, including out of memory\n" - "- MallocHelp - this help!\n"); + "environment variables that can be set for debug:\n" + "- MallocLogFile to create/append messages to file instead of stderr\n" + "- MallocGuardEdges to add 2 guard pages for each large block\n" + "- MallocDoNotProtectPrelude to disable protection (when previous flag set)\n" + "- MallocDoNotProtectPostlude to disable protection (when previous flag set)\n" + "- MallocStackLogging to record all stacks. Tools like leaks can then be applied\n" + "- MallocStackLoggingNoCompact to record all stacks. Needed for malloc_history\n" + "- MallocStackLoggingDirectory to set location of stack logs, which can grow large; default is /tmp\n" + "- MallocScribble to detect writing on free blocks and missing initializers:\n" + " 0x55 is written upon free and 0xaa is written on allocation\n" + "- MallocCheckHeapStart to start checking the heap after operations\n" + "- MallocCheckHeapEach to repeat the checking of the heap after operations\n" + "- MallocCheckHeapSleep to sleep seconds on heap corruption\n" + "- MallocCheckHeapAbort to abort on heap corruption if is non-zero\n" + "- MallocCorruptionAbort to abort on malloc errors, but not on out of memory for 32-bit processes\n" + " MallocCorruptionAbort is always set on 64-bit processes\n" + "- MallocErrorAbort to abort on any malloc error, including out of memory\n"\ + "- MallocTracing to emit kdebug trace points on malloc entry points\n"\ + "- MallocHelp - this help!\n"); } } malloc_zone_t * malloc_create_zone(vm_size_t start_size, unsigned flags) { - malloc_zone_t *zone; + malloc_zone_t *zone; /* start_size doesn't actually appear to be used, but we test anyway. */ if (start_size > MALLOC_ABSOLUTE_MAX_SIZE) { return NULL; } - if (!_malloc_is_initialized) _malloc_initialize(); + _malloc_initialize_once(); zone = create_scalable_zone(start_size, flags | malloc_debug_flags); malloc_zone_register(zone); return zone; @@ -685,10 +1219,10 @@ malloc_create_zone(vm_size_t start_size, unsigned flags) void malloc_create_legacy_default_zone(void) { - malloc_zone_t *zone; + malloc_zone_t *zone; int i; - if (!_malloc_is_initialized) _malloc_initialize(); + _malloc_initialize_once(); zone = create_legacy_scalable_zone(0, malloc_debug_flags); MALLOC_LOCK(); @@ -698,7 +1232,7 @@ malloc_create_legacy_default_zone(void) // Establish the legacy scalable zone just created as the default zone. // malloc_zone_t *hold = malloc_zones[0]; - if(hold->zone_name && strcmp(hold->zone_name, DEFAULT_MALLOC_ZONE_STRING) == 0) { + if (hold->zone_name && strcmp(hold->zone_name, DEFAULT_MALLOC_ZONE_STRING) == 0) { malloc_set_zone_name(hold, NULL); } malloc_set_zone_name(zone, DEFAULT_MALLOC_ZONE_STRING); @@ -717,7 +1251,8 @@ malloc_create_legacy_default_zone(void) } void -malloc_destroy_zone(malloc_zone_t *zone) { +malloc_destroy_zone(malloc_zone_t *zone) +{ malloc_set_zone_name(zone, NULL); // Deallocate zone name wherever it may reside PR_7701095 malloc_zone_unregister(zone); zone->destroy(zone); @@ -726,24 +1261,29 @@ malloc_destroy_zone(malloc_zone_t *zone) { /********* Block creation and manipulation ************/ static void -internal_check(void) { - static vm_address_t *frames = NULL; - static unsigned num_frames; +internal_check(void) +{ + static vm_address_t *frames = NULL; + static unsigned num_frames; if (malloc_zone_check(NULL)) { - if (!frames) vm_allocate(mach_task_self(), (void *)&frames, vm_page_size, 1); - thread_stack_pcs(frames, vm_page_size/sizeof(vm_address_t) - 1, &num_frames); + if (!frames) { + vm_allocate(mach_task_self(), (void *)&frames, vm_page_size, 1); + } + thread_stack_pcs(frames, (unsigned)(vm_page_size / sizeof(vm_address_t) - 1), &num_frames); } else { _SIMPLE_STRING b = _simple_salloc(); - if (b) - _simple_sprintf(b, "*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1); - else - _malloc_printf(MALLOC_PRINTF_NOLOG, "*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1); - malloc_printf("*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1); + if (b) { + _simple_sprintf(b, "*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter - 1); + } else { + _malloc_printf(MALLOC_PRINTF_NOLOG, "*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter - 1); + } + malloc_printf("*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter - 1); if (frames) { - unsigned index = 1; + unsigned index = 1; if (b) { _simple_sappend(b, "Stack for last operation where the malloc check succeeded: "); - while (index < num_frames) _simple_sprintf(b, "%p ", frames[index++]); + while (index < num_frames) + _simple_sprintf(b, "%p ", frames[index++]); malloc_printf("%s\n(Use 'atos' for a symbolic stack)\n", _simple_string(b)); } else { /* @@ -752,27 +1292,34 @@ internal_check(void) { * print to the file descriptor. */ _malloc_printf(MALLOC_PRINTF_NOLOG, "Stack for last operation where the malloc check succeeded: "); - while (index < num_frames) _malloc_printf(MALLOC_PRINTF_NOLOG, "%p ", frames[index++]); + while (index < num_frames) + _malloc_printf(MALLOC_PRINTF_NOLOG, "%p ", frames[index++]); _malloc_printf(MALLOC_PRINTF_NOLOG, "\n(Use 'atos' for a symbolic stack)\n"); } } if (malloc_check_each > 1) { - unsigned recomm_each = (malloc_check_each > 10) ? malloc_check_each/10 : 1; - unsigned recomm_start = (malloc_check_counter > malloc_check_each+1) ? malloc_check_counter-1-malloc_check_each : 1; - malloc_printf("*** Recommend using 'setenv MallocCheckHeapStart %d; setenv MallocCheckHeapEach %d' to narrow down failure\n", recomm_start, recomm_each); + unsigned recomm_each = (malloc_check_each > 10) ? malloc_check_each / 10 : 1; + unsigned recomm_start = + (malloc_check_counter > malloc_check_each + 1) ? malloc_check_counter - 1 - malloc_check_each : 1; + malloc_printf( + "*** Recommend using 'setenv MallocCheckHeapStart %d; setenv MallocCheckHeapEach %d' to narrow down failure\n", + recomm_start, recomm_each); } if (malloc_check_abort) { - CRSetCrashLogMessage(b ? _simple_string(b) : "*** MallocCheckHeap: FAILED check"); + if (b) { + _os_set_crash_log_message_dynamic(_simple_string(b)); + } else { + _os_set_crash_log_message("*** MallocCheckHeap: FAILED check"); + } abort(); - } else if (b) + } else if (b) { _simple_sfree(b); + } if (malloc_check_sleep > 0) { - _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping for %d seconds to leave time to attach\n", - malloc_check_sleep); + _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping for %d seconds to leave time to attach\n", malloc_check_sleep); sleep(malloc_check_sleep); } else if (malloc_check_sleep < 0) { - _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping once for %d seconds to leave time to attach\n", - -malloc_check_sleep); + _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping once for %d seconds to leave time to attach\n", -malloc_check_sleep); sleep(-malloc_check_sleep); malloc_check_sleep = 0; } @@ -781,138 +1328,190 @@ internal_check(void) { } void * -malloc_zone_malloc(malloc_zone_t *zone, size_t size) { - void *ptr; +malloc_zone_malloc(malloc_zone_t *zone, size_t size) +{ + MALLOC_TRACE(TRACE_malloc | DBG_FUNC_START, (uintptr_t)zone, size, 0, 0); + + void *ptr; if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } if (size > MALLOC_ABSOLUTE_MAX_SIZE) { return NULL; } - ptr = zone->malloc(zone, size); - if (malloc_logger) + + ptr = zone->malloc(zone, size); // if lite zone is passed in then we still call the lite methods + + + if (malloc_logger) { malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); + } + + MALLOC_TRACE(TRACE_malloc | DBG_FUNC_END, (uintptr_t)zone, size, (uintptr_t)ptr, 0); return ptr; } void * -malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { - void *ptr; +malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) +{ + void *ptr; + size_t alloc_size; if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } - if (size > MALLOC_ABSOLUTE_MAX_SIZE) { + if (os_mul_overflow(num_items, size, &alloc_size) || alloc_size > MALLOC_ABSOLUTE_MAX_SIZE){ + errno = ENOMEM; return NULL; } + ptr = zone->calloc(zone, num_items, size); - if (malloc_logger) - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE | MALLOC_LOG_TYPE_CLEARED, (uintptr_t)zone, (uintptr_t)(num_items * size), 0, - (uintptr_t)ptr, 0); + + if (malloc_logger) { + malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE | MALLOC_LOG_TYPE_CLEARED, (uintptr_t)zone, + (uintptr_t)(num_items * size), 0, (uintptr_t)ptr, 0); + } return ptr; } void * -malloc_zone_valloc(malloc_zone_t *zone, size_t size) { - void *ptr; +malloc_zone_valloc(malloc_zone_t *zone, size_t size) +{ + void *ptr; if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } if (size > MALLOC_ABSOLUTE_MAX_SIZE) { return NULL; } + ptr = zone->valloc(zone, size); - if (malloc_logger) + + if (malloc_logger) { malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); + } return ptr; } void * -malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) { - void *new_ptr; +malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) +{ + MALLOC_TRACE(TRACE_realloc | DBG_FUNC_START, (uintptr_t)zone, (uintptr_t)ptr, size, 0); + + void *new_ptr; if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } if (size > MALLOC_ABSOLUTE_MAX_SIZE) { return NULL; } + new_ptr = zone->realloc(zone, ptr, size); - if (malloc_logger) - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, (uintptr_t)size, - (uintptr_t)new_ptr, 0); + + if (malloc_logger) { + malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, + (uintptr_t)ptr, (uintptr_t)size, (uintptr_t)new_ptr, 0); + } + MALLOC_TRACE(TRACE_realloc | DBG_FUNC_END, (uintptr_t)zone, (uintptr_t)ptr, size, (uintptr_t)new_ptr); return new_ptr; } void -malloc_zone_free(malloc_zone_t *zone, void *ptr) { - if (malloc_logger) +malloc_zone_free(malloc_zone_t *zone, void *ptr) +{ + MALLOC_TRACE(TRACE_free, (uintptr_t)zone, (uintptr_t)ptr, 0, 0); + + if (malloc_logger) { malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0); + } if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } + zone->free(zone, ptr); } static void -malloc_zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size) { - if (malloc_logger) +malloc_zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size) +{ + MALLOC_TRACE(TRACE_free, (uintptr_t)zone, (uintptr_t)ptr, size, 0); + + if (malloc_logger) { malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0); + } if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } + zone->free_definite_size(zone, ptr, size); } malloc_zone_t * -malloc_zone_from_ptr(const void *ptr) { - if (!ptr) +malloc_zone_from_ptr(const void *ptr) +{ + if (!ptr) { return NULL; - else + } else { return find_registered_zone(ptr, NULL); + } } void * -malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) { - void *ptr; - if (zone->version < 5) // Version must be >= 5 to look at the new memalign field. - return NULL; - if (!(zone->memalign)) +malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) +{ + MALLOC_TRACE(TRACE_memalign | DBG_FUNC_START, (uintptr_t)zone, alignment, size, 0); + + void *ptr; + if (zone->version < 5) { // Version must be >= 5 to look at the new memalign field. return NULL; + } if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } if (size > MALLOC_ABSOLUTE_MAX_SIZE) { return NULL; } - if (alignment < sizeof( void *) || // excludes 0 == alignment - 0 != (alignment & (alignment - 1))) { // relies on sizeof(void *) being a power of two. + if (alignment < sizeof(void *) || // excludes 0 == alignment + 0 != (alignment & (alignment - 1))) { // relies on sizeof(void *) being a power of two. + return NULL; + } + + if (!(zone->memalign)) { return NULL; } ptr = zone->memalign(zone, alignment, size); - if (malloc_logger) + + if (malloc_logger) { malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0); + } + + MALLOC_TRACE(TRACE_memalign | DBG_FUNC_END, (uintptr_t)zone, alignment, size, (uintptr_t)ptr); return ptr; } /********* Functions for zone implementors ************/ void -malloc_zone_register(malloc_zone_t *zone) { +malloc_zone_register(malloc_zone_t *zone) +{ MALLOC_LOCK(); malloc_zone_register_while_locked(zone); MALLOC_UNLOCK(); } void -malloc_zone_unregister(malloc_zone_t *z) { - unsigned index; +malloc_zone_unregister(malloc_zone_t *z) +{ + unsigned index; - if (malloc_num_zones == 0) + if (malloc_num_zones == 0) { return; + } MALLOC_LOCK(); for (index = 0; index < malloc_num_zones; ++index) { - if (z != malloc_zones[index]) + if (z != malloc_zones[index]) { continue; + } // Modify the page to be allow write access, so that we can update the // malloc_zones array. @@ -935,7 +1534,9 @@ malloc_zone_unregister(malloc_zone_t *z) { pFRZCounterDrain = p; __sync_synchronize(); // Full memory barrier - while (0 != *pFRZCounterDrain) { yield(); } + while (0 != *pFRZCounterDrain) { + yield(); + } MALLOC_UNLOCK(); @@ -946,8 +1547,9 @@ malloc_zone_unregister(malloc_zone_t *z) { } void -malloc_set_zone_name(malloc_zone_t *z, const char *name) { - char *newName; +malloc_set_zone_name(malloc_zone_t *z, const char *name) +{ + char *newName; mprotect(z, sizeof(malloc_zone_t), PROT_READ | PROT_WRITE); if (z->zone_name) { @@ -968,7 +1570,8 @@ malloc_set_zone_name(malloc_zone_t *z, const char *name) { } const char * -malloc_get_zone_name(malloc_zone_t *zone) { +malloc_get_zone_name(malloc_zone_t *zone) +{ return zone->zone_name; } @@ -977,8 +1580,7 @@ malloc_get_zone_name(malloc_zone_t *zone) { * subset of printf format specifiers, but it doesn't call malloc. */ -__attribute__((visibility("hidden"))) -void +__attribute__((visibility("hidden"))) void _malloc_vprintf(int flags, const char *format, va_list ap) { _SIMPLE_STRING b; @@ -1001,8 +1603,7 @@ _malloc_vprintf(int flags, const char *format, va_list ap) _simple_sfree(b); } -__attribute__((visibility("hidden"))) -void +__attribute__((visibility("hidden"))) void _malloc_printf(int flags, const char *format, ...) { va_list ap; @@ -1025,9 +1626,10 @@ malloc_printf(const char *format, ...) /********* Generic ANSI callouts ************/ void * -malloc(size_t size) { - void *retval; - retval = malloc_zone_malloc(inline_malloc_default_zone(), size); +malloc(size_t size) +{ + void *retval; + retval = malloc_zone_malloc(default_zone, size); if (retval == NULL) { errno = ENOMEM; } @@ -1035,9 +1637,10 @@ malloc(size_t size) { } void * -calloc(size_t num_items, size_t size) { - void *retval; - retval = malloc_zone_calloc(inline_malloc_default_zone(), num_items, size); +calloc(size_t num_items, size_t size) +{ + void *retval; + retval = malloc_zone_calloc(default_zone, num_items, size); if (retval == NULL) { errno = ENOMEM; } @@ -1045,37 +1648,43 @@ calloc(size_t num_items, size_t size) { } void -free(void *ptr) { - malloc_zone_t *zone; - size_t size; - if (!ptr) +free(void *ptr) +{ + malloc_zone_t *zone; + size_t size; + if (!ptr) { return; + } zone = find_registered_zone(ptr, &size); if (!zone) { - malloc_printf("*** error for object %p: pointer being freed was not allocated\n" - "*** set a breakpoint in malloc_error_break to debug\n", ptr); + malloc_printf( + "*** error for object %p: pointer being freed was not allocated\n" + "*** set a breakpoint in malloc_error_break to debug\n", + ptr); malloc_error_break(); - if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION|SCALABLE_MALLOC_ABORT_ON_ERROR))) { + if ((malloc_debug_flags & (MALLOC_ABORT_ON_CORRUPTION | MALLOC_ABORT_ON_ERROR))) { _SIMPLE_STRING b = _simple_salloc(); if (b) { _simple_sprintf(b, "*** error for object %p: pointer being freed was not allocated\n", ptr); - CRSetCrashLogMessage(_simple_string(b)); + _os_set_crash_log_message_dynamic(_simple_string(b)); } else { - CRSetCrashLogMessage("*** error: pointer being freed was not allocated\n"); + _os_set_crash_log_message("*** error: pointer being freed was not allocated\n"); } abort(); } - } else if (zone->version >= 6 && zone->free_definite_size) + } else if (zone->version >= 6 && zone->free_definite_size) { malloc_zone_free_definite_size(zone, ptr, size); - else + } else { malloc_zone_free(zone, ptr); + } } void * -realloc(void *in_ptr, size_t new_size) { - void *retval = NULL; - void *old_ptr; - malloc_zone_t *zone; +realloc(void *in_ptr, size_t new_size) +{ + void *retval = NULL; + void *old_ptr; + malloc_zone_t *zone; // SUSv3: "If size is 0 and ptr is not a null pointer, the object // pointed to is freed. If the space cannot be allocated, the object @@ -1087,20 +1696,22 @@ realloc(void *in_ptr, size_t new_size) { // size." So we only free the original memory if the allocation succeeds. old_ptr = (new_size == 0) ? NULL : in_ptr; if (!old_ptr) { - retval = malloc_zone_malloc(inline_malloc_default_zone(), new_size); + retval = malloc_zone_malloc(default_zone, new_size); } else { zone = find_registered_zone(old_ptr, NULL); if (!zone) { - malloc_printf("*** error for object %p: pointer being realloc'd was not allocated\n" - "*** set a breakpoint in malloc_error_break to debug\n", old_ptr); + malloc_printf( + "*** error for object %p: pointer being realloc'd was not allocated\n" + "*** set a breakpoint in malloc_error_break to debug\n", + old_ptr); malloc_error_break(); - if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION|SCALABLE_MALLOC_ABORT_ON_ERROR))) { + if ((malloc_debug_flags & (MALLOC_ABORT_ON_CORRUPTION | MALLOC_ABORT_ON_ERROR))) { _SIMPLE_STRING b = _simple_salloc(); if (b) { _simple_sprintf(b, "*** error for object %p: pointer being realloc'd was not allocated\n", old_ptr); - CRSetCrashLogMessage(_simple_string(b)); + _os_set_crash_log_message_dynamic(_simple_string(b)); } else { - CRSetCrashLogMessage("*** error: pointer being realloc'd was not allocated\n"); + _os_set_crash_log_message("*** error: pointer being realloc'd was not allocated\n"); } abort(); } @@ -1117,9 +1728,10 @@ realloc(void *in_ptr, size_t new_size) { } void * -valloc(size_t size) { - void *retval; - malloc_zone_t *zone = inline_malloc_default_zone(); +valloc(size_t size) +{ + void *retval; + malloc_zone_t *zone = default_zone; retval = malloc_zone_valloc(zone, size); if (retval == NULL) { errno = ENOMEM; @@ -1128,24 +1740,28 @@ valloc(size_t size) { } extern void -vfree(void *ptr) { +vfree(void *ptr) +{ free(ptr); } size_t -malloc_size(const void *ptr) { - size_t size = 0; +malloc_size(const void *ptr) +{ + size_t size = 0; - if (!ptr) + if (!ptr) { return size; + } (void)find_registered_zone(ptr, &size); return size; } size_t -malloc_good_size (size_t size) { - malloc_zone_t *zone = inline_malloc_default_zone(); +malloc_good_size(size_t size) +{ + malloc_zone_t *zone = default_zone; return zone->introspect->good_size(zone, size); } @@ -1168,18 +1784,18 @@ malloc_good_size (size_t size) { int posix_memalign(void **memptr, size_t alignment, size_t size) { - void *retval; + void *retval; /* POSIX is silent on NULL == memptr !?! */ - retval = malloc_zone_memalign(inline_malloc_default_zone(), alignment, size); + retval = malloc_zone_memalign(default_zone, alignment, size); if (retval == NULL) { // To avoid testing the alignment constraints redundantly, we'll rely on the // test made in malloc_zone_memalign to vet each request. Only if that test fails // and returns NULL, do we arrive here to detect the bogus alignment and give the // required EINVAL return. - if (alignment < sizeof( void *) || // excludes 0 == alignment - 0 != (alignment & (alignment - 1))) { // relies on sizeof(void *) being a power of two. + if (alignment < sizeof(void *) || // excludes 0 == alignment + 0 != (alignment & (alignment - 1))) { // relies on sizeof(void *) being a power of two. return EINVAL; } return ENOMEM; @@ -1189,10 +1805,32 @@ posix_memalign(void **memptr, size_t alignment, size_t size) } } +void * +reallocarray(void * in_ptr, size_t nmemb, size_t size){ + size_t alloc_size; + if (os_mul_overflow(nmemb, size, &alloc_size)){ + errno = ENOMEM; + return NULL; + } + return realloc(in_ptr, alloc_size); +} + +void * +reallocarrayf(void * in_ptr, size_t nmemb, size_t size){ + size_t alloc_size; + if (os_mul_overflow(nmemb, size, &alloc_size)){ + errno = ENOMEM; + return NULL; + } + return reallocf(in_ptr, alloc_size); +} + static malloc_zone_t * -find_registered_purgeable_zone(void *ptr) { - if (!ptr) +find_registered_purgeable_zone(void *ptr) +{ + if (!ptr) { return NULL; + } /* * Look for a zone which contains ptr. If that zone does not have the purgeable malloc flag @@ -1205,21 +1843,25 @@ find_registered_purgeable_zone(void *ptr) { /* FIXME: would really like a zone->introspect->flags->purgeable check, but haven't determined * binary compatibility impact of changing the introspect struct yet. */ - if (!zone) + if (!zone) { return NULL; + } /* Check to make sure pointer is page aligned and size is multiple of page size */ - if ((size < vm_page_size) || ((size % vm_page_size) != 0)) + if ((size < vm_page_size) || ((size % vm_page_size) != 0)) { return NULL; + } return zone; } void -malloc_make_purgeable(void *ptr) { +malloc_make_purgeable(void *ptr) +{ malloc_zone_t *zone = find_registered_purgeable_zone(ptr); - if (!zone) + if (!zone) { return; + } int state = VM_PURGABLE_VOLATILE; vm_purgable_control(mach_task_self(), (vm_address_t)ptr, VM_PURGABLE_SET_STATE, &state); @@ -1229,21 +1871,129 @@ malloc_make_purgeable(void *ptr) { /* Returns true if ptr is valid. Ignore the return value from vm_purgeable_control and only report * state. */ int -malloc_make_nonpurgeable(void *ptr) { +malloc_make_nonpurgeable(void *ptr) +{ malloc_zone_t *zone = find_registered_purgeable_zone(ptr); - if (!zone) + if (!zone) { return 0; + } int state = VM_PURGABLE_NONVOLATILE; vm_purgable_control(mach_task_self(), (vm_address_t)ptr, VM_PURGABLE_SET_STATE, &state); - if (state == VM_PURGABLE_EMPTY) + if (state == VM_PURGABLE_EMPTY) { return EFAULT; + } return 0; } -size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) +void +malloc_enter_process_memory_limit_warn_mode(void) +{ + // +} + +#if ENABLE_MEMORY_RESOURCE_EXCEPTION_HANDLING + +// Is the system elible to turn on/off MSL lite in response to memory resource exceptions +// +// Return true if +// - The user has not explicitly opted out +// and +// - Either the user has explicitly opted in or this is an Apple Internal enabled build + +static boolean_t +check_is_eligible_for_lite_mode_mre_handling(void) +{ + struct stat stat_buf; + + // User opted out + if (stat("/var/db/disableLiteModeMemoryResourceExceptionHandling", &stat_buf) == 0) { + return false; + } + + // User opted in + if (stat("/var/db/enableLiteModeMemoryResourceExceptionHandling", &stat_buf) == 0) { + return true; + } + + + // Not enabled for everything else + return false; +} + +// Not thread-safe, but it's called from malloc_memory_event_handler which already assumes +// single thread execution. +static boolean_t +is_eligible_for_lite_mode_mre_handling(void) +{ + static boolean_t is_eligible = false; + static boolean_t needs_check = true; + + if (needs_check) { + is_eligible = check_is_eligible_for_lite_mode_mre_handling(); + needs_check = false; + } + + return is_eligible; +} + +#endif + +// Note that malloc_memory_event_handler is not thread-safe, and we are relying on the callers of this for synchronization +void +malloc_memory_event_handler(unsigned long event) +{ + if (event & NOTE_MEMORYSTATUS_PRESSURE_WARN) { + malloc_zone_pressure_relief(0, 0); + } + +#if ENABLE_MEMORY_RESOURCE_EXCEPTION_HANDLING + static boolean_t warn_mode_entered = false; + static boolean_t warn_mode_disable_retries = false; + + // If we have reached EXC_RESOURCE, we no longer need stack log data. + // If we are under system-wide memory pressure, we should jettison stack log data. + if ((event & (NOTE_MEMORYSTATUS_PROC_LIMIT_CRITICAL | NOTE_MEMORYSTATUS_PRESSURE_CRITICAL)) && + !warn_mode_disable_retries) { + // If we have crossed the EXC_RESOURCE limit once already, there is no point in + // collecting stack logs in the future, even if we missed a previous chance to + // collect data because nobody is going to ask us for it again. + warn_mode_disable_retries = true; + + // Only try to clean up stack log data if it was enabled through a proc limit warning. + // User initiated stack logging should proceed unimpeded. + if (warn_mode_entered) { + malloc_printf("malloc_memory_event_handler: stopping stack-logging\n"); + turn_off_stack_logging(); + __malloc_lock_stack_logging(); + __delete_uniquing_table_memory_while_locked(); + __malloc_unlock_stack_logging(); + + warn_mode_entered = false; + } + } + + // Enable stack logging if we are approaching the process limit, provided + // we aren't under system wide memory pressure and we're allowed to try again. + if ((event & NOTE_MEMORYSTATUS_PROC_LIMIT_WARN) && + !(event & NOTE_MEMORYSTATUS_PRESSURE_CRITICAL) && + !warn_mode_entered && !warn_mode_disable_retries && + is_eligible_for_lite_mode_mre_handling()) { + malloc_printf("malloc_memory_event_handler: approaching memory limit. Starting stack-logging.\n"); + if (turn_on_stack_logging(stack_logging_mode_lite)) { + warn_mode_entered = true; + + // set the maximum allocation threshold + max_lite_mallocs = MAX_LITE_MALLOCS; + } + } +#endif +} + +size_t +malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) { if (!zone) { unsigned index = 0; @@ -1253,25 +2003,30 @@ size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) MALLOC_LOCK(); while (index < malloc_num_zones) { zone = malloc_zones[index++]; - if (zone->version < 8) + if (zone->version < 8) { continue; - if (NULL == zone->pressure_relief) + } + if (NULL == zone->pressure_relief) { continue; - if (0 == goal) /* Greedy */ + } + if (0 == goal) { /* Greedy */ total += zone->pressure_relief(zone, 0); - else if (goal > total) + } else if (goal > total) { total += zone->pressure_relief(zone, goal - total); - else /* total >= goal */ + } else { /* total >= goal */ break; + } } MALLOC_UNLOCK(); return total; } else { // Assumes zone is not destroyed for the duration of this call - if (zone->version < 8) + if (zone->version < 8) { return 0; - if (NULL == zone->pressure_relief) + } + if (NULL == zone->pressure_relief) { return 0; + } return zone->pressure_relief(zone, goal); } } @@ -1279,18 +2034,21 @@ size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) /********* Batch methods ************/ unsigned -malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested) { - unsigned (*batch_malloc)(malloc_zone_t *, size_t, void **, unsigned) = zone-> batch_malloc; - if (! batch_malloc) +malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested) +{ + if (!zone->batch_malloc) { return 0; + } if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } - unsigned batched = batch_malloc(zone, size, results, num_requested); + unsigned batched = zone->batch_malloc(zone, size, results, num_requested); + if (malloc_logger) { - unsigned index = 0; + unsigned index = 0; while (index < batched) { - malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)results[index], 0); + malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, + (uintptr_t)results[index], 0); index++; } } @@ -1298,24 +2056,27 @@ malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsig } void -malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num) { +malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num) +{ if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) { internal_check(); } if (malloc_logger) { - unsigned index = 0; + unsigned index = 0; while (index < num) { - malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)to_be_freed[index], 0, 0, 0); + malloc_logger( + MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)to_be_freed[index], 0, 0, 0); index++; } } - void (*batch_free)(malloc_zone_t *, void **, unsigned) = zone-> batch_free; - if (batch_free) { - batch_free(zone, to_be_freed, num); + + if (zone->batch_free) { + zone->batch_free(zone, to_be_freed, num); } else { - void (*free_fun)(malloc_zone_t *, void *) = zone->free; + void (*free_fun)(malloc_zone_t *, void *) = zone->free; + while (num--) { - void *ptr = *to_be_freed++; + void *ptr = *to_be_freed++; free_fun(zone, ptr); } } @@ -1324,22 +2085,27 @@ malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num) { /********* Functions for performance tools ************/ static kern_return_t -_malloc_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) { +_malloc_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) +{ *ptr = (void *)address; return 0; } kern_return_t -malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count) { - // Note that the 2 following addresses are not correct if the address of the target is different from your own. This notably occurs if the address of System.framework is slid (e.g. different than at B & I ) - vm_address_t remote_malloc_zones = (vm_address_t)&malloc_zones; - vm_address_t remote_malloc_num_zones = (vm_address_t)&malloc_num_zones; - kern_return_t err; - vm_address_t zones_address; - vm_address_t *zones_address_ref; - unsigned num_zones; - unsigned *num_zones_ref; - if (!reader) reader = _malloc_default_reader; +malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count) +{ + // Note that the 2 following addresses are not correct if the address of the target is different from your own. This notably + // occurs if the address of System.framework is slid (e.g. different than at B & I ) + vm_address_t remote_malloc_zones = (vm_address_t)&malloc_zones; + vm_address_t remote_malloc_num_zones = (vm_address_t)&malloc_num_zones; + kern_return_t err; + vm_address_t zones_address; + vm_address_t *zones_address_ref; + unsigned num_zones; + unsigned *num_zones_ref; + if (!reader) { + reader = _malloc_default_reader; + } // printf("Read malloc_zones at address %p should be %p\n", &malloc_zones, malloc_zones); err = reader(task, remote_malloc_zones, sizeof(void *), (void **)&zones_address_ref); // printf("Read malloc_zones[%p]=%p\n", remote_malloc_zones, *zones_address_ref); @@ -1370,9 +2136,12 @@ malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **address /********* Debug helpers ************/ void -malloc_zone_print_ptr_info(void *ptr) { - malloc_zone_t *zone; - if (!ptr) return; +malloc_zone_print_ptr_info(void *ptr) +{ + malloc_zone_t *zone; + if (!ptr) { + return; + } zone = malloc_zone_from_ptr(ptr); if (zone) { printf("ptr %p in registered zone %p\n", ptr, zone); @@ -1382,13 +2151,16 @@ malloc_zone_print_ptr_info(void *ptr) { } boolean_t -malloc_zone_check(malloc_zone_t *zone) { - boolean_t ok = 1; +malloc_zone_check(malloc_zone_t *zone) +{ + boolean_t ok = 1; if (!zone) { - unsigned index = 0; + unsigned index = 0; while (index < malloc_num_zones) { zone = malloc_zones[index++]; - if (!zone->introspect->check(zone)) ok = 0; + if (!zone->introspect->check(zone)) { + ok = 0; + } } } else { ok = zone->introspect->check(zone); @@ -1397,9 +2169,10 @@ malloc_zone_check(malloc_zone_t *zone) { } void -malloc_zone_print(malloc_zone_t *zone, boolean_t verbose) { +malloc_zone_print(malloc_zone_t *zone, boolean_t verbose) +{ if (!zone) { - unsigned index = 0; + unsigned index = 0; while (index < malloc_num_zones) { zone = malloc_zones[index++]; zone->introspect->print(zone, verbose); @@ -1410,13 +2183,14 @@ malloc_zone_print(malloc_zone_t *zone, boolean_t verbose) { } void -malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) { +malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) +{ if (!zone) { memset(stats, 0, sizeof(*stats)); - unsigned index = 0; + unsigned index = 0; while (index < malloc_num_zones) { zone = malloc_zones[index++]; - malloc_statistics_t this_stats; + malloc_statistics_t this_stats; zone->introspect->statistics(zone, &this_stats); stats->blocks_in_use += this_stats.blocks_in_use; stats->size_in_use += this_stats.size_in_use; @@ -1429,9 +2203,10 @@ malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) { } void -malloc_zone_log(malloc_zone_t *zone, void *address) { +malloc_zone_log(malloc_zone_t *zone, void *address) +{ if (!zone) { - unsigned index = 0; + unsigned index = 0; while (index < malloc_num_zones) { zone = malloc_zones[index++]; zone->introspect->log(zone, address); @@ -1444,7 +2219,8 @@ malloc_zone_log(malloc_zone_t *zone, void *address) { /********* Misc other entry points ************/ static void -DefaultMallocError(int x) { +DefaultMallocError(int x) +{ #if USE_SLEEP_RATHER_THAN_ABORT malloc_printf("*** error %d\n", x); sleep(3600); @@ -1453,28 +2229,23 @@ DefaultMallocError(int x) { if (b) { _simple_sprintf(b, "*** error %d", x); malloc_printf("%s\n", _simple_string(b)); - CRSetCrashLogMessage(_simple_string(b)); + _os_set_crash_log_message_dynamic(_simple_string(b)); } else { _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error %d", x); - CRSetCrashLogMessage("*** DefaultMallocError called"); + _os_set_crash_log_message("*** DefaultMallocError called"); } abort(); #endif } -void (* - malloc_error(void (*func)(int)))(int) { +void (*malloc_error(void (*func)(int)))(int) +{ return DefaultMallocError; } -/* Stack logging fork-handling prototypes */ -extern void __stack_logging_fork_prepare(); -extern void __stack_logging_fork_parent(); -extern void __stack_logging_fork_child(); -extern void __stack_logging_early_finished(); - static void -_malloc_lock_all(void (*callout)(void)) { +_malloc_lock_all(void (*callout)(void)) +{ unsigned index = 0; MALLOC_LOCK(); while (index < malloc_num_zones) { @@ -1485,7 +2256,8 @@ _malloc_lock_all(void (*callout)(void)) { } static void -_malloc_unlock_all(void (*callout)(void)) { +_malloc_unlock_all(void (*callout)(void)) +{ unsigned index = 0; callout(); while (index < malloc_num_zones) { @@ -1495,28 +2267,49 @@ _malloc_unlock_all(void (*callout)(void)) { MALLOC_UNLOCK(); } +static void +_malloc_reinit_lock_all(void (*callout)(void)) +{ + unsigned index = 0; + callout(); + while (index < malloc_num_zones) { + malloc_zone_t *zone = malloc_zones[index++]; + if (zone->version < 9) { // Version must be >= 9 to look at reinit_lock + zone->introspect->force_unlock(zone); + } else { + zone->introspect->reinit_lock(zone); + } + } + MALLOC_REINIT_LOCK(); +} + + // Called prior to fork() to guarantee that malloc is not in any critical // sections during the fork(); prevent any locks from being held by non- // surviving threads after the fork. void -_malloc_fork_prepare(void) { +_malloc_fork_prepare(void) +{ return _malloc_lock_all(&__stack_logging_fork_prepare); } // Called in the parent process after fork() to resume normal operation. void -_malloc_fork_parent(void) { +_malloc_fork_parent(void) +{ return _malloc_unlock_all(&__stack_logging_fork_parent); } // Called in the child process after fork() to resume normal operation. void -_malloc_fork_child(void) { +_malloc_fork_child(void) +{ #if CONFIG_NANOZONE - if (_malloc_is_initialized && _malloc_engaged_nano) - nano_forked_zone(inline_malloc_default_zone()); + if (_malloc_initialize_pred && _malloc_engaged_nano) { + nano_forked_zone((nanozone_t *)inline_malloc_default_zone()); + } #endif - return _malloc_unlock_all(&__stack_logging_fork_child); + return _malloc_reinit_lock_all(&__stack_logging_fork_child); } /* @@ -1537,42 +2330,50 @@ mstats(void) m.chunks_used = s.blocks_in_use; m.bytes_used = s.size_in_use; m.chunks_free = 0; - m.bytes_free = m.bytes_total - m.bytes_used; /* isn't this somewhat obvious? */ + m.bytes_free = m.bytes_total - m.bytes_used; /* isn't this somewhat obvious? */ - return(m); + return (m); } boolean_t malloc_zone_enable_discharge_checking(malloc_zone_t *zone) { - if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields. + if (zone->version < 7) { // Version must be >= 7 to look at the new discharge checking fields. return FALSE; - if (NULL == zone->introspect->enable_discharge_checking) + } + if (NULL == zone->introspect->enable_discharge_checking) { return FALSE; + } return zone->introspect->enable_discharge_checking(zone); } void malloc_zone_disable_discharge_checking(malloc_zone_t *zone) { - if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields. + if (zone->version < 7) { // Version must be >= 7 to look at the new discharge checking fields. return; - if (NULL == zone->introspect->disable_discharge_checking) + } + if (NULL == zone->introspect->disable_discharge_checking) { return; + } zone->introspect->disable_discharge_checking(zone); } void malloc_zone_discharge(malloc_zone_t *zone, void *memory) { - if (NULL == zone) + if (NULL == zone) { zone = malloc_zone_from_ptr(memory); - if (NULL == zone) + } + if (NULL == zone) { return; - if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields. + } + if (zone->version < 7) { // Version must be >= 7 to look at the new discharge checking fields. return; - if (NULL == zone->introspect->discharge) + } + if (NULL == zone->introspect->discharge) { return; + } zone->introspect->discharge(zone, memory); } @@ -1580,20 +2381,24 @@ void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)) { if (!zone) { - unsigned index = 0; + unsigned index = 0; while (index < malloc_num_zones) { zone = malloc_zones[index++]; - if (zone->version < 7) + if (zone->version < 7) { continue; - if (NULL == zone->introspect->enumerate_discharged_pointers) + } + if (NULL == zone->introspect->enumerate_discharged_pointers) { continue; + } zone->introspect->enumerate_discharged_pointers(zone, report_discharged); } } else { - if (zone->version < 7) + if (zone->version < 7) { return; - if (NULL == zone->introspect->enumerate_discharged_pointers) + } + if (NULL == zone->introspect->enumerate_discharged_pointers) { return; + } zone->introspect->enumerate_discharged_pointers(zone, report_discharged); } } @@ -1605,7 +2410,8 @@ malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void (^report_dis #endif void -set_malloc_singlethreaded(boolean_t single) { +set_malloc_singlethreaded(boolean_t single) +{ static boolean_t warned = 0; if (!warned) { #if PHASE_OUT_OLD_MALLOC @@ -1616,7 +2422,8 @@ set_malloc_singlethreaded(boolean_t single) { } void -malloc_singlethreaded(void) { +malloc_singlethreaded(void) +{ static boolean_t warned = 0; if (!warned) { malloc_printf("*** OBSOLETE: malloc_singlethreaded()\n"); @@ -1625,7 +2432,8 @@ malloc_singlethreaded(void) { } int -malloc_debug(int level) { +malloc_debug(int level) +{ malloc_printf("*** OBSOLETE: malloc_debug()\n"); return 0; } diff --git a/src/libmalloc/src/malloc_internal.h b/src/libmalloc/src/malloc_internal.h deleted file mode 100644 index 0a0b3c4e7..000000000 --- a/src/libmalloc/src/malloc_internal.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2013 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef __MALLOC_INTERNAL_H -#define __MALLOC_INTERNAL_H - -#include -//#include - -#if TARGET_OS_EMBEDDED && !defined(MALLOC_USE_OS_LOCK_HANDOFF) -#define MALLOC_USE_OS_LOCK_HANDOFF 1 // -#endif - -#if !TARGET_IPHONE_SIMULATOR || MALLOC_USE_OS_LOCK_HANDOFF -//#define MALLOC_USE_OS_LOCK 1 // -#endif - -#if MALLOC_USE_OS_LOCK_HANDOFF -typedef os_lock_handoff_s _malloc_lock_s; -#define _MALLOC_LOCK_INIT OS_LOCK_HANDOFF_INIT -#elif MALLOC_USE_OS_LOCK -typedef os_lock_spin_s _malloc_lock_s; -#define _MALLOC_LOCK_INIT OS_LOCK_SPIN_INIT -#else -#include -typedef OSSpinLock _malloc_lock_s; -#define _MALLOC_LOCK_INIT OS_SPINLOCK_INIT -#endif - -__attribute__((always_inline)) -static inline void -_malloc_lock_init(_malloc_lock_s *lock) { - const _malloc_lock_s _malloc_lock_init = _MALLOC_LOCK_INIT; - *lock = _malloc_lock_init; -} - -#if MALLOC_USE_OS_LOCK -__attribute__((always_inline)) -static inline void -_malloc_lock_lock(_malloc_lock_s *lock) { - return os_lock_lock(lock); -} - -__attribute__((always_inline)) -static inline bool -_malloc_lock_trylock(_malloc_lock_s *lock) { - return os_lock_trylock(lock); -} - -__attribute__((always_inline)) -static inline void -_malloc_lock_unlock(_malloc_lock_s *lock) { - return os_lock_unlock(lock); -} - -#else // MALLOC_USE_OS_LOCK - -__attribute__((always_inline)) -static inline void -_malloc_lock_lock(_malloc_lock_s *lock) { - return OSSpinLockLock(lock); -} - -__attribute__((always_inline)) -static inline bool -_malloc_lock_trylock(_malloc_lock_s *lock) { - return OSSpinLockTry(lock); -} - -__attribute__((always_inline)) -static inline void -_malloc_lock_unlock(_malloc_lock_s *lock) { - return OSSpinLockUnlock(lock); -} - -#endif // MALLOC_USE_OS_LOCK - - -#endif // __MALLOC_INTERNAL_H diff --git a/src/libmalloc/src/malloc_printf.h b/src/libmalloc/src/malloc_printf.h deleted file mode 100644 index 5f10683e8..000000000 --- a/src/libmalloc/src/malloc_printf.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -extern void malloc_printf(const char *fmt, ...); - -#define MALLOC_PRINTF_LEVEL_MASK 0x0f -#define MALLOC_PRINTF_NOLOG 0x10 -#define MALLOC_PRINTF_NOPREFIX 0x20 - -extern void _malloc_printf(int flags, const char *fmt, ...); -extern void _malloc_vprintf(int flags, const char *fmt, va_list ap); diff --git a/src/libmalloc/src/nano_malloc.c b/src/libmalloc/src/nano_malloc.c index 036783f90..649af69e6 100644 --- a/src/libmalloc/src/nano_malloc.c +++ b/src/libmalloc/src/nano_malloc.c @@ -21,199 +21,22 @@ * @APPLE_LICENSE_HEADER_END@ */ -#ifdef __LP64__ /* nano_malloc for 64bit ABI */ -#define NDEBUG 1 -#define NANO_FREE_DEQUEUE_DILIGENCE 1 /* Check for corrupt free list */ +#include "internal.h" -#include <_simple.h> -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include /* for _dyld_get_image_slide() */ -#include /* for _NSGetMachExecuteHeader() */ - -#include - -#if defined(__x86_64__) -#define __APPLE_API_PRIVATE -#include -#define _COMM_PAGE_VERSION_REQD 9 -#undef __APPLE_API_PRIVATE -#else -Unknown Architecture -#endif - -#include "scalable_malloc.h" -#include "malloc_internal.h" -#include "malloc_printf.h" - -#include - -#include "bitarray.h" - -#ifndef VM_MEMORY_MALLOC_NANO /* Until osfmk/mach/vm_statistics.h is updated in xnu */ -#define VM_MEMORY_MALLOC_NANO 11 -#endif - -extern uint64_t malloc_entropy[2]; -/********************* DEFINITIONS ************************/ - -#define INLINE __inline__ -#define ALWAYSINLINE __attribute__((always_inline)) -#define NOINLINE __attribute__((noinline)) - -#if defined(__x86_64__) -#define CACHE_LINE 64 -#define CACHE_ALIGN __attribute__ ((aligned (64) )) -#else -#define CACHE_ALIGN /* TBD for other platforms */ -#endif - -#define NANO_MAG_INDEX(nz) (_os_cpu_number() >> nz->hyper_shift) - -#define SCRIBBLE_BYTE 0xaa /* allocated scribble */ -#define SCRABBLE_BYTE 0x55 /* free()'d scribble */ -#define SCRUBBLE_BYTE 0xdd /* madvise(..., MADV_FREE) scriblle */ - -#define MAX_RECORDER_BUFFER 256 - -/************* nanozone address field layout ******************/ - -#if defined(__x86_64) -#define NANO_SIGNATURE_BITS 20 -#define NANOZONE_SIGNATURE 0x00006ULL // 0x00006nnnnnnnnnnn the address range devoted to us. -#define NANO_MAG_BITS 5 -#define NANO_BAND_BITS 18 -#define NANO_SLOT_BITS 4 -#define NANO_OFFSET_BITS 17 - -#else -#error Unknown Architecture -#endif - -#if defined(__BIG_ENDIAN__) -struct nano_blk_addr_s { - uint64_t -nano_signature:NANO_SIGNATURE_BITS, // 0x00006nnnnnnnnnnn the address range devoted to us. -nano_mag_index:NANO_MAG_BITS, // the core that allocated this block -nano_band:NANO_BAND_BITS, -nano_slot:NANO_SLOT_BITS, // bucket of homogenous quanta-multiple blocks -nano_offset:NANO_OFFSET_BITS; // locates the block -}; -#else -// least significant bits declared first -struct nano_blk_addr_s { - uint64_t -nano_offset:NANO_OFFSET_BITS, // locates the block -nano_slot:NANO_SLOT_BITS, // bucket of homogenous quanta-multiple blocks -nano_band:NANO_BAND_BITS, -nano_mag_index:NANO_MAG_BITS, // the core that allocated this block -nano_signature:NANO_SIGNATURE_BITS; // 0x00006nnnnnnnnnnn the address range devoted to us. -}; -#endif - -typedef union { - uint64_t addr; - struct nano_blk_addr_s fields; -} nano_blk_addr_t; - -/* Are we using the nano allocator? Set by the initializer. */ -__attribute__((visibility("hidden"))) -boolean_t _malloc_engaged_nano; - -#define NANO_MAX_SIZE 256 /* Buckets sized {16, 32, 48, 64, 80, 96, 112, ...} */ -#define SHIFT_NANO_QUANTUM 4 -#define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM) // 16 -#define NANO_QUANTA_MASK 0xFULL // NANO_REGIME_QUANTA_SIZE - 1 - -#define SLOT_IN_BAND_SIZE (1 << NANO_OFFSET_BITS) -#define SLOT_KEY_LIMIT (1 << NANO_SLOT_BITS) /* Must track nano_slot width */ -#define BAND_SIZE (1 << (NANO_SLOT_BITS + NANO_OFFSET_BITS)) /* == Number of bytes covered by a page table entry */ -#define NANO_MAG_SIZE (1 << NANO_MAG_BITS) -#define NANO_SLOT_SIZE (1 << NANO_SLOT_BITS) - -/****************************** zone itself ***********************************/ - -/* - * Note that objects whose adddress are held in pointers here must be pursued - * individually in the nano_in_use_enumeration() routines. - */ - -typedef struct chained_block_s { - uintptr_t double_free_guard; - struct chained_block_s *next; -} *chained_block_t; - -typedef struct nano_meta_s { - OSQueueHead slot_LIFO CACHE_ALIGN; - unsigned int slot_madvised_log_page_count; - volatile uintptr_t slot_current_base_addr; - volatile uintptr_t slot_limit_addr; - volatile size_t slot_objects_mapped; - volatile size_t slot_objects_skipped; - bitarray_t slot_madvised_pages; - volatile uintptr_t slot_bump_addr CACHE_ALIGN; // position on cache line distinct from that of slot_LIFO - volatile boolean_t slot_exhausted; - unsigned int slot_bytes; - unsigned int slot_objects; -} *nano_meta_admin_t; - -typedef struct nanozone_s { // vm_allocate()'d, so page-aligned to begin with. - malloc_zone_t basic_zone; // first page will be given read-only protection - uint8_t pad[PAGE_MAX_SIZE - sizeof(malloc_zone_t)]; - - // remainder of structure is R/W (contains no function pointers) - // page-aligned - struct nano_meta_s meta_data[NANO_MAG_SIZE][NANO_SLOT_SIZE]; // max: NANO_MAG_SIZE cores x NANO_SLOT_SIZE slots for nano blocks {16 .. 256} - _malloc_lock_s band_resupply_lock[NANO_MAG_SIZE]; - uintptr_t band_max_mapped_baseaddr[NANO_MAG_SIZE]; - size_t core_mapped_size[NANO_MAG_SIZE]; - - unsigned debug_flags; - unsigned our_signature; - unsigned phys_ncpus; - unsigned logical_ncpus; - unsigned hyper_shift; - - /* security cookie */ - uintptr_t cookie; - - /* - * The nano zone constructed by create_nano_zone() would like to hand off tiny, small, and large - * allocations to the default scalable zone. Record the latter as the "helper" zone here. - */ - malloc_zone_t *helper_zone; -} nanozone_t; - -#define SZONE_PAGED_SIZE ((sizeof(nanozone_t) + vm_page_size - 1) & ~ (vm_page_size - 1)) +/* nano_malloc for 64bit ABI */ +#if CONFIG_NANOZONE /********************* PROTOTYPES ***********************/ -extern void malloc_error_break(void); - // msg prints after fmt, ... -static NOINLINE void nanozone_error(nanozone_t *nanozone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...) -__printflike(5, 6); +static MALLOC_NOINLINE void +nanozone_error(nanozone_t *nanozone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...) __printflike(5, 6); static void nano_statistics(nanozone_t *nanozone, malloc_statistics_t *stats); /********************* VERY LOW LEVEL UTILITIES ************************/ // msg prints after fmt, ... -static NOINLINE void +static MALLOC_NOINLINE void nanozone_error(nanozone_t *nanozone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...) { va_list ap; @@ -253,40 +76,24 @@ nanozone_error(nanozone_t *nanozone, int is_corruption, const char *msg, const v // Call abort() if this is a memory corruption error and the abort on // corruption flag is set, or if any error should abort. - if ((is_corruption && (nanozone->debug_flags & SCALABLE_MALLOC_ABORT_ON_CORRUPTION)) || - (nanozone->debug_flags & SCALABLE_MALLOC_ABORT_ON_ERROR)) { - CRSetCrashLogMessage(b ? _simple_string(b) : msg); + if ((is_corruption && (nanozone->debug_flags & MALLOC_ABORT_ON_CORRUPTION)) || + (nanozone->debug_flags & MALLOC_ABORT_ON_ERROR)) { + _os_set_crash_log_message_dynamic(b ? _simple_string(b) : msg); abort(); } else if (b) { _simple_sfree(b); } } -static void -protect(void *address, size_t size, unsigned protection, unsigned debug_flags) -{ - kern_return_t err; - - if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_PRELUDE)) { - err = mprotect((void *)((uintptr_t)address - vm_page_size), vm_page_size, protection); - if (err) { - malloc_printf("*** can't protect(%p) region for prelude guard page at %p\n", - protection,(uintptr_t)address - (1 << vm_page_shift)); - } - } - if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE)) { - err = mprotect((void *)((uintptr_t)address + size), vm_page_size, protection); - if (err) { - malloc_printf("*** can't protect(%p) region for postlude guard page at %p\n", - protection, (uintptr_t)address + size); - } - } -} - static void * -allocate_based_pages(nanozone_t *nanozone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label, void *base_addr) -{ - boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; +allocate_based_pages(nanozone_t *nanozone, + size_t size, + unsigned char align, + unsigned debug_flags, + int vm_page_label, + void *base_addr) +{ + boolean_t add_guard_pages = debug_flags & MALLOC_ADD_GUARD_PAGES; mach_vm_address_t vm_addr; uintptr_t addr; mach_vm_size_t allocation_size = round_page(size); @@ -294,20 +101,24 @@ allocate_based_pages(nanozone_t *nanozone, size_t size, unsigned char align, uns int alloc_flags = VM_FLAGS_ANYWHERE | VM_MAKE_TAG(vm_page_label); kern_return_t kr; - if (!allocation_size) allocation_size = vm_page_size; - if (add_guard_pages) allocation_size += 2 * vm_page_size; - if (allocation_size < size) // size_t arithmetic wrapped! + if (!allocation_size) { + allocation_size = vm_page_size; + } + if (add_guard_pages) { + allocation_size += 2 * vm_page_size; + } + if (allocation_size < size) { // size_t arithmetic wrapped! return NULL; + } vm_addr = round_page((mach_vm_address_t)base_addr); - if (!vm_addr) vm_addr = vm_page_size; - kr = mach_vm_map(mach_task_self(), &vm_addr, allocation_size, - allocation_mask, alloc_flags, MEMORY_OBJECT_NULL, 0, FALSE, + if (!vm_addr) { + vm_addr = vm_page_size; + } + kr = mach_vm_map(mach_task_self(), &vm_addr, allocation_size, allocation_mask, alloc_flags, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT); if (kr) { - nanozone_error(nanozone, 0, "can't allocate pages", NULL, - "*** mach_vm_map(size=%lu) failed (error code=%d)\n", - size, kr); + nanozone_error(nanozone, 0, "can't allocate pages", NULL, "*** mach_vm_map(size=%lu) failed (error code=%d)\n", size, kr); return NULL; } addr = (uintptr_t)vm_addr; @@ -320,15 +131,15 @@ allocate_based_pages(nanozone_t *nanozone, size_t size, unsigned char align, uns } static void * -allocate_pages(nanozone_t *nanozone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label) +nano_allocate_pages(nanozone_t *nanozone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label) { return allocate_based_pages(nanozone, size, align, debug_flags, vm_page_label, 0); } static void -deallocate_pages(nanozone_t *nanozone, void *addr, size_t size, unsigned debug_flags) +nano_deallocate_pages(nanozone_t *nanozone, void *addr, size_t size, unsigned debug_flags) { - boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES; + boolean_t add_guard_pages = debug_flags & MALLOC_ADD_GUARD_PAGES; mach_vm_address_t vm_addr = (mach_vm_address_t)addr; mach_vm_size_t allocation_size = size; kern_return_t kr; @@ -338,8 +149,9 @@ deallocate_pages(nanozone_t *nanozone, void *addr, size_t size, unsigned debug_f allocation_size += 2 * vm_page_size; } kr = mach_vm_deallocate(mach_task_self(), vm_addr, allocation_size); - if (kr && nanozone) + if (kr && nanozone) { nanozone_error(nanozone, 0, "Can't deallocate_pages at", addr, NULL); + } } /* @@ -348,7 +160,7 @@ deallocate_pages(nanozone_t *nanozone, void *addr, size_t size, unsigned debug_f */ static boolean_t -segregated_band_grow(nanozone_t *nanozone, nano_meta_admin_t pMeta, unsigned int slot_bytes, unsigned int mag_index) +segregated_band_grow(nanozone_t *nanozone, nano_meta_admin_t pMeta, size_t slot_bytes, unsigned int mag_index) { nano_blk_addr_t u; // the compiler holds this in a register uintptr_t p, s; @@ -363,33 +175,37 @@ segregated_band_grow(nanozone_t *nanozone, nano_meta_admin_t pMeta, unsigned int u.fields.nano_offset = 0; p = u.addr; - pMeta->slot_bytes = slot_bytes; + pMeta->slot_bytes = (unsigned int)slot_bytes; pMeta->slot_objects = SLOT_IN_BAND_SIZE / slot_bytes; } else { p = pMeta->slot_current_base_addr + BAND_SIZE; // Growing, so stride ahead by BAND_SIZE u.addr = (uint64_t)p; - if (0 == u.fields.nano_band) // Did the band index wrap? + if (0 == u.fields.nano_band) { // Did the band index wrap? return FALSE; + } assert(slot_bytes == pMeta->slot_bytes); } pMeta->slot_current_base_addr = p; mach_vm_address_t vm_addr = p & ~((uintptr_t)(BAND_SIZE - 1)); // Address of the (2MB) band covering this (128KB) slot - - if (nanozone->band_max_mapped_baseaddr[mag_index] < vm_addr) { - // Obtain the next band to cover this slot - kern_return_t kr = mach_vm_map(mach_task_self(), &vm_addr, BAND_SIZE, - 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_NANO), MEMORY_OBJECT_NULL, 0, FALSE, - VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT); - - void *q = (uintptr_t)vm_addr; - if (kr || q != (void *)(p & ~((uintptr_t)(BAND_SIZE - 1)))) // Must get exactly what we asked for - return FALSE; - - nanozone->band_max_mapped_baseaddr[mag_index] = vm_addr; - } + + if (nanozone->band_max_mapped_baseaddr[mag_index] < vm_addr) { + // Obtain the next band to cover this slot + kern_return_t kr = mach_vm_map(mach_task_self(), &vm_addr, BAND_SIZE, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_NANO), + MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT); + + void *q = (void *)vm_addr; + if (kr || q != (void *)(p & ~((uintptr_t)(BAND_SIZE - 1)))) { // Must get exactly what we asked for + if (!kr) { + mach_vm_deallocate(mach_task_self(), vm_addr, BAND_SIZE); + } + return FALSE; + } + + nanozone->band_max_mapped_baseaddr[mag_index] = vm_addr; + } // Randomize the starting allocation from this slot (introduces 11 to 14 bits of entropy) if (0 == pMeta->slot_objects_mapped) { // First encounter? @@ -410,9 +226,9 @@ segregated_band_grow(nanozone_t *nanozone, nano_meta_admin_t pMeta, unsigned int s = u.addr; // Base for this core. // Set the high water mark for this CPU's entire magazine, if this resupply raised it. - watermark = nanozone->core_mapped_size[mag_index]; - hiwater = MAX( watermark, p - s + SLOT_IN_BAND_SIZE ); - nanozone->core_mapped_size[mag_index] = hiwater; + watermark = nanozone->core_mapped_size[mag_index]; + hiwater = MAX(watermark, p - s + SLOT_IN_BAND_SIZE); + nanozone->core_mapped_size[mag_index] = hiwater; return TRUE; } @@ -426,19 +242,19 @@ divrem(unsigned long a, unsigned int b, unsigned int *remainder) return a / b; } -static INLINE void * -segregated_next_block(nanozone_t *nanozone, nano_meta_admin_t pMeta, unsigned int slot_bytes, unsigned int mag_index) +static MALLOC_INLINE void * +segregated_next_block(nanozone_t *nanozone, nano_meta_admin_t pMeta, size_t slot_bytes, unsigned int mag_index) { while (1) { uintptr_t theLimit = pMeta->slot_limit_addr; // Capture the slot limit that bounds slot_bump_addr right now uintptr_t b = OSAtomicAdd64Barrier(slot_bytes, (volatile int64_t *)&(pMeta->slot_bump_addr)); b -= slot_bytes; // Atomic op returned addr of *next* free block. Subtract to get addr for *this* allocation. - if (b < theLimit) { // Did we stay within the bound of the present slot allocation? + if (b < theLimit) { // Did we stay within the bound of the present slot allocation? return (void *)b; // Yep, so the slot_bump_addr this thread incremented is good to go } else { if (pMeta->slot_exhausted) { // exhausted all the bands availble for this slot? - return 0; // We're toast + return 0; // We're toast } else { // One thread will grow the heap, others will see its been grown and retry allocation _malloc_lock_lock(&nanozone->band_resupply_lock[mag_index]); @@ -462,58 +278,62 @@ segregated_next_block(nanozone_t *nanozone, nano_meta_admin_t pMeta, unsigned in } } -static INLINE unsigned int -segregated_size_to_fit(nanozone_t *nanozone, size_t size, unsigned int *pKey) +static MALLOC_INLINE size_t +segregated_size_to_fit(nanozone_t *nanozone, size_t size, size_t *pKey) { - unsigned int k, slot_bytes; + size_t k, slot_bytes; - if (0 == size) + if (0 == size) { size = NANO_REGIME_QUANTA_SIZE; // Historical behavior - + } k = (size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM; // round up and shift for number of quanta - slot_bytes = k << SHIFT_NANO_QUANTUM; // multiply by power of two quanta size - *pKey = k - 1; // Zero-based! + slot_bytes = k << SHIFT_NANO_QUANTUM; // multiply by power of two quanta size + *pKey = k - 1; // Zero-based! return slot_bytes; } -static INLINE index_t +static MALLOC_INLINE index_t offset_to_index(nanozone_t *nanozone, nano_meta_admin_t pMeta, uintptr_t offset) { unsigned int slot_bytes = pMeta->slot_bytes; unsigned int slot_objects = pMeta->slot_objects; // SLOT_IN_BAND_SIZE / slot_bytes; - unsigned int rem; - unsigned long quo = divrem(offset, BAND_SIZE, &rem); + unsigned int rem; + unsigned long quo = divrem(offset, BAND_SIZE, &rem); - assert(0 == rem%slot_bytes); - return (quo * slot_objects) + (rem / slot_bytes); + assert(0 == rem % slot_bytes || pMeta->slot_exhausted); + return (index_t)((quo * slot_objects) + (rem / slot_bytes)); } -static INLINE uintptr_t +static MALLOC_INLINE uintptr_t index_to_offset(nanozone_t *nanozone, nano_meta_admin_t pMeta, index_t i) { unsigned int slot_bytes = pMeta->slot_bytes; unsigned int slot_objects = pMeta->slot_objects; // SLOT_IN_BAND_SIZE / slot_bytes; - unsigned int rem; - unsigned long quo = divrem(i, slot_objects, &rem); - + unsigned int rem; + unsigned long quo = divrem(i, slot_objects, &rem); + return (quo * BAND_SIZE) + (rem * slot_bytes); } static kern_return_t -segregated_in_use_enumerator(task_t task, void *context, unsigned type_mask, nanozone_t *nanozone, - memory_reader_t reader, vm_range_recorder_t recorder) -{ - unsigned int mag_index, slot_key; - vm_range_t ptr_range; - vm_range_t buffer[MAX_RECORDER_BUFFER]; - kern_return_t err; - unsigned count = 0; +segregated_in_use_enumerator(task_t task, + void *context, + unsigned type_mask, + nanozone_t *nanozone, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + unsigned int mag_index, slot_key; + vm_range_t ptr_range; + vm_range_t buffer[MAX_RECORDER_BUFFER]; + kern_return_t err; + unsigned count = 0; for (mag_index = 0; mag_index < nanozone->phys_ncpus; mag_index++) { - uintptr_t clone_magazine; // magazine base for ourselves - nano_blk_addr_t p; // slot base for remote - uintptr_t clone_slot_base; // slot base for ourselves (tracks with "p") + uintptr_t clone_magazine; // magazine base for ourselves + nano_blk_addr_t p; // slot base for remote + uintptr_t clone_slot_base; // slot base for ourselves (tracks with "p") // Establish p as base address for slot 0 in remote p.fields.nano_signature = NANOZONE_SIGNATURE; @@ -538,15 +358,15 @@ segregated_in_use_enumerator(task_t task, void *context, unsigned type_mask, nan clone_slot_base = clone_magazine = 0; // and won't be used in this loop } - for (slot_key = 0; slot_key < SLOT_KEY_LIMIT; - p.addr += SLOT_IN_BAND_SIZE, // Advance to next slot base for remote - clone_slot_base += SLOT_IN_BAND_SIZE, // Advance to next slot base for ourselves - slot_key++) { + for (slot_key = 0; slot_key < SLOT_KEY_LIMIT; p.addr += SLOT_IN_BAND_SIZE, // Advance to next slot base for remote + clone_slot_base += SLOT_IN_BAND_SIZE, // Advance to next slot base for ourselves + slot_key++) { nano_meta_admin_t pMeta = &(nanozone->meta_data[mag_index][slot_key]); size_t slot_objects_mapped = pMeta->slot_objects_mapped; // capture this volatile count - if (0 == slot_objects_mapped) // Nothing allocated in this magazine for this slot? + if (0 == slot_objects_mapped) { // Nothing allocated in this magazine for this slot? continue; + } if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) { /* do NOTHING as there is no distinct admin region */ @@ -554,7 +374,7 @@ segregated_in_use_enumerator(task_t task, void *context, unsigned type_mask, nan if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) { nano_blk_addr_t q = p; - uintptr_t skip_adj = index_to_offset(nanozone, pMeta, pMeta->slot_objects_skipped); + uintptr_t skip_adj = index_to_offset(nanozone, pMeta, (index_t)pMeta->slot_objects_skipped); while (q.addr < pMeta->slot_limit_addr) { ptr_range.address = q.addr + skip_adj; @@ -568,14 +388,15 @@ segregated_in_use_enumerator(task_t task, void *context, unsigned type_mask, nan if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) { nano_blk_addr_t q = p; uintptr_t slot_band, clone_slot_band_base = clone_slot_base; - uintptr_t skip_adj = index_to_offset(nanozone, pMeta, pMeta->slot_objects_skipped); + uintptr_t skip_adj = index_to_offset(nanozone, pMeta, (index_t)pMeta->slot_objects_skipped); while (q.addr < pMeta->slot_limit_addr) { // read slot in each remote band. Lands in some random location. size_t len = MIN(pMeta->slot_bump_addr - q.addr, SLOT_IN_BAND_SIZE); err = reader(task, (vm_address_t)(q.addr + skip_adj), len - skip_adj, (void **)&slot_band); - if (err) + if (err) { return err; + } // Place the data just read in the correct position relative to the local magazine. memcpy((void *)(clone_slot_band_base + skip_adj), (void *)slot_band, len - skip_adj); @@ -590,65 +411,73 @@ segregated_in_use_enumerator(task_t task, void *context, unsigned type_mask, nan int log_size = 64 - __builtin_clzl(slot_objects_mapped); bitarray_t slot_bitarray = bitarray_create(log_size); - if (!slot_bitarray) + if (!slot_bitarray) { return errno; + } chained_block_t t; - unsigned stoploss = slot_objects_mapped; - while ((t = OSAtomicDequeue( &(pMeta->slot_LIFO), offsetof(struct chained_block_s,next) + (clone_slot_base - p.addr)))) { + unsigned stoploss = (unsigned)slot_objects_mapped; + while ((t = OSAtomicDequeue( + &(pMeta->slot_LIFO), offsetof(struct chained_block_s, next) + (clone_slot_base - p.addr)))) { if (0 == stoploss) { malloc_printf("Free list walk in segregated_in_use_enumerator exceeded object count."); break; } stoploss--; - uintptr_t offset = ((uintptr_t)t - p.addr); // offset from beginning of slot, task-independent - index_t block_index = offset_to_index(nanozone, pMeta, offset); + uintptr_t offset = ((uintptr_t)t - p.addr); // offset from beginning of slot, task-independent + index_t block_index = offset_to_index(nanozone, pMeta, offset); - if (block_index < slot_objects_mapped) + if (block_index < slot_objects_mapped) { bitarray_set(slot_bitarray, log_size, block_index); + } } // N.B. pMeta->slot_LIFO in *this* task is now drained (remote free list has *not* been disturbed) // Copy the bitarray_t denoting madvise()'d pages (if any) into *this* task's address space bitarray_t madv_page_bitarray; int log_page_count; - + if (pMeta->slot_madvised_pages) { log_page_count = pMeta->slot_madvised_log_page_count; - err = reader(task, (vm_address_t)(pMeta->slot_madvised_pages), bitarray_size(log_page_count), (void **)&madv_page_bitarray); - if (err) + err = reader(task, (vm_address_t)(pMeta->slot_madvised_pages), bitarray_size(log_page_count), + (void **)&madv_page_bitarray); + if (err) { return err; + } } else { madv_page_bitarray = NULL; log_page_count = 0; } - + // Enumerate all the block indices issued to date, and report those not on the free list index_t i; - for (i = pMeta->slot_objects_skipped; i < slot_objects_mapped; ++i) { + for (i = (index_t)pMeta->slot_objects_skipped; i < slot_objects_mapped; ++i) { uintptr_t block_offset = index_to_offset(nanozone, pMeta, i); - if (p.addr + block_offset >= pMeta->slot_bump_addr) + if (p.addr + block_offset >= pMeta->slot_bump_addr) { break; + } // blocks falling on madvise()'d pages are free! So not enumerated. if (madv_page_bitarray) { nano_blk_addr_t q; index_t pgnum, pgnum_end; - + q.addr = p.addr + block_offset; - pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_page_shift; + pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> + vm_kernel_page_shift; q.addr += pMeta->slot_bytes - 1; - pgnum_end = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_page_shift; - - if (pgnum < (1 << log_page_count)) {// bounds check for bitarray_get()'s that follow + pgnum_end = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> + vm_kernel_page_shift; + + if (pgnum < (1 << log_page_count)) { // bounds check for bitarray_get()'s that follow if (bitarray_get(madv_page_bitarray, log_page_count, pgnum) || - bitarray_get(madv_page_bitarray, log_page_count, pgnum_end)) { + bitarray_get(madv_page_bitarray, log_page_count, pgnum_end)) { continue; } } } - + if (!bitarray_get(slot_bitarray, log_size, i)) { buffer[count].address = p.addr + block_offset; buffer[count].size = (slot_key + 1) << SHIFT_NANO_QUANTUM; @@ -683,121 +512,182 @@ segregated_in_use_enumerator(task_t task, void *context, unsigned type_mask, nan * the extent of the nano allocation regime -- (0, 256]. */ -static INLINE size_t +static MALLOC_INLINE MALLOC_UNUSED boolean_t +_nano_block_inuse_p(nanozone_t *nanozone, const void *ptr) +{ + nano_blk_addr_t p; // happily, the compiler holds this in a register + nano_meta_admin_t pMeta; + chained_block_t head = NULL, tail = NULL, t; + boolean_t inuse = TRUE; + + p.addr = (uint64_t)ptr; // place ptr on the dissecting table + + pMeta = &(nanozone->meta_data[p.fields.nano_mag_index][p.fields.nano_slot]); + + // pop elements off the free list all the while looking for ptr. + unsigned stoploss = (unsigned)pMeta->slot_objects_mapped; + while ((t = OSAtomicDequeue(&(pMeta->slot_LIFO), offsetof(struct chained_block_s, next)))) { + if (0 == stoploss) { + nanozone_error( + nanozone, 1, "Free list walk in _nano_block_inuse_p exceeded object count.", (void *)&(pMeta->slot_LIFO), NULL); + } + stoploss--; + + if (NULL == head) { + head = t; + } else { + tail->next = t; + } + tail = t; + + if (ptr == t) { + inuse = FALSE; + break; + } + } + if (tail) { + tail->next = NULL; + } + + // push the free list extracted above back onto the LIFO, all at once + if (head) { + OSAtomicEnqueue(&(pMeta->slot_LIFO), head, (uintptr_t)tail - (uintptr_t)head + offsetof(struct chained_block_s, next)); + } + + return inuse; +} + +static MALLOC_INLINE size_t __nano_vet_and_size(nanozone_t *nanozone, const void *ptr) { // Extracts the size of the block in bytes. Checks for a plausible ptr. - nano_blk_addr_t p; // the compiler holds this in a register - nano_meta_admin_t pMeta; + nano_blk_addr_t p; // the compiler holds this in a register + nano_meta_admin_t pMeta; p.addr = (uint64_t)ptr; // Begin the dissection of ptr - if (nanozone->phys_ncpus <= p.fields.nano_mag_index) + if (nanozone->our_signature != p.fields.nano_signature) { return 0; + } - if (p.fields.nano_offset & NANO_QUANTA_MASK) // stray low-order bits? + if (nanozone->phys_ncpus <= p.fields.nano_mag_index) { return 0; + } + + if (p.fields.nano_offset & NANO_QUANTA_MASK) { // stray low-order bits? + return 0; + } pMeta = &(nanozone->meta_data[p.fields.nano_mag_index][p.fields.nano_slot]); - if ((void *)(pMeta->slot_bump_addr) <= ptr) + if ((void *)(pMeta->slot_bump_addr) <= ptr) { return 0; // Beyond what's ever been allocated! - - if ((p.fields.nano_offset % pMeta->slot_bytes) != 0) + } + if ((p.fields.nano_offset % pMeta->slot_bytes) != 0) { return 0; // Not an exact multiple of the block size for this slot - + } return pMeta->slot_bytes; } -static INLINE size_t +static MALLOC_INLINE size_t _nano_vet_and_size_of_live(nanozone_t *nanozone, const void *ptr) { - size_t size = __nano_vet_and_size(nanozone, ptr); - if (size && ((((chained_block_t)ptr)->double_free_guard ^ nanozone->cookie) != 0xBADDC0DEDEADBEADULL)) - return size; // Common case: not on a free list, hence live. Return its size. - else - // ptr is either on a free list (its got the correct canary) in which case return zero, OR - // the caller has stored the canary value in the double_free_guard slot entirely by coincidence - // and the block is a live allocation. The latter is very unlikely (1 in 2^64) so just return 0. - return 0; + size_t size = __nano_vet_and_size(nanozone, ptr); + + if (0 == size) { // ptr fails sanity check? + return 0; + } + + // We have the invariant: If ptr is on a free list, then ptr->double_free_guard is the canary. + // So if ptr->double_free_guard is NOT the canary, then ptr is not on a free list, hence is live. + if ((((chained_block_t)ptr)->double_free_guard ^ nanozone->cookie) != 0xBADDC0DEDEADBEADULL) { + return size; // Common case: not on a free list, hence live. Return its size. + } else { + // confirm that ptr is live despite ptr->double_free_guard having the canary value + if (_nano_block_inuse_p(nanozone, ptr)) { + return size; // live block that exhibits canary + } else { + return 0; // ptr wasn't live after all (likely a double free) + } + } } -static INLINE size_t +static MALLOC_INLINE size_t _nano_vet_and_size_of_free(nanozone_t *nanozone, const void *ptr) { - size_t size = __nano_vet_and_size(nanozone, ptr); - if (size && ((((chained_block_t)ptr)->double_free_guard ^ nanozone->cookie) == 0xBADDC0DEDEADBEADULL)) - return size; - else - return 0; + size_t size = __nano_vet_and_size(nanozone, ptr); + + if (0 == size) { // ptr fails sanity check? + return 0; + } + + // ptr was just dequed from a free list, so ptr->double_free_guard must have the canary value. + if ((((chained_block_t)ptr)->double_free_guard ^ nanozone->cookie) == 0xBADDC0DEDEADBEADULL) { + return size; // return the size of this well formed free block. + } else { + return 0; // Broken invariant: If ptr is on a free list, then ptr->double_free_guard is the canary. (likely use after free) + } } static void * _nano_malloc_check_clear(nanozone_t *nanozone, size_t size, boolean_t cleared_requested) { - void *ptr; - unsigned int slot_key; - unsigned int slot_bytes = segregated_size_to_fit(nanozone, size, &slot_key); // Note slot_key is set here - unsigned int mag_index = NANO_MAG_INDEX(nanozone); + MALLOC_TRACE(TRACE_nano_malloc, (uintptr_t)nanozone, size, cleared_requested, 0); + + void *ptr; + size_t slot_key; + size_t slot_bytes = segregated_size_to_fit(nanozone, size, &slot_key); // Note slot_key is set here + unsigned int mag_index = NANO_MAG_INDEX(nanozone); - nano_meta_admin_t pMeta = &(nanozone->meta_data[mag_index][slot_key]); + nano_meta_admin_t pMeta = &(nanozone->meta_data[mag_index][slot_key]); - ptr = OSAtomicDequeue( &(pMeta->slot_LIFO), offsetof(struct chained_block_s,next)); + ptr = OSAtomicDequeue(&(pMeta->slot_LIFO), offsetof(struct chained_block_s, next)); if (ptr) { #if NANO_FREE_DEQUEUE_DILIGENCE - size_t gotSize; - nano_blk_addr_t p; // the compiler holds this in a register + size_t gotSize; + nano_blk_addr_t p; // the compiler holds this in a register p.addr = (uint64_t)ptr; // Begin the dissection of ptr if (nanozone->our_signature != p.fields.nano_signature) { - nanozone_error(nanozone, 1, - "Invalid signature for pointer dequeued from free list", ptr, NULL); + nanozone_error(nanozone, 1, "Invalid signature for pointer dequeued from free list", ptr, NULL); } if (mag_index != p.fields.nano_mag_index) { - nanozone_error(nanozone, 1, - "Mismatched magazine for pointer dequeued from free list", ptr, NULL); + nanozone_error(nanozone, 1, "Mismatched magazine for pointer dequeued from free list", ptr, NULL); } gotSize = _nano_vet_and_size_of_free(nanozone, ptr); if (0 == gotSize) { - nanozone_error(nanozone, 1, - "Invalid pointer dequeued from free list", ptr, NULL); + nanozone_error(nanozone, 1, "Invalid pointer dequeued from free list", ptr, NULL); } if (gotSize != slot_bytes) { - nanozone_error(nanozone, 1, - "Mismatched size for pointer dequeued from free list", ptr, NULL); + nanozone_error(nanozone, 1, "Mismatched size for pointer dequeued from free list", ptr, NULL); } if ((((chained_block_t)ptr)->double_free_guard ^ nanozone->cookie) != 0xBADDC0DEDEADBEADULL) { - nanozone_error(nanozone, 1, - "Heap corruption detected, free list canary is damaged", ptr, NULL); + nanozone_error(nanozone, 1, "Heap corruption detected, free list canary is damaged", ptr, NULL); } #if defined(DEBUG) - void *next = (void *) (((chained_block_t)ptr)->next); + void *next = (void *)(((chained_block_t)ptr)->next); if (next) { p.addr = (uint64_t)next; // Begin the dissection of next if (nanozone->our_signature != p.fields.nano_signature) { - nanozone_error(nanozone, 1, - "Invalid next signature for pointer dequeued from free list (showing ptr, next)", - ptr, ", %p", next); + nanozone_error(nanozone, 1, "Invalid next signature for pointer dequeued from free list (showing ptr, next)", ptr, + ", %p", next); } if (mag_index != p.fields.nano_mag_index) { - nanozone_error(nanozone, 1, - "Mismatched next magazine for pointer dequeued from free list (showing ptr, next)", - ptr, ", %p", next); + nanozone_error(nanozone, 1, "Mismatched next magazine for pointer dequeued from free list (showing ptr, next)", ptr, + ", %p", next); } gotSize = _nano_vet_and_size_of_free(nanozone, next); if (0 == gotSize) { - nanozone_error(nanozone, 1, - "Invalid next for pointer dequeued from free list (showing ptr, next)", - ptr, ", %p", next); + nanozone_error( + nanozone, 1, "Invalid next for pointer dequeued from free list (showing ptr, next)", ptr, ", %p", next); } if (gotSize != slot_bytes) { - nanozone_error(nanozone, 1, - "Mismatched next size for pointer dequeued from free list (showing ptr, next)", - ptr, ", %p", next); + nanozone_error(nanozone, 1, "Mismatched next size for pointer dequeued from free list (showing ptr, next)", ptr, + ", %p", next); } } #endif /* DEBUG */ @@ -809,9 +699,9 @@ _nano_malloc_check_clear(nanozone_t *nanozone, size_t size, boolean_t cleared_re ptr = segregated_next_block(nanozone, pMeta, slot_bytes, mag_index); } - if (cleared_requested && ptr) + if (cleared_requested && ptr) { memset(ptr, 0, slot_bytes); // TODO: Needs a memory barrier after memset to ensure zeroes land first? - + } return ptr; } @@ -823,112 +713,71 @@ _nano_malloc_check_scribble(nanozone_t *nanozone, size_t size) /* * Scribble on allocated memory when requested. */ - if ((nanozone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && ptr && size) + if ((nanozone->debug_flags & MALLOC_DO_SCRIBBLE) && ptr && size) { memset(ptr, SCRIBBLE_BYTE, _nano_vet_and_size_of_live(nanozone, ptr)); - - return ptr; -} - -static INLINE boolean_t -_nano_block_inuse_p(nanozone_t *nanozone, const void *ptr) -{ - nano_blk_addr_t p; // happily, the compiler holds this in a register - nano_meta_admin_t pMeta; - chained_block_t head = NULL, tail = NULL, t; - boolean_t inuse = TRUE; - - p.addr = (uint64_t)ptr; // place ptr on the dissecting table - - pMeta = &(nanozone->meta_data[p.fields.nano_mag_index][p.fields.nano_slot]); - - if ((void *)(pMeta->slot_bump_addr) <= ptr) - return FALSE; // Beyond what's ever been allocated, so trivially not in use. - - // pop elements off the free list all the while looking for ptr. - unsigned stoploss = pMeta->slot_objects_mapped; - while ((t = OSAtomicDequeue( &(pMeta->slot_LIFO), offsetof(struct chained_block_s,next)))) { - if (0 == stoploss) { - nanozone_error(nanozone, 1, "Free list walk in _nano_block_inuse_p exceeded object count.", - (void *)&(pMeta->slot_LIFO), NULL); - } - stoploss--; - - if (NULL == head) - head = t; - else - tail->next = t; - tail = t; - - if (ptr == t) { - inuse = FALSE; - break; - } } - if (tail) - tail->next = NULL; - // push the free list extracted above back onto the LIFO, all at once - if (head) - OSAtomicEnqueue( &(pMeta->slot_LIFO), head, (uintptr_t)tail - (uintptr_t)head + offsetof(struct chained_block_s,next)); - - return inuse; + return ptr; } -static INLINE size_t +static MALLOC_INLINE size_t _nano_size(nanozone_t *nanozone, const void *ptr) { - return _nano_vet_and_size_of_live(nanozone, ptr); + return _nano_vet_and_size_of_live(nanozone, ptr); } -static INLINE size_t +static MALLOC_INLINE size_t _nano_good_size(nanozone_t *nanozone, size_t size) { - return (size <= NANO_REGIME_QUANTA_SIZE) ? - NANO_REGIME_QUANTA_SIZE : - (((size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM) << SHIFT_NANO_QUANTUM); + return (size <= NANO_REGIME_QUANTA_SIZE) ? NANO_REGIME_QUANTA_SIZE + : (((size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM) << SHIFT_NANO_QUANTUM); } -static INLINE void _nano_free_trusted_size_check_scribble(nanozone_t *nanozone, void *ptr, size_t trusted_size, boolean_t do_scribble) ALWAYSINLINE; +static MALLOC_INLINE void _nano_free_trusted_size_check_scribble(nanozone_t *nanozone, + void *ptr, + size_t trusted_size, + boolean_t do_scribble) MALLOC_ALWAYS_INLINE; -static INLINE void +static MALLOC_INLINE void _nano_free_trusted_size_check_scribble(nanozone_t *nanozone, void *ptr, size_t trusted_size, boolean_t do_scribble) { if (trusted_size) { nano_blk_addr_t p; // happily, the compiler holds this in a register nano_meta_admin_t pMeta; - if (do_scribble) + if (do_scribble) { (void)memset(ptr, SCRABBLE_BYTE, trusted_size); + } ((chained_block_t)ptr)->double_free_guard = (0xBADDC0DEDEADBEADULL ^ nanozone->cookie); p.addr = (uint64_t)ptr; // place ptr on the dissecting table pMeta = &(nanozone->meta_data[p.fields.nano_mag_index][p.fields.nano_slot]); - OSAtomicEnqueue( &(pMeta->slot_LIFO), ptr, offsetof(struct chained_block_s,next)); + OSAtomicEnqueue(&(pMeta->slot_LIFO), ptr, offsetof(struct chained_block_s, next)); } else { nanozone_error(nanozone, 1, "Freeing unallocated pointer", ptr, NULL); } } -static INLINE void _nano_free_check_scribble(nanozone_t *nanozone, void *ptr, boolean_t do_scribble) ALWAYSINLINE; +static MALLOC_INLINE void _nano_free_check_scribble(nanozone_t *nanozone, void *ptr, boolean_t do_scribble) MALLOC_ALWAYS_INLINE; -static INLINE void +static MALLOC_INLINE void _nano_free_check_scribble(nanozone_t *nanozone, void *ptr, boolean_t do_scribble) { - _nano_free_trusted_size_check_scribble(nanozone, ptr, _nano_vet_and_size_of_live(nanozone, ptr), do_scribble); + _nano_free_trusted_size_check_scribble(nanozone, ptr, _nano_vet_and_size_of_live(nanozone, ptr), do_scribble); } -static INLINE void * +static MALLOC_INLINE void * _nano_realloc(nanozone_t *nanozone, void *ptr, size_t new_size) { - size_t old_size, new_good_size, valid_size; - void *new_ptr; + size_t old_size, new_good_size, valid_size; + void *new_ptr; if (FALSE && NULL == ptr) { // ptr has our_signature so can't be NULL, but if it were Posix sez ... // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. return _nano_malloc_check_scribble(nanozone, new_size); } else if (0 == new_size) { // If size is 0 and ptr is not a null pointer, the object pointed to is freed. - _nano_free_check_scribble(nanozone, ptr, (nanozone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE)); + _nano_free_check_scribble(nanozone, ptr, (nanozone->debug_flags & MALLOC_DO_SCRIBBLE)); // If size is 0, either a null pointer or a unique pointer that can be successfully passed // to free() shall be returned. return _nano_malloc_check_scribble(nanozone, 1); @@ -947,8 +796,9 @@ _nano_realloc(nanozone_t *nanozone, void *ptr, size_t new_size) /* Serious shrinkage (more than half). FALL THROUGH to alloc/copy/free. */ } else { /* Let's hang on to what we got. */ - if (nanozone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) + if (nanozone->debug_flags & MALLOC_DO_SCRIBBLE) { memset(ptr + new_size, SCRIBBLE_BYTE, old_size - new_size); + } return ptr; } @@ -956,21 +806,22 @@ _nano_realloc(nanozone_t *nanozone, void *ptr, size_t new_size) * Allocate a new buffer and copy. */ new_ptr = _nano_malloc_check_scribble(nanozone, new_good_size); - if (new_ptr == NULL) + if (new_ptr == NULL) { return NULL; + } valid_size = MIN(old_size, new_good_size); memcpy(new_ptr, ptr, valid_size); - _nano_free_check_scribble(nanozone, ptr, (nanozone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE)); + _nano_free_check_scribble(nanozone, ptr, (nanozone->debug_flags & MALLOC_DO_SCRIBBLE)); return new_ptr; } -static INLINE void +static MALLOC_INLINE void _nano_destroy(nanozone_t *nanozone) { /* Now destroy the separate nanozone region */ - deallocate_pages(nanozone, (void *)nanozone, SZONE_PAGED_SIZE, 0); + nano_deallocate_pages(nanozone, (void *)nanozone, NANOZONE_PAGED_SIZE, 0); } /****************** nanozone dispatch **********************/ @@ -1007,8 +858,9 @@ nano_malloc_scribble(nanozone_t *nanozone, size_t size) /* * Scribble on allocated memory. */ - if (size) + if (size) { memset(ptr, SCRIBBLE_BYTE, _nano_vet_and_size_of_live(nanozone, ptr)); + } return ptr; } else { @@ -1030,8 +882,9 @@ nano_calloc(nanozone_t *nanozone, size_t num_items, size_t size) if ((num_items | size) & 0xffffffff00000000ul) { // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic __uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size); - if ((uint64_t)(product >> 64)) // compiles to test on upper register of register pair + if ((uint64_t)(product >> 64)) { // compiles to test on upper register of register pair return NULL; + } } } @@ -1061,22 +914,23 @@ nano_valloc(nanozone_t *nanozone, size_t size) return zone->valloc(zone, size); } -static INLINE void __nano_free_definite_size(nanozone_t *nanozone, void *ptr, size_t size, boolean_t do_scribble) ALWAYSINLINE; +static MALLOC_INLINE void +__nano_free_definite_size(nanozone_t *nanozone, void *ptr, size_t size, boolean_t do_scribble) MALLOC_ALWAYS_INLINE; -static INLINE void +static MALLOC_INLINE void __nano_free_definite_size(nanozone_t *nanozone, void *ptr, size_t size, boolean_t do_scribble) { nano_blk_addr_t p; // happily, the compiler holds this in a register p.addr = (uint64_t)ptr; // place ptr on the dissecting table if (nanozone->our_signature == p.fields.nano_signature) { - if (size == ((p.fields.nano_slot + 1) << SHIFT_NANO_QUANTUM)) { // "Trust but verify." - _nano_free_trusted_size_check_scribble(nanozone, ptr, size, do_scribble); - return; + if (size == ((p.fields.nano_slot + 1) << SHIFT_NANO_QUANTUM)) { // "Trust but verify." + _nano_free_trusted_size_check_scribble(nanozone, ptr, size, do_scribble); + return; + } else { + nanozone_error(nanozone, 1, "Freeing pointer whose size was misdeclared", ptr, NULL); + } } else { - nanozone_error(nanozone, 1, "Freeing pointer whose size was misdeclared", ptr, NULL); - } - } else { malloc_zone_t *zone = (malloc_zone_t *)(nanozone->helper_zone); zone->free_definite_size(zone, ptr, size); return; @@ -1096,19 +950,25 @@ nano_free_definite_size_scribble(nanozone_t *nanozone, void *ptr, size_t size) __nano_free_definite_size(nanozone, ptr, size, 1); } -static INLINE void __nano_free(nanozone_t *nanozone, void *ptr, boolean_t do_scribble) ALWAYSINLINE; +static MALLOC_INLINE void __nano_free(nanozone_t *nanozone, void *ptr, boolean_t do_scribble) MALLOC_ALWAYS_INLINE; -static INLINE void +static MALLOC_INLINE void __nano_free(nanozone_t *nanozone, void *ptr, boolean_t do_scribble) { - nano_blk_addr_t p; // happily, the compiler holds this in a register + MALLOC_TRACE(TRACE_nano_free, (uintptr_t)nanozone, (uintptr_t)ptr, do_scribble, 0); - if (!ptr) + if (!ptr) { return; // Protect against malloc_zone_free() passing NULL. + } - p.addr = (uint64_t)ptr; // place ptr on the dissecting table - if (nanozone->our_signature == p.fields.nano_signature) { - _nano_free_check_scribble(nanozone, ptr, do_scribble); + // exhausting a slot may result in a pointer with + // the nanozone prefix being given to nano_free via malloc_zone_free. Calling + // vet_and_size here, instead of in _nano_free_check_scribble means we can + // early-out into the helper_zone if it turns out nano does not own this ptr. + size_t sz = _nano_vet_and_size_of_live(nanozone, ptr); + + if (sz) { + _nano_free_trusted_size_check_scribble(nanozone, ptr, sz, do_scribble); return; } else { malloc_zone_t *zone = (malloc_zone_t *)(nanozone->helper_zone); @@ -1129,9 +989,9 @@ nano_forked_free(nanozone_t *nanozone, void *ptr) { nano_blk_addr_t p; // happily, the compiler holds this in a register - if (!ptr) + if (!ptr) { return; // Protect against malloc_zone_free() passing NULL. - + } p.addr = (uint64_t)ptr; // place ptr on the dissecting table if (nanozone->our_signature == p.fields.nano_signature) { /* NOTHING. Drop it on the floor as nanozone metadata could be fouled by fork. */ @@ -1180,15 +1040,15 @@ nano_realloc(nanozone_t *nanozone, void *ptr, size_t new_size) p.addr = (uint64_t)ptr; // place ptr on the dissecting table if (NULL == ptr) { // could occur through malloc_zone_realloc() path - // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. + // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. return nano_malloc(nanozone, new_size); } else if (nanozone->our_signature == p.fields.nano_signature) { // Our signature? - if (new_size <= NANO_MAX_SIZE) { // nano to nano? + if (new_size <= NANO_MAX_SIZE) { // nano to nano? void *q = _nano_realloc(nanozone, ptr, new_size); if (q) { return q; } else { // nano exhausted - /* FALLTHROUGH to helper zone copying case */ + /* FALLTHROUGH to helper zone copying case */ } } @@ -1205,7 +1065,7 @@ nano_realloc(nanozone_t *nanozone, void *ptr, size_t new_size) if (new_ptr) { size_t valid_size = MIN(old_size, new_size); memcpy(new_ptr, ptr, valid_size); - _nano_free_check_scribble(nanozone, ptr, (nanozone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE)); + _nano_free_check_scribble(nanozone, ptr, (nanozone->debug_flags & MALLOC_DO_SCRIBBLE)); return new_ptr; } else { /* Original ptr is left intact */ @@ -1230,18 +1090,18 @@ nano_forked_realloc(nanozone_t *nanozone, void *ptr, size_t new_size) p.addr = (uint64_t)ptr; // place ptr on the dissecting table if (NULL == ptr) { // could occur through malloc_zone_realloc() path - // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. + // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. return nano_forked_malloc(nanozone, new_size); } else if (nanozone->our_signature == p.fields.nano_signature) { // Our signature? - if (0 == new_size) { - // If size is 0 and ptr is not a null pointer, the object pointed to is freed. - // However as nanozone metadata could be fouled by fork, we'll intentionally leak it. - - // If size is 0, either a null pointer or a unique pointer that can be successfully passed - // to free() shall be returned. - return nano_forked_malloc(nanozone, 1); - } - + if (0 == new_size) { + // If size is 0 and ptr is not a null pointer, the object pointed to is freed. + // However as nanozone metadata could be fouled by fork, we'll intentionally leak it. + + // If size is 0, either a null pointer or a unique pointer that can be successfully passed + // to free() shall be returned. + return nano_forked_malloc(nanozone, 1); + } + size_t old_size = _nano_vet_and_size_of_live(nanozone, ptr); if (!old_size) { @@ -1283,13 +1143,14 @@ nano_destroy(nanozone_t *nanozone) static unsigned nano_batch_malloc(nanozone_t *nanozone, size_t size, void **results, unsigned count) { - unsigned found = 0; + unsigned found = 0; if (size <= NANO_MAX_SIZE) { while (found < count) { void *ptr = _nano_malloc_check_clear(nanozone, size, 0); - if (!ptr) + if (!ptr) { break; + } *results++ = ptr; found++; @@ -1315,34 +1176,38 @@ nano_forked_batch_malloc(nanozone_t *nanozone, size_t size, void **results, unsi static void nano_batch_free(nanozone_t *nanozone, void **to_be_freed, unsigned count) { - void *ptr; + void *ptr; // frees all the pointers in to_be_freed // note that to_be_freed may be overwritten during the process - if (!count) + if (!count) { return; + } while (count--) { ptr = to_be_freed[count]; - if (ptr) + if (ptr) { nano_free(nanozone, ptr); + } } } static void nano_forked_batch_free(nanozone_t *nanozone, void **to_be_freed, unsigned count) { - void *ptr; + void *ptr; // frees all the pointers in to_be_freed // note that to_be_freed may be overwritten during the process - if (!count) + if (!count) { return; + } while (count--) { ptr = to_be_freed[count]; - if (ptr) + if (ptr) { nano_forked_free(nanozone, ptr); + } } } @@ -1356,11 +1221,11 @@ nano_memalign(nanozone_t *nanozone, size_t alignment, size_t size) static size_t nano_try_madvise(nanozone_t *nanozone, size_t goal) { - unsigned int mag_index, slot_key; - size_t bytes_toward_goal = 0; + unsigned int mag_index, slot_key; + size_t bytes_toward_goal = 0; for (mag_index = 0; mag_index < nanozone->phys_ncpus; mag_index++) { - nano_blk_addr_t p; + nano_blk_addr_t p; // Establish p as base address for band 0, slot 0, offset 0 p.fields.nano_signature = NANOZONE_SIGNATURE; @@ -1369,13 +1234,11 @@ nano_try_madvise(nanozone_t *nanozone, size_t goal) p.fields.nano_slot = 0; p.fields.nano_offset = 0; - for (slot_key = 0; slot_key < SLOT_KEY_LIMIT; - p.addr += SLOT_IN_BAND_SIZE, // Advance to next slot base - slot_key++) { - + for (slot_key = 0; slot_key < SLOT_KEY_LIMIT; p.addr += SLOT_IN_BAND_SIZE, // Advance to next slot base + slot_key++) { // _malloc_printf(ASL_LEVEL_WARNING,"nano_try_madvise examining slot base %p\n", p.addr); nano_meta_admin_t pMeta = &(nanozone->meta_data[mag_index][slot_key]); - uintptr_t slot_bump_addr = pMeta->slot_bump_addr; // capture this volatile pointer + uintptr_t slot_bump_addr = pMeta->slot_bump_addr; // capture this volatile pointer size_t slot_objects_mapped = pMeta->slot_objects_mapped; // capture this volatile count if (0 == slot_objects_mapped) { // Nothing allocated in this magazine for this slot? @@ -1386,13 +1249,15 @@ nano_try_madvise(nanozone_t *nanozone, size_t goal) bitarray_t slot_bitarray = bitarray_create(log_size); unsigned int slot_bytes = pMeta->slot_bytes; - int log_page_count = 64 - __builtin_clzl((slot_objects_mapped * slot_bytes) / vm_page_size); + int log_page_count = 64 - __builtin_clzl((slot_objects_mapped * slot_bytes) / vm_kernel_page_size); log_page_count = 1 + MAX(0, log_page_count); bitarray_t page_bitarray = bitarray_create(log_page_count); - // _malloc_printf(ASL_LEVEL_WARNING,"slot_bitarray: %db page_bitarray: %db\n", bitarray_size(log_size), bitarray_size(log_page_count)); + // _malloc_printf(ASL_LEVEL_WARNING,"slot_bitarray: %db page_bitarray: %db\n", bitarray_size(log_size), + // bitarray_size(log_page_count)); if (!slot_bitarray) { malloc_printf("bitarray_create(%d) in nano_try_madvise returned errno=%d.", log_size, errno); + free(page_bitarray); return bytes_toward_goal; } @@ -1403,30 +1268,33 @@ nano_try_madvise(nanozone_t *nanozone, size_t goal) } chained_block_t head = NULL, tail = NULL, t; - unsigned stoploss = slot_objects_mapped; - while ((t = OSAtomicDequeue( &(pMeta->slot_LIFO), offsetof(struct chained_block_s,next)))) { + unsigned stoploss = (unsigned)slot_objects_mapped; + while ((t = OSAtomicDequeue(&(pMeta->slot_LIFO), offsetof(struct chained_block_s, next)))) { if (0 == stoploss) { malloc_printf("Free list walk in nano_try_madvise exceeded object count."); break; } stoploss--; - uintptr_t offset = ((uintptr_t)t - p.addr); // offset from beginning of slot - index_t block_index = offset_to_index(nanozone, pMeta, offset); + uintptr_t offset = ((uintptr_t)t - p.addr); // offset from beginning of slot + index_t block_index = offset_to_index(nanozone, pMeta, offset); // build a simple linked list of the free blocks we're able to obtain - if (NULL == head) + if (NULL == head) { head = t; - else + } else { tail->next = t; + } tail = t; // take note in a bitarray_t of each free block we're able to obtain (allows fast lookup below) - if (block_index < slot_objects_mapped) + if (block_index < slot_objects_mapped) { bitarray_set(slot_bitarray, log_size, block_index); + } } - if (tail) + if (tail) { tail->next = NULL; + } if (NULL == head) { free(slot_bitarray); @@ -1437,31 +1305,35 @@ nano_try_madvise(nanozone_t *nanozone, size_t goal) index_t i; nano_blk_addr_t q; size_t pgnum; - for (i = pMeta->slot_objects_skipped; i < slot_objects_mapped; ++i) { + for (i = (index_t)pMeta->slot_objects_skipped; i < slot_objects_mapped; ++i) { uintptr_t block_offset = index_to_offset(nanozone, pMeta, i); - if (p.addr + block_offset >= slot_bump_addr) + if (p.addr + block_offset >= slot_bump_addr) { break; + } if (!bitarray_get(slot_bitarray, log_size, i)) { // is block i allocated or already on an madvise'd page? // Mark the page(s) it resides on as live q.addr = p.addr + block_offset; - pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_page_shift; - bitarray_set(page_bitarray, log_page_count, pgnum); + pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> + vm_kernel_page_shift; + bitarray_set(page_bitarray, log_page_count, (index_t)pgnum); q.addr += slot_bytes - 1; - pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_page_shift; - bitarray_set(page_bitarray, log_page_count, pgnum); + pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> + vm_kernel_page_shift; + bitarray_set(page_bitarray, log_page_count, (index_t)pgnum); } } free(slot_bitarray); - q.addr = p.addr + index_to_offset(nanozone, pMeta, pMeta->slot_objects_skipped); - index_t pgstart = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_page_shift; + q.addr = p.addr + index_to_offset(nanozone, pMeta, (index_t)pMeta->slot_objects_skipped); + index_t pgstart = + ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_kernel_page_shift; q.addr = slot_bump_addr - slot_bytes; - pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_page_shift; + pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_kernel_page_shift; // _malloc_printf(ASL_LEVEL_WARNING,"Examining %d pages. Slot base %p.\n", pgnum - pgstart + 1, p.addr); @@ -1483,11 +1355,11 @@ nano_try_madvise(nanozone_t *nanozone, size_t goal) bitarray_t will_madvise_pages = bitarray_create(log_page_count); int num_advised = 0; - + for (i = pgstart; i < pgnum; ++i) { if ((i < (1 << log_page_count)) && // bounds check for the bitarray_get()'s that follow. - !bitarray_get(pMeta->slot_madvised_pages, log_page_count, i) && // already madvise'd? - !bitarray_get(page_bitarray, log_page_count, i)) // no live allocations? + !bitarray_get(pMeta->slot_madvised_pages, log_page_count, i) && // already madvise'd? + !bitarray_get(page_bitarray, log_page_count, i)) // no live allocations? { num_advised++; bitarray_set(will_madvise_pages, log_page_count, i); @@ -1497,72 +1369,81 @@ nano_try_madvise(nanozone_t *nanozone, size_t goal) if (num_advised) { chained_block_t new_head = NULL, new_tail = NULL; - // _malloc_printf(ASL_LEVEL_WARNING,"Constructing residual free list starting at %p num_advised %d\n", head, num_advised); + // _malloc_printf(ASL_LEVEL_WARNING,"Constructing residual free list starting at %p num_advised %d\n", head, + // num_advised); t = head; while (t) { q.addr = (uintptr_t)t; - index_t pgnum_start = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_page_shift; + index_t pgnum_start = + ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> + vm_kernel_page_shift; q.addr += slot_bytes - 1; - index_t pgnum_end = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_page_shift; + index_t pgnum_end = + ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> + vm_kernel_page_shift; // bounds check for the bitarray_get()'s that follow. If the pgnum is beyond the // capacity of the will_madvise_pages just restore the block to the free list. if (pgnum_start >= (1 << log_page_count)) { - if (NULL == new_head) + if (NULL == new_head) { new_head = t; - else + } else { new_tail->next = t; + } new_tail = t; } // If the block nowhere lies on an madvise()'d page restore it to the slot free list. else if (!bitarray_get(will_madvise_pages, log_page_count, pgnum_start) && !bitarray_get(will_madvise_pages, log_page_count, pgnum_end)) { - if (NULL == new_head) + if (NULL == new_head) { new_head = t; - else + } else { new_tail->next = t; + } new_tail = t; } t = t->next; } - if (new_tail) + if (new_tail) { new_tail->next = NULL; + } // push the free list extracted above back onto the LIFO, all at once - if (new_head) - OSAtomicEnqueue( &(pMeta->slot_LIFO), new_head, - (uintptr_t)new_tail - (uintptr_t)new_head + offsetof(struct chained_block_s,next)); + if (new_head) { + OSAtomicEnqueue(&(pMeta->slot_LIFO), new_head, + (uintptr_t)new_tail - (uintptr_t)new_head + offsetof(struct chained_block_s, next)); + } } else { // _malloc_printf(ASL_LEVEL_WARNING,"Reinstating free list since no pages were madvised (%d).\n", num_advised); - if (head) - OSAtomicEnqueue( &(pMeta->slot_LIFO), head, - (uintptr_t)tail - (uintptr_t)head + offsetof(struct chained_block_s,next)); + if (head) { + OSAtomicEnqueue(&(pMeta->slot_LIFO), head, + (uintptr_t)tail - (uintptr_t)head + offsetof(struct chained_block_s, next)); + } } for (i = pgstart; i < pgnum; ++i) { if ((i < (1 << log_page_count)) && bitarray_get(will_madvise_pages, log_page_count, i)) { q = p; - q.fields.nano_band = (i << vm_page_shift) >> NANO_OFFSET_BITS; - q.fields.nano_offset = (i << vm_page_shift) & ((1 << NANO_OFFSET_BITS) - 1); - // _malloc_printf(ASL_LEVEL_WARNING,"Entire page non-live: %d. Slot base %p, madvising %p\n", i, p.addr, q.addr); - - if (nanozone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) - memset((void *)q.addr, SCRUBBLE_BYTE, vm_page_size); -#if TARGET_OS_EMBEDDED - if (-1 == madvise((void *)q.addr, vm_page_size, MADV_FREE)) -#else - if (-1 == madvise((void *)q.addr, vm_page_size, MADV_FREE_REUSABLE)) -#endif + q.fields.nano_band = (i << vm_kernel_page_shift) >> NANO_OFFSET_BITS; + q.fields.nano_offset = (i << vm_kernel_page_shift) & ((1 << NANO_OFFSET_BITS) - 1); + // _malloc_printf(ASL_LEVEL_WARNING,"Entire page non-live: %d. Slot base %p, madvising %p\n", i, p.addr, + // q.addr); + + if (nanozone->debug_flags & MALLOC_DO_SCRIBBLE) { + memset((void *)q.addr, SCRUBBLE_BYTE, vm_kernel_page_size); + } + + if (-1 == madvise((void *)q.addr, vm_kernel_page_size, MADV_FREE_REUSABLE)) { - /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ + /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */ #if DEBUG_MADVISE - nanozone_error(nanozone, 0, "madvise(..., MADV_FREE_REUSABLE) failed", - (void *)cwq.addrpgLo, "length=%d\n", vm_page_size); + nanozone_error(nanozone, 0, "madvise(..., MADV_FREE_REUSABLE) failed", (void *)cwq.addrpgLo, + "length=%d\n", vm_page_size); #endif } else { - bytes_toward_goal += vm_page_size; - bitarray_set(pMeta->slot_madvised_pages, log_page_count, i); + bytes_toward_goal += vm_kernel_page_size; + bitarray_set(pMeta->slot_madvised_pages, log_page_count, i); } } } @@ -1574,8 +1455,9 @@ nano_try_madvise(nanozone_t *nanozone, size_t goal) pMeta->slot_madvised_log_page_count = 0; } - if (goal && bytes_toward_goal >= goal) + if (goal && bytes_toward_goal >= goal) { return bytes_toward_goal; + } } } } @@ -1598,16 +1480,24 @@ nanozone_default_reader(task_t task, vm_address_t address, vm_size_t size, void } static kern_return_t -nano_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, vm_range_recorder_t recorder) -{ - nanozone_t *nanozone; - kern_return_t err; - - if (!reader) reader = nanozone_default_reader; +nano_ptr_in_use_enumerator(task_t task, + void *context, + unsigned type_mask, + vm_address_t zone_address, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + nanozone_t *nanozone; + kern_return_t err; + + if (!reader) { + reader = nanozone_default_reader; + } err = reader(task, zone_address, sizeof(nanozone_t), (void **)&nanozone); - if (err) return err; + if (err) { + return err; + } err = segregated_in_use_enumerator(task, context, type_mask, nanozone, reader, recorder); return err; @@ -1616,9 +1506,9 @@ nano_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_ad static size_t nano_good_size(nanozone_t *nanozone, size_t size) { - if (size <= NANO_MAX_SIZE) + if (size <= NANO_MAX_SIZE) { return _nano_good_size(nanozone, size); - else { + } else { malloc_zone_t *zone = (malloc_zone_t *)(nanozone->helper_zone); return zone->introspect->good_size(zone, size); } @@ -1638,14 +1528,17 @@ nano_check_all(nanozone_t *nanozone, const char *function) static boolean_t nanozone_check(nanozone_t *nanozone) { - if ((++nanozone_check_counter % 10000) == 0) + if ((++nanozone_check_counter % 10000) == 0) { _malloc_printf(ASL_LEVEL_NOTICE, "at nanozone_check counter=%d\n", nanozone_check_counter); + } - if (nanozone_check_counter < nanozone_check_start) + if (nanozone_check_counter < nanozone_check_start) { return 1; + } - if (nanozone_check_counter % nanozone_check_modulo) + if (nanozone_check_counter % nanozone_check_modulo) { return 1; + } return nano_check_all(nanozone, ""); } @@ -1656,28 +1549,30 @@ count_free(nanozone_t *nanozone, nano_meta_admin_t pMeta) chained_block_t head = NULL, tail = NULL, t; unsigned count = 0; - unsigned stoploss = pMeta->slot_objects_mapped; - while ((t = OSAtomicDequeue( &(pMeta->slot_LIFO), offsetof(struct chained_block_s,next)))) { + unsigned stoploss = (unsigned)pMeta->slot_objects_mapped; + while ((t = OSAtomicDequeue(&(pMeta->slot_LIFO), offsetof(struct chained_block_s, next)))) { if (0 == stoploss) { - nanozone_error(nanozone, 1, "Free list walk in count_free exceeded object count.", - (void *)&(pMeta->slot_LIFO), NULL); + nanozone_error(nanozone, 1, "Free list walk in count_free exceeded object count.", (void *)&(pMeta->slot_LIFO), NULL); } stoploss--; - if (NULL == head) + if (NULL == head) { head = t; - else + } else { tail->next = t; + } tail = t; count++; } - if (tail) + if (tail) { tail->next = NULL; + } // push the free list extracted above back onto the LIFO, all at once - if (head) - OSAtomicEnqueue( &(pMeta->slot_LIFO), head, (uintptr_t)tail - (uintptr_t)head + offsetof(struct chained_block_s,next)); + if (head) { + OSAtomicEnqueue(&(pMeta->slot_LIFO), head, (uintptr_t)tail - (uintptr_t)head + offsetof(struct chained_block_s, next)); + } return count; } @@ -1685,16 +1580,15 @@ count_free(nanozone_t *nanozone, nano_meta_admin_t pMeta) static void nano_print(nanozone_t *nanozone, boolean_t verbose) { - unsigned int mag_index, slot_key; + unsigned int mag_index, slot_key; malloc_statistics_t stats; nano_statistics(nanozone, &stats); - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "Nanozone %p: inUse=%d(%dKB) touched=%dKB allocated=%dMB\n", - nanozone, stats.blocks_in_use, stats.size_in_use>>10, stats.max_size_in_use>>10, stats.size_allocated>>20); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "Nanozone %p: inUse=%d(%dKB) touched=%dKB allocated=%dMB\n", + nanozone, stats.blocks_in_use, stats.size_in_use >> 10, stats.max_size_in_use >> 10, stats.size_allocated >> 20); for (mag_index = 0; mag_index < nanozone->phys_ncpus; mag_index++) { - nano_blk_addr_t p; + nano_blk_addr_t p; // Establish p as base address for band 0, slot 0, offset 0 p.fields.nano_signature = NANOZONE_SIGNATURE; @@ -1703,22 +1597,20 @@ nano_print(nanozone_t *nanozone, boolean_t verbose) p.fields.nano_slot = 0; p.fields.nano_offset = 0; - for (slot_key = 0; slot_key < SLOT_KEY_LIMIT; - p.addr += SLOT_IN_BAND_SIZE, // Advance to next slot base - slot_key++) { - + for (slot_key = 0; slot_key < SLOT_KEY_LIMIT; p.addr += SLOT_IN_BAND_SIZE, // Advance to next slot base + slot_key++) { nano_meta_admin_t pMeta = &(nanozone->meta_data[mag_index][slot_key]); - uintptr_t slot_bump_addr = pMeta->slot_bump_addr; // capture this volatile pointer + uintptr_t slot_bump_addr = pMeta->slot_bump_addr; // capture this volatile pointer size_t slot_objects_mapped = pMeta->slot_objects_mapped; // capture this volatile count if (0 == slot_objects_mapped) { // Nothing allocated in this magazine for this slot? - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "Magazine %2d(%3d) Unrealized\n",mag_index, (slot_key + 1) << SHIFT_NANO_QUANTUM); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "Magazine %2d(%3d) Unrealized\n", mag_index, + (slot_key + 1) << SHIFT_NANO_QUANTUM); continue; } uintptr_t offset = (0 == slot_bump_addr ? 0 : slot_bump_addr - p.addr); - unsigned blocks_touched = offset_to_index(nanozone, pMeta, offset) - pMeta->slot_objects_skipped; + unsigned blocks_touched = offset_to_index(nanozone, pMeta, offset) - (unsigned)pMeta->slot_objects_skipped; unsigned blocks_now_free = count_free(nanozone, pMeta); unsigned blocks_in_use = blocks_touched - blocks_now_free; @@ -1727,9 +1619,9 @@ nano_print(nanozone_t *nanozone, boolean_t verbose) size_t size_allocated = ((offset / BAND_SIZE) + 1) * SLOT_IN_BAND_SIZE; _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, - "Magazine %2d(%3d) [%p, %3dKB] \t Allocations in use=%4d \t Bytes in use=%db \t Untouched=%dKB\n", - mag_index, (slot_key + 1) << SHIFT_NANO_QUANTUM, p, - (size_allocated>>10), blocks_in_use, size_in_use, (size_allocated - size_hiwater)>>10); + "Magazine %2d(%3d) [%p, %3dKB] \t Allocations in use=%4d \t Bytes in use=%db \t Untouched=%dKB\n", mag_index, + (slot_key + 1) << SHIFT_NANO_QUANTUM, p, (size_allocated >> 10), blocks_in_use, size_in_use, + (size_allocated - size_hiwater) >> 10); if (!verbose) { continue; @@ -1744,58 +1636,65 @@ nano_print(nanozone_t *nanozone, boolean_t verbose) } chained_block_t head = NULL, tail = NULL, t; - unsigned stoploss = slot_objects_mapped; - while ((t = OSAtomicDequeue( &(pMeta->slot_LIFO), offsetof(struct chained_block_s,next)))) { + unsigned stoploss = (unsigned)slot_objects_mapped; + while ((t = OSAtomicDequeue(&(pMeta->slot_LIFO), offsetof(struct chained_block_s, next)))) { if (0 == stoploss) { malloc_printf("Free list walk in nano_print exceeded object count."); break; } stoploss--; - uintptr_t offset = ((uintptr_t)t - p.addr); // offset from beginning of slot - index_t block_index = offset_to_index(nanozone, pMeta, offset); + uintptr_t offset = ((uintptr_t)t - p.addr); // offset from beginning of slot + index_t block_index = offset_to_index(nanozone, pMeta, offset); - if (NULL == head) + if (NULL == head) { head = t; - else + } else { tail->next = t; + } tail = t; - if (block_index < slot_objects_mapped) + if (block_index < slot_objects_mapped) { bitarray_set(slot_bitarray, log_size, block_index); + } } - if (tail) + if (tail) { tail->next = NULL; + } index_t i; - for (i = 0; i < slot_objects_mapped; ++i) { + for (i = 0; i < slot_objects_mapped; ++i) { nano_blk_addr_t q; size_t pgnum; uintptr_t block_offset = index_to_offset(nanozone, pMeta, i); - if (p.addr + block_offset >= slot_bump_addr) + if (p.addr + block_offset >= slot_bump_addr) { break; + } q.addr = p.addr + block_offset; - pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> vm_page_shift; + pgnum = ((((unsigned)q.fields.nano_band) << NANO_OFFSET_BITS) | ((unsigned)q.fields.nano_offset)) >> + vm_kernel_page_shift; if (i < pMeta->slot_objects_skipped) { - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,"_"); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "_"); } else if (bitarray_get(slot_bitarray, log_size, i)) { - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,"F"); - } else if (pMeta->slot_madvised_pages && (pgnum < ( 1 << pMeta->slot_madvised_log_page_count)) && - bitarray_get(pMeta->slot_madvised_pages, pMeta->slot_madvised_log_page_count, pgnum)) { - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,"M"); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "F"); + } else if (pMeta->slot_madvised_pages && (pgnum < (1 << pMeta->slot_madvised_log_page_count)) && + bitarray_get(pMeta->slot_madvised_pages, pMeta->slot_madvised_log_page_count, (index_t)pgnum)) { + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "M"); } else { - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,"."); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "."); } } - _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,"\n"); + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "\n"); free(slot_bitarray); // push the free list extracted above back onto the LIFO, all at once - if (head) - OSAtomicEnqueue( &(pMeta->slot_LIFO), head, (uintptr_t)tail - (uintptr_t)head + offsetof(struct chained_block_s,next)); + if (head) { + OSAtomicEnqueue( + &(pMeta->slot_LIFO), head, (uintptr_t)tail - (uintptr_t)head + offsetof(struct chained_block_s, next)); + } } } } @@ -1813,7 +1712,7 @@ nano_force_lock(nanozone_t *nanozone) int i; for (i = 0; i < nanozone->phys_ncpus; ++i) { - _malloc_lock_lock(&nanozone->band_resupply_lock[i]); + _malloc_lock_lock(&nanozone->band_resupply_lock[i]); } } @@ -1823,19 +1722,29 @@ nano_force_unlock(nanozone_t *nanozone) int i; for (i = 0; i < nanozone->phys_ncpus; ++i) { - _malloc_lock_unlock(&nanozone->band_resupply_lock[i]); + _malloc_lock_unlock(&nanozone->band_resupply_lock[i]); + } +} + +static void +nano_reinit_lock(nanozone_t *nanozone) +{ + int i; + + for (i = 0; i < nanozone->phys_ncpus; ++i) { + _malloc_lock_init(&nanozone->band_resupply_lock[i]); } } static void nano_statistics(nanozone_t *nanozone, malloc_statistics_t *stats) { - int i,j; + int i, j; bzero(stats, sizeof(*stats)); for (i = 0; i < nanozone->phys_ncpus; ++i) { - nano_blk_addr_t p; + nano_blk_addr_t p; // Establish p as base address for slot 0 in this CPU magazine p.fields.nano_signature = NANOZONE_SIGNATURE; @@ -1844,16 +1753,15 @@ nano_statistics(nanozone_t *nanozone, malloc_statistics_t *stats) p.fields.nano_slot = 0; p.fields.nano_offset = 0; - for (j = 0; j < NANO_SLOT_SIZE; - p.addr += SLOT_IN_BAND_SIZE, // Advance to next slot base - ++j) { + for (j = 0; j < NANO_SLOT_SIZE; p.addr += SLOT_IN_BAND_SIZE, // Advance to next slot base + ++j) { nano_meta_admin_t pMeta = &nanozone->meta_data[i][j]; uintptr_t offset = pMeta->slot_bump_addr - p.addr; if (0 == pMeta->slot_current_base_addr) { // Nothing allocated in this magazine for this slot? continue; } else { - unsigned blocks_touched = offset_to_index(nanozone, pMeta, offset) - pMeta->slot_objects_skipped; + unsigned blocks_touched = offset_to_index(nanozone, pMeta, offset) - (unsigned)pMeta->slot_objects_skipped; unsigned blocks_now_free = count_free(nanozone, pMeta); unsigned blocks_in_use = blocks_touched - blocks_now_free; @@ -1877,10 +1785,10 @@ _nano_locked(nanozone_t *nanozone) int i; for (i = 0; i < nanozone->phys_ncpus; ++i) { - if (_malloc_lock_trylock(&nanozone->band_resupply_lock[i])) { - _malloc_lock_unlock(&nanozone->band_resupply_lock[i]); - return TRUE; - } + if (_malloc_lock_trylock(&nanozone->band_resupply_lock[i])) { + _malloc_lock_unlock(&nanozone->band_resupply_lock[i]); + return TRUE; + } } return FALSE; } @@ -1894,19 +1802,12 @@ nano_locked(nanozone_t *nanozone) } static const struct malloc_introspection_t nano_introspect = { - (void *)nano_ptr_in_use_enumerator, - (void *)nano_good_size, - (void *)nanozone_check, - (void *)nano_print, - nano_log, - (void *)nano_force_lock, - (void *)nano_force_unlock, - (void *)nano_statistics, - (void *)nano_locked, - NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */ + (void *)nano_ptr_in_use_enumerator, (void *)nano_good_size, (void *)nanozone_check, (void *)nano_print, nano_log, + (void *)nano_force_lock, (void *)nano_force_unlock, (void *)nano_statistics, (void *)nano_locked, NULL, NULL, NULL, + NULL, /* Zone enumeration version 7 and forward. */ + (void *)nano_reinit_lock, // reinit_lock version 9 and foward }; // marked as const to spare the DATA section -__attribute__((visibility("hidden"))) void nano_forked_zone(nanozone_t *nanozone) { @@ -1930,122 +1831,121 @@ nano_forked_zone(nanozone_t *nanozone) nanozone->basic_zone.batch_malloc = (void *)nano_forked_batch_malloc; nanozone->basic_zone.batch_free = (void *)nano_forked_batch_free; nanozone->basic_zone.introspect = (struct malloc_introspection_t *)&nano_introspect; /* Unchanged. */ - nanozone->basic_zone.memalign = (void *)nano_memalign; /* Unchanged. */ + nanozone->basic_zone.memalign = (void *)nano_memalign; /* Unchanged. */ nanozone->basic_zone.free_definite_size = (void *)nano_forked_free_definite_size; mprotect(nanozone, sizeof(nanozone->basic_zone), PROT_READ); - } -__attribute__((visibility("hidden"))) malloc_zone_t * create_nano_zone(size_t initial_size, malloc_zone_t *helper_zone, unsigned debug_flags) { - nanozone_t *nanozone; + nanozone_t *nanozone; int i, j; - if (!_malloc_engaged_nano) return NULL; + if (!_malloc_engaged_nano) { + return NULL; + } #if defined(__x86_64__) if (_COMM_PAGE_VERSION_REQD > (*((uint16_t *)_COMM_PAGE_VERSION))) { - malloc_printf("*** FATAL ERROR - comm page version mismatch.\n"); - exit(-1); + MALLOC_PRINTF_FATAL_ERROR((*((uint16_t *)_COMM_PAGE_VERSION)), "comm page version mismatch"); } #endif /* get memory for the zone. */ - nanozone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC); - if (!nanozone) + nanozone = nano_allocate_pages(NULL, NANOZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC); + if (!nanozone) { return NULL; + } /* set up the basic_zone portion of the nanozone structure */ - nanozone->basic_zone.version = 8; + nanozone->basic_zone.version = 9; nanozone->basic_zone.size = (void *)nano_size; - nanozone->basic_zone.malloc = (debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) ? (void *)nano_malloc_scribble : (void *)nano_malloc; + nanozone->basic_zone.malloc = (debug_flags & MALLOC_DO_SCRIBBLE) ? (void *)nano_malloc_scribble : (void *)nano_malloc; nanozone->basic_zone.calloc = (void *)nano_calloc; nanozone->basic_zone.valloc = (void *)nano_valloc; - nanozone->basic_zone.free = (debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) ? (void *)nano_free_scribble : (void *)nano_free; + nanozone->basic_zone.free = (debug_flags & MALLOC_DO_SCRIBBLE) ? (void *)nano_free_scribble : (void *)nano_free; nanozone->basic_zone.realloc = (void *)nano_realloc; nanozone->basic_zone.destroy = (void *)nano_destroy; nanozone->basic_zone.batch_malloc = (void *)nano_batch_malloc; nanozone->basic_zone.batch_free = (void *)nano_batch_free; nanozone->basic_zone.introspect = (struct malloc_introspection_t *)&nano_introspect; nanozone->basic_zone.memalign = (void *)nano_memalign; - nanozone->basic_zone.free_definite_size = (debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) ? - (void *)nano_free_definite_size_scribble : (void *)nano_free_definite_size; - + nanozone->basic_zone.free_definite_size = (debug_flags & MALLOC_DO_SCRIBBLE) ? (void *)nano_free_definite_size_scribble + : (void *)nano_free_definite_size; + nanozone->basic_zone.pressure_relief = (void *)nano_pressure_relief; - + nanozone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */ nanozone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */ - + mprotect(nanozone, sizeof(nanozone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */ - + /* set up the remainder of the nanozone structure */ nanozone->debug_flags = debug_flags; nanozone->our_signature = NANOZONE_SIGNATURE; - - /* Query the number of configured processors. */ + +/* Query the number of configured processors. */ #if defined(__x86_64__) nanozone->phys_ncpus = *(uint8_t *)(uintptr_t)_COMM_PAGE_PHYSICAL_CPUS; nanozone->logical_ncpus = *(uint8_t *)(uintptr_t)_COMM_PAGE_LOGICAL_CPUS; #else #error Unknown architecture #endif - - if (nanozone->phys_ncpus > sizeof(nanozone->core_mapped_size)/sizeof(nanozone->core_mapped_size[0])) { + + if (nanozone->phys_ncpus > sizeof(nanozone->core_mapped_size) / sizeof(nanozone->core_mapped_size[0])) { _malloc_printf(ASL_LEVEL_NOTICE, "nano zone abandoned because NCPUS mismatch.\n"); return NULL; } - + if (0 != (nanozone->logical_ncpus % nanozone->phys_ncpus)) { - malloc_printf("*** FATAL ERROR - logical_ncpus % phys_ncpus != 0.\n"); - exit(-1); + MALLOC_PRINTF_FATAL_ERROR(nanozone->logical_ncpus % nanozone->phys_ncpus, "logical_ncpus % phys_ncpus != 0"); } - - switch (nanozone->logical_ncpus/nanozone->phys_ncpus) { - case 1: - nanozone->hyper_shift = 0; - break; - case 2: - nanozone->hyper_shift = 1; - break; - case 4: - nanozone->hyper_shift = 2; - break; - default: - malloc_printf("*** FATAL ERROR - logical_ncpus / phys_ncpus not 1, 2, or 4.\n"); - exit(-1); + + switch (nanozone->logical_ncpus / nanozone->phys_ncpus) { + case 1: + nanozone->hyper_shift = 0; + break; + case 2: + nanozone->hyper_shift = 1; + break; + case 4: + nanozone->hyper_shift = 2; + break; + default: + MALLOC_PRINTF_FATAL_ERROR(nanozone->logical_ncpus / nanozone->phys_ncpus, "logical_ncpus / phys_ncpus not 1, 2, or 4"); } - + /* Initialize slot queue heads and resupply locks. */ OSQueueHead q0 = OS_ATOMIC_QUEUE_INIT; for (i = 0; i < nanozone->phys_ncpus; ++i) { - _malloc_lock_init(&nanozone->band_resupply_lock[i]); - + _malloc_lock_init(&nanozone->band_resupply_lock[i]); + for (j = 0; j < NANO_SLOT_SIZE; ++j) { nanozone->meta_data[i][j].slot_LIFO = q0; } } - + /* Initialize the security token. */ - if (0 == _dyld_get_image_slide((const struct mach_header*)_NSGetMachExecuteHeader())) { + if (0 == _dyld_get_image_slide((const struct mach_header *)_NSGetMachExecuteHeader())) { // zero slide when ASLR has been disabled by boot-arg. Eliminate cloaking. malloc_entropy[0] = 0; malloc_entropy[1] = 0; } nanozone->cookie = (uintptr_t)malloc_entropy[0] & 0x0000ffffffff0000ULL; // scramble central 32bits with this cookie - - /* Nano zone does not support SCALABLE_MALLOC_ADD_GUARD_PAGES. */ - if (nanozone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) { + + /* Nano zone does not support MALLOC_ADD_GUARD_PAGES. */ + if (nanozone->debug_flags & MALLOC_ADD_GUARD_PAGES) { _malloc_printf(ASL_LEVEL_INFO, "nano zone does not support guard pages\n"); - nanozone->debug_flags &= ~SCALABLE_MALLOC_ADD_GUARD_PAGES; + nanozone->debug_flags &= ~MALLOC_ADD_GUARD_PAGES; } - + nanozone->helper_zone = helper_zone; - + return (malloc_zone_t *)nanozone; } -#endif /* defined(__LP64__) */ + +#endif // CONFIG_NANOZONE /* vim: set noet:ts=4:sw=4:cindent: */ diff --git a/src/libmalloc/src/nano_malloc.h b/src/libmalloc/src/nano_malloc.h new file mode 100644 index 000000000..36204abe6 --- /dev/null +++ b/src/libmalloc/src/nano_malloc.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __NANO_MALLOC_H +#define __NANO_MALLOC_H + +#define MALLOC_HELPER_ZONE_STRING "MallocHelperZone" + +// Forward decl for the nanozone. +typedef struct nanozone_s nanozone_t; + +// Nano malloc enabled flag +MALLOC_NOEXPORT +extern boolean_t _malloc_engaged_nano; + +MALLOC_NOEXPORT +malloc_zone_t * +create_nano_zone(size_t initial_size, malloc_zone_t *helper_zone, unsigned debug_flags); + +MALLOC_NOEXPORT +void +nano_forked_zone(nanozone_t *nanozone); + +#endif // __NANO_MALLOC_H diff --git a/src/libmalloc/src/nano_zone.h b/src/libmalloc/src/nano_zone.h new file mode 100644 index 000000000..758ef9ccc --- /dev/null +++ b/src/libmalloc/src/nano_zone.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#ifndef __NANO_ZONE_H +#define __NANO_ZONE_H + +#if CONFIG_NANOZONE + +/********************* DEFINITIONS ************************/ + +#define NANO_MAG_INDEX(nz) (_os_cpu_number() >> nz->hyper_shift) + +#define MAX_RECORDER_BUFFER 256 + +/************* nanozone address field layout ******************/ + +#if defined(__x86_64) +#define NANO_SIGNATURE_BITS 20 +#define NANOZONE_SIGNATURE 0x00006ULL // 0x00006nnnnnnnnnnn the address range devoted to us. +#define NANO_MAG_BITS 5 +#define NANO_BAND_BITS 18 +#define NANO_SLOT_BITS 4 +#define NANO_OFFSET_BITS 17 + +#else +#error Unknown Architecture +#endif + +// clang-format really dislikes the bitfields here +// clang-format off +#if defined(__BIG_ENDIAN__) +struct nano_blk_addr_s { + uint64_t + nano_signature:NANO_SIGNATURE_BITS, // 0x00006nnnnnnnnnnn the address range devoted to us. + nano_mag_index:NANO_MAG_BITS, // the core that allocated this block + nano_band:NANO_BAND_BITS, + nano_slot:NANO_SLOT_BITS, // bucket of homogenous quanta-multiple blocks + nano_offset:NANO_OFFSET_BITS; // locates the block +}; +#else +// least significant bits declared first +struct nano_blk_addr_s { + uint64_t + nano_offset:NANO_OFFSET_BITS, // locates the block + nano_slot:NANO_SLOT_BITS, // bucket of homogenous quanta-multiple blocks + nano_band:NANO_BAND_BITS, + nano_mag_index:NANO_MAG_BITS, // the core that allocated this block + nano_signature:NANO_SIGNATURE_BITS; // 0x00006nnnnnnnnnnn the address range devoted to us. +}; +#endif +// clang-format on + +typedef union { + uint64_t addr; + struct nano_blk_addr_s fields; +} nano_blk_addr_t; + +#define NANO_MAX_SIZE 256 /* Buckets sized {16, 32, 48, 64, 80, 96, 112, ...} */ +#define SHIFT_NANO_QUANTUM 4 +#define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM) // 16 +#define NANO_QUANTA_MASK 0xFULL // NANO_REGIME_QUANTA_SIZE - 1 + +#define SLOT_IN_BAND_SIZE (1 << NANO_OFFSET_BITS) +#define SLOT_KEY_LIMIT (1 << NANO_SLOT_BITS) /* Must track nano_slot width */ +#define BAND_SIZE (1 << (NANO_SLOT_BITS + NANO_OFFSET_BITS)) /* == Number of bytes covered by a page table entry */ +#define NANO_MAG_SIZE (1 << NANO_MAG_BITS) +#define NANO_SLOT_SIZE (1 << NANO_SLOT_BITS) + +/****************************** zone itself ***********************************/ + +/* + * Note that objects whose adddress are held in pointers here must be pursued + * individually in the nano_in_use_enumeration() routines. + */ + +typedef struct chained_block_s { + uintptr_t double_free_guard; + struct chained_block_s *next; +} *chained_block_t; + +typedef struct nano_meta_s { + OSQueueHead slot_LIFO MALLOC_NANO_CACHE_ALIGN; + unsigned int slot_madvised_log_page_count; + volatile uintptr_t slot_current_base_addr; + volatile uintptr_t slot_limit_addr; + volatile size_t slot_objects_mapped; + volatile size_t slot_objects_skipped; + bitarray_t slot_madvised_pages; + // position on cache line distinct from that of slot_LIFO + volatile uintptr_t slot_bump_addr MALLOC_NANO_CACHE_ALIGN; + volatile boolean_t slot_exhausted; + unsigned int slot_bytes; + unsigned int slot_objects; +} *nano_meta_admin_t; + +// vm_allocate()'d, so page-aligned to begin with. +typedef struct nanozone_s { + // first page will be given read-only protection + malloc_zone_t basic_zone; + uint8_t pad[PAGE_MAX_SIZE - sizeof(malloc_zone_t)]; + + // remainder of structure is R/W (contains no function pointers) + // page-aligned + // max: NANO_MAG_SIZE cores x NANO_SLOT_SIZE slots for nano blocks {16 .. 256} + struct nano_meta_s meta_data[NANO_MAG_SIZE][NANO_SLOT_SIZE]; + _malloc_lock_s band_resupply_lock[NANO_MAG_SIZE]; + uintptr_t band_max_mapped_baseaddr[NANO_MAG_SIZE]; + size_t core_mapped_size[NANO_MAG_SIZE]; + + unsigned debug_flags; + unsigned our_signature; + unsigned phys_ncpus; + unsigned logical_ncpus; + unsigned hyper_shift; + + /* security cookie */ + uintptr_t cookie; + + /* + * The nano zone constructed by create_nano_zone() would like to hand off tiny, small, and large + * allocations to the default scalable zone. Record the latter as the "helper" zone here. + */ + malloc_zone_t *helper_zone; +} nanozone_t; + +#define NANOZONE_PAGED_SIZE ((sizeof(nanozone_t) + vm_page_size - 1) & ~ (vm_page_size - 1)) + +#endif // CONFIG_NANOZONE + +#endif // __NANO_ZONE_H diff --git a/src/libmalloc/src/platform.h b/src/libmalloc/src/platform.h new file mode 100644 index 000000000..89dd1d539 --- /dev/null +++ b/src/libmalloc/src/platform.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __PLATFORM_H +#define __PLATFORM_H + +#if TARGET_OS_EMBEDDED +#define MALLOC_TARGET_IOS 1 +#else // MALLOC_TARGET_IOS +#define MALLOC_TARGET_IOS 0 +#endif // MALLOC_TARGET_IOS + +#ifdef __LP64__ +#define MALLOC_TARGET_64BIT 1 +#else // __LP64__ +#define MALLOC_TARGET_64BIT 0 +#endif + +// +#if MALLOC_TARGET_IOS +# define CONFIG_MADVISE_PRESSURE_RELIEF 0 +#else // MALLOC_TARGET_IOS +# define CONFIG_MADVISE_PRESSURE_RELIEF 1 +#endif // MALLOC_TARGET_IOS + +// +#if MALLOC_TARGET_IOS +# define CONFIG_RECIRC_DEPOT 0 +# define CONFIG_AGGRESSIVE_MADVISE 1 +#else // MALLOC_TARGET_IOS +# define CONFIG_RECIRC_DEPOT 1 +# define CONFIG_AGGRESSIVE_MADVISE 0 +#endif // MALLOC_TARGET_IOS + +// +#define CONFIG_RELAXED_INVARIANT_CHECKS 1 + +// +#define CONFIG_MADVISE_STYLE MADV_FREE_REUSABLE + +// +#if TARGET_OS_SIMULATOR +#define CONFIG_OS_LOCK_HANDOFF 1 +#elif MALLOC_TARGET_IOS +#define CONFIG_OS_LOCK_UNFAIR 1 +#else // MALLOC_TARGET_IOS +#define CONFIG_OS_LOCK_UNFAIR 1 +#endif // MALLOC_TARGET_IOS + +#if MALLOC_TARGET_64BIT +#define CONFIG_NANOZONE 0 // disable, because it uses atomic queues, which require PFZ +#define CONFIG_ASLR_INTERNAL 0 +#else // MALLOC_TARGET_64BIT +#define CONFIG_NANOZONE 0 +#define CONFIG_ASLR_INTERNAL 1 +#endif // MALLOC_TARGET_64BIT + +// enable nano checking for corrupt free list +#define NANO_FREE_DEQUEUE_DILIGENCE 1 + +// This governs a last-free cache of 1 that bypasses the free-list for each region size +#define CONFIG_TINY_CACHE 1 +#define CONFIG_SMALL_CACHE 1 + +// The large last-free cache (aka. death row cache) +#if MALLOC_TARGET_IOS +#define CONFIG_LARGE_CACHE 0 +#else +#define CONFIG_LARGE_CACHE 1 +#endif + +// compile-time MALLOC_SMALL cut-off size +#if MALLOC_TARGET_IOS +#define CONFIG_SMALL_CUTTOFF_127KB 0 +#else +#define CONFIG_SMALL_CUTTOFF_127KB 1 +#endif // MALLOC_TARGET_IOS + +// memory resource exception handling +#if MALLOC_TARGET_IOS || TARGET_OS_SIMULATOR +#define ENABLE_MEMORY_RESOURCE_EXCEPTION_HANDLING 0 +#else +#define ENABLE_MEMORY_RESOURCE_EXCEPTION_HANDLING 1 +#endif + +// presence of commpage memsize +#define CONFIG_HAS_COMMPAGE_MEMSIZE 1 + +#endif // __PLATFORM_H diff --git a/src/libmalloc/src/printf.h b/src/libmalloc/src/printf.h new file mode 100644 index 000000000..ce631ca98 --- /dev/null +++ b/src/libmalloc/src/printf.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +extern void malloc_printf(const char *fmt, ...); + +#define MALLOC_PRINTF_LEVEL_MASK 0x0f +#define MALLOC_PRINTF_NOLOG 0x10 +#define MALLOC_PRINTF_NOPREFIX 0x20 + +extern void _malloc_printf(int flags, const char *fmt, ...); +extern void _malloc_vprintf(int flags, const char *fmt, va_list ap); diff --git a/src/libmalloc/src/purgeable_malloc.c b/src/libmalloc/src/purgeable_malloc.c new file mode 100644 index 000000000..9829079e4 --- /dev/null +++ b/src/libmalloc/src/purgeable_malloc.c @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#include "internal.h" + +// +// purgeable zones have their own "large" allocation pool, but share "tiny" and "large" +// heaps with a helper_zone identified in the call to create_purgeable_zone() +// +static size_t +purgeable_size(szone_t *szone, const void *ptr) +{ + // Only claim our large allocations, leave the shared tiny/small for the helper zone to claim. + return szone_size_try_large(szone, ptr); +} + +static void * +purgeable_malloc(szone_t *szone, size_t size) +{ + if (size <= szone->large_threshold) { + return szone_malloc(szone->helper_zone, size); + } else { + return szone_malloc(szone, size); + } +} + +static void * +purgeable_calloc(szone_t *szone, size_t num_items, size_t size) +{ + size_t total_bytes = num_items * size; + + // Check for overflow of integer multiplication + if (num_items > 1) { +#if __LP64__ /* size_t is uint64_t */ + if ((num_items | size) & 0xffffffff00000000ul) { + // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic + __uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size); + if ((uint64_t)(product >> 64)) { // compiles to test on upper register of register pair + return NULL; + } + } +#else /* size_t is uint32_t */ + if ((num_items | size) & 0xffff0000ul) { + // num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic + uint64_t product = ((uint64_t)num_items) * ((uint64_t)size); + if ((uint32_t)(product >> 32)) { // compiles to test on upper register of register pair + return NULL; + } + } +#endif + } + + if (total_bytes <= szone->large_threshold) { + return szone_calloc(szone->helper_zone, 1, total_bytes); + } else { + return szone_calloc(szone, 1, total_bytes); + } +} + +static void * +purgeable_valloc(szone_t *szone, size_t size) +{ + if (size <= szone->large_threshold) { + return szone_valloc(szone->helper_zone, size); + } else { + return szone_valloc(szone, size); + } +} + +static void +purgeable_free(szone_t *szone, void *ptr) +{ + large_entry_t *entry; + + SZONE_LOCK(szone); + entry = large_entry_for_pointer_no_lock(szone, ptr); + SZONE_UNLOCK(szone); + if (entry) { + return free_large(szone, ptr); + } else { + return szone_free(szone->helper_zone, ptr); + } +} + +static void +purgeable_free_definite_size(szone_t *szone, void *ptr, size_t size) +{ + if (size <= szone->large_threshold) { + return szone_free_definite_size(szone->helper_zone, ptr, size); + } else { + return szone_free_definite_size(szone, ptr, size); + } +} + +static void * +purgeable_realloc(szone_t *szone, void *ptr, size_t new_size) +{ + size_t old_size; + + if (NULL == ptr) { + // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size. + return purgeable_malloc(szone, new_size); + } else if (0 == new_size) { + // If size is 0 and ptr is not a null pointer, the object pointed to is freed. + purgeable_free(szone, ptr); + // If size is 0, either a null pointer or a unique pointer that can be successfully passed + // to free() shall be returned. + return purgeable_malloc(szone, 1); + } + + old_size = purgeable_size(szone, ptr); // Now ptr can be safely size()'d + if (!old_size) { + old_size = szone_size(szone->helper_zone, ptr); + } + + if (!old_size) { + szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL); + return NULL; + } + + // Distinguish 4 cases: {oldsize, newsize} x { <= , > large_threshold } + // and deal with the allocation crossing from the purgeable zone to the helper zone and vice versa. + if (old_size <= szone->large_threshold) { + if (new_size <= szone->large_threshold) { + return szone_realloc(szone->helper_zone, ptr, new_size); + } else { + // allocation crosses from helper to purgeable zone + void *new_ptr = purgeable_malloc(szone, new_size); + if (new_ptr) { + memcpy(new_ptr, ptr, old_size); + szone_free_definite_size(szone->helper_zone, ptr, old_size); + } + return new_ptr; // in state VM_PURGABLE_NONVOLATILE + } + } else { + if (new_size <= szone->large_threshold) { + // allocation crosses from purgeable to helper zone + void *new_ptr = szone_malloc(szone->helper_zone, new_size); + if (new_ptr) { + memcpy(new_ptr, ptr, new_size); + purgeable_free_definite_size(szone, ptr, old_size); + } + return new_ptr; + } else { + void *new_ptr = purgeable_malloc(szone, new_size); + if (new_ptr) { + memcpy(new_ptr, ptr, MIN(old_size, new_size)); + purgeable_free_definite_size(szone, ptr, old_size); + } + return new_ptr; // in state VM_PURGABLE_NONVOLATILE + } + } + /* NOTREACHED */ +} + +static void +purgeable_destroy(szone_t *szone) +{ + /* destroy large entries */ + size_t index = szone->num_large_entries; + large_entry_t *large; + vm_range_t range_to_deallocate; + + while (index--) { + large = szone->large_entries + index; + if (large->address) { + // we deallocate_pages, including guard pages + deallocate_pages(szone, (void *)(large->address), large->size, szone->debug_flags); + } + } + large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate); + if (range_to_deallocate.size) { + deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0); + } + + /* Now destroy the separate szone region */ + deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0); +} + +static unsigned +purgeable_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) +{ + return szone_batch_malloc(szone->helper_zone, size, results, count); +} + +static void +purgeable_batch_free(szone_t *szone, void **to_be_freed, unsigned count) +{ + return szone_batch_free(szone->helper_zone, to_be_freed, count); +} + +static void * +purgeable_memalign(szone_t *szone, size_t alignment, size_t size) +{ + if (size <= szone->large_threshold) { + return szone_memalign(szone->helper_zone, alignment, size); + } else { + return szone_memalign(szone, alignment, size); + } +} + +static kern_return_t +purgeable_ptr_in_use_enumerator(task_t task, + void *context, + unsigned type_mask, + vm_address_t zone_address, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + szone_t *szone; + kern_return_t err; + + if (!reader) { + reader = _szone_default_reader; + } + + err = reader(task, zone_address, sizeof(szone_t), (void **)&szone); + if (err) { + return err; + } + + err = large_in_use_enumerator( + task, context, type_mask, (vm_address_t)szone->large_entries, szone->num_large_entries, reader, recorder); + return err; +} + +static size_t +purgeable_good_size(szone_t *szone, size_t size) +{ + if (size <= szone->large_threshold) { + return szone_good_size(szone->helper_zone, size); + } else { + return szone_good_size(szone, size); + } +} + +static boolean_t +purgeable_check(szone_t *szone) +{ + return 1; +} + +static void +purgeable_print(szone_t *szone, boolean_t verbose) +{ + _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "Scalable zone %p: inUse=%u(%y) flags=%d\n", szone, + szone->num_large_objects_in_use, szone->num_bytes_in_large_objects, szone->debug_flags); +} + +static void +purgeable_log(malloc_zone_t *zone, void *log_address) +{ + szone_t *szone = (szone_t *)zone; + + szone->log_address = log_address; +} + +static void +purgeable_force_lock(szone_t *szone) +{ + SZONE_LOCK(szone); +} + +static void +purgeable_force_unlock(szone_t *szone) +{ + SZONE_UNLOCK(szone); +} + +static void +purgeable_reinit_lock(szone_t *szone) +{ + SZONE_REINIT_LOCK(szone); +} + +static void +purgeable_statistics(szone_t *szone, malloc_statistics_t *stats) +{ + stats->blocks_in_use = szone->num_large_objects_in_use; + stats->size_in_use = stats->max_size_in_use = stats->size_allocated = szone->num_bytes_in_large_objects; +} + +static boolean_t +purgeable_locked(szone_t *szone) +{ + int tookLock; + + tookLock = SZONE_TRY_LOCK(szone); + if (tookLock == 0) { + return 1; + } + SZONE_UNLOCK(szone); + return 0; +} + +static size_t +purgeable_pressure_relief(szone_t *szone, size_t goal) +{ + return szone_pressure_relief(szone, goal) + szone_pressure_relief(szone->helper_zone, goal); +} + +static const struct malloc_introspection_t purgeable_introspect = { + (void *)purgeable_ptr_in_use_enumerator, (void *)purgeable_good_size, (void *)purgeable_check, (void *)purgeable_print, + purgeable_log, (void *)purgeable_force_lock, (void *)purgeable_force_unlock, (void *)purgeable_statistics, + (void *)purgeable_locked, NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */ + (void *)purgeable_reinit_lock, // reinit_lock version 9 and foward +}; // marked as const to spare the DATA section + +malloc_zone_t * +create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags) +{ + szone_t *szone; + uint64_t hw_memsize = 0; + + /* get memory for the zone. */ + szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC); + if (!szone) { + return NULL; + } + + /* set up the szone structure */ +#if 0 +#warning LOG enabled + szone->log_address = ~0; +#endif + +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__) + hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE; +#else + size_t uint64_t_size = sizeof(hw_memsize); + + sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0); +#endif + + szone->trg[0].nextgen = &(szone->trg[1]); + szone->trg[1].nextgen = &(szone->trg[0]); + szone->tiny_region_generation = &(szone->trg[0]); + + szone->tiny_region_generation->hashed_regions = szone->initial_tiny_regions; + szone->tiny_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS; + szone->tiny_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT; + + szone->srg[0].nextgen = &(szone->srg[1]); + szone->srg[1].nextgen = &(szone->srg[0]); + szone->small_region_generation = &(szone->srg[0]); + + szone->small_region_generation->hashed_regions = szone->initial_small_regions; + szone->small_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS; + szone->small_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT; + + /* Purgeable zone does not participate in the adaptive "largemem" sizing. */ + szone->is_largemem = 0; + szone->large_threshold = LARGE_THRESHOLD; + szone->vm_copy_threshold = VM_COPY_THRESHOLD; + +#if CONFIG_LARGE_CACHE + szone->large_entry_cache_reserve_limit = + hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%] + + /* Reset protection when returning a previous large allocation? */ + int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System"); + if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 112) /* CFSystemVersionSnowLeopard */) { + szone->large_legacy_reset_mprotect = TRUE; + } else { + szone->large_legacy_reset_mprotect = FALSE; + } +#endif + + szone->basic_zone.version = 9; + szone->basic_zone.size = (void *)purgeable_size; + szone->basic_zone.malloc = (void *)purgeable_malloc; + szone->basic_zone.calloc = (void *)purgeable_calloc; + szone->basic_zone.valloc = (void *)purgeable_valloc; + szone->basic_zone.free = (void *)purgeable_free; + szone->basic_zone.realloc = (void *)purgeable_realloc; + szone->basic_zone.destroy = (void *)purgeable_destroy; + szone->basic_zone.batch_malloc = (void *)purgeable_batch_malloc; + szone->basic_zone.batch_free = (void *)purgeable_batch_free; + szone->basic_zone.introspect = (struct malloc_introspection_t *)&purgeable_introspect; + szone->basic_zone.memalign = (void *)purgeable_memalign; + szone->basic_zone.free_definite_size = (void *)purgeable_free_definite_size; + szone->basic_zone.pressure_relief = (void *)purgeable_pressure_relief; + + szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */ + szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */ + mprotect(szone, sizeof(szone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */ + + szone->debug_flags = debug_flags | MALLOC_PURGEABLE; + + /* Purgeable zone does not support MALLOC_ADD_GUARD_PAGES. */ + if (szone->debug_flags & MALLOC_ADD_GUARD_PAGES) { + _malloc_printf(ASL_LEVEL_INFO, "purgeable zone does not support guard pages\n"); + szone->debug_flags &= ~MALLOC_ADD_GUARD_PAGES; + } + + _malloc_lock_init(&szone->large_szone_lock); + + szone->helper_zone = (struct szone_s *)malloc_default_zone; + + CHECK(szone, __PRETTY_FUNCTION__); + return (malloc_zone_t *)szone; +} diff --git a/src/libmalloc/src/purgeable_malloc.h b/src/libmalloc/src/purgeable_malloc.h new file mode 100644 index 000000000..20e6705ff --- /dev/null +++ b/src/libmalloc/src/purgeable_malloc.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __PURGEABLE_MALLOC_H +#define __PURGEABLE_MALLOC_H + +/* Create a new zone that supports malloc_make{un}purgeable() discipline. */ +MALLOC_NOEXPORT +malloc_zone_t * +create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags); + +#endif // __PURGEABLE_MALLOC_H diff --git a/src/libmalloc/src/scalable_malloc.h b/src/libmalloc/src/scalable_malloc.h deleted file mode 100644 index d6cf189cf..000000000 --- a/src/libmalloc/src/scalable_malloc.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#define SCALABLE_MALLOC_ADD_GUARD_PAGES (1 << 0) - // add a guard page before and after each VM region to help debug -#define SCALABLE_MALLOC_DONT_PROTECT_PRELUDE (1 << 1) - // do not protect prelude page -#define SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE (1 << 2) - // do not protect postlude page -#define SCALABLE_MALLOC_DO_SCRIBBLE (1 << 3) - // write 0x55 onto free blocks -#define SCALABLE_MALLOC_ABORT_ON_ERROR (1 << 4) - // call abort() on any malloc error, such as double free or out of memory. -#define SCALABLE_MALLOC_PURGEABLE (1 << 5) - // allocate objects such that they may be used with VM purgability APIs -#define SCALABLE_MALLOC_ABORT_ON_CORRUPTION (1 << 6) - // call abort() on malloc errors, but not on out of memory. - -extern malloc_zone_t *create_scalable_zone(size_t initial_size, unsigned debug_flags); - /* Create a new zone that scales for small objects or large objects */ - -extern malloc_zone_t *create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags); - /* Create a new zone that supports malloc_make{un}purgeable() discipline. */ - -extern malloc_zone_t *create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags); - /* - * For use by CheckFix: create a new zone whose behavior is, apart from - * the use of death-row and per-CPU magazines, that of Leopard. - */ - -/***** Private API for debug and performance tools ********/ - -extern boolean_t scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone); - /* Fills stats with some statistics; - 1 is returned on success; else 0 is returned - Currently: subzone=0 => tiny; subzone=1 => small; subzone=2 => large; subzone=3 => huge; any other subzone => returns 0 - */ - diff --git a/src/libmalloc/src/stack_logging.c b/src/libmalloc/src/stack_logging.c deleted file mode 100644 index bc73758be..000000000 --- a/src/libmalloc/src/stack_logging.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (c) 1999, 2000, 2002-2008 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* Bertrand from vmutils -> CF -> System */ - -#include "malloc.h" -#include "malloc_printf.h" -#include "malloc_internal.h" -#include "stack_logging.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -extern void thread_stack_pcs(vm_address_t *, unsigned, unsigned *); - -static inline void *allocate_pages(unsigned) __attribute__((always_inline)); -static inline void *allocate_pages(unsigned bytes) { - void *address; - if (vm_allocate(mach_task_self(), (vm_address_t *)&address, bytes, - VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)| TRUE)) { - malloc_printf("*** out of memory while stack logging\n"); - CRSetCrashLogMessage("*** out of memory while stack logging\n"); - abort(); - } - return (void *)address; -} - -static inline void deallocate_pages(void *, unsigned) __attribute__((always_inline)); -static inline void deallocate_pages(void *ptr, unsigned bytes) { - vm_deallocate(mach_task_self(), (vm_address_t)ptr, bytes); -} - -static inline void copy_pages(const void *, void *, unsigned) __attribute__((always_inline)); -static inline void copy_pages(const void *source, void *dest, unsigned bytes) { - if (vm_copy(mach_task_self(), (vm_address_t)source, bytes, (vm_address_t)dest)) memmove(dest, source, bytes); -} - -/*************** Uniquing stack ***********/ - -#define MAX_COLLIDE 8 - -#define MAX_NUM_PC 512 - -static int enter_pair_in_table(unsigned *table, unsigned numPages, unsigned *uniquedParent, unsigned thisPC) { - // uniquedParent is in-out; return 1 is collisions max not exceeded - unsigned base = numPages * vm_page_size / (sizeof(int)*2*2); - unsigned hash = base + (((*uniquedParent) << 4) ^ (thisPC >> 2)) % (base - 1); // modulo odd number for hashing - unsigned collisions = MAX_COLLIDE; - while (collisions--) { - unsigned *head = table + hash*2; - if (! head[0] && !head[1]) { - /* end of chain; store this entry! */ - /* Note that we need to test for both head[0] and head[1] as (0, -1) is a valid entry */ - head[0] = thisPC; - head[1] = *uniquedParent; - *uniquedParent = hash; - return 1; - } - if ((head[0] == thisPC) && (head[1] == *uniquedParent)) { - /* we found the proper entry, the value for the pair is the entry offset */ - *uniquedParent = hash; - return 1; - } - hash++; - if (hash == base*2) hash = base; - } - return 0; -} - -static unsigned -stack_logging_get_unique_stack(unsigned **table, unsigned *table_num_pages, unsigned *stack_entries, unsigned count, unsigned num_hot_to_skip) { - unsigned uniquedParent = (unsigned)-1; - // we skip the warmest entries that are an artefact of the code - while (num_hot_to_skip--) { - if (count > 0) { stack_entries++; count--; } - } - while (count--) { - unsigned thisPC = stack_entries[count]; - while (!enter_pair_in_table(*table, *table_num_pages, &uniquedParent, thisPC)) { - unsigned *newTable; - unsigned oldBytes = (*table_num_pages) * vm_page_size; - newTable = allocate_pages(oldBytes*2); - copy_pages(*table, newTable, oldBytes); - deallocate_pages(*table, oldBytes); - *table_num_pages *= 2; - *table = newTable; - } - } - return uniquedParent; -} - -/*************** Logging stack and arguments ***********/ - -stack_logging_record_list_t *stack_logging_the_record_list = NULL; - -int stack_logging_enable_logging = 0; -int stack_logging_dontcompact = 0; -int stack_logging_finished_init = 0; -int stack_logging_postponed = 0; - -static _malloc_lock_s stack_logging_spin_lock = _MALLOC_LOCK_INIT; - -static stack_logging_record_list_t *GrowLogRecords(stack_logging_record_list_t *records, unsigned desiredNumRecords) { - stack_logging_record_list_t *new_records; - unsigned old_size = records->overall_num_bytes; - if (desiredNumRecords*sizeof(stack_logging_record_t)+sizeof(stack_logging_record_list_t) < records->overall_num_bytes) return records; - records->overall_num_bytes += records->overall_num_bytes + vm_page_size; // in order to always get an even number of pages - new_records = allocate_pages(records->overall_num_bytes); - copy_pages(records, new_records, old_size); - deallocate_pages(records, old_size); - return new_records; -} - -static void prepare_to_log_stack(void) { - if (!stack_logging_the_record_list) { - unsigned totalSize = 4 * vm_page_size; - stack_logging_the_record_list = allocate_pages(totalSize); - memset(stack_logging_the_record_list, 0, sizeof(stack_logging_record_list_t)); - stack_logging_the_record_list->overall_num_bytes = totalSize; - stack_logging_the_record_list->uniquing_table_num_pages = 128; - stack_logging_the_record_list->uniquing_table = allocate_pages(stack_logging_the_record_list->uniquing_table_num_pages * vm_page_size); - } -} - -void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_to_skip) { - stack_logging_record_t *rec; - if (!stack_logging_enable_logging) return; - // printf("stack_logging_log_stack 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result); - if (type & stack_logging_flag_zone) { - // just process it now and be done with it! - arg1 = arg2; arg2 = arg3; arg3 = 0; type &= ~stack_logging_flag_zone; - } - if (type == (stack_logging_type_dealloc|stack_logging_type_alloc)) { - if (arg1 == result) return; // realloc had no effect, skipping - if (!arg1) { - // realloc(NULL, size) same as malloc(size) - type = stack_logging_type_alloc; arg1 = arg2; arg2 = arg3; arg3 = 0; - } else { - // realloc(arg1, arg2) -> result is same as free(arg1); malloc(arg2) -> result - stack_logging_log_stack(stack_logging_type_dealloc, arg1, 0, 0, 0, num_hot_to_skip+1); - stack_logging_log_stack(stack_logging_type_alloc, arg2, 0, 0, result, num_hot_to_skip+1); - return; - } - } - if (type == stack_logging_type_dealloc) { - // simple free - if (!arg1) return; // free(nil) - } - prepare_to_log_stack(); - _malloc_lock_lock(&stack_logging_spin_lock); - stack_logging_the_record_list = GrowLogRecords(stack_logging_the_record_list, stack_logging_the_record_list->num_records + 1); - rec = stack_logging_the_record_list->records + stack_logging_the_record_list->num_records; - // We take care of the common case of alloc-dealloc - if (!stack_logging_dontcompact && stack_logging_the_record_list->num_records && (type == stack_logging_type_dealloc) && arg1 && ((rec-1)->type == stack_logging_type_alloc) && (arg1 == STACK_LOGGING_DISGUISE((rec-1)->address))) { - stack_logging_the_record_list->num_records--; - // printf("Erased previous record in alloc-dealloc sequence\n"); - } else { - unsigned stack_entries[MAX_NUM_PC]; - unsigned count = 0; - rec->type = type; - if (type == stack_logging_type_dealloc) { - rec->argument = 0; - rec->address = STACK_LOGGING_DISGUISE(arg1); // we disguise the address - } else if (type == stack_logging_type_alloc) { - rec->argument = arg1; - rec->address = STACK_LOGGING_DISGUISE(result); // we disguise the address - } else { - rec->argument = arg2; - rec->address = STACK_LOGGING_DISGUISE(arg1); // we disguise the address - } - // printf("Before getting samples 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result); - thread_stack_pcs((vm_address_t *)stack_entries, MAX_NUM_PC - 1, &count); - // We put at the bottom of the stack a marker that denotes the thread (+1 for good measure...) - stack_entries[count++] = (int)(uintptr_t)_os_tsd_get_direct(__TSD_THREAD_SELF) + 1; - /* now let's unique the sample */ - // printf("Uniquing 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result); - rec->uniqued_stack = stack_logging_get_unique_stack(&stack_logging_the_record_list->uniquing_table, &stack_logging_the_record_list->uniquing_table_num_pages, stack_entries, count, num_hot_to_skip+2); // we additionally skip the warmest 2 entries that are an artefact of the code - stack_logging_the_record_list->num_records++; - } - _malloc_lock_unlock(&stack_logging_spin_lock); -} - -static kern_return_t default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) { - *ptr = (void *)address; - return 0; -} - -static kern_return_t get_remote_records(task_t task, memory_reader_t reader, stack_logging_record_list_t **records) { - // sets records - vm_address_t *remote_records_address_ref; - kern_return_t err; - *records = NULL; - err = reader(task, (vm_address_t)&stack_logging_the_record_list, sizeof(vm_address_t), (void **)&remote_records_address_ref); - if (err) return err; - if (!*remote_records_address_ref) { - // printf("stack_logging: no stack record\n"); - return 0; - } - // printf("stack_logging: stack records at %p\n", (void *)(*remote_records_address_ref)); - // printf("stack_logging: reading %d bytes\n", sizeof(stack_logging_record_list_t)); - err = reader(task, *remote_records_address_ref, sizeof(stack_logging_record_list_t), (void **)records); // get the list head - if (err) return err; - // printf("stack_logging: overall num bytes = %d\n", records->overall_num_bytes); - return reader(task, *remote_records_address_ref, (*records)->overall_num_bytes, (void **)records); -} - -kern_return_t stack_logging_get_frames(task_t task, memory_reader_t reader, vm_address_t address, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames) { - stack_logging_record_list_t *records; - kern_return_t err; - unsigned index; - unsigned disguised = STACK_LOGGING_DISGUISE(address); - if (!reader) reader = default_reader; - *num_frames = 0; - err = get_remote_records(task, reader, &records); - if (err || !records) return err; - // printf("stack_logging: %d records\n", records->num_records); - index = 0; - while (index < records->num_records) { - stack_logging_record_t *record = records->records + index; - if (record->address == disguised) { - return stack_logging_frames_for_uniqued_stack(task, reader, record->uniqued_stack, stack_frames_buffer, max_stack_frames, num_frames); - } - index++; - } - fprintf(stderr, "*** stack_logging: no record found for %p\n", (void *)address); - return 0; -} - -kern_return_t stack_logging_enumerate_records(task_t task, memory_reader_t reader, vm_address_t address, void enumerator(stack_logging_record_t, void *), void *context) { - stack_logging_record_list_t *records; - kern_return_t err; - unsigned index; - unsigned disguised = STACK_LOGGING_DISGUISE(address); - if (!reader) reader = default_reader; - err = get_remote_records(task, reader, &records); - if (err || !records) return err; - // printf("stack_logging: %d records\n", records->num_records); - index = 0; - while (index < records->num_records) { - stack_logging_record_t *record = records->records + index; - if (!address || (record->address == disguised)) enumerator(*record, context); - index++; - } - return 0; -} - -kern_return_t stack_logging_frames_for_uniqued_stack(task_t task, memory_reader_t reader, unsigned uniqued_stack, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames) { - stack_logging_record_list_t *records; - unsigned *uniquing_table; - kern_return_t err; - if (!reader) reader = default_reader; - *num_frames = 0; - err = get_remote_records(task, reader, &records); - if (err || !records) return err; - err = reader(task, (vm_address_t)records->uniquing_table, records->uniquing_table_num_pages * vm_page_size, (void **)&uniquing_table); - if (err) return err; - while (max_stack_frames && (uniqued_stack != -1)) { - unsigned thisPC; - if ((uniqued_stack * 2 + 1) * sizeof(unsigned) >= records->uniquing_table_num_pages * vm_page_size) { - fprintf(stderr, "*** stack_logging: Invalid uniqued stack 0x%x", uniqued_stack); - break; - } - thisPC = uniquing_table[uniqued_stack * 2]; - uniqued_stack = uniquing_table[uniqued_stack * 2 + 1]; - if (!thisPC && !uniqued_stack) { - // Invalid entry - fprintf(stderr, "*** stack_logging: Invalid entry 0x%x", thisPC); - break; - } - stack_frames_buffer[0] = thisPC; - stack_frames_buffer++; - (*num_frames)++; - max_stack_frames--; - } - return 0; -} - -/* vim: set noet:ts=4:sw=4:cindent: */ diff --git a/src/libmalloc/src/stack_logging.h b/src/libmalloc/src/stack_logging.h deleted file mode 100644 index 8a4093246..000000000 --- a/src/libmalloc/src/stack_logging.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 1999-2007 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import - -#define stack_logging_type_free 0 -#define stack_logging_type_generic 1 /* anything that is not allocation/deallocation */ -#define stack_logging_type_alloc 2 /* malloc, realloc, etc... */ -#define stack_logging_type_dealloc 4 /* free, realloc, etc... */ -#define stack_logging_type_vm_allocate 16 /* vm_allocate or mmap */ -#define stack_logging_type_vm_deallocate 32 /* vm_deallocate or munmap */ -#define stack_logging_type_mapped_file_or_shared_mem 128 - -// The valid flags include those from VM_FLAGS_ALIAS_MASK, which give the user_tag of allocated VM regions. -#define stack_logging_valid_type_flags ( \ - stack_logging_type_generic | \ - stack_logging_type_alloc | \ - stack_logging_type_dealloc | \ - stack_logging_type_vm_allocate | \ - stack_logging_type_vm_deallocate | \ - stack_logging_type_mapped_file_or_shared_mem | \ - VM_FLAGS_ALIAS_MASK); - -// Following flags are absorbed by stack_logging_log_stack() -#define stack_logging_flag_zone 8 /* NSZoneMalloc, etc... */ -#define stack_logging_flag_cleared 64 /* for NewEmptyHandle */ - -#define STACK_LOGGING_VM_USER_TAG(flags) (((flags) & VM_FLAGS_ALIAS_MASK) >> 24) - - -/* Macro used to disguise addresses so that leak finding can work */ -#define STACK_LOGGING_DISGUISE(address) ((address) ^ 0x00005555) /* nicely idempotent */ - -extern int stack_logging_enable_logging; /* when clear, no logging takes place */ -extern int stack_logging_dontcompact; /* default is to compact; when set does not compact alloc/free logs; useful for tracing history */ -extern int stack_logging_finished_init; /* set after we've returned from the Libsystem initialiser */ -extern int stack_logging_postponed; /* set if we needed to postpone logging till after initialisation */ - - -extern void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_to_skip); - /* This is the old log-to-memory logger, which is now deprecated. It remains for compatibility with performance tools that haven't been updated to disk_stack_logging_log_stack() yet. */ - -extern void __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip); - /* Fits as the malloc_logger; logs malloc/free/realloc events and can log custom events if called directly */ - - -/* 64-bit-aware stack log access. As new SPI, these routines are prefixed with double-underscore to avoid conflict with Libsystem clients. */ - -typedef struct { - uint32_t type_flags; - uint64_t stack_identifier; - uint64_t argument; - mach_vm_address_t address; -} mach_stack_logging_record_t; - -extern kern_return_t __mach_stack_logging_set_file_path(task_t task, char* file_path); - -extern kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); - /* Gets the last allocation record (malloc, realloc, or free) about address */ - -extern kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context); - /* Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records */ - -extern kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); - /* Given a uniqued_stack fills stack_frames_buffer */ - - -#pragma mark - -#pragma mark Legacy - -/* The following is the old 32-bit-only, in-process-memory stack logging. This is deprecated and clients should move to the above 64-bit-aware disk stack logging SPI. */ - -typedef struct { - unsigned type; - unsigned uniqued_stack; - unsigned argument; - unsigned address; /* disguised, to avoid confusing leaks */ -} stack_logging_record_t; - -typedef struct { - unsigned overall_num_bytes; - unsigned num_records; - unsigned lock; /* 0 means OK to lock; used for inter-process locking */ - unsigned *uniquing_table; /* allocated using vm_allocate() */ - /* hashtable organized as (PC, uniqued parent) - Only the second half of the table is active - To enable us to grow dynamically */ - unsigned uniquing_table_num_pages; /* number of pages of the table */ - unsigned extra_retain_count; /* not used by stack_logging_log_stack */ - unsigned filler[2]; /* align to cache lines for better performance */ - stack_logging_record_t records[0]; /* records follow here */ -} stack_logging_record_list_t; - -extern stack_logging_record_list_t *stack_logging_the_record_list; - /* This is the global variable containing all logs */ - -extern kern_return_t stack_logging_get_frames(task_t task, memory_reader_t reader, vm_address_t address, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames); - /* Gets the last record in stack_logging_the_record_list about address */ - -#define STACK_LOGGING_ENUMERATION_PROVIDED 1 // temporary to avoid dependencies between projects - -extern kern_return_t stack_logging_enumerate_records(task_t task, memory_reader_t reader, vm_address_t address, void enumerator(stack_logging_record_t, void *), void *context); - /* Gets all the records about address; - If !address, gets all records */ - -extern kern_return_t stack_logging_frames_for_uniqued_stack(task_t task, memory_reader_t reader, unsigned uniqued_stack, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames); - /* Given a uniqued_stack fills stack_frames_buffer */ - - - -extern void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *num); - /* Convenience to fill buffer with the PCs of the frames, starting with the hot frames; - num: returned number of frames - */ - diff --git a/src/libmalloc/src/stack_logging_disk.c b/src/libmalloc/src/stack_logging_disk.c index 8b849b4e1..5756215e1 100644 --- a/src/libmalloc/src/stack_logging_disk.c +++ b/src/libmalloc/src/stack_logging_disk.c @@ -21,28 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include <_simple.h> // as included by malloc.c, this defines ASL_LEVEL_INFO -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // for TARGET_OS_EMBEDDED, TARGET_IPHONE_SIMULATOR -#include "stack_logging.h" -#include "malloc_printf.h" -#include "malloc_internal.h" +#include "internal.h" #pragma mark - #pragma mark Defines @@ -60,7 +39,6 @@ #define ASL_LEVEL_INFO stderr #endif -#define STACK_LOGGING_MAX_STACK_SIZE 512 #define STACK_LOGGING_BLOCK_WRITING_SIZE 8192 #define STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED 3 @@ -80,7 +58,7 @@ // 32K-47K slots -> 18 collisions // 48K-79K slots -> 19 collisions // 80K-96K slots -> 20 collisions -#define INITIAL_MAX_COLLIDE 19 +#define INITIAL_MAX_COLLIDE 19 #define DEFAULT_UNIQUING_PAGE_SIZE 256 #pragma mark - @@ -89,119 +67,161 @@ #define STACK_LOGGING_FLAGS_SHIFT 56 #define STACK_LOGGING_USER_TAG_SHIFT 24 #define STACK_LOGGING_FLAGS(longlongvar) (uint32_t)((uint64_t)(longlongvar) >> STACK_LOGGING_FLAGS_SHIFT) -#define STACK_LOGGING_FLAGS_AND_USER_TAG(longlongvar) (uint32_t)(STACK_LOGGING_FLAGS(longlongvar) | (((uint64_t)(longlongvar) & 0x00FF000000000000ull) >> STACK_LOGGING_USER_TAG_SHIFT) ) +#define STACK_LOGGING_FLAGS_AND_USER_TAG(longlongvar) \ + (uint32_t)(STACK_LOGGING_FLAGS(longlongvar) | (((uint64_t)(longlongvar)&0x00FF000000000000ull) >> STACK_LOGGING_USER_TAG_SHIFT)) #define STACK_LOGGING_OFFSET_MASK 0x0000FFFFFFFFFFFFull -#define STACK_LOGGING_OFFSET(longlongvar) ((longlongvar) & STACK_LOGGING_OFFSET_MASK) +#define STACK_LOGGING_OFFSET(longlongvar) ((longlongvar)&STACK_LOGGING_OFFSET_MASK) -#define STACK_LOGGING_OFFSET_AND_FLAGS(longlongvar, type_flags) ( ((uint64_t)(longlongvar) & STACK_LOGGING_OFFSET_MASK) | ((uint64_t)(type_flags) << STACK_LOGGING_FLAGS_SHIFT) | (((uint64_t)(type_flags) & 0xFF000000ull) << STACK_LOGGING_USER_TAG_SHIFT) ) +#define STACK_LOGGING_OFFSET_AND_FLAGS(longlongvar, type_flags) \ + (((uint64_t)(longlongvar)&STACK_LOGGING_OFFSET_MASK) | ((uint64_t)(type_flags) << STACK_LOGGING_FLAGS_SHIFT) | \ + (((uint64_t)(type_flags)&0xFF000000ull) << STACK_LOGGING_USER_TAG_SHIFT)) #pragma mark - #pragma mark Types typedef struct { - uintptr_t argument; - uintptr_t address; - uint64_t offset_and_flags; // top 8 bits are actually the flags! + uintptr_t argument; + uintptr_t address; + uint64_t offset_and_flags; // top 8 bits are actually the flags! } stack_logging_index_event; typedef struct { - uint32_t argument; - uint32_t address; - uint64_t offset_and_flags; // top 8 bits are actually the flags! + uint32_t argument; + uint32_t address; + uint64_t offset_and_flags; // top 8 bits are actually the flags! } stack_logging_index_event32; typedef struct { - uint64_t argument; - uint64_t address; - uint64_t offset_and_flags; // top 8 bits are actually the flags! + uint64_t argument; + uint64_t address; + uint64_t offset_and_flags; // top 8 bits are actually the flags! } stack_logging_index_event64; // backtrace uniquing table chunks used in client-side stack log reading code, // in case we can't read the whole table in one mach_vm_read() call. typedef struct table_chunk_header { - uint64_t num_nodes_in_chunk; - uint64_t table_chunk_size; - mach_vm_address_t *table_chunk; - struct table_chunk_header *next_table_chunk_header; + uint64_t num_nodes_in_chunk; + uint64_t table_chunk_size; + mach_vm_address_t *table_chunk; + struct table_chunk_header *next_table_chunk_header; } table_chunk_header_t; -#pragma pack(push,4) -typedef struct { - uint64_t numPages; // number of pages of the table - uint64_t numNodes; - uint64_t tableSize; - uint64_t untouchableNodes; - mach_vm_address_t table_address; - int32_t max_collide; - // 'table_address' is just an always 64-bit version of the pointer-sized 'table' field to remotely read; - // it's important that the offset of 'table_address' in the struct does not change between 32 and 64-bit. +#pragma pack(push, 4) +typedef struct backtrace_uniquing_table { + uint64_t numPages; // number of pages of the table + uint64_t numNodes; + uint64_t tableSize; + uint64_t untouchableNodes; + mach_vm_address_t table_address; + int32_t max_collide; +// 'table_address' is just an always 64-bit version of the pointer-sized 'table' field to remotely read; +// it's important that the offset of 'table_address' in the struct does not change between 32 and 64-bit. #if BACKTRACE_UNIQUING_DEBUG uint64_t nodesFull; uint64_t backtracesContained; #endif union { - mach_vm_address_t *table; // in "target" process; allocated using vm_allocate() - table_chunk_header_t *first_table_chunk_hdr; // in analysis process + mach_vm_address_t *table; // in "target" process; allocated using vm_allocate() + table_chunk_header_t *first_table_chunk_hdr; // in analysis process } u; + uint64_t max_table_size; + bool in_client_process : 1; + bool nodes_use_refcount : 1; + unsigned refcount; } backtrace_uniquing_table; #pragma pack(pop) // for storing/looking up allocations that haven't yet be written to disk; consistent size across 32/64-bit processes. // It's important that these fields don't change alignment due to the architecture because they may be accessed from an // analyzing process with a different arch - hence the pragmas. -#pragma pack(push,4) +#pragma pack(push, 4) typedef struct { - uint64_t start_index_offset; - uint32_t next_free_index_buffer_offset; - char index_buffer[STACK_LOGGING_BLOCK_WRITING_SIZE]; - backtrace_uniquing_table *uniquing_table; + uint64_t start_index_offset; + uint32_t next_free_index_buffer_offset; + char index_buffer[STACK_LOGGING_BLOCK_WRITING_SIZE]; + backtrace_uniquing_table *uniquing_table; } stack_buffer_shared_memory; #pragma pack(pop) // target process address -> record table (for __mach_stack_logging_get_frames) typedef struct { - uint64_t address; - uint64_t index_file_offset; + uint64_t address; + uint64_t index_file_offset; } remote_index_node; // for caching index information client-side: typedef struct { - size_t cache_size; - size_t cache_node_capacity; - uint32_t collision_allowance; - remote_index_node *table_memory; // this can be malloced; it's on the client side. - stack_buffer_shared_memory *shmem; // shared memory + size_t cache_size; + size_t cache_node_capacity; + uint32_t collision_allowance; + remote_index_node *table_memory; // this can be malloced; it's on the client side. + stack_buffer_shared_memory *shmem; // shared memory stack_buffer_shared_memory snapshot; // memory snapshot of the remote process' shared memory - uint32_t last_pre_written_index_size; - uint64_t last_index_file_offset; + uint32_t last_pre_written_index_size; + uint64_t last_index_file_offset; backtrace_uniquing_table uniquing_table_snapshot; // snapshot of the remote process' uniquing table + boolean_t lite_mode; } remote_index_cache; // for reading stack history information from remote processes: typedef struct { - task_t remote_task; - pid_t remote_pid; - int32_t task_is_64_bit; - int32_t in_use_count; - FILE *index_file_stream; - uint64_t remote_stack_buffer_shared_memory_address; - remote_index_cache *cache; + task_t remote_task; + pid_t remote_pid; + int32_t task_is_64_bit; + boolean_t task_uses_lite_mode; + int32_t in_use_count; + FILE *index_file_stream; + uint64_t remote_stack_buffer_shared_memory_address; + remote_index_cache *cache; } remote_task_file_streams; +typedef mach_vm_address_t slot_address; +typedef uint64_t slot_parent; +typedef uint64_t slot_refcount; +typedef uint64_t table_slot_index; + +#pragma pack(push,16) +typedef struct { + union { + struct { + uint64_t slot0; + uint64_t slot1; + } slots; + + struct { + slot_address address:48; + slot_parent parent:32; + slot_refcount refcount:48; + } refcount_slot; + + struct { + slot_address address:64; + slot_parent parent:64; + } normal_slot; + }; + +} table_slot_t; +#pragma pop + +_Static_assert(sizeof(table_slot_t) == 16, "table_slot_t must be 128 bits"); + #pragma mark - #pragma mark Constants/Globals -static _malloc_lock_s stack_logging_lock = _MALLOC_LOCK_INIT; +int stack_logging_enable_logging = 0; +int stack_logging_dontcompact = 0; +int stack_logging_finished_init = 0; +int stack_logging_postponed = 0; +int stack_logging_mode = stack_logging_mode_none; -// support for multi-threaded forks -extern void __stack_logging_fork_prepare(); -extern void __stack_logging_fork_parent(); -extern void __stack_logging_fork_child(); -extern void __stack_logging_early_finished(); +#define MAX_PARENT_NORMAL +#define MAX_PARENT_REFCOUNT -// support for gdb and others checking for stack_logging locks -extern boolean_t __stack_logging_locked(); +static const slot_parent slot_no_parent_normal = 0xFFFFFFFFFFFFFFFF; // 64 bits +static const slot_parent slot_no_parent_refcount = 0xFFFFFFFF; // 32 bits + +static _malloc_lock_s stack_logging_lock = _MALLOC_LOCK_INIT; // single-thread access variables static stack_buffer_shared_memory *pre_write_buffers; @@ -211,10 +231,12 @@ static uintptr_t last_logged_malloc_address = 0; // Constants to define part of stack logging file path names. // File names are of the form stack-logs..
..XXXXXX.index // where
is the address of the pre_write_buffers VM region in the target -// process that will need to be mapped into analysis tool processes. +// process that will need to be mapped into analysis tool processes. static const char *stack_log_file_base_name = "stack-logs."; static const char *stack_log_file_suffix = ".index"; +static FILE *open_log_file_at_path(char *pathname, remote_task_file_streams *streams); + char *__stack_log_file_path__ = NULL; static int index_file_descriptor = -1; @@ -224,137 +246,197 @@ static uint32_t next_remote_task_fd = 0; static uint32_t remote_task_fd_count = 0; static _malloc_lock_s remote_fd_list_lock = _MALLOC_LOCK_INIT; +uint64_t __mach_stack_logging_shared_memory_address = 0; + // activation variables static int logging_use_compaction = 1; // set this to zero to always disable compaction. // We set malloc_logger to NULL to disable logging, if we encounter errors // during file writing -typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip); +typedef void(malloc_logger_t)(uint32_t type, + uintptr_t arg1, + uintptr_t arg2, + uintptr_t arg3, + uintptr_t result, + uint32_t num_hot_frames_to_skip); extern malloc_logger_t *malloc_logger; -extern malloc_logger_t *__syscall_logger; // use this to set up syscall logging (e.g., vm_allocate, vm_deallocate, mmap, munmap) +extern malloc_logger_t *__syscall_logger; // use this to set up syscall logging (e.g., vm_allocate, vm_deallocate, mmap, munmap) #pragma mark - #pragma mark In-Memory Backtrace Uniquing -static __attribute__((always_inline)) -inline void* -allocate_pages(uint64_t memSize) +static __attribute__((always_inline)) inline void * +sld_allocate_pages(uint64_t memSize) { mach_vm_address_t allocatedMem = 0ull; - if (mach_vm_allocate(mach_task_self(), &allocatedMem, memSize, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)) != KERN_SUCCESS) { + if (mach_vm_allocate(mach_task_self(), &allocatedMem, memSize, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)) != + KERN_SUCCESS) { malloc_printf("allocate_pages(): virtual memory exhausted!\n"); } - return (void*)(uintptr_t)allocatedMem; + return (void *)(uintptr_t)allocatedMem; } -static __attribute__((always_inline)) -inline int -deallocate_pages(void* memPointer, uint64_t memSize) +static __attribute__((always_inline)) inline int +sld_deallocate_pages(void *memPointer, uint64_t memSize) { return mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)memPointer, memSize); } -static backtrace_uniquing_table* -__create_uniquing_table(void) +static const uint64_t max_table_size_lite = UINT32_MAX; +static const uint64_t max_table_size_normal = UINT64_MAX; + +static backtrace_uniquing_table * +__create_uniquing_table(boolean_t lite_mode) { - backtrace_uniquing_table *uniquing_table = (backtrace_uniquing_table*)allocate_pages((uint64_t)round_page(sizeof(backtrace_uniquing_table))); - if (!uniquing_table) return NULL; + backtrace_uniquing_table *uniquing_table = + (backtrace_uniquing_table *)sld_allocate_pages((uint64_t)round_page(sizeof(backtrace_uniquing_table))); + if (!uniquing_table) { + return NULL; + } bzero(uniquing_table, sizeof(backtrace_uniquing_table)); uniquing_table->numPages = DEFAULT_UNIQUING_PAGE_SIZE; uniquing_table->tableSize = uniquing_table->numPages * vm_page_size; uniquing_table->numNodes = ((uniquing_table->tableSize / (sizeof(mach_vm_address_t) * 2)) >> 1) << 1; // make sure it's even. - uniquing_table->u.table = (mach_vm_address_t*)(uintptr_t)allocate_pages(uniquing_table->tableSize); + uniquing_table->u.table = (mach_vm_address_t *)(uintptr_t)sld_allocate_pages(uniquing_table->tableSize); uniquing_table->table_address = (uintptr_t)uniquing_table->u.table; uniquing_table->max_collide = INITIAL_MAX_COLLIDE; uniquing_table->untouchableNodes = 0; + uniquing_table->max_table_size = (lite_mode) ? max_table_size_lite : max_table_size_normal; + uniquing_table->nodes_use_refcount = lite_mode; + uniquing_table->in_client_process = 0; #if BACKTRACE_UNIQUING_DEBUG - malloc_printf("create_uniquing_table(): creating. size: %lldKB == %lldMB, numnodes: %lld (%lld untouchable)\n", uniquing_table->tableSize >> 10, uniquing_table->tableSize >> 20, uniquing_table->numNodes, uniquing_table->untouchableNodes); - malloc_printf("create_uniquing_table(): table: %p; end: %p\n", uniquing_table->table, (void*)((uintptr_t)uniquing_table->table + (uintptr_t)uniquing_table->tableSize)); + malloc_printf("create_uniquing_table(): creating. size: %lldKB == %lldMB, numnodes: %lld (%lld untouchable)\n", + uniquing_table->tableSize >> 10, uniquing_table->tableSize >> 20, uniquing_table->numNodes, + uniquing_table->untouchableNodes); + malloc_printf("create_uniquing_table(): table: %p; end: %p\n", uniquing_table->u.table, + (void *)((uintptr_t)uniquing_table->u.table + (uintptr_t)uniquing_table->tableSize)); #endif return uniquing_table; } static void -__destroy_uniquing_table(backtrace_uniquing_table* table) +__destroy_uniquing_table(backtrace_uniquing_table *table) { - deallocate_pages(table->u.table, table->tableSize); - deallocate_pages(table, sizeof(backtrace_uniquing_table)); + assert(!table->in_client_process); + sld_deallocate_pages(table->u.table, table->tableSize); + sld_deallocate_pages(table, sizeof(backtrace_uniquing_table)); } -static void +static boolean_t __expand_uniquing_table(backtrace_uniquing_table *uniquing_table) { + assert(!uniquing_table->in_client_process); mach_vm_address_t *oldTable = uniquing_table->u.table; uint64_t oldsize = uniquing_table->tableSize; uint64_t oldnumnodes = uniquing_table->numNodes; + uint64_t newsize = (uniquing_table->numPages << EXPAND_FACTOR) * vm_page_size; + + if (newsize > uniquing_table->max_table_size) { + malloc_printf("no more space in uniquing table\n"); + return false; + } + uniquing_table->numPages = uniquing_table->numPages << EXPAND_FACTOR; uniquing_table->tableSize = uniquing_table->numPages * vm_page_size; uniquing_table->numNodes = ((uniquing_table->tableSize / (sizeof(mach_vm_address_t) * 2)) >> 1) << 1; // make sure it's even. - mach_vm_address_t *newTable = (mach_vm_address_t*)(uintptr_t)allocate_pages(uniquing_table->tableSize); + mach_vm_address_t *newTable = (mach_vm_address_t *)(uintptr_t)sld_allocate_pages(uniquing_table->tableSize); uniquing_table->u.table = newTable; uniquing_table->table_address = (uintptr_t)uniquing_table->u.table; uniquing_table->max_collide = uniquing_table->max_collide + COLLISION_GROWTH_RATE; - if (mach_vm_copy(mach_task_self(), (mach_vm_address_t)(uintptr_t)oldTable, oldsize, (mach_vm_address_t)(uintptr_t)newTable) != KERN_SUCCESS) { + if (mach_vm_copy(mach_task_self(), (mach_vm_address_t)(uintptr_t)oldTable, oldsize, (mach_vm_address_t)(uintptr_t)newTable) != + KERN_SUCCESS) { malloc_printf("expandUniquingTable(): VMCopyFailed\n"); } uniquing_table->untouchableNodes = oldnumnodes; #if BACKTRACE_UNIQUING_DEBUG - malloc_printf("expandUniquingTable(): expanded from nodes full: %lld of: %lld (~%2d%%); to nodes: %lld (inactive = %lld); unique bts: %lld\n", - uniquing_table->nodesFull, oldnumnodes, (int)(((uniquing_table->nodesFull * 100.0) / (double)oldnumnodes) + 0.5), - uniquing_table->numNodes, uniquing_table->untouchableNodes, uniquing_table->backtracesContained); - malloc_printf("expandUniquingTable(): allocate: %p; end: %p\n", newTable, (void*)((uintptr_t)newTable + (uintptr_t)(uniquing_table->tableSize))); - malloc_printf("expandUniquingTable(): deallocate: %p; end: %p\n", oldTable, (void*)((uintptr_t)oldTable + (uintptr_t)oldsize)); + malloc_printf( + "expandUniquingTable(): expanded from nodes full: %lld of: %lld (~%2d%%); to nodes: %lld (inactive = %lld); unique " + "bts: %lld\n", + uniquing_table->nodesFull, oldnumnodes, (int)(((uniquing_table->nodesFull * 100.0) / (double)oldnumnodes) + 0.5), + uniquing_table->numNodes, uniquing_table->untouchableNodes, uniquing_table->backtracesContained); + malloc_printf("expandUniquingTable(): allocate: %p; end: %p\n", newTable, + (void *)((uintptr_t)newTable + (uintptr_t)(uniquing_table->tableSize))); + malloc_printf("expandUniquingTable(): deallocate: %p; end: %p\n", oldTable, (void *)((uintptr_t)oldTable + (uintptr_t)oldsize)); + malloc_printf("expandUniquingTable(): new size = %llu\n", newsize); #endif - if (deallocate_pages(oldTable, oldsize) != KERN_SUCCESS) { + if (sld_deallocate_pages(oldTable, oldsize) != KERN_SUCCESS) { malloc_printf("expandUniquingTable(): mach_vm_deallocate failed. [%p]\n", uniquing_table->u.table); } + + return true; +} + +static void +add_new_slot(table_slot_t *table_slot, mach_vm_address_t address, table_slot_index parent, bool use_refcount, size_t ptr_size) +{ + assert(use_refcount == (ptr_size > 0)); + + table_slot_t new_slot; + + if (use_refcount) { + new_slot.refcount_slot.address = address; + new_slot.refcount_slot.parent = parent; + new_slot.refcount_slot.refcount = ptr_size; + } else { + new_slot.normal_slot.address = address; + new_slot.normal_slot.parent = parent; + } + + *table_slot = new_slot; +} + +static void +increment_slot_refcount(table_slot_t *table_slot, size_t ptr_size) +{ + table_slot->refcount_slot.refcount += ptr_size; } static int -__enter_frames_in_table(backtrace_uniquing_table *uniquing_table, uint64_t *foundIndex, mach_vm_address_t *frames, int32_t count) +enter_frames_in_table(backtrace_uniquing_table *uniquing_table, uint64_t *foundIndex, mach_vm_address_t *frames, int32_t count, size_t ptr_size) { + assert(!uniquing_table->in_client_process); + boolean_t use_refcount = (ptr_size > 0); + // The hash values need to be the same size as the addresses (because we use the value -1), for clarity, define a new type typedef mach_vm_address_t hash_index_t; - - mach_vm_address_t thisPC; - hash_index_t hash, uParent = (hash_index_t)(-1ll), modulus = (uniquing_table->numNodes-uniquing_table->untouchableNodes-1); - int32_t collisions, lcopy = count, returnVal = 1; + + hash_index_t uParent = use_refcount ? slot_no_parent_refcount : slot_no_parent_normal; + hash_index_t modulus = (uniquing_table->numNodes-uniquing_table->untouchableNodes-1); + + int32_t lcopy = count; + int32_t returnVal = 1; hash_index_t hash_multiplier = ((uniquing_table->numNodes - uniquing_table->untouchableNodes)/(uniquing_table->max_collide*2+1)); - mach_vm_address_t *node; + while (--lcopy >= 0) { - thisPC = frames[lcopy]; - - // hash = initialHash(uniquing_table, uParent, thisPC); - hash = uniquing_table->untouchableNodes + (((uParent << 4) ^ (thisPC >> 2)) % modulus); - collisions = uniquing_table->max_collide; + mach_vm_address_t thisPC = frames[lcopy]; + hash_index_t hash = uniquing_table->untouchableNodes + (((uParent << 4) ^ (thisPC >> 2)) % modulus); + int32_t collisions = uniquing_table->max_collide; while (collisions--) { - node = uniquing_table->u.table + (hash * 2); - - if (*node == 0 && node[1] == 0) { - // blank; store this entry! - // Note that we need to test for both head[0] and head[1] as (0, -1) is a valid entry - node[0] = thisPC; - node[1] = uParent; + table_slot_t *table_slot = (table_slot_t *) (uniquing_table->u.table + (hash * 2)); + + if (table_slot->slots.slot0 == 0 && table_slot->slots.slot1 == 0) { + add_new_slot(table_slot, thisPC, uParent, uniquing_table->nodes_use_refcount, ptr_size); uParent = hash; -#if BACKTRACE_UNIQUING_DEBUG - uniquing_table->nodesFull++; - if (lcopy == 0) { - uniquing_table->backtracesContained++; - } -#endif break; } - if (*node == thisPC && node[1] == uParent) { - // hit! retrieve index and go. + + slot_address address = use_refcount ? table_slot->refcount_slot.address : table_slot->normal_slot.address; + slot_parent parent = use_refcount ? table_slot->refcount_slot.parent : table_slot->normal_slot.parent; + + if (address == thisPC && parent == uParent) { uParent = hash; + + if (use_refcount) + increment_slot_refcount(table_slot, ptr_size); + break; } @@ -371,7 +453,9 @@ __enter_frames_in_table(backtrace_uniquing_table *uniquing_table, uint64_t *foun } } - if (returnVal) *foundIndex = uParent; + if (returnVal) { + *foundIndex = uParent; + } return returnVal; } @@ -388,11 +472,12 @@ static bool getenv_from_process(pid_t pid, char *env_var_name, char *env_var_val #define BASE16 16 static void -append_int(char * filename, uint64_t inputValue, unsigned base, size_t maxLength) +append_int(char *filename, uint64_t inputValue, unsigned base, size_t maxLength) { const char *digits = "0123456789abcdef"; - if (base > strlen(digits)) return; // sanity check - + if (base > strlen(digits)) { + return; // sanity check + } size_t len = strlen(filename); uint32_t count = 0; @@ -402,13 +487,14 @@ append_int(char * filename, uint64_t inputValue, unsigned base, size_t maxLength count++; } - if (len + count >= maxLength) return; // don't modify the string if it would violate maxLength - + if (len + count >= maxLength) { + return; // don't modify the string if it would violate maxLength + } filename[len + count] = '\0'; value = inputValue; uint32_t i; - for (i = 0 ; i < count ; i ++) { + for (i = 0; i < count; i++) { filename[len + count - 1 - i] = digits[value % base]; value /= base; } @@ -441,9 +527,11 @@ postpone_stack_logging(void) * Allocating and releasing target buffer is the caller's responsibility. */ static bool -get_writeable_logging_directory(char* target) +get_writeable_logging_directory(char *target) { - if (!target) return false; + if (!target) { + return false; + } char *evn_log_directory = getenv("MallocStackLoggingDirectory"); if (evn_log_directory) { @@ -467,20 +555,87 @@ get_writeable_logging_directory(char* target) } if (stack_logging_finished_init) { - size_t n = confstr(_CS_DARWIN_USER_TEMP_DIR, target, (size_t) PATH_MAX); - if ((n > 0) && (n < PATH_MAX)) return true; + size_t n = confstr(_CS_DARWIN_USER_TEMP_DIR, target, (size_t)PATH_MAX); + if ((n > 0) && (n < PATH_MAX)) { + return true; + } } else { /* Can't call confstr during init, so postpone - logging till after */ + * logging till after */ postpone_stack_logging(); } *target = '\0'; return false; } +// Stolen from libc. Ugly hack because arc4random uses malloc so we can't call Libc's mkstemps. +int getentropy(void *, size_t); +static int +my_mkstemps(char *path, size_t slen) +{ + char *start, *trv, *suffp, *carryp; + char *pad; + char carrybuf[MAXPATHLEN]; + int fd; + + for (trv = path; *trv != '\0'; ++trv) { + ; + } + trv -= slen; + suffp = trv; + --trv; + + /* Fill space with random characters */ + uint8_t randbuf[8]; + unsigned int randbuf_offset = 0; + getentropy(randbuf, sizeof(randbuf)); + static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + while (trv >= path && *trv == 'X') { + *trv-- = padchar[randbuf[randbuf_offset++ % sizeof(randbuf)] % sizeof(padchar)]; + } + start = trv + 1; + + /* save first combination of random characters */ + memcpy(carrybuf, start, suffp - start); + + for (;;) { + if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR, 0600)) >= 0) { + return fd; + } + if (errno != EEXIST) { + return -1; + } + + /* If we have a collision, cycle through the space of filenames */ + for (trv = start, carryp = carrybuf;;) { + /* have we tried all possible permutations? */ + if (trv == suffp) { + return -1; /* yes - exit with EEXIST */ + } + pad = strchr(padchar, *trv); + if (pad == NULL) { + /* this should never happen */ + errno = EIO; + return -1; + } + /* increment character */ + *trv = (*++pad == '\0') ? padchar[0] : *pad; + /* carry to next position? */ + if (*trv == *carryp) { + /* increment position and loop */ + ++trv; + ++carryp; + } else { + /* try with new name */ + break; + } + } + } +} + // If successful, returns path to log file that was created, otherwise NULL. static char * -create_log_file(void) +create_log_file() { pid_t pid = getpid(); const char *progname = getprogname(); @@ -488,7 +643,7 @@ create_log_file(void) if (__stack_log_file_path__ == NULL) { // On first use, allocate space directly from the OS without using malloc - __stack_log_file_path__ = allocate_pages((uint64_t)round_page(PATH_MAX)); + __stack_log_file_path__ = sld_allocate_pages((uint64_t)round_page(PATH_MAX)); if (__stack_log_file_path__ == NULL) { _malloc_printf(ASL_LEVEL_INFO, "unable to allocate memory for stack log file path\n"); return NULL; @@ -505,11 +660,11 @@ create_log_file(void) // Add the '/' only if it's not already there. Having multiple '/' characters works // but is unsightly when we print these stack log file names out. size_t stack_log_len = strlen(__stack_log_file_path__); - if (__stack_log_file_path__[stack_log_len-1] != '/') { + if (__stack_log_file_path__[stack_log_len - 1] != '/') { // use strlcat to null-terminate for the next strlcat call, and to check buffer size strlcat(__stack_log_file_path__ + stack_log_len, "/", (size_t)PATH_MAX); } - + // Append the file name to __stack_log_file_path__ but don't use snprintf since // it can cause malloc() calls. // @@ -520,20 +675,20 @@ create_log_file(void) // to create shared memory segments so including the address of the VM region in the // file name is a simple way to communicate the address to analysis tools so the // stack log reading code can map in the region with mach_vm_remap(). - + strlcat(__stack_log_file_path__, stack_log_file_base_name, (size_t)PATH_MAX); append_int(__stack_log_file_path__, pid, BASE10, (size_t)PATH_MAX); strlcat(__stack_log_file_path__, ".", (size_t)PATH_MAX); - append_int(__stack_log_file_path__, pre_write_buffers, BASE16, (size_t)PATH_MAX); + append_int(__stack_log_file_path__, (uint64_t)pre_write_buffers, BASE16, (size_t)PATH_MAX); if (progname && progname[0] != '\0') { strlcat(__stack_log_file_path__, ".", (size_t)PATH_MAX); strlcat(__stack_log_file_path__, progname, (size_t)PATH_MAX); } strlcat(__stack_log_file_path__, ".XXXXXX", (size_t)PATH_MAX); strlcat(__stack_log_file_path__, stack_log_file_suffix, (size_t)PATH_MAX); - + // Securely create the log file. - if ((index_file_descriptor = mkstemps(__stack_log_file_path__, (int)strlen(stack_log_file_suffix))) != -1) { + if ((index_file_descriptor = my_mkstemps(__stack_log_file_path__, (int)strlen(stack_log_file_suffix))) != -1) { _malloc_printf(ASL_LEVEL_INFO, "stack logs being written into %s\n", __stack_log_file_path__); created_log_location = __stack_log_file_path__; } else { @@ -551,7 +706,9 @@ create_log_file(void) static int delete_logging_file(char *log_location) { - if (log_location == NULL || log_location[0] == '\0') return 0; + if (log_location == NULL || log_location[0] == '\0') { + return 0; + } struct stat statbuf; if (unlink(log_location) != 0 && stat(log_location, &statbuf) == 0) { @@ -583,7 +740,7 @@ is_process_running(pid_t pid) sysctl(mib, 4, kpt, &size, NULL, (size_t)0); // size is either 1 or 0 entries when we ask for a single pid - return (size==sizeof(struct kinfo_proc)); + return (size == sizeof(struct kinfo_proc)); } // Stack log files can be quite large and aren't useful after the process that created them no longer exists because @@ -603,59 +760,69 @@ is_process_running(pid_t pid) // The pattern is essentially a relative path, where a level that start with '<' matches any name, otherwise // it has to be an exact name match. See the calling function for examples. static void -reap_orphaned_log_files_in_hierarchy(char *directory, char *remaining_path_format) +reap_orphaned_log_files_in_hierarchy(char *directory, char *remaining_path_format, pid_t target_pid, remote_task_file_streams *streams) { DIR *dp; struct dirent *entry; - + // Ensure that we can access this directory - permissions or sandbox'ing might prevent it. if (access(directory, R_OK | W_OK | X_OK) == -1 || (dp = opendir(directory)) == NULL) { //_malloc_printf(ASL_LEVEL_INFO, "reaping: no access to %s\n", directory); return; } - + char pathname[PATH_MAX]; strlcpy(pathname, directory, (size_t)PATH_MAX); size_t pathname_len = strlen(pathname); - if (pathname[pathname_len-1] != '/') pathname[pathname_len++] = '/'; + if (pathname[pathname_len - 1] != '/') { + pathname[pathname_len++] = '/'; + } char *suffix = pathname + pathname_len; - + // Recurse down to deeper levels of the temp directory hierarchy if necessary. if (remaining_path_format) { char *separator = remaining_path_format; - while (*separator != '/' && *separator != '\0') { separator++; } + while (*separator != '/' && *separator != '\0') { + separator++; + } size_t length_to_match = (*remaining_path_format == '<') ? 0 : separator - remaining_path_format; char *next_remaining_path_format = (*separator == '\0') ? NULL : separator + 1; - - while ( (entry = readdir(dp)) != NULL ) { + + while ((entry = readdir(dp)) != NULL) { if (entry->d_type == DT_DIR && entry->d_name[0] != '.') { if (length_to_match > 0 && strncmp(entry->d_name, remaining_path_format, length_to_match) != 0) { continue; } strlcpy(suffix, entry->d_name, (size_t)PATH_MAX - pathname_len); - reap_orphaned_log_files_in_hierarchy(pathname, next_remaining_path_format); + reap_orphaned_log_files_in_hierarchy(pathname, next_remaining_path_format, target_pid, streams); } } closedir(dp); - + return; } - + // OK, we found a lowest-level directory matching , and we have access to it. // Reap any unnecessary stack log files in here. - + //_malloc_printf(ASL_LEVEL_INFO, "reaping: looking in %s\n", directory); - + // __stack_log_file_path__ may be NULL if this code is running in an analysis tool client process that is not // itself running with MallocStackLogging set. char *curproc_stack_log_file = __stack_log_file_path__ ? strrchr(__stack_log_file_path__, '/') + 1 : NULL; pid_t curpid = getpid(); size_t prefix_length = strlen(stack_log_file_base_name); - - while ( (entry = readdir(dp)) != NULL ) { - if ( (entry->d_type == DT_REG || entry->d_type == DT_LNK) && ( strncmp( entry->d_name, stack_log_file_base_name, prefix_length) == 0 ) ) { + + while ((entry = readdir(dp)) != NULL) { + if ((entry->d_type == DT_REG || entry->d_type == DT_LNK) && + (strncmp(entry->d_name, stack_log_file_base_name, prefix_length) == 0)) { long pid = strtol(&entry->d_name[prefix_length], (char **)NULL, 10); - if ( ! is_process_running((pid_t)pid) || (pid == curpid && curproc_stack_log_file && strcmp(entry->d_name, curproc_stack_log_file) != 0) ) { + if (pid == target_pid && streams != NULL) { + strlcpy(suffix, entry->d_name, (size_t)PATH_MAX - pathname_len); + open_log_file_at_path(pathname, streams); + } + else if (!is_process_running((pid_t)pid) || + (pid == curpid && curproc_stack_log_file && strcmp(entry->d_name, curproc_stack_log_file) != 0)) { strlcpy(suffix, entry->d_name, (size_t)PATH_MAX - pathname_len); if (delete_logging_file(pathname) == 0) { if (pid == curpid) { @@ -671,29 +838,30 @@ reap_orphaned_log_files_in_hierarchy(char *directory, char *remaining_path_forma } static void -reap_orphaned_log_files(pid_t pid) +reap_orphaned_log_files(pid_t target_pid, remote_task_file_streams *streams) { - reap_orphaned_log_files_in_hierarchy(_PATH_TMP, NULL); + reap_orphaned_log_files_in_hierarchy(_PATH_TMP, NULL, target_pid, streams); - char *env_var_names[] = { "TMPDIR", "MallocStackLoggingDirectory" }; + char *env_var_names[] = {"TMPDIR", "MallocStackLoggingDirectory"}; for (unsigned i = 0; i < sizeof(env_var_names) / sizeof(char *); i++) { char directory[PATH_MAX]; - bool success = getenv_from_process(pid, env_var_names[i], directory, sizeof(directory)); + bool success = getenv_from_process(target_pid, env_var_names[i], directory, sizeof(directory)); if (success && strcmp(directory, _PATH_TMP) != 0) { - reap_orphaned_log_files_in_hierarchy(directory, NULL); + reap_orphaned_log_files_in_hierarchy(directory, NULL, target_pid, streams); } } - + // Now reap files left over in any other accessible app-specific temp directories. // These could be from sandbox'ed apps. #if TARGET_OS_EMBEDDED - char *root_of_temp_directories = "/private/var/mobile/Containers/Data/Application"; // ugh - hard-coding to user name "mobile". Works for all iOS's up to now. + char *root_of_temp_directories = "/private/var/mobile/Containers/Data/Application"; // ugh - hard-coding to user name "mobile". + // Works for all iOS's up to now. char *temp_directories_path_format = "/tmp"; #else char *root_of_temp_directories = "/private/var/folders"; char *temp_directories_path_format = "//T"; #endif - reap_orphaned_log_files_in_hierarchy(root_of_temp_directories, temp_directories_path_format); + reap_orphaned_log_files_in_hierarchy(root_of_temp_directories, temp_directories_path_format, target_pid, streams); } /* @@ -707,6 +875,29 @@ disable_stack_logging(void) stack_logging_enable_logging = 0; malloc_logger = NULL; __syscall_logger = NULL; + disable_stack_logging_lite(); +} + +static boolean_t uniquing_table_memory_was_deleted = false; + +__attribute__((visibility("hidden"))) boolean_t +__uniquing_table_memory_was_deleted(void) +{ + return uniquing_table_memory_was_deleted; +} + +__attribute__((visibility("hidden"))) void +__delete_uniquing_table_memory_while_locked(void) +{ + // Clean out the memory (if not done already) + if (pre_write_buffers && pre_write_buffers->uniquing_table != NULL) { + __destroy_uniquing_table(pre_write_buffers->uniquing_table); + pre_write_buffers->uniquing_table = NULL; + uniquing_table_memory_was_deleted = true; + } + + // Clear the shared memory address so client tools won't look for the uniquing table memory + __mach_stack_logging_shared_memory_address = 0; } /* A wrapper around write() that will try to reopen the index/stack file and @@ -715,7 +906,8 @@ disable_stack_logging(void) * programs like to do that and calling abort() on them is rude. */ static ssize_t -robust_write(int fd, const void *buf, size_t nbyte) { +robust_write(int fd, const void *buf, size_t nbyte) +{ extern int errno; ssize_t written = write(fd, buf, nbyte); if (written == -1 && errno == EBADF) { @@ -737,7 +929,7 @@ robust_write(int fd, const void *buf, size_t nbyte) { if (fd < 3) { // If we somehow got stdin/out/err, we need to relinquish them and // get another fd. - int fds_to_close[3] = { 0 }; + int fds_to_close[3] = {0}; while (fd < 3) { if (fd == -1) { _malloc_printf(ASL_LEVEL_INFO, "unable to re-open stack logging file %s\n", file_to_reopen); @@ -749,9 +941,15 @@ robust_write(int fd, const void *buf, size_t nbyte) { } // We have an fd we like. Close the ones we opened. - if (fds_to_close[0]) close(0); - if (fds_to_close[1]) close(1); - if (fds_to_close[2]) close(2); + if (fds_to_close[0]) { + close(0); + } + if (fds_to_close[1]) { + close(1); + } + if (fds_to_close[2]) { + close(2); + } } *fd_to_reset = fd; @@ -765,7 +963,7 @@ flush_data(void) { ssize_t written; // signed size_t size_t remaining; - char * p; + char *p; if (index_file_descriptor == -1) { if (create_log_file() == NULL) { @@ -779,8 +977,8 @@ flush_data(void) while (remaining > 0) { written = robust_write(index_file_descriptor, p, remaining); if (written == -1) { - _malloc_printf(ASL_LEVEL_INFO, "Unable to write to stack logging file %s (%s)\n", - __stack_log_file_path__, strerror(errno)); + _malloc_printf( + ASL_LEVEL_INFO, "Unable to write to stack logging file %s (%s)\n", __stack_log_file_path__, strerror(errno)); disable_stack_logging(); return; } @@ -792,9 +990,8 @@ flush_data(void) pre_write_buffers->next_free_index_buffer_offset = 0; } -__attribute__((visibility("hidden"))) -void -__prepare_to_log_stacks(void) +__attribute__((visibility("hidden"))) boolean_t +__prepare_to_log_stacks(boolean_t lite_mode) { if (!pre_write_buffers) { last_logged_malloc_address = 0ul; @@ -810,11 +1007,12 @@ __prepare_to_log_stacks(void) // processes that may have sandbox restrictions that don't allow the creation of shared memory regions, // we're using this "create a region and put its address in the stack log file name" approach. size_t full_shared_mem_size = sizeof(stack_buffer_shared_memory); - pre_write_buffers = mmap(0, full_shared_mem_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL), 0); + pre_write_buffers = mmap( + 0, full_shared_mem_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL), 0); if (MAP_FAILED == pre_write_buffers) { _malloc_printf(ASL_LEVEL_INFO, "error creating VM region for stack logging output buffers\n"); disable_stack_logging(); - return; + return false; } // Store and use the buffer offsets in shared memory so that they can be accessed remotely @@ -822,47 +1020,55 @@ __prepare_to_log_stacks(void) pre_write_buffers->next_free_index_buffer_offset = 0; // create the backtrace uniquing table - pre_write_buffers->uniquing_table = __create_uniquing_table(); + pre_write_buffers->uniquing_table = __create_uniquing_table(lite_mode); if (!pre_write_buffers->uniquing_table) { _malloc_printf(ASL_LEVEL_INFO, "error while allocating stack uniquing table\n"); disable_stack_logging(); - return; + return false; } uint64_t stack_buffer_sz = (uint64_t)round_page(sizeof(vm_address_t) * STACK_LOGGING_MAX_STACK_SIZE); - stack_buffer = (vm_address_t*)allocate_pages(stack_buffer_sz); + stack_buffer = (vm_address_t *)sld_allocate_pages(stack_buffer_sz); if (!stack_buffer) { _malloc_printf(ASL_LEVEL_INFO, "error while allocating stack trace buffer\n"); disable_stack_logging(); - return; + return false; } - // this call ensures that the log files exist; analyzing processes will rely on this assumption. - if (create_log_file() == NULL) { - /* postponement support requires cleaning up these structures now */ - __destroy_uniquing_table(pre_write_buffers->uniquing_table); - deallocate_pages(stack_buffer, stack_buffer_sz); - stack_buffer = NULL; - - munmap(pre_write_buffers, full_shared_mem_size); - pre_write_buffers = NULL; - - if (!stack_logging_postponed) { - disable_stack_logging(); + // lite_mode doesn't use a file + if (lite_mode) { + __mach_stack_logging_shared_memory_address = (uint64_t) pre_write_buffers; + } else { + // this call ensures that the log files exist; analyzing processes will rely on this assumption. + if (create_log_file() == NULL) { + /* postponement support requires cleaning up these structures now */ + __destroy_uniquing_table(pre_write_buffers->uniquing_table); + sld_deallocate_pages(stack_buffer, stack_buffer_sz); + stack_buffer = NULL; + + munmap(pre_write_buffers, full_shared_mem_size); + pre_write_buffers = NULL; + + if (!stack_logging_postponed) { + disable_stack_logging(); + } + return false; } - return; } } + + return true; } -static void +__attribute__((visibility("hidden"))) void __prepare_to_log_stacks_stage2(void) { static int stage2done = 0; - if (! stage2done) { - // malloc() can be called by the following, so these need to be done outside the stack_logging_lock but after the buffers have been set up. - atexit(delete_log_files); // atexit() can call malloc() + if (!stage2done) { + // malloc() can be called by the following, so these need to be done outside the stack_logging_lock but after the buffers + // have been set up. + atexit(delete_log_files); // atexit() can call malloc() // Reaping orphaned stack log files from dead processes is a nicety, to help // reduce wasted disk space. But we don't *always* have to do it. Specifically, @@ -886,18 +1092,131 @@ __prepare_to_log_stacks_stage2(void) } } if (should_reap) { - reap_orphaned_log_files(getpid()); // this calls opendir() which calls malloc() + reap_orphaned_log_files(getpid(), NULL); // this calls opendir() which calls malloc() } stage2done = 1; } } +__attribute__((visibility("hidden"))) void +__malloc_lock_stack_logging() +{ + _malloc_lock_lock(&stack_logging_lock); +} + +__attribute__((visibility("hidden"))) void +__malloc_unlock_stack_logging() +{ + _malloc_lock_unlock(&stack_logging_lock); +} + +const uint64_t __invalid_stack_id = (uint64_t)(-1ll); + +// returns the stack id or invalid_stack_id if any kind of error +// this needs to be done while stack_logging_lock is locked) + +__attribute__((visibility("hidden"))) uint64_t +__enter_stack_into_table_while_locked(vm_address_t self_thread, uint32_t num_hot_to_skip, boolean_t add_thread_id, size_t ptr_size) +{ + // gather stack + uint32_t count; + thread_stack_pcs(stack_buffer, STACK_LOGGING_MAX_STACK_SIZE - 1, &count); // only gather up to STACK_LOGGING_MAX_STACK_SIZE-1 since we append thread id + + if (add_thread_id) { + stack_buffer[count++] = self_thread + 1; // stuffing thread # in the coldest slot. Add 1 to match what the old stack logging did. + } + + // skip stack frames after the malloc call + num_hot_to_skip += 4; + + if (count <= num_hot_to_skip) { + // Oops! Didn't get a valid backtrace from thread_stack_pcs(). + return __invalid_stack_id; + } + + // unique stack in memory + count -= num_hot_to_skip; + +#if __LP64__ + mach_vm_address_t *frames = (mach_vm_address_t*)stack_buffer + num_hot_to_skip; +#else + mach_vm_address_t frames[STACK_LOGGING_MAX_STACK_SIZE]; + uint32_t i; + for (i = 0; i < count; i++) { + frames[i] = stack_buffer[i+num_hot_to_skip]; + } +#endif + + uint64_t uniqueStackIdentifier = __invalid_stack_id; + + while (!enter_frames_in_table(pre_write_buffers->uniquing_table, &uniqueStackIdentifier, frames, count, ptr_size)) { + if (!__expand_uniquing_table(pre_write_buffers->uniquing_table)) + return __invalid_stack_id; + } + + return uniqueStackIdentifier; +} + +static void +decrement_ref_count(table_slot_t *table_slot, size_t ptr_size) +{ + if (table_slot->refcount_slot.refcount > 0) { + table_slot->refcount_slot.refcount -= ptr_size; + + if (table_slot->refcount_slot.refcount == 0) { + table_slot->slots.slot0 = table_slot->slots.slot1 = 0; + } + } +} + +__attribute__((visibility("hidden"))) void +__decrement_table_slot_refcount(uint64_t stack_id, size_t ptr_size) +{ + __malloc_lock_stack_logging(); + + // see if msl lite was disabled behind our backs + if (!is_stack_logging_lite_enabled()) { + __malloc_unlock_stack_logging(); + return; + } + + backtrace_uniquing_table *uniquing_table = pre_write_buffers->uniquing_table; + + assert(uniquing_table->nodes_use_refcount); + assert(!uniquing_table->in_client_process); + + slot_parent parent = stack_id; + slot_parent prev_parent = __invalid_stack_id; + + do { + if (parent == prev_parent) { + malloc_printf("circular parent reference in __decrement_table_slot_refcount\n"); + break; + } + + prev_parent = parent; + + table_slot_t *table_slot = (table_slot_t *) (uniquing_table->u.table + (parent * 2)); + + parent = table_slot->refcount_slot.parent; + decrement_ref_count(table_slot, ptr_size); + } while (parent != slot_no_parent_refcount); + + __malloc_unlock_stack_logging(); +} void -__disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t arg2, uintptr_t arg3, uintptr_t return_val, uint32_t num_hot_to_skip) +__disk_stack_logging_log_stack(uint32_t type_flags, + uintptr_t zone_ptr, + uintptr_t arg2, + uintptr_t arg3, + uintptr_t return_val, + uint32_t num_hot_to_skip) { - if (!stack_logging_enable_logging || stack_logging_postponed) return; + if (!stack_logging_enable_logging || stack_logging_postponed) { + return; + } uintptr_t size; uintptr_t ptr_arg; @@ -906,13 +1225,15 @@ __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_ if (type_flags & stack_logging_type_alloc && type_flags & stack_logging_type_dealloc) { size = arg3; ptr_arg = arg2; // the original pointer - if (ptr_arg == return_val) return; // realloc had no effect, skipping - + if (ptr_arg == return_val) { + return; // realloc had no effect, skipping + } if (ptr_arg == 0) { // realloc(NULL, size) same as malloc(size) type_flags ^= stack_logging_type_dealloc; } else { // realloc(arg1, arg2) -> result is same as free(arg1); malloc(arg2) -> result - __disk_stack_logging_log_stack(stack_logging_type_dealloc, zone_ptr, ptr_arg, (uintptr_t)0, (uintptr_t)0, num_hot_to_skip + 1); + __disk_stack_logging_log_stack( + stack_logging_type_dealloc, zone_ptr, ptr_arg, (uintptr_t)0, (uintptr_t)0, num_hot_to_skip + 1); __disk_stack_logging_log_stack(stack_logging_type_alloc, zone_ptr, size, (uintptr_t)0, return_val, num_hot_to_skip + 1); return; } @@ -926,20 +1247,25 @@ __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_ // the trouble. ptr_arg = arg2; size = arg3; - if (ptr_arg == 0) return; // free(nil) + if (ptr_arg == 0) { + return; // free(nil) + } } if (type_flags & stack_logging_type_alloc || type_flags & stack_logging_type_vm_allocate) { - if (return_val == 0) return; // alloc that failed + if (return_val == 0) { + return; // alloc that failed + } size = arg2; } if (type_flags & stack_logging_type_vm_allocate || type_flags & stack_logging_type_vm_deallocate) { mach_port_t targetTask = (mach_port_t)zone_ptr; // For now, ignore "injections" of VM into other tasks. - if (targetTask != mach_task_self()) return; + if (targetTask != mach_task_self()) { + return; + } } - type_flags &= stack_logging_valid_type_flags; vm_address_t self_thread = (vm_address_t)_os_tsd_get_direct(__TSD_THREAD_SELF); @@ -957,12 +1283,13 @@ __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_ // lock and enter _malloc_lock_lock(&stack_logging_lock); - thread_doing_logging = self_thread; // for preventing deadlock'ing on stack logging on a single thread + thread_doing_logging = self_thread; // for preventing deadlock'ing on stack logging on a single thread // now actually begin - __prepare_to_log_stacks(); + __prepare_to_log_stacks(false); - // since there could have been a fatal (to stack logging) error such as the log files not being created, check these variables before continuing + // since there could have been a fatal (to stack logging) error such as the log files not being created, check these variables + // before continuing if (!stack_logging_enable_logging || stack_logging_postponed) { thread_doing_logging = 0; _malloc_lock_unlock(&stack_logging_lock); @@ -976,7 +1303,8 @@ __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_ } // compaction - if (last_logged_malloc_address && (type_flags & stack_logging_type_dealloc) && STACK_LOGGING_DISGUISE(ptr_arg) == last_logged_malloc_address) { + if (last_logged_malloc_address && (type_flags & stack_logging_type_dealloc) && + STACK_LOGGING_DISGUISE(ptr_arg) == last_logged_malloc_address) { // *waves hand* the last allocation never occurred pre_write_buffers->next_free_index_buffer_offset -= (uint32_t)sizeof(stack_logging_index_event); last_logged_malloc_address = 0ul; @@ -986,35 +1314,14 @@ __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_ return; } - // gather stack - uint32_t count; - thread_stack_pcs(stack_buffer, STACK_LOGGING_MAX_STACK_SIZE-1, &count); // only gather up to STACK_LOGGING_MAX_STACK_SIZE-1 since we append thread id - stack_buffer[count++] = self_thread + 1; // stuffing thread # in the coldest slot. Add 1 to match what the old stack logging did. - num_hot_to_skip += 2; - if (count <= num_hot_to_skip) { - // Oops! Didn't get a valid backtrace from thread_stack_pcs(). + uint64_t uniqueStackIdentifier = __enter_stack_into_table_while_locked(self_thread, num_hot_to_skip, true, 0); + + if (uniqueStackIdentifier == __invalid_stack_id) { thread_doing_logging = 0; _malloc_lock_unlock(&stack_logging_lock); return; } - // unique stack in memory - count -= num_hot_to_skip; -#if __LP64__ - mach_vm_address_t *frames = (mach_vm_address_t*)stack_buffer + num_hot_to_skip; -#else - mach_vm_address_t frames[STACK_LOGGING_MAX_STACK_SIZE]; - uint32_t i; - for (i = 0; i < count; i++) { - frames[i] = stack_buffer[i+num_hot_to_skip]; - } -#endif - - uint64_t uniqueStackIdentifier = (uint64_t)(-1ll); - while (!__enter_frames_in_table(pre_write_buffers->uniquing_table, &uniqueStackIdentifier, frames, (int32_t)count)) { - __expand_uniquing_table(pre_write_buffers->uniquing_table); - } - stack_logging_index_event current_index; if (type_flags & stack_logging_type_alloc || type_flags & stack_logging_type_vm_allocate) { current_index.address = STACK_LOGGING_DISGUISE(return_val); @@ -1038,7 +1345,8 @@ __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_ } // store bytes in buffers - memcpy(pre_write_buffers->index_buffer+pre_write_buffers->next_free_index_buffer_offset, ¤t_index, sizeof(stack_logging_index_event)); + memcpy(pre_write_buffers->index_buffer + pre_write_buffers->next_free_index_buffer_offset, ¤t_index, + sizeof(stack_logging_index_event)); pre_write_buffers->next_free_index_buffer_offset += (uint32_t)sizeof(stack_logging_index_event); thread_doing_logging = 0; @@ -1046,34 +1354,40 @@ __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_ } void -__stack_logging_fork_prepare(void) { +__stack_logging_fork_prepare(void) +{ _malloc_lock_lock(&stack_logging_lock); } void -__stack_logging_fork_parent(void) { +__stack_logging_fork_parent(void) +{ _malloc_lock_unlock(&stack_logging_lock); } void -__stack_logging_fork_child(void) { +__stack_logging_fork_child(void) +{ malloc_logger = NULL; stack_logging_enable_logging = 0; - _malloc_lock_unlock(&stack_logging_lock); + _malloc_lock_init(&stack_logging_lock); } void -__stack_logging_early_finished(void) { +__stack_logging_early_finished(void) +{ stack_logging_finished_init = 1; stack_logging_postponed = 0; } -__attribute__((visibility("hidden"))) -boolean_t +// support for gdb and others checking for stack_logging locks +__attribute__((visibility("hidden"))) boolean_t __stack_logging_locked(void) { bool acquired_lock = _malloc_lock_trylock(&stack_logging_lock); - if (acquired_lock) _malloc_lock_unlock(&stack_logging_lock); + if (acquired_lock) { + _malloc_lock_unlock(&stack_logging_lock); + } return (acquired_lock ? false : true); } @@ -1083,20 +1397,27 @@ __stack_logging_locked(void) #pragma mark - Design notes: /* - - this first one will look through the index, find the "stack_identifier" (i.e. the offset in the log file), and call the third function listed here. - extern kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *num_frames); - // Gets the last allocation record about address - - if !address, will load index and iterate through (expensive) - else will load just index, search for stack, and then use third function here to retrieve. (also expensive) - extern kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context); - // Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records - - this function will load the stack file, look for the stack, and follow up to STACK_LOGGING_FORCE_FULL_BACKTRACE_EVERY references to reconstruct. - extern kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); - // Given a uniqued_stack fills stack_frames_buffer - + * + * this first one will look through the index, find the "stack_identifier" (i.e. the offset in the log file), and call the third + * function listed here. + * extern kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t + * stack_frames_buffer, uint32_t max_stack_frames, uint32_t *num_frames); + * // Gets the last allocation record about address + * + * if !address, will load index and iterate through (expensive) + * else will load just index, search for stack, and then use third function here to retrieve. (also expensive) + * extern kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void + * enumerator(mach_stack_logging_record_t, void *), void *context); + * // Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies + * enumerator to all records + * + * this function will load the stack file, look for the stack, and follow up to STACK_LOGGING_FORCE_FULL_BACKTRACE_EVERY references + * to + * reconstruct. + * extern kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t + * stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); + * // Given a uniqued_stack fills stack_frames_buffer + * */ #pragma mark - @@ -1104,10 +1425,13 @@ __stack_logging_locked(void) // This is client-side code to get a stack log from a uniquing_table. static void -free_uniquing_table_chunks(backtrace_uniquing_table *uniquing_table) { +free_uniquing_table_chunks(backtrace_uniquing_table *uniquing_table) +{ table_chunk_header_t *table_chunk_header = uniquing_table->u.first_table_chunk_hdr; + assert(uniquing_table->in_client_process); while (table_chunk_header) { - mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)(table_chunk_header->table_chunk), table_chunk_header->table_chunk_size); + mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)(table_chunk_header->table_chunk), + table_chunk_header->table_chunk_size); table_chunk_header_t *next = table_chunk_header->next_table_chunk_header; free(table_chunk_header); table_chunk_header = next; @@ -1115,35 +1439,41 @@ free_uniquing_table_chunks(backtrace_uniquing_table *uniquing_table) { } static kern_return_t -read_uniquing_table_from_task(task_t remote_task, backtrace_uniquing_table *uniquing_table) { +read_uniquing_table_from_task(task_t remote_task, backtrace_uniquing_table *uniquing_table) +{ + assert(uniquing_table->in_client_process); mach_vm_address_t next_address_to_read = uniquing_table->table_address; uint64_t remaining_size_to_read = uniquing_table->tableSize; - const mach_vm_size_t two_gigabytes = 2ull * 1024 * 1024 * 1024; // attempting to read 4 GB in one call fails, so try a max of 2 GB + const mach_vm_size_t two_gigabytes = + 2ull * 1024 * 1024 * 1024; // attempting to read 4 GB in one call fails, so try a max of 2 GB table_chunk_header_t **table_chunk_hdr_ptr = &(uniquing_table->u.first_table_chunk_hdr); *table_chunk_hdr_ptr = NULL; - + while (remaining_size_to_read > 0ull) { vm_address_t local_table_chunk_address = 0ul; mach_msg_type_number_t local_table_chunk_size = 0; - + mach_vm_size_t next_size_to_read = (remaining_size_to_read > two_gigabytes) ? two_gigabytes : remaining_size_to_read; while (1) { - kern_return_t err = mach_vm_read(remote_task, next_address_to_read, next_size_to_read, &local_table_chunk_address, &local_table_chunk_size); + kern_return_t err = mach_vm_read( + remote_task, next_address_to_read, next_size_to_read, &local_table_chunk_address, &local_table_chunk_size); if (err == KERN_SUCCESS) { *table_chunk_hdr_ptr = malloc(sizeof(table_chunk_header_t)); table_chunk_header_t *table_chunk_hdr = *table_chunk_hdr_ptr; - table_chunk_hdr->num_nodes_in_chunk = local_table_chunk_size / (sizeof(mach_vm_address_t) * 2);; - table_chunk_hdr->table_chunk = local_table_chunk_address; + table_chunk_hdr->num_nodes_in_chunk = local_table_chunk_size / (sizeof(mach_vm_address_t) * 2); + ; + table_chunk_hdr->table_chunk = (mach_vm_address_t *)local_table_chunk_address; table_chunk_hdr->table_chunk_size = local_table_chunk_size; - table_chunk_hdr->next_table_chunk_header = NULL; // initialize it, in case it is the last chunk - table_chunk_hdr_ptr = &(table_chunk_hdr->next_table_chunk_header); // set up to assign next chunk to this + table_chunk_hdr->next_table_chunk_header = NULL; // initialize it, in case it is the last chunk + table_chunk_hdr_ptr = &(table_chunk_hdr->next_table_chunk_header); // set up to assign next chunk to this next_address_to_read += local_table_chunk_size; remaining_size_to_read -= local_table_chunk_size; - //fprintf(stderr, "requested %#qx, got %#x of %#qx at %p from backtrace uniquing table of target process\n", next_size_to_read, local_table_chunk_size, uniquing_table->tableSize, table_chunk_hdr); + // fprintf(stderr, "requested %#qx, got %#x of %#qx at %p from backtrace uniquing table of target process\n", + // next_size_to_read, local_table_chunk_size, uniquing_table->tableSize, table_chunk_hdr); break; } else { - //fprintf(stderr, "requested %#qx, failed\n", next_size_to_read); + // fprintf(stderr, "requested %#qx, failed\n", next_size_to_read); next_size_to_read /= 2; if (next_size_to_read <= 1024 * 1024) { // We couldn't even map one megabyte? Let's call that an error... @@ -1159,6 +1489,7 @@ read_uniquing_table_from_task(task_t remote_task, backtrace_uniquing_table *uniq static mach_vm_address_t * get_node_from_uniquing_table(backtrace_uniquing_table *uniquing_table, uint64_t index_pos) { + assert(uniquing_table->in_client_process); table_chunk_header_t *table_chunk_hdr = uniquing_table->u.first_table_chunk_hdr; uint64_t start_node_of_chunk = 0; while (table_chunk_hdr && index_pos > start_node_of_chunk + table_chunk_hdr->num_nodes_in_chunk) { @@ -1167,44 +1498,76 @@ get_node_from_uniquing_table(backtrace_uniquing_table *uniquing_table, uint64_t start_node_of_chunk += table_chunk_hdr->num_nodes_in_chunk; } } - assert(table_chunk_hdr); + + // Handle case where someone passes an invalid stack id + // get_node_from_uniquing_table should be more tolerant + if (!table_chunk_hdr) { + return NULL; + } + uint64_t index_in_chunk = index_pos - start_node_of_chunk; mach_vm_address_t *node = table_chunk_hdr->table_chunk + (index_in_chunk * 2); return node; } static void -unwind_stack_from_table_index(backtrace_uniquing_table *uniquing_table, uint64_t index_pos, mach_vm_address_t *out_frames_buffer, uint32_t *out_frames_count, uint32_t max_frames) +unwind_stack_from_table_index(backtrace_uniquing_table *uniquing_table, + uint64_t index_pos, + mach_vm_address_t *out_frames_buffer, + uint32_t *out_frames_count, + uint32_t max_frames, + boolean_t use_refcount) { mach_vm_address_t *node = get_node_from_uniquing_table(uniquing_table, index_pos); uint32_t foundFrames = 0; - if (index_pos < uniquing_table->numNodes) { + slot_parent end_parent = use_refcount ? slot_no_parent_refcount : slot_no_parent_normal; + + if (node && index_pos < uniquing_table->numNodes) { while (foundFrames < max_frames) { - out_frames_buffer[foundFrames++] = node[0]; - if (node[1] == (mach_vm_address_t)(-1ll)) break; - node = get_node_from_uniquing_table(uniquing_table, node[1]); + table_slot_t *table_slot = (table_slot_t *) (node); + + slot_address address = use_refcount ? table_slot->refcount_slot.address : table_slot->normal_slot.address; + + out_frames_buffer[foundFrames++] = address; + + if (use_refcount && table_slot->refcount_slot.refcount == 0) { + break; + } + + slot_parent parent = use_refcount ? table_slot->refcount_slot.parent : table_slot->normal_slot.parent; + + if (parent == end_parent) { + break; + } + + node = get_node_from_uniquing_table(uniquing_table, parent); } } - + *out_frames_count = foundFrames; } #pragma mark - caching __attribute__((always_inline)) static inline size_t -hash_index(uint64_t address, size_t max_pos) { - return (size_t)((address >> 2) % (max_pos-1)); // simplicity rules. +hash_index(uint64_t address, size_t max_pos) +{ + return (size_t)((address >> 2) % (max_pos - 1)); // simplicity rules. } __attribute__((always_inline)) static inline size_t -hash_multiplier(size_t capacity, uint32_t allowed_collisions) { - return (capacity/(allowed_collisions*2+1)); +hash_multiplier(size_t capacity, uint32_t allowed_collisions) +{ + return (capacity / (allowed_collisions * 2 + 1)); } __attribute__((always_inline)) static inline size_t -next_hash(size_t hash, size_t multiplier, size_t capacity, uint32_t collisions) { +next_hash(size_t hash, size_t multiplier, size_t capacity, uint32_t collisions) +{ hash += multiplier * collisions; - if (hash >= capacity) hash -= capacity; + if (hash >= capacity) { + hash -= capacity; + } return hash; } @@ -1228,7 +1591,7 @@ transfer_node(remote_index_cache *cache, remote_index_node *old_node) } while (collisions <= cache->collision_allowance); if (collisions > cache->collision_allowance) { - fprintf(stderr, "reporting bad hash function! disk stack logging reader %lu bit. (transfer_node)\n", sizeof(void*)*8); + fprintf(stderr, "reporting bad hash function! disk stack logging reader %lu bit. (transfer_node)\n", sizeof(void *) * 8); } } @@ -1243,7 +1606,7 @@ expand_cache(remote_index_cache *cache) cache->cache_size <<= 2; cache->cache_node_capacity <<= 2; cache->collision_allowance += 3; - cache->table_memory = (void*)calloc(cache->cache_node_capacity, sizeof(remote_index_node)); + cache->table_memory = (void *)calloc(cache->cache_node_capacity, sizeof(remote_index_node)); // repopulate (expensive!) size_t i; @@ -1253,7 +1616,9 @@ expand_cache(remote_index_cache *cache) } } free(old_table); - // printf("cache expanded to %0.2f mb (eff: %3.0f%%, capacity: %lu, nodes: %llu, llnodes: %llu)\n", ((float)(cache->cache_size))/(1 << 20), ((float)(cache->cache_node_count)*100.0)/((float)(cache->cache_node_capacity)), cache->cache_node_capacity, cache->cache_node_count, cache->cache_llnode_count); + // printf("cache expanded to %0.2f mb (eff: %3.0f%%, capacity: %lu, nodes: %llu, llnodes: %llu)\n", + //((float)(cache->cache_size))/(1 << 20), ((float)(cache->cache_node_count)*100.0)/((float)(cache->cache_node_capacity)), + // cache->cache_node_capacity, cache->cache_node_count, cache->cache_llnode_count); } static void @@ -1288,7 +1653,8 @@ insert_node(remote_index_cache *cache, uint64_t address, uint64_t index_file_off // share the region itself via shm_open(). The VM_FLAGS_RETURN_DATA_ADDR flag is necessary // for iOS in case the target process uses a different VM page size than the analysis tool process. static mach_vm_address_t -map_shared_memory_from_task(task_t sourceTask, mach_vm_address_t sourceAddress, mach_vm_size_t sourceSize) { +map_shared_memory_from_task(task_t sourceTask, mach_vm_address_t sourceAddress, mach_vm_size_t sourceSize) +{ #if TARGET_OS_EMBEDDED int mapRequestFlags = VM_FLAGS_ANYWHERE | VM_FLAGS_RETURN_DATA_ADDR; mach_vm_address_t mapRequestAddress = sourceAddress; @@ -1302,7 +1668,8 @@ map_shared_memory_from_task(task_t sourceTask, mach_vm_address_t sourceAddress, mach_vm_address_t mappedAddress = 0; vm_prot_t outCurrentProt = VM_PROT_NONE; vm_prot_t outMaxProt = VM_PROT_NONE; - kern_return_t err = mach_vm_remap(mach_task_self(), &mappedAddress, mapRequestSize, 0, mapRequestFlags, sourceTask, mapRequestAddress, false, &outCurrentProt, &outMaxProt, VM_INHERIT_NONE); + kern_return_t err = mach_vm_remap(mach_task_self(), &mappedAddress, mapRequestSize, 0, mapRequestFlags, sourceTask, + mapRequestAddress, false, &outCurrentProt, &outMaxProt, VM_INHERIT_NONE); if (err != KERN_SUCCESS) { return 0; } @@ -1316,18 +1683,22 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) // create from scratch if necessary. if (!cache) { - descriptors->cache = cache = (remote_index_cache*)calloc((size_t)1, sizeof(remote_index_cache)); + descriptors->cache = cache = (remote_index_cache *)calloc((size_t)1, sizeof(remote_index_cache)); cache->cache_node_capacity = 1 << 14; cache->collision_allowance = 17; cache->last_index_file_offset = 0; - cache->cache_size = cache->cache_node_capacity*sizeof(remote_index_node); - cache->table_memory = (void*)calloc(cache->cache_node_capacity, sizeof(remote_index_node)); + cache->cache_size = cache->cache_node_capacity * sizeof(remote_index_node); + cache->table_memory = (void *)calloc(cache->cache_node_capacity, sizeof(remote_index_node)); - cache->shmem = map_shared_memory_from_task(descriptors->remote_task, descriptors->remote_stack_buffer_shared_memory_address, sizeof(stack_buffer_shared_memory)); - if (! cache->shmem) { + cache->shmem = (stack_buffer_shared_memory *)map_shared_memory_from_task(descriptors->remote_task, + descriptors->remote_stack_buffer_shared_memory_address, sizeof(stack_buffer_shared_memory)); + if (!cache->shmem) { // failed to connect to the shared memory region; warn and continue. - _malloc_printf(ASL_LEVEL_INFO, "warning: unable to map shared memory from %llx in target process %d; no stack backtraces will be available.\n", descriptors->remote_stack_buffer_shared_memory_address, descriptors->remote_pid); + _malloc_printf(ASL_LEVEL_INFO, + "warning: unable to map shared memory from %llx in target process %d; no stack backtraces will be available.\n", + descriptors->remote_stack_buffer_shared_memory_address, descriptors->remote_pid); } + cache->lite_mode = descriptors->task_uses_lite_mode; } // suspend and see how much updating there is to do. there are three scenarios, listed below @@ -1337,13 +1708,20 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) } struct stat file_statistics; - fstat(fileno(descriptors->index_file_stream), &file_statistics); + + if (descriptors->index_file_stream) { + fstat(fileno(descriptors->index_file_stream), &file_statistics); + } else { + file_statistics.st_size = 0; + } + size_t read_size = (descriptors->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); uint64_t read_this_update = 0; // the delta indecies is a complex number; there are three cases: // 1. there is no shared memory (or we can't connect); diff the last_index_file_offset from the filesize. - // 2. the only updates have been in shared memory; disk file didn't change at all. delta_indecies should be zero, scan snapshot only. + // 2. the only updates have been in shared memory; disk file didn't change at all. delta_indecies should be zero, scan snapshot + // only. // 3. the updates have flushed to disk, meaning that most likely there is new data on disk that wasn't read from shared memory. // correct delta_indecies for the pre-scanned amount and read the new data from disk and shmem. uint64_t delta_indecies = (file_statistics.st_size - cache->last_index_file_offset) / read_size; @@ -1365,6 +1743,11 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) } } + // need to update the snapshot if in lite mode and haven't yet read the uniquing table + if (descriptors->task_uses_lite_mode && cache->uniquing_table_snapshot.numPages == 0) { + update_snapshot = true; + } + // if a snapshot is necessary, memcpy from remote frozen process' memory // note: there were two ways to do this - spin lock or suspend. suspend allows us to // analyze processes even if they were artificially suspended. with a lock, there'd be @@ -1376,23 +1759,31 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) vm_address_t local_uniquing_address = 0ul; mach_msg_type_number_t local_uniquing_size = 0; mach_vm_size_t desired_size = round_page(sizeof(backtrace_uniquing_table)); - if ((err = mach_vm_read(descriptors->remote_task, cache->shmem->uniquing_table, desired_size, &local_uniquing_address, &local_uniquing_size)) != KERN_SUCCESS - || local_uniquing_size != desired_size) { - fprintf(stderr, "error while attempting to mach_vm_read remote stack uniquing table (%d): %s\n", err, mach_error_string(err)); + if ((err = mach_vm_read(descriptors->remote_task, (mach_vm_address_t)cache->shmem->uniquing_table, desired_size, + &local_uniquing_address, &local_uniquing_size)) != KERN_SUCCESS || + local_uniquing_size != desired_size) { + fprintf(stderr, "error while attempting to mach_vm_read remote stack uniquing table (%d): %s\n", err, + mach_error_string(err)); } else { // the mach_vm_read was successful, so acquire the uniquing table // need to re-read the table, so deallocate the current memory + cache->uniquing_table_snapshot.in_client_process = true; free_uniquing_table_chunks(&cache->uniquing_table_snapshot); // The following line copies the uniquing table structure data, but the actual uniquing table memory is invalid // since it's a pointer from the remote process. - cache->uniquing_table_snapshot = *((backtrace_uniquing_table*)local_uniquing_address); + cache->uniquing_table_snapshot = *((backtrace_uniquing_table *)local_uniquing_address); + cache->uniquing_table_snapshot.nodes_use_refcount = cache->lite_mode; + cache->uniquing_table_snapshot.u.first_table_chunk_hdr = NULL; + cache->uniquing_table_snapshot.in_client_process = true; + // Read the uniquing table memory from the target process. err = read_uniquing_table_from_task(descriptors->remote_task, &(cache->uniquing_table_snapshot)); if (err) { - fprintf(stderr, "error while attempting to mach_vm_read remote stack uniquing table contents (%d): %s\n", err, mach_error_string(err)); + fprintf(stderr, "error while attempting to mach_vm_read remote stack uniquing table contents (%d): %s\n", err, + mach_error_string(err)); } // Check the error status below, after further deallocating and resuming the target task. @@ -1404,14 +1795,16 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) if (descriptors->remote_task != mach_task_self()) { task_resume(descriptors->remote_task); } - + if (err != KERN_SUCCESS) { - // To Do: further clean up allocated resources, and also try to prevent printing numerous identical "out of memory" errors (maybe we should abort?). + // To Do: further clean up allocated resources, and also try to prevent printing numerous identical "out of memory" errors + // (maybe we should abort?). return err; } - if (!update_snapshot && delta_indecies == 0) return KERN_SUCCESS; // absolutely no updating needed. - + if (!update_snapshot && delta_indecies == 0) { + return KERN_SUCCESS; // absolutely no updating needed. + } FILE *the_index = (descriptors->index_file_stream); // prepare for the read; target process could be 32 or 64 bit. @@ -1423,13 +1816,14 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) uint32_t i; if (delta_indecies) { char bufferSpace[4096]; // 4 kb - target_32_index = (stack_logging_index_event32*)bufferSpace; - target_64_index = (stack_logging_index_event64*)bufferSpace; - size_t number_slots = (size_t)(4096/read_size); + target_32_index = (stack_logging_index_event32 *)bufferSpace; + target_64_index = (stack_logging_index_event64 *)bufferSpace; + size_t number_slots = (size_t)(4096 / read_size); size_t read_count = 0; if (fseeko(the_index, (off_t)(cache->last_index_file_offset), SEEK_SET)) { - fprintf(stderr, "error while attempting to cache information from remote stack index file. (update_cache_for_file_streams)\n"); + fprintf(stderr, + "error while attempting to cache information from remote stack index file. (update_cache_for_file_streams)\n"); } off_t current_index_position = cache->last_index_file_offset; do { @@ -1443,7 +1837,8 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) } } else { for (i = 0; i < read_count; i++) { - insert_node(cache, (mach_vm_address_t)STACK_LOGGING_DISGUISE(target_32_index[i].address), (uint64_t)current_index_position); + insert_node(cache, (mach_vm_address_t)STACK_LOGGING_DISGUISE(target_32_index[i].address), + (uint64_t)current_index_position); read_this_update++; current_index_position += read_size; } @@ -1457,43 +1852,78 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors) } if (update_snapshot) { - target_32_index = (stack_logging_index_event32*)(cache->snapshot.index_buffer); - target_64_index = (stack_logging_index_event64*)(cache->snapshot.index_buffer); + target_32_index = (stack_logging_index_event32 *)(cache->snapshot.index_buffer); + target_64_index = (stack_logging_index_event64 *)(cache->snapshot.index_buffer); uint32_t free_snapshot_scan_index = cache->snapshot.next_free_index_buffer_offset / (uint32_t)read_size; off_t current_index_position = cache->snapshot.start_index_offset; if (descriptors->task_is_64_bit) { for (i = last_snapshot_scan_index; i < free_snapshot_scan_index; i++) { - insert_node(cache, STACK_LOGGING_DISGUISE(target_64_index[i].address), (uint64_t)(current_index_position + (i * read_size))); + insert_node(cache, STACK_LOGGING_DISGUISE(target_64_index[i].address), + (uint64_t)(current_index_position + (i * read_size))); } } else { for (i = last_snapshot_scan_index; i < free_snapshot_scan_index; i++) { - insert_node(cache, (mach_vm_address_t)STACK_LOGGING_DISGUISE(target_32_index[i].address), (uint64_t)(current_index_position + (i * read_size))); + insert_node(cache, (mach_vm_address_t)STACK_LOGGING_DISGUISE(target_32_index[i].address), + (uint64_t)(current_index_position + (i * read_size))); } } } - + return KERN_SUCCESS; } static void destroy_cache_for_file_streams(remote_task_file_streams *descriptors) { + if (!descriptors->cache) { + return; + } if (descriptors->cache->shmem) { munmap(descriptors->cache->shmem, sizeof(stack_buffer_shared_memory)); } free(descriptors->cache->table_memory); + free_uniquing_table_chunks(&descriptors->cache->uniquing_table_snapshot); free(descriptors->cache); descriptors->cache = NULL; } #pragma mark - internal +static FILE * +open_log_file_at_path(char *pathname, remote_task_file_streams *streams) { + FILE *file = fopen(pathname, "r"); + if (!file) { + return NULL; + } + + char *log_file_name = strrchr(pathname, '/'); + char *p = log_file_name; + + // File names are of the form stack-logs..
..XXXXXX.index + if (p) p = strchr(p, '.'); // skip past "stack-logs" + if (p) p = strchr(p + 1, '.'); // skip past "." + if (p) p++; // skip past '.' + + if (!p) { + return NULL; + } + + char *shared_memory_address_string = p; + + // The hex address of the remote_index_cache in the target process + // is given in the stack log file name, following the pid and a period. + streams->remote_stack_buffer_shared_memory_address = strtoll(shared_memory_address_string, NULL, 16); + streams->index_file_stream = file; + + return file; +} + // In the stack log analysis process, find the stack logging file for target process // by scanning the given directory for entries with names of the form "stack-logs..*.index" // If we find such an entry then open that stack logging file. static FILE * -open_log_file_from_directory(pid_t pid, char* directory, remote_task_file_streams *streams) +open_log_file_from_directory(pid_t pid, char *directory, remote_task_file_streams *streams) { DIR *dp; struct dirent *entry; @@ -1505,23 +1935,20 @@ open_log_file_from_directory(pid_t pid, char* directory, remote_task_file_stream if (access(directory, R_OK | X_OK) == 0 && (dp = opendir(directory)) != NULL) { // It's OK to use snprintf in this routine since it should only be called by the clients // of stack logging, and thus calls to malloc are OK. - snprintf(prefix_and_pid , (size_t)PATH_MAX, "%s%d.", stack_log_file_base_name, pid); // make sure to use "%s%d." rather than just "%s%d" to match the whole pid + snprintf(prefix_and_pid, (size_t)PATH_MAX, "%s%d.", stack_log_file_base_name, + pid); // make sure to use "%s%d." rather than just "%s%d" to match the whole pid size_t prefix_and_pid_length = strlen(prefix_and_pid); - while ( (entry = readdir(dp)) != NULL ) { - if ( strncmp( entry->d_name, prefix_and_pid, prefix_and_pid_length) == 0 ) { + while ((entry = readdir(dp)) != NULL) { + if (strncmp(entry->d_name, prefix_and_pid, prefix_and_pid_length) == 0) { snprintf(pathname, (size_t)PATH_MAX, "%s/%s", directory, entry->d_name); - file = fopen(pathname, "r"); - - // The hex address of the remote_index_cache in the target process - // is given in the stack log file name, following the pid and a period. - streams->remote_stack_buffer_shared_memory_address = strtoll(entry->d_name + prefix_and_pid_length, NULL, 16); + file = open_log_file_at_path(pathname, streams); break; } } closedir(dp); } - streams->index_file_stream = file; + return file; } @@ -1532,7 +1959,7 @@ open_log_file_from_directory(pid_t pid, char* directory, remote_task_file_stream // logging code in the target process as well, we copy the result into the // env_var_value_buf of length max_path_len supplied by the caller. static bool -getenv_from_process(pid_t pid, char *env_var_name, char *env_var_value_buf, size_t buf_length ) +getenv_from_process(pid_t pid, char *env_var_name, char *env_var_value_buf, size_t buf_length) { env_var_value_buf[0] = '\0'; @@ -1544,7 +1971,7 @@ getenv_from_process(pid_t pid, char *env_var_name, char *env_var_value_buf, size // is still running. if (pid == getpid()) { char *env_var_value = getenv(env_var_name); - if (! env_var_value) { + if (!env_var_value) { return false; } else { strlcpy(env_var_value_buf, env_var_value, buf_length); @@ -1553,7 +1980,7 @@ getenv_from_process(pid_t pid, char *env_var_name, char *env_var_value_buf, size } int mib[3]; - size_t argbufSize = 0; // Must initialize this to 0 so this works when compiled for x86_64. + size_t argbufSize = 0; // Must initialize this to 0 so this works when compiled for x86_64. // First get the maximum arguments size, to determine the necessary buffer size. mib[0] = CTL_KERN; @@ -1561,32 +1988,38 @@ getenv_from_process(pid_t pid, char *env_var_name, char *env_var_value_buf, size size_t size = sizeof(argbufSize); int ret = sysctl(mib, 2, &argbufSize, &size, NULL, 0); - if (ret != 0) return false; + if (ret != 0) { + return false; + } mib[0] = CTL_KERN; - mib[1] = KERN_PROCARGS2; // The older KERN_PROCARGS is deprecated. + mib[1] = KERN_PROCARGS2; // The older KERN_PROCARGS is deprecated. mib[2] = pid; - char *argbuf = (char *) alloca(argbufSize); - ret = sysctl(mib, 3, argbuf, &argbufSize, (void*)NULL, 0); - if (ret != 0) return false; - argbuf[argbufSize - 1] = '\0'; // make sure the buffer is null-terminated + char *argbuf = (char *)alloca(argbufSize); + ret = sysctl(mib, 3, argbuf, &argbufSize, (void *)NULL, 0); + if (ret != 0) { + return false; + } + argbuf[argbufSize - 1] = '\0'; // make sure the buffer is null-terminated char *p = argbuf; char *endp = &argbuf[argbufSize]; // Skip over argc, which is always 4 bytes long (int-sized), even in 64-bit architectures. - int argumentCount = *((int*)argbuf); + int argumentCount = *((int *)argbuf); p += sizeof(argumentCount); // Skip over arguments, using the argumentCount read from the start of argbuf. - argumentCount++; // increment argumentCount to also skip saved exec path, which comes first + argumentCount++; // increment argumentCount to also skip saved exec path, which comes first for (int argumentNum = 0; argumentNum < argumentCount && p < endp; argumentNum++) { - while (p < endp && *p != '\0') p++; - while (p < endp && *p == '\0') p++; // saved exec path sometimes has multiple nul's + while (p < endp && *p != '\0') + p++; + while (p < endp && *p == '\0') + p++; // saved exec path sometimes has multiple nul's } size_t env_var_name_length = strlen(env_var_name); - + // Examine environment variables. while ((p + env_var_name_length + 1) < endp && *p != '\0') { if (strncmp(p, env_var_name, env_var_name_length) == 0 && p[env_var_name_length] == '=') { @@ -1595,42 +2028,53 @@ getenv_from_process(pid_t pid, char *env_var_name, char *env_var_value_buf, size //_malloc_printf(ASL_LEVEL_INFO, "found env var %s='%s'\n", env_var_name, env_var_value_buf); return true; } - while (p < endp && *p != '\0') p++; + while (p < endp && *p != '\0') + p++; p++; } return false; } static FILE * -open_log_file(pid_t pid, remote_task_file_streams *streams) +open_log_file(pid_t target_pid, remote_task_file_streams *streams) { static bool already_reaped = false; - if (! already_reaped) { - reap_orphaned_log_files(pid); // reap any left-over log files (for non-existant processes, but not for this analysis process) + if (!already_reaped) { + // reap any left-over log files (for non-existent processes, but not for this analysis process) + reap_orphaned_log_files(target_pid, streams); already_reaped = true; } - + + if (streams->index_file_stream != NULL) { // reap_orphaned_log_files opened the file + return streams->index_file_stream; + } + // Since we're searching for the log file here, not creating it, we can search in any order we want. // So look at MallocStackLoggingDirectory last since that is almost never set. - FILE *file = open_log_file_from_directory(pid, _PATH_TMP, streams); - if (! file) { - char *env_var_names[] = { "TMPDIR", "MallocStackLoggingDirectory" }; + FILE *file = open_log_file_from_directory(target_pid, _PATH_TMP, streams); + if (!file) { + char *env_var_names[] = {"TMPDIR", "MallocStackLoggingDirectory"}; for (unsigned i = 0; i < sizeof(env_var_names) / sizeof(char *); i++) { char directory[PATH_MAX]; - bool success = getenv_from_process(pid, env_var_names[i], directory, sizeof(directory)); + bool success = getenv_from_process(target_pid, env_var_names[i], directory, sizeof(directory)); if (success) { - file = open_log_file_from_directory(pid, directory, streams); - if (file) break; + file = open_log_file_from_directory(target_pid, directory, streams); + if (file) { + break; + } } } } return file; } -static remote_task_file_streams* -retain_file_streams_for_task(task_t task) +// shared_memory_address is non-zero when in lite mode and this is called for the first time on a task +static remote_task_file_streams * +retain_file_streams_for_task(task_t task, vm_address_t shared_memory_address) { - if (task == MACH_PORT_NULL) return NULL; + if (task == MACH_PORT_NULL) { + return NULL; + } _malloc_lock_lock(&remote_fd_list_lock); @@ -1649,7 +2093,9 @@ retain_file_streams_for_task(task_t task) if (remote_task_fd_count == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) { while (remote_fds[next_remote_task_fd].in_use_count > 0) { next_remote_task_fd++; - if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) next_remote_task_fd = 0; + if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) { + next_remote_task_fd = 0; + } failures++; if (failures >= STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) { _malloc_lock_unlock(&remote_fd_list_lock); @@ -1669,19 +2115,23 @@ retain_file_streams_for_task(task_t task) remote_task_file_streams *this_task_streams = &remote_fds[next_remote_task_fd]; - open_log_file(pid, this_task_streams); - - // check if opens failed - if (this_task_streams->index_file_stream == NULL) { - _malloc_lock_unlock(&remote_fd_list_lock); - return NULL; + if (shared_memory_address != 0) { + this_task_streams->remote_stack_buffer_shared_memory_address = shared_memory_address; + this_task_streams->task_uses_lite_mode = true; + } else { + open_log_file(pid, this_task_streams); + + if (this_task_streams->index_file_stream == NULL) { + _malloc_lock_unlock(&remote_fd_list_lock); + return NULL; + } } // check if target pid is running 64-bit - int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; + int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; struct kinfo_proc processInfo; size_t bufsize = sizeof(processInfo); - if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, (size_t)0) == 0 && bufsize > 0) { + if (sysctl(mib, (unsigned)(sizeof(mib) / sizeof(int)), &processInfo, &bufsize, NULL, (size_t)0) == 0 && bufsize > 0) { this_task_streams->task_is_64_bit = processInfo.kp_proc.p_flag & P_LP64; } else { this_task_streams->task_is_64_bit = 0; @@ -1692,7 +2142,9 @@ retain_file_streams_for_task(task_t task) this_task_streams->remote_task = task; this_task_streams->remote_pid = pid; next_remote_task_fd++; - if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) next_remote_task_fd = 0; + if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) { + next_remote_task_fd = 0; + } remote_task_fd_count = MIN(remote_task_fd_count + 1, STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED); _malloc_lock_unlock(&remote_fd_list_lock); @@ -1718,21 +2170,66 @@ release_file_streams_for_task(task_t task) #pragma mark - extern +kern_return_t +__mach_stack_logging_start_reading(task_t task, vm_address_t shared_memory_address, boolean_t *uses_lite_mode) +{ + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, shared_memory_address); + if (remote_fd == NULL) { + return KERN_FAILURE; + } + + *uses_lite_mode = remote_fd->task_uses_lite_mode; + + return KERN_SUCCESS; +} + +kern_return_t +__mach_stack_logging_stop_reading(task_t task) +{ + kern_return_t err = KERN_SUCCESS; + + release_file_streams_for_task(task); + + _malloc_lock_lock(&remote_fd_list_lock); + + for (uint32_t i = 0; i < remote_task_fd_count; i++) { + if (remote_fds[i].remote_task == task) { + if (remote_fds[i].in_use_count > 0) { + // Hmm... the client is in the middle of a stack log reading call? + err = KERN_FAILURE; + } else { + // remote_fds[i].in_use_count is 0 so don't decrement it! + fclose(remote_fds[i].index_file_stream); + destroy_cache_for_file_streams(&remote_fds[i]); + } + break; + } + } + + _malloc_lock_unlock(&remote_fd_list_lock); + + return err; +} + // This function is no longer used. It was a hack that required an analysis tool process // to read the target tasks's __stack_log_file_path__ variable then pass the value of // that to this function. This is now handled automatically all within this file, by // having the stack log reading code read the environment variables of the target process. // This function should be removed once no clients are calling it. kern_return_t -__mach_stack_logging_set_file_path(task_t task, char* file_path) +__mach_stack_logging_set_file_path(task_t task, char *file_path) { return KERN_SUCCESS; } kern_return_t -__mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count) +__mach_stack_logging_get_frames(task_t task, + mach_vm_address_t address, + mach_vm_address_t *stack_frames_buffer, + uint32_t max_stack_frames, + uint32_t *count) { - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task); + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, 0); if (remote_fd == NULL) { return KERN_FAILURE; } @@ -1772,10 +2269,14 @@ __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_ // must be in shared memory if (remote_fd->cache->shmem) { if (remote_fd->task_is_64_bit) { - target_64_index = (stack_logging_index_event64*)(remote_fd->cache->snapshot.index_buffer + (located_file_position - remote_fd->cache->snapshot.start_index_offset)); + target_64_index = (stack_logging_index_event64 *)(remote_fd->cache->snapshot.index_buffer + + (located_file_position - + remote_fd->cache->snapshot.start_index_offset)); located_file_position = STACK_LOGGING_OFFSET(target_64_index->offset_and_flags); } else { - target_32_index = (stack_logging_index_event32*)(remote_fd->cache->snapshot.index_buffer + (located_file_position - remote_fd->cache->snapshot.start_index_offset)); + target_32_index = (stack_logging_index_event32 *)(remote_fd->cache->snapshot.index_buffer + + (located_file_position - + remote_fd->cache->snapshot.start_index_offset)); located_file_position = STACK_LOGGING_OFFSET(target_32_index->offset_and_flags); } } else { @@ -1786,15 +2287,16 @@ __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_ // it's written to disk char bufferSpace[128]; - size_t read_size = (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); + size_t read_size = + (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); fseeko(remote_fd->index_file_stream, (off_t)located_file_position, SEEK_SET); size_t read_count = fread(bufferSpace, read_size, (size_t)1, remote_fd->index_file_stream); if (read_count) { if (remote_fd->task_is_64_bit) { - target_64_index = (stack_logging_index_event64*)bufferSpace; + target_64_index = (stack_logging_index_event64 *)bufferSpace; located_file_position = STACK_LOGGING_OFFSET(target_64_index->offset_and_flags); } else { - target_32_index = (stack_logging_index_event32*)bufferSpace; + target_32_index = (stack_logging_index_event32 *)bufferSpace; located_file_position = STACK_LOGGING_OFFSET(target_32_index->offset_and_flags); } } else { @@ -1812,11 +2314,13 @@ __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_ return __mach_stack_logging_frames_for_uniqued_stack(task, located_file_position, stack_frames_buffer, max_stack_frames, count); } - kern_return_t -__mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context) +__mach_stack_logging_enumerate_records(task_t task, + mach_vm_address_t address, + void enumerator(mach_stack_logging_record_t, void *), + void *context) { - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task); + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, 0); if (remote_fd == NULL) { return KERN_FAILURE; } @@ -1831,17 +2335,17 @@ __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, v release_file_streams_for_task(task); return err; } - + FILE *the_index = (remote_fd->index_file_stream); // prepare for the read; target process could be 32 or 64 bit. char bufferSpace[2048]; // 2 kb - stack_logging_index_event32 *target_32_index = (stack_logging_index_event32*)bufferSpace; - stack_logging_index_event64 *target_64_index = (stack_logging_index_event64*)bufferSpace; + stack_logging_index_event32 *target_32_index = (stack_logging_index_event32 *)bufferSpace; + stack_logging_index_event64 *target_64_index = (stack_logging_index_event64 *)bufferSpace; uint32_t target_addr_32 = (uint32_t)STACK_LOGGING_DISGUISE((uint32_t)address); uint64_t target_addr_64 = STACK_LOGGING_DISGUISE((uint64_t)address); size_t read_size = (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32)); - size_t number_slots = (size_t)(2048/read_size); + size_t number_slots = (size_t)(2048 / read_size); uint64_t total_slots = remote_fd->cache->last_index_file_offset / read_size; // perform the search @@ -1849,17 +2353,22 @@ __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, v int64_t current_file_offset = 0; uint32_t i; do { - // at this point, we need to read index events; read them from the file until it's necessary to grab them from the shared memory snapshot + // at this point, we need to read index events; read them from the file until it's necessary to grab them from the shared + // memory snapshot // and crop file reading to the point where we last scanned number_slots = (size_t)MIN(number_slots, total_slots); // if out of file to read (as of the time we entered this function), try to use shared memory snapshot if (number_slots == 0) { - if (remote_fd->cache->shmem && remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset > (uint64_t)current_file_offset) { + if (remote_fd->cache->shmem && + remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset > + (uint64_t)current_file_offset) { // use shared memory - target_32_index = (stack_logging_index_event32*)remote_fd->cache->snapshot.index_buffer; - target_64_index = (stack_logging_index_event64*)remote_fd->cache->snapshot.index_buffer; - read_count = (uint32_t)(remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset - current_file_offset) / read_size; + target_32_index = (stack_logging_index_event32 *)remote_fd->cache->snapshot.index_buffer; + target_64_index = (stack_logging_index_event64 *)remote_fd->cache->snapshot.index_buffer; + read_count = (uint32_t)(remote_fd->cache->snapshot.start_index_offset + + remote_fd->cache->snapshot.next_free_index_buffer_offset - current_file_offset) / + read_size; current_file_offset += read_count * read_size; } else { break; @@ -1899,19 +2408,229 @@ __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, v return err; } +kern_return_t +__mach_stack_logging_frames_for_uniqued_stack(task_t task, + uint64_t stack_identifier, + mach_vm_address_t *stack_frames_buffer, + uint32_t max_stack_frames, + uint32_t *count) +{ + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, 0); + if (remote_fd == NULL) { + return KERN_FAILURE; + } + + // ensure that the uniquing table snapshot is valid + kern_return_t err = update_cache_for_file_streams(remote_fd); + if (err != KERN_SUCCESS) { + release_file_streams_for_task(task); + return err; + } + + bool lite_mode = remote_fd->cache->lite_mode; + + unwind_stack_from_table_index(&remote_fd->cache->uniquing_table_snapshot, stack_identifier, stack_frames_buffer, count, max_stack_frames, lite_mode); + + release_file_streams_for_task(task); + + if (*count) { + return KERN_SUCCESS; + } else { + return KERN_FAILURE; + } +} kern_return_t -__mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count) +__attribute__((visibility("default"))) +__mach_stack_logging_uniquing_table_read_stack(struct backtrace_uniquing_table *uniquing_table, + uint64_t stackid, + mach_vm_address_t *out_frames_buffer, + uint32_t *out_frames_count, + uint32_t max_frames) { - remote_task_file_streams *remote_fd = retain_file_streams_for_task(task); - if (remote_fd == NULL) return KERN_FAILURE; + unwind_stack_from_table_index(uniquing_table, stackid, out_frames_buffer, out_frames_count, max_frames, uniquing_table-> + nodes_use_refcount); + return *out_frames_count ? KERN_SUCCESS : KERN_FAILURE; +} - unwind_stack_from_table_index(&remote_fd->cache->uniquing_table_snapshot, stack_identifier, stack_frames_buffer, count, max_stack_frames); + +struct backtrace_uniquing_table * +__mach_stack_logging_copy_uniquing_table(task_t task) +{ + remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, 0); + if (remote_fd == NULL) { + return NULL; + } + + // ensure that the uniquing table snapshot is valid + kern_return_t err = update_cache_for_file_streams(remote_fd); + if (err != KERN_SUCCESS || remote_fds->cache->uniquing_table_snapshot.numPages == 0) { + release_file_streams_for_task(task); + return NULL; + } + + /* Steal the uniqing table snapshot. A new snapshot will be taken next time someone calls + * update_cache_for_file_streams + */ + backtrace_uniquing_table *table = malloc(sizeof(backtrace_uniquing_table)); + memcpy(table, &remote_fds->cache->uniquing_table_snapshot, sizeof(backtrace_uniquing_table)); + bzero(&remote_fds->cache->uniquing_table_snapshot, sizeof(backtrace_uniquing_table)); + remote_fds->cache->uniquing_table_snapshot.in_client_process = true; + + table->refcount = 1; release_file_streams_for_task(task); - if (*count) return KERN_SUCCESS; - else return KERN_FAILURE; + return table; +} + + +void +__mach_stack_logging_uniquing_table_release(struct backtrace_uniquing_table *table) +{ + if (!table) { + return; + } + assert(table->refcount > 0); + table->refcount--; + if (table->refcount == 0) { + free_uniquing_table_chunks(table); + free(table); + } +} + +void +__mach_stack_logging_uniquing_table_retain(struct backtrace_uniquing_table *table) +{ + assert(table->refcount > 0); + table->refcount++; +} + +static const size_t uniquingTableDataAlign = 16 * 1024; +static const size_t uniquingTableHeaderLength = 16; + +static inline size_t roundUp(size_t x, size_t alignment) +{ + return x + (-x % alignment); +} + +size_t +__mach_stack_logging_uniquing_table_sizeof(struct backtrace_uniquing_table *table) +{ + size_t size = 0; + size += uniquingTableHeaderLength; //header + size += sizeof(backtrace_uniquing_table); + size = roundUp(size, uniquingTableDataAlign); + assert(table->in_client_process); + table_chunk_header_t *table_chunk_header = table->u.first_table_chunk_hdr; + while (table_chunk_header) { + size += 2 * sizeof(mach_vm_address_t) * table_chunk_header->num_nodes_in_chunk; + table_chunk_header = table_chunk_header->next_table_chunk_header; + } + return size; +} + + +void * +__mach_stack_logging_uniquing_table_serialize(struct backtrace_uniquing_table *table, mach_vm_size_t *size) +{ + *size = __mach_stack_logging_uniquing_table_sizeof(table); + + mach_vm_address_t buffer_address = 0; + kern_return_t kr = mach_vm_allocate(mach_task_self(), &buffer_address, *size, VM_FLAGS_ANYWHERE); + if (kr != KERN_SUCCESS) { + *size = 0; + return NULL; + } + + void *buffer = (void*)buffer_address; + + uint8_t *p = buffer; + + memcpy(p, "MslUniquingTable", uniquingTableHeaderLength); + p += uniquingTableHeaderLength; + + memcpy(p, table, sizeof(backtrace_uniquing_table)); + p += sizeof(backtrace_uniquing_table); + + p = ((uint8_t*)buffer) + roundUp(p - (uint8_t*)buffer, uniquingTableDataAlign); + + table_chunk_header_t *table_chunk_header = table->u.first_table_chunk_hdr; + uint64_t num_nodes = 0; + while (table_chunk_header) { + num_nodes += table_chunk_header->num_nodes_in_chunk; + size_t chunk_size = 2 * sizeof(mach_vm_address_t) * table_chunk_header->num_nodes_in_chunk; + kr = mach_vm_copy(mach_task_self(), (mach_vm_address_t)table_chunk_header->table_chunk, chunk_size, (vm_address_t)p); + if (kr != KERN_SUCCESS) { + memcpy(p, table_chunk_header->table_chunk, chunk_size); + } + p += chunk_size; + table_chunk_header = table_chunk_header->next_table_chunk_header; + } + + assert(num_nodes == table->numNodes); + + return buffer; +} + +struct backtrace_uniquing_table * +__mach_stack_logging_uniquing_table_copy_from_serialized(void *buffer, size_t size) +{ + if (size < uniquingTableHeaderLength + sizeof(backtrace_uniquing_table)) { + return NULL; + } + uint8_t *p = buffer; + + if (strncmp(buffer, "MslUniquingTable", uniquingTableHeaderLength) != 0) { + return NULL; + } + p += uniquingTableHeaderLength; + + backtrace_uniquing_table *table = malloc(sizeof(backtrace_uniquing_table)); + memcpy(table, p, sizeof(backtrace_uniquing_table)); + p += sizeof(backtrace_uniquing_table); + + p = ((uint8_t*)buffer) + roundUp(p - (uint8_t*)buffer, uniquingTableDataAlign); + + table->u.first_table_chunk_hdr = malloc(sizeof(table_chunk_header_t)); + table->refcount = 1; + + mach_vm_size_t chunkSize = 2 * table->numNodes * sizeof(mach_vm_address_t); + + mach_vm_address_t chunkAddr = 0; + + if (roundUp(uniquingTableHeaderLength + sizeof(backtrace_uniquing_table), uniquingTableDataAlign) + chunkSize < size ) { + goto fail; + } + + kern_return_t kr = mach_vm_allocate(mach_task_self(), &chunkAddr, chunkSize, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)); + if (kr != KERN_SUCCESS) { + goto fail; + } + + table->u.first_table_chunk_hdr->num_nodes_in_chunk = table->numNodes; + table->u.first_table_chunk_hdr->table_chunk_size = chunkSize; + table->u.first_table_chunk_hdr->table_chunk = (mach_vm_address_t*) chunkAddr; + table->u.first_table_chunk_hdr->next_table_chunk_header = NULL; + + kr = mach_vm_copy(mach_task_self(), (mach_vm_address_t)p, chunkSize, (mach_vm_address_t) table->u.first_table_chunk_hdr->table_chunk); + if (kr != KERN_SUCCESS) { + goto fail; + } + + return table; + +fail: + if (table) { + if (table->u.first_table_chunk_hdr) { + free(table->u.first_table_chunk_hdr); + } + free(table); + } + if (chunkAddr) { + mach_vm_deallocate(mach_task_self(), chunkAddr, chunkSize); + } + return NULL; } @@ -1929,23 +2648,35 @@ main() size_t total_globals = 0ul; fprintf(stderr, "master test process is %d\n", getpid()); - fprintf(stderr, "sizeof pre_write_buffers: %lu\n", sizeof(pre_write_buffers)); total_globals += sizeof(pre_write_buffers); - fprintf(stderr, "sizeof stack_buffer: %lu\n", sizeof(stack_buffer)); total_globals += sizeof(stack_buffer); - fprintf(stderr, "sizeof last_logged_malloc_address: %lu\n", sizeof(last_logged_malloc_address)); total_globals += sizeof(last_logged_malloc_address); - fprintf(stderr, "sizeof stack_log_file_base_name: %lu\n", sizeof(stack_log_file_base_name)); total_globals += sizeof(stack_log_file_base_name); - fprintf(stderr, "sizeof stack_log_file_suffix: %lu\n", sizeof(stack_log_file_suffix)); total_globals += sizeof(stack_log_file_suffix); - fprintf(stderr, "sizeof __stack_log_file_path__ (index_file_path): %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX; - fprintf(stderr, "sizeof index_file_descriptor: %lu\n", sizeof(index_file_descriptor)); total_globals += sizeof(index_file_descriptor); - fprintf(stderr, "sizeof remote_fds: %lu\n", sizeof(remote_fds)); total_globals += sizeof(remote_fds); - fprintf(stderr, "sizeof next_remote_task_fd: %lu\n", sizeof(next_remote_task_fd)); total_globals += sizeof(next_remote_task_fd); - fprintf(stderr, "sizeof remote_task_fd_count: %lu\n", sizeof(remote_task_fd_count)); total_globals += sizeof(remote_task_fd_count); - fprintf(stderr, "sizeof remote_fd_list_lock: %lu\n", sizeof(remote_fd_list_lock)); total_globals += sizeof(remote_fd_list_lock); - fprintf(stderr, "sizeof logging_use_compaction: %lu\n", sizeof(logging_use_compaction)); total_globals += sizeof(logging_use_compaction); - + fprintf(stderr, "sizeof pre_write_buffers: %lu\n", sizeof(pre_write_buffers)); + total_globals += sizeof(pre_write_buffers); + fprintf(stderr, "sizeof stack_buffer: %lu\n", sizeof(stack_buffer)); + total_globals += sizeof(stack_buffer); + fprintf(stderr, "sizeof last_logged_malloc_address: %lu\n", sizeof(last_logged_malloc_address)); + total_globals += sizeof(last_logged_malloc_address); + fprintf(stderr, "sizeof stack_log_file_base_name: %lu\n", sizeof(stack_log_file_base_name)); + total_globals += sizeof(stack_log_file_base_name); + fprintf(stderr, "sizeof stack_log_file_suffix: %lu\n", sizeof(stack_log_file_suffix)); + total_globals += sizeof(stack_log_file_suffix); + fprintf(stderr, "sizeof __stack_log_file_path__ (index_file_path): %lu\n", (size_t)PATH_MAX); + total_globals += (size_t)PATH_MAX; + fprintf(stderr, "sizeof index_file_descriptor: %lu\n", sizeof(index_file_descriptor)); + total_globals += sizeof(index_file_descriptor); + fprintf(stderr, "sizeof remote_fds: %lu\n", sizeof(remote_fds)); + total_globals += sizeof(remote_fds); + fprintf(stderr, "sizeof next_remote_task_fd: %lu\n", sizeof(next_remote_task_fd)); + total_globals += sizeof(next_remote_task_fd); + fprintf(stderr, "sizeof remote_task_fd_count: %lu\n", sizeof(remote_task_fd_count)); + total_globals += sizeof(remote_task_fd_count); + fprintf(stderr, "sizeof remote_fd_list_lock: %lu\n", sizeof(remote_fd_list_lock)); + total_globals += sizeof(remote_fd_list_lock); + fprintf(stderr, "sizeof logging_use_compaction: %lu\n", sizeof(logging_use_compaction)); + total_globals += sizeof(logging_use_compaction); + fprintf(stderr, "size of all global data: %lu\n", total_globals); - + create_log_file(); - + // create a few child processes and exit them cleanly so their logs should get cleaned up fprintf(stderr, "\ncreating child processes and exiting cleanly\n"); for (i = 0; i < 3; i++) { @@ -1957,7 +2688,7 @@ main() } wait(&status); } - + // create a few child processes and abruptly _exit them, leaving their logs around fprintf(stderr, "\ncreating child processes and exiting abruptly, leaving logs around\n"); for (i = 0; i < 3; i++) { @@ -1969,7 +2700,7 @@ main() } wait(&status); } - + // this should reap any remaining logs fprintf(stderr, "\nexiting master test process %d\n", getpid()); delete_log_files(); diff --git a/src/libmalloc/src/stack_logging_internal.h b/src/libmalloc/src/stack_logging_internal.h new file mode 100644 index 000000000..711c45a77 --- /dev/null +++ b/src/libmalloc/src/stack_logging_internal.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef stack_logging_disk_h +#define stack_logging_disk_h + +extern int stack_logging_enable_logging; /* when clear, no logging takes place */ +extern int stack_logging_dontcompact; /* default is to compact; when set does not compact alloc/free logs; useful for tracing history */ +extern int stack_logging_finished_init; /* set after we've returned from the Libsystem initialiser */ +extern int stack_logging_postponed; /* set if we needed to postpone logging till after initialisation */ +extern int stack_logging_mode; + +extern const uint64_t __invalid_stack_id; + +// returns the stack id +uint64_t __enter_stack_into_table_while_locked(vm_address_t self_thread, uint32_t num_hot_to_skip, boolean_t add_thread_id, size_t ptr_size); + +void __malloc_lock_stack_logging(); +void __malloc_unlock_stack_logging(); + +// support for gdb and others checking for stack_logging locks +extern boolean_t __stack_logging_locked(); + +extern boolean_t __prepare_to_log_stacks(boolean_t lite_mode); +extern void __prepare_to_log_stacks_stage2(); + +// support for multi-threaded forks +extern void __stack_logging_fork_prepare(); +extern void __stack_logging_fork_parent(); +extern void __stack_logging_fork_child(); +extern void __stack_logging_early_finished(); + +void __decrement_table_slot_refcount(uint64_t stackID, size_t size); + +void __delete_uniquing_table_memory_while_locked(); +boolean_t __uniquing_table_memory_was_deleted(void); + +boolean_t is_stack_logging_lite_enabled(void); + + +#endif /* stack_logging_disk_h */ diff --git a/src/libmalloc/src/thresholds.h b/src/libmalloc/src/thresholds.h new file mode 100644 index 000000000..b561fb002 --- /dev/null +++ b/src/libmalloc/src/thresholds.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2015 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __THRESHOLDS_H +#define __THRESHOLDS_H + +/* + * Tiny region size definitions; these are split into quanta of 16 bytes, + * 64520 blocks is the magical value of how many quanta we can fit in a 1mb + * region including the region trailer and metadata. + */ +#define SHIFT_TINY_QUANTUM 4 +#define SHIFT_TINY_CEIL_BLOCKS 16 // ceil(log2(NUM_TINY_BLOCKS)) +#define TINY_QUANTUM (1 << SHIFT_TINY_QUANTUM) +#define NUM_TINY_BLOCKS 64520 +#define NUM_TINY_CEIL_BLOCKS (1 << SHIFT_TINY_CEIL_BLOCKS) + +/* + * Small region size defintions. + * + * We can only represent up to 1<<15 for msize; but we choose to stay + * even below that to avoid the convention msize=0 => msize = (1<<15) + */ +#define SHIFT_SMALL_QUANTUM (SHIFT_TINY_QUANTUM + 5) // 9 +#define SMALL_QUANTUM (1 << SHIFT_SMALL_QUANTUM) // 512 bytes +#define SHIFT_SMALL_CEIL_BLOCKS 14 // ceil(log2(NUM_SMALL_BLOCKs)) +#define NUM_SMALL_BLOCKS 16319 +#define NUM_SMALL_CEIL_BLOCKS (1 << SHIFT_SMALL_CEIL_BLOCKS) +#define SMALL_BLOCKS_ALIGN (SHIFT_SMALL_CEIL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23 + +/* + * The number of slots in the free-list for small blocks. To avoid going to + * vm system as often on large memory machines, increase the number of free list + * spots above some amount of RAM installed in the system. + */ +#define NUM_SMALL_SLOTS 32 +#define NUM_SMALL_SLOTS_LARGEMEM 256 +#define SMALL_BITMAP_WORDS 8 + +#if MALLOC_TARGET_64BIT +#define NUM_TINY_SLOTS 64 // number of slots for free-lists +#else // MALLOC_TARGET_64BIT +#define NUM_TINY_SLOTS 32 // number of slots for free-lists +#endif // MALLOC_TARGET_64BIT + +/* + * The threshold above which we start allocating from the small + * magazines. Computed from the largest allocation we can make + * in the tiny region (currently 1008 bytes on 64-bit, and + * 496 bytes on 32-bit). + */ +#define SMALL_THRESHOLD ((NUM_TINY_SLOTS - 1) * TINY_QUANTUM) + +/* + * The threshold above which we start allocating from the large + * "region" (ie. direct vm_allocates). The LARGEMEM size is used + * on systems that have more than 1GB RAM. + */ +#define LARGE_THRESHOLD (15 * 1024) +#define LARGE_THRESHOLD_LARGEMEM (127 * 1024) + +/* + * When all memory is touched after a copy, vm_copy() is always a lose + * But if the memory is only read, vm_copy() wins over memmove() at 3 or 4 pages + * (on a G3/300MHz) + * + * This must be larger than LARGE_THRESHOLD + */ +#define VM_COPY_THRESHOLD (40 * 1024) +#define VM_COPY_THRESHOLD_LARGEMEM (128 * 1024) + +/* + * Large entry cache (death row) sizes. The large cache is bounded with + * an overall top limit size, each entry is allowed a given slice of + * that limit. + */ +#if MALLOC_TARGET_64BIT +#define LARGE_ENTRY_CACHE_SIZE 16 +#define LARGE_CACHE_SIZE_LIMIT ((vm_size_t)0x80000000) /* 2Gb */ +#define LARGE_CACHE_SIZE_ENTRY_LIMIT (LARGE_CACHE_SIZE_LIMIT / LARGE_ENTRY_CACHE_SIZE) +#else // MALLOC_TARGET_64BIT +#define LARGE_ENTRY_CACHE_SIZE 8 +#define LARGE_CACHE_SIZE_LIMIT ((vm_size_t)0x02000000) /* 32Mb */ +#define LARGE_CACHE_SIZE_ENTRY_LIMIT (LARGE_CACHE_SIZE_LIMIT / LARGE_ENTRY_CACHE_SIZE) +#endif // MALLOC_TARGET_64BIT + +/* + * Large entry cache (death row) "flotsam" limits. Until the large cache + * contains at least "high" bytes, the cache is not cleaned under memory + * pressure. After that, memory pressure notifications cause cache cleaning + * until the large cache drops below the "low" limit. + */ +#define SZONE_FLOTSAM_THRESHOLD_LOW (1024 * 512) +#define SZONE_FLOTSAM_THRESHOLD_HIGH (1024 * 1024) + +/* + * Density threshold used in determining the level of emptiness before + * moving regions to the recirc depot. + */ +#define DENSITY_THRESHOLD(a) \ + ((a) - ((a) >> 2)) // "Emptiness" f = 0.25, so "Density" is (1 - f)*a. Generally: ((a) - ((a) >> -log2(f))) + +/* Sanity checks. */ + +#if (LARGE_THRESHOLD > NUM_SMALL_SLOTS * SMALL_QUANTUM) +#error LARGE_THRESHOLD should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM +#endif + +#if (LARGE_THRESHOLD_LARGEMEM > NUM_SMALL_SLOTS_LARGEMEM * SMALL_QUANTUM) +#error LARGE_THRESHOLD_LARGEMEM should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM +#endif + +#endif // __THRESHOLDS_H diff --git a/src/libmalloc/src/trace.h b/src/libmalloc/src/trace.h new file mode 100644 index 000000000..2a0b15d28 --- /dev/null +++ b/src/libmalloc/src/trace.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef __TRACE_H +#define __TRACE_H + +// defines these two subclasses for us: +// DBG_UMALLOC_EXTERNAL - for external entry points into malloc +// DBG_UMALLOC_INTERNAL - for tracing internal malloc state + +#ifndef _MALLOC_BUILDING_CODES_ +#include +#define MALLOC_TRACE(code,arg1,arg2,arg3,arg4) \ + { if (malloc_tracing_enabled) { kdebug_trace(code, arg1, arg2, arg3, arg4); } } +#define TRACE_CODE(name, subclass, code) \ + static const int TRACE_##name = KDBG_EVENTID(DBG_UMALLOC, subclass, code) +#else +# define DBG_UMALLOC 51 +# define DBG_UMALLOC_EXTERNAL 0x1 +# define DBG_UMALLOC_INTERNAL 0x2 +# define STR(x) #x +# define TRACE_CODE(name, subclass, code) \ + printf("0x%x\t%s\n", ((DBG_UMALLOC << 24) | ((subclass & 0xff) << 16) | ((code & 0x3fff) << 2)), STR(name)) +#endif + +// "external" trace points +TRACE_CODE(malloc, DBG_UMALLOC_EXTERNAL, 0x01); +TRACE_CODE(free, DBG_UMALLOC_EXTERNAL, 0x02); +TRACE_CODE(realloc, DBG_UMALLOC_EXTERNAL, 0x03); +TRACE_CODE(memalign, DBG_UMALLOC_EXTERNAL, 0x04); + +// "internal" trace points +TRACE_CODE(nano_malloc, DBG_UMALLOC_INTERNAL, 0x1); +TRACE_CODE(tiny_malloc, DBG_UMALLOC_INTERNAL, 0x2); +TRACE_CODE(small_malloc, DBG_UMALLOC_INTERNAL, 0x3); +TRACE_CODE(large_malloc, DBG_UMALLOC_INTERNAL, 0x4); +TRACE_CODE(nano_free, DBG_UMALLOC_INTERNAL, 0x5); +TRACE_CODE(tiny_free, DBG_UMALLOC_INTERNAL, 0x6); +TRACE_CODE(small_free, DBG_UMALLOC_INTERNAL, 0x7); +TRACE_CODE(large_free, DBG_UMALLOC_INTERNAL, 0x8); + +#endif // __TRACE_H diff --git a/src/libmalloc/xcodeconfig/interposable.list b/src/libmalloc/xcodeconfig/interposable.list new file mode 100644 index 000000000..0e12582cc --- /dev/null +++ b/src/libmalloc/xcodeconfig/interposable.list @@ -0,0 +1 @@ +_realloc diff --git a/src/libmalloc/xcodeconfig/libmalloc.xcconfig b/src/libmalloc/xcodeconfig/libmalloc.xcconfig index c1728e62e..47c09613b 100644 --- a/src/libmalloc/xcodeconfig/libmalloc.xcconfig +++ b/src/libmalloc/xcodeconfig/libmalloc.xcconfig @@ -1,14 +1,19 @@ #include "/Makefiles/CoreOS/Xcode/BSD.xcconfig" -#include "/AppleInternal/XcodeConfig/SimulatorSupport.xcconfig" DEAD_CODE_STRIPPING = NO -SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator iphoneosnano iphonesimulatornano +SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator BUILD_VARIANTS = normal debug +SDKROOT = macosx.internal -OTHER_CFLAGS = -fdollars-in-identifiers -fno-common -OTHER_CFLAGS_debug = -fstack-protector -fno-inline -O0 -DDEBUG=1 +GCC_PREPROCESSOR_DEFINITIONS = OS_UNFAIR_LOCK_INLINE=1 _FORTIFY_SOURCE=0 NDEBUG +// TODO: Add -fno-stack-protector when uplink to Libc is removed +OTHER_CFLAGS = -fdollars-in-identifiers -fno-common -momit-leaf-frame-pointer +OTHER_CFLAGS_debug = -fstack-protector -fno-inline -O0 -DDEBUG=1 -UNDEBUG + +GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES +CLANG_WARN_INT_CONVERSION = YES //GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES GCC_WARN_UNUSED_FUNCTION = YES GCC_WARN_UNUSED_LABEL = YES @@ -16,32 +21,35 @@ GCC_WARN_UNUSED_LABEL = YES GCC_WARN_UNUSED_VALUE = YES GCC_WARN_UNUSED_VARIABLE = YES +//GCC_OPTIMIZATION_LEVEL = 0 +LLVM_LTO = YES + +SIM_SUFFIX[sdk=*simulator*] = _sim + LINK_WITH_STANDARD_LIBRARIES = NO -OTHER_LDFLAGS = -all_load -L/usr/lib/system -umbrella System $(CR_LDFLAGS) $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(UPLINK_LDFLAGS) +OTHER_LDFLAGS = -all_load -L/usr/lib/system -umbrella System $(CR_LDFLAGS) $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(UPLINK_LDFLAGS) $(INTERPOSE_LDFLAGS) CR_LDFLAGS = -lCrashReporterClient LIBCOMPILER_RT_LDFLAGS = -lcompiler_rt -LIBPLATFORM_LDFLAGS = -lsystem_platform -LIBPLATFORM_LDFLAGS[sdk=iphonesimulator*] = -lsystem_sim_platform -LIBSYSCALL_LDFLAGS = -lsystem_kernel -LIBSYSCALL_LDFLAGS[sdk=iphonesimulator*] = -lsystem_sim_kernel +LIBPLATFORM_LDFLAGS = -lsystem$(SIM_SUFFIX)_platform +LIBSYSCALL_LDFLAGS = -lsystem$(SIM_SUFFIX)_kernel LIBDYLD_LDFLAGS = -ldyld -// TODO: Eliminate the crosslink between libmalloc and Libc (stdio for stack logging, spinlocks) +// TODO: Eliminate the crosslink between libmalloc and Libc (13046853) UPLINK_LDFLAGS = -Wl,-upward-lsystem_c -UPLINK_LDFLAGS[sdk=iphonesimulator*] = -Wl,-upward-lsystem_sim_c + +INTERPOSE_LDFLAGS = -Wl,-interposable_list,$(SRCROOT)/xcodeconfig/interposable.list ORDER_FILE = $(SDKROOT)/$(APPLE_INTERNAL_DIR)/OrderFiles/$(PRODUCT_NAME).order -ORDER_FILE[sdk=iphonesimulator*] = +ORDER_FILE[sdk=*simulator*] = DYLIB_CURRENT_VERSION = $(CURRENT_PROJECT_VERSION) PRODUCT_NAME = libsystem_malloc -PUBLIC_HEADERS_FOLDER_PATH = $(INSTALL_PATH_PREFIX)/usr/include/malloc -PRIVATE_HEADERS_FOLDER_PATH = $(INSTALL_PATH_PREFIX)/usr/local/include +PUBLIC_HEADERS_FOLDER_PATH = /usr/include/malloc +PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include -INSTALL_PATH_ACTUAL = /usr/lib/system -INSTALL_PATH[sdk=macosx*] = $(INSTALL_PATH_ACTUAL) +INSTALL_PATH = /usr/lib/system SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders HEADER_SEARCH_PATHS = $(DERIVED_FILES_DIR)/dtrace $(SRCROOT)/include $(SYSTEM_FRAMEWORK_HEADERS) $(SDKROOT)/usr/local/include $(inherited) diff --git a/src/libmalloc/xcodeconfig/libmalloc_eos.xcconfig b/src/libmalloc/xcodeconfig/libmalloc_eos.xcconfig index 96fbd3bbb..273535abb 100644 --- a/src/libmalloc/xcodeconfig/libmalloc_eos.xcconfig +++ b/src/libmalloc/xcodeconfig/libmalloc_eos.xcconfig @@ -2,6 +2,7 @@ BUILD_VARIANTS = normal EXECUTABLE_PREFIX = lib +GENERATE_MASTER_OBJECT_FILE = YES INSTALL_PATH = /usr/local/lib/eOS PRODUCT_NAME = malloc_eOS SKIP_INSTALL = YES diff --git a/src/libmalloc/xcodeconfig/libmalloc_static.xcconfig b/src/libmalloc/xcodeconfig/libmalloc_static.xcconfig new file mode 100644 index 000000000..6b37fab5f --- /dev/null +++ b/src/libmalloc/xcodeconfig/libmalloc_static.xcconfig @@ -0,0 +1,11 @@ +#include "libmalloc.xcconfig" + +BUILD_VARIANTS = normal debug +EXECUTABLE_PREFIX = lib +GENERATE_MASTER_OBJECT_FILE = YES +INSTALL_PATH = /usr/local/lib/system +PRODUCT_NAME = malloc +STRIP_INSTALLED_PRODUCT = NO +VERSIONING_SYSTEM = apple-generic +MACH_O_TYPE = staticlib +OTHER_LDFLAGS = diff --git a/src/libmalloc/xcodescripts/install-codes.sh b/src/libmalloc/xcodescripts/install-codes.sh new file mode 100644 index 000000000..723c4dbdb --- /dev/null +++ b/src/libmalloc/xcodescripts/install-codes.sh @@ -0,0 +1,7 @@ +#!/bin/bash -e +# install kdebug trace files based on the input file +INPUT=${SCRIPT_INPUT_FILE_0} +OUTPUT=${SCRIPT_OUTPUT_FILE_0} + +# pre-process the source and pass through perl it +xcrun cc -E -I${SDKROOT}/System/Library/Frameworks/System.framework/PrivateHeaders -D_MALLOC_BUILDING_CODES_ "${INPUT}" | perl > "${OUTPUT}" diff --git a/src/libmalloc/xcodescripts/manpages.sh b/src/libmalloc/xcodescripts/manpages.sh index 35647c531..213f0b9af 100755 --- a/src/libmalloc/xcodescripts/manpages.sh +++ b/src/libmalloc/xcodescripts/manpages.sh @@ -1,9 +1,10 @@ #!/bin/bash -e if [ "$ACTION" = installhdrs ]; then exit 0; fi -if [[ "$PLATFORM_NAME" =~ iphone ]]; then exit 0; fi +if [[ "$PLATFORM_NAME" != "macosx" ]]; then exit 0; fi + +UNIFDEF_FLAGS="" -UNIFDEF_FLAGS="-D__OPEN_SOURCE__" MANPAGES_LIST="${SRCROOT}/man/manpages.lst" FILES=$(find -E ${SRCROOT} -regex '.*/[^.]+\.[0-9]' -type f) diff --git a/src/libmalloc/xcodescripts/reindent.sh b/src/libmalloc/xcodescripts/reindent.sh new file mode 100755 index 000000000..023598312 --- /dev/null +++ b/src/libmalloc/xcodescripts/reindent.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# +# Reindent CWD recursively using clang-format (assumed to be in your PATH), +# and per-component or per-directory .clang-format style specifications. +# + +CPUS=`sysctl -n hw.logicalcpu` +CLANGFORMAT=${CLANGFORMAT:=`xcrun -find clang-format`} + +if [ ! -x "${CLANGFORMAT}" ]; then + echo "Could not find clang-format" 1>&2 + exit 1 +fi + +echo "Using ${CLANGFORMAT} to reindent, using concurrency of ${CPUS}" + +find -x . \! \( \( -name BUILD -o -name EXTERNAL_HEADERS -o -name libMicro -o -name zlib -o -name .svn -o -name .git -o -name cscope.\* -o -name \*~ \) -prune \) -type f \( -name \*.c -o -name \*.cpp \) -print0 | \ + xargs -0 -P "${CPUS}" -n 10 "${CLANGFORMAT}" -style=file -i +ret=$? + +if [ $ret -ne 0 ]; then + echo "reindent failed: $ret" 1>&2 + exit 1 +fi + +exit 0 + diff --git a/src/libsystem/alloc_once_private.h b/src/libsystem/alloc_once_private.h index da5a5eaa9..a565d459b 100644 --- a/src/libsystem/alloc_once_private.h +++ b/src/libsystem/alloc_once_private.h @@ -38,26 +38,28 @@ /* Keys for use with os_once_alloc. */ /* Keys for Libsystem. */ -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_NOTIFY 0 -#define OS_ALLOC_ONCE_KEY_LIBXPC 1 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_C 2 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_INFO 3 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_NETWORK 4 -#define OS_ALLOC_ONCE_KEY_LIBCACHE 5 -#define OS_ALLOC_ONCE_KEY_LIBCOMMONCRYPTO 6 -#define OS_ALLOC_ONCE_KEY_LIBDISPATCH 7 -#define OS_ALLOC_ONCE_KEY_LIBDYLD 8 -#define OS_ALLOC_ONCE_KEY_LIBKEYMGR 9 -#define OS_ALLOC_ONCE_KEY_LIBLAUNCH 10 -#define OS_ALLOC_ONCE_KEY_LIBMACHO 11 -#define OS_ALLOC_ONCE_KEY_OS_TRACE 12 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_BLOCKS 13 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_MALLOC 14 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_PLATFORM 15 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_PTHREAD 16 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_STATS 17 -#define OS_ALLOC_ONCE_KEY_LIBSECINIT 18 -#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_CORESERVICES 19 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_NOTIFY 0 +#define OS_ALLOC_ONCE_KEY_LIBXPC 1 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_C 2 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_INFO 3 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_NETWORK 4 +#define OS_ALLOC_ONCE_KEY_LIBCACHE 5 +#define OS_ALLOC_ONCE_KEY_LIBCOMMONCRYPTO 6 +#define OS_ALLOC_ONCE_KEY_LIBDISPATCH 7 +#define OS_ALLOC_ONCE_KEY_LIBDYLD 8 +#define OS_ALLOC_ONCE_KEY_LIBKEYMGR 9 +#define OS_ALLOC_ONCE_KEY_LIBLAUNCH 10 +#define OS_ALLOC_ONCE_KEY_LIBMACHO 11 +#define OS_ALLOC_ONCE_KEY_OS_TRACE 12 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_BLOCKS 13 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_MALLOC 14 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_PLATFORM 15 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_PTHREAD 16 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_STATS 17 +#define OS_ALLOC_ONCE_KEY_LIBSECINIT 18 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_CORESERVICES 19 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_SYMPTOMS 20 +#define OS_ALLOC_ONCE_KEY_LIBSYSTEM_PLATFORM_ASL 21 /* Keys OS_ALLOC_ONCE_KEY_MAX - 10 upwards are reserved for the system. */ #define OS_ALLOC_ONCE_KEY_RESERVED_0 (OS_ALLOC_ONCE_KEY_MAX - 10) -- 2.51.2