mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-07 19:58:30 +00:00
Improve cancellations, randomness, and time
- Exhaustively document cancellation points - Rename SIGCANCEL to SIGTHR just like BSDs - Further improve POSIX thread cancellations - Ensure asynchronous cancellations work correctly - Elevate the quality of getrandom() and getentropy() - Make futexes cancel correctly on OpenBSD 6.x and 7.x - Add reboot.com and shutdown.com to examples directory - Remove underscore prefix from awesome timespec_*() APIs - Create assertions that help verify our cancellation points - Remove bad timespec APIs (cmp generalizes eq/ne/gt/gte/lt/lte)
This commit is contained in:
parent
0d7c265392
commit
3f0bcdc3ef
173 changed files with 1599 additions and 782 deletions
2
libc/sysv/calls/__sys_openat_nc.s
Normal file
2
libc/sysv/calls/__sys_openat_nc.s
Normal file
|
@ -0,0 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall __sys_openat_nc,0x1d41411f321d0101,globl,hidden
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_copy_file_range,0xffffff239ffff146,globl,hidden
|
||||
.scall sys_copy_file_range,0xffffffa39ffff946,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_getrandom,0xfff807a3329f493e,globl,hidden
|
||||
.scall sys_getrandom,0x85b007a3321f493e,globl,hidden
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_tgkill,0xfffffffffffff0ea,globl,hidden
|
||||
.scall sys_tgkill,0xffffff1e1ffff0ea,globl,hidden
|
||||
|
|
|
@ -168,10 +168,10 @@ syscon sig SIGPROF 27 27 27 27 27 27 # profiling timer expired;
|
|||
syscon sig SIGWINCH 28 28 28 28 28 28 # terminal resized; unix consensus & faked on nt
|
||||
syscon sig SIGIO 29 23 23 23 23 29 # bsd consensus
|
||||
syscon sig SIGSYS 31 12 12 12 12 31 # wut; bsd consensus
|
||||
syscon sig SIGINFO 0 29 29 29 29 0 # bsd consensus
|
||||
syscon sig SIGEMT 0 7 7 7 7 0 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead
|
||||
syscon sig SIGINFO 63 29 29 29 29 63 # bsd consensus
|
||||
syscon sig SIGEMT 64 7 7 7 7 64 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead
|
||||
syscon sig SIGPWR 30 30 30 30 32 30 # not implemented in most community editions of system five; consider doing this using SIGUSR1 or SIGUSR2 instead
|
||||
syscon sig SIGCANCEL 32 7 65 7 33 32 # SIGRTMIN+0; faked as SIGEMT on XNU and OpenBSD
|
||||
syscon sig SIGTHR 32 7 32 32 33 32 # used by pthread_cancel(); SIGRTMIN+0 on Linux/NetBSD; faked as SIGEMT on XNU (what is SIG32 on XNU anyway?)
|
||||
syscon sig SIGRTMIN 32 0 65 0 33 32
|
||||
syscon sig SIGRTMAX 64 0 126 0 63 64
|
||||
syscon compat SIGPOLL 29 23 23 23 23 29 # same as SIGIO
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/consts/syscon.internal.inc"
|
||||
.syscon sig,SIGEMT,0,7,7,7,7,0
|
||||
.syscon sig,SIGEMT,64,7,7,7,7,64
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/consts/syscon.internal.inc"
|
||||
.syscon sig,SIGINFO,0,29,29,29,29,0
|
||||
.syscon sig,SIGINFO,63,29,29,29,29,63
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
.include "o/libc/sysv/consts/syscon.internal.inc"
|
||||
.syscon sig,SIGCANCEL,32,7,65,7,33,32
|
||||
.syscon sig,SIGTHR,32,7,32,32,33,32
|
|
@ -7,7 +7,7 @@ COSMOPOLITAN_C_START_
|
|||
extern const int SIGABRT;
|
||||
extern const int SIGALRM;
|
||||
extern const int SIGBUS;
|
||||
extern const int SIGCANCEL;
|
||||
extern const int SIGTHR;
|
||||
extern const int SIGCHLD;
|
||||
extern const int SIGCONT;
|
||||
extern const int SIGEMT;
|
||||
|
@ -73,7 +73,7 @@ COSMOPOLITAN_C_END_
|
|||
#define SIGXFSZ LITERALLY(25)
|
||||
|
||||
#define SIGBUS SYMBOLIC(SIGBUS)
|
||||
#define SIGCANCEL SYMBOLIC(SIGCANCEL)
|
||||
#define SIGTHR SYMBOLIC(SIGTHR)
|
||||
#define SIGCHLD SYMBOLIC(SIGCHLD)
|
||||
#define SIGCONT SYMBOLIC(SIGCONT)
|
||||
#define SIGEMT SYMBOLIC(SIGEMT)
|
||||
|
|
|
@ -100,7 +100,8 @@ scall __sys_wait4 0x9c180b807280783d globl hidden
|
|||
scall sys_kill 0x02507a025202503e globl hidden # kill(pid, sig, 1) b/c xnu
|
||||
scall sys_killpg 0x092fff092fffffff globl hidden
|
||||
scall sys_clone 0x11fffffffffff038 globl hidden
|
||||
scall sys_tkill 0x13e0771b121480c8 globl hidden # thr_kill() on freebsd; _lwp_kill() on netbsd; thrkill() on openbsd where arg3 should be 0; __pthread_kill() on XNU
|
||||
scall sys_tkill 0x13e0771b121480c8 globl hidden # thr_kill() on FreeBSD; _lwp_kill() on NetBSD; thrkill() on OpenBSD where arg3 should be 0 or tcb; __pthread_kill() on XNU
|
||||
scall sys_tgkill 0xffffff1e1ffff0ea globl hidden # thr_kill2() on FreeBSD
|
||||
scall sys_futex 0x0a60531c6ffff0ca globl hidden # raises SIGSYS on NetBSD; _umtx_op() on FreeBSD
|
||||
scall sys_futex_cp 0x8a68539c6ffff8ca globl hidden # intended for futex wait ops
|
||||
scall sys_set_robust_list 0x0a7ffffffffff111 globl # no wrapper
|
||||
|
@ -265,7 +266,6 @@ scall sys_ktimer_settime 0xffffff0edfffffff globl # no wrapper
|
|||
scall sys_clock_settime 0x1ac0580e9ffff0e3 globl # no wrapper
|
||||
scall sys_clock_gettime 0x1ab0570e8ffff0e4 globl hidden # Linux 2.6+ (c. 2003); XNU uses magic address
|
||||
scall sys_clock_getres 0x1ad0590eaffff0e5 globl hidden
|
||||
scall sys_tgkill 0xfffffffffffff0ea globl hidden
|
||||
scall sys_mbind 0xfffffffffffff0ed globl # no wrapper; numa numa yeah
|
||||
scall set_mempolicy 0xfffffffffffff0ee globl
|
||||
scall get_mempolicy 0xfffffffffffff0ef globl
|
||||
|
@ -286,6 +286,7 @@ scall sys_inotify_init 0xfffffffffffff0fd globl # wicked # no wrapper
|
|||
scall sys_inotify_add_watch 0xfffffffffffff0fe globl # no wrapper
|
||||
scall sys_inotify_rm_watch 0xfffffffffffff0ff globl # no wrapper
|
||||
scall __sys_openat 0x9d49419f329cf901 globl hidden # Linux 2.6.16+ (c. 2007)
|
||||
scall __sys_openat_nc 0x1d41411f321d0101 globl hidden # openat_nocancel() on xnu
|
||||
scall sys_mkdirat 0x1cd13e1f021db102 globl hidden
|
||||
scall sys_fchownat 0x1d013b1eb21d4104 globl hidden # @asyncsignalsafe
|
||||
scall sys_utime 0xfffffffffffff084 globl hidden
|
||||
|
@ -350,7 +351,7 @@ scall sys_sched_setattr 0xfffffffffffff13a globl # ├─ desktop replaced with
|
|||
scall sys_sched_getattr 0xfffffffffffff13b globl # ├─ karen sandler requires systemd init and boot for tablet gui
|
||||
scall sys_renameat2 0xfffffffffffff13c globl # └─ debian founder ian murdock found strangled with vacuum cord
|
||||
#scall seccomp 0xfffffffffffff13d globl # wrapped manually
|
||||
scall sys_getrandom 0xfff807a3329f493e globl hidden # Linux 3.17+ and getentropy() on XNU/OpenBSD, coming to NetBSD in 9.2
|
||||
scall sys_getrandom 0x85b007a3321f493e globl hidden # Linux 3.17+; FreeBSD 12+; NetBSD v9.2+; getentropy() on XNU/OpenBSD
|
||||
scall sys_memfd_create 0xfffffffffffff13f globl hidden
|
||||
scall sys_kexec_file_load 0xfffffffffffff140 globl # no wrapper
|
||||
scall sys_bpf 0xfffffffffffff141 globl # no wrapper
|
||||
|
@ -358,7 +359,7 @@ scall sys_execveat 0xfffffffffffff142 globl # no wrapper
|
|||
scall sys_userfaultfd 0xfffffffffffff143 globl # no wrapper; Linux 4.3+ (c. 2015)
|
||||
scall sys_membarrier 0xfffffffffffff144 globl # no wrapper; Linux 4.3+ (c. 2015)
|
||||
scall sys_mlock2 0xfffffffffffff145 globl # no wrapper; Linux 4.5+ (c. 2016)
|
||||
scall sys_copy_file_range 0xffffff239ffff146 globl hidden # Linux 4.5+ (c. 2016), FreeBSD 13+
|
||||
scall sys_copy_file_range 0xffffffa39ffff946 globl hidden # Linux 4.5+ (c. 2016), FreeBSD 13+
|
||||
scall sys_preadv2 0xfffffffffffff147 globl # no wrapper
|
||||
scall sys_pwritev2 0xfffffffffffff148 globl # no wrapper
|
||||
scall sys_pkey_mprotect 0xfffffffffffff149 globl # no wrapper
|
||||
|
|
|
@ -110,7 +110,7 @@ __pid: .quad 0
|
|||
|
||||
systemfive_cp:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
mov %rsp,%rbp # so backtraces work
|
||||
systemfive_cancellable: # our pthread_cancel() miracle code
|
||||
cmpb $0,__tls_enabled(%rip) # inspired by the musl libc design!
|
||||
je 1f # we handle linux and bsd together!
|
||||
|
@ -120,21 +120,24 @@ systemfive_cancellable: # our pthread_cancel() miracle code
|
|||
jz 1f # it's spawn() probably
|
||||
testb $PT_NOCANCEL,0x00(%r10) # PosixThread::flags
|
||||
jnz 1f # canceler no cancelling
|
||||
#if IsModeDbg()
|
||||
testb $PT_INCANCEL,0x00(%r10)
|
||||
jz 5f
|
||||
#endif
|
||||
cmp $0,0x04(%r10) # PosixThread::cancelled
|
||||
jne systemfive_cancel # tail call for masked mode
|
||||
jne systemfive_cancel # we will tail call below
|
||||
1: mov %rcx,%r10 # move the fourth argument
|
||||
clc # no cancellable system calls exist
|
||||
syscall # that have 7+ args on the bsd OSes
|
||||
systemfive_cancellable_end: # i/o calls park here for long time
|
||||
pop %rbp
|
||||
jc systemfive_errno
|
||||
jmp 0f
|
||||
jc 3f # we're now out of the limbo state!
|
||||
1: cmp $-4095,%rax # but we still check again on eintr
|
||||
jae 2f
|
||||
jnc 2f
|
||||
neg %rax # turns bsd errno to system v errno
|
||||
2: cmp $-4095,%rax # but we still check again on eintr
|
||||
jae 3f # branch because system call failed
|
||||
ret # done if the system call succeeded
|
||||
2: neg %eax # now examine the nature of failure
|
||||
3: cmp EINTR(%rip),%eax # did SIGCANCEL cancel our i/o call
|
||||
3: neg %eax # now examine the nature of failure
|
||||
cmp EINTR(%rip),%eax # did the SIGTHR cancel our IO call
|
||||
jne systemfive_errno # werent interrupted by OnSigCancel
|
||||
cmpb $0,__tls_enabled(%rip) # make sure it's safe to grab %fs:0
|
||||
je systemfive_errno # tls is disabled we can't continue
|
||||
|
@ -146,11 +149,22 @@ systemfive_cancellable_end: # i/o calls park here for long time
|
|||
jnz systemfive_errno # cancellation is disabled
|
||||
cmp $0,0x04(%rcx) # PosixThread::cancelled
|
||||
je systemfive_errno # we aren't actually cancelled
|
||||
jmp 1f # now we are in fact cancelled
|
||||
systemfive_cancel:
|
||||
jmp 4f # now we are in fact cancelled
|
||||
systemfive_cancel: # SIGTHR will jump here too
|
||||
pop %rbp
|
||||
1: jmp _pthread_cancel_sys # must be linked if we're cancelled
|
||||
.weak _pthread_cancel_sys
|
||||
4: jmp _pthread_cancel_sys # tail call
|
||||
.weak _pthread_cancel_sys # must be linked if we're cancelled
|
||||
#if IsModeDbg()
|
||||
not_a_cancellation_point: # need BEGIN/END_CANCELLATION_POINT
|
||||
nop
|
||||
.weak report_cancellation_point
|
||||
5: ezlea report_cancellation_point,cx
|
||||
test %rcx,%rcx
|
||||
jz 6f
|
||||
call *%rcx
|
||||
6: ud2
|
||||
nop
|
||||
#endif
|
||||
.globl systemfive_cancellable_end
|
||||
.globl systemfive_cancellable
|
||||
.globl systemfive_cancel
|
||||
|
@ -169,7 +183,7 @@ systemfive_linux:
|
|||
mov %rsp,%rbp # having frame will help backtraces
|
||||
syscall # this is known as a context switch
|
||||
pop %rbp # next we check to see if it failed
|
||||
0: cmp $-4095,%rax # system five nexgen32e abi § a.2.1
|
||||
cmp $-4095,%rax # system five nexgen32e abi § a.2.1
|
||||
jae systemfive_error # encodes errno as neg return value
|
||||
ret
|
||||
.endfn systemfive_linux,globl,hidden
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue