diff --git a/build/definitions.mk b/build/definitions.mk index 038aa8afb..aaadbfd60 100644 --- a/build/definitions.mk +++ b/build/definitions.mk @@ -155,9 +155,11 @@ SANITIZER = \ -fsanitize=address NO_MAGIC = \ + -ffreestanding \ -fno-stack-protector \ -fwrapv \ - -fno-sanitize=all + -fno-sanitize=all \ + -fpatchable-function-entry=0,0 OLD_CODE = \ -fno-strict-aliasing \ diff --git a/examples/greenbean.c b/examples/greenbean.c index 3fb066bc6..e67925056 100644 --- a/examples/greenbean.c +++ b/examples/greenbean.c @@ -186,6 +186,7 @@ void *Worker(void *id) { do { // parse the incoming http message InitHttpMessage(&msg, kHttpRequest); + // wait for http message (non-fragmented required) // we're not terrible concerned when errors happen here unassert(!pthread_setcancelstate(PTHREAD_CANCEL_MASKED, 0)); if ((got = read(client, inbuf, sizeof(inbuf))) <= 0) break; @@ -198,9 +199,8 @@ void *Worker(void *id) { #if LOGGING // log the incoming http message unsigned clientip = ntohl(clientaddr.sin_addr.s_addr); - kprintf("\r\e[K%6P get some %d.%d.%d.%d:%d %#.*s\n", - (clientip & 0xff000000) >> 030, (clientip & 0x00ff0000) >> 020, - (clientip & 0x0000ff00) >> 010, (clientip & 0x000000ff) >> 000, + kprintf("\r\e[K%6P get some %hhu.%hhu.%hhu.%hhu:%hu %#.*s\n", + clientip >> 24, clientip >> 16, clientip >> 8, clientip, ntohs(clientaddr.sin_port), msg.uri.b - msg.uri.a, inbuf + msg.uri.a); SomethingHappened(); @@ -314,10 +314,8 @@ int main(int argc, char *argv[]) { // Cosmo's GetHostIps() API is much easier than ioctl(SIOCGIFCONF) uint32_t *hostips; for (hostips = gc(GetHostIps()), i = 0; hostips[i]; ++i) { - kprintf("listening on http://%d.%d.%d.%d:%d\n", - (hostips[i] & 0xff000000) >> 030, (hostips[i] & 0x00ff0000) >> 020, - (hostips[i] & 0x0000ff00) >> 010, (hostips[i] & 0x000000ff) >> 000, - PORT); + kprintf("listening on http://%hhu.%hhu.%hhu.%hhu:%hu\n", hostips[i] >> 24, + hostips[i] >> 16, hostips[i] >> 8, hostips[i], PORT); } // you can pass the number of threads you want as the first command arg @@ -414,7 +412,7 @@ int main(int argc, char *argv[]) { while (!a_termsig) { PrintStatus(); unassert(!pthread_cond_wait(&statuscond, &statuslock)); - usleep(20); + usleep(10 * 1000); } unassert(!pthread_mutex_unlock(&statuslock)); diff --git a/libc/crt/crt.S b/libc/crt/crt.S index e7af029b2..39dc047a1 100644 --- a/libc/crt/crt.S +++ b/libc/crt/crt.S @@ -121,6 +121,7 @@ _start: mov x0,sp // setup the stack + mov x28,#0 mov x29,#0 mov x30,#0 ldr x1,=ape_stack_round diff --git a/libc/log/appendresourcereport.c b/libc/log/appendresourcereport.c index b48c5fd6f..e5b8e4678 100644 --- a/libc/log/appendresourcereport.c +++ b/libc/log/appendresourcereport.c @@ -81,15 +81,15 @@ void AppendResourceReport(char **b, struct rusage *ru, const char *nl) { ticks = ceill((long double)(utime + stime) / (1000000.L / CLK_TCK)); if (ru->ru_idrss) { AppendMetric(st, "needed ", lroundl(ru->ru_idrss / ticks), - " memory on average"); - } - if (ru->ru_isrss) { - AppendMetric(st, "needed ", lroundl(ru->ru_isrss / ticks), - " stack on average"); + "kb private on average"); } if (ru->ru_ixrss) { AppendMetric(st, "needed ", lroundl(ru->ru_ixrss / ticks), - " shared on average"); + "kb shared on average"); + } + if (ru->ru_isrss) { + AppendMetric(st, "needed ", lroundl(ru->ru_isrss / ticks), + "kb stack on average"); } } if (ru->ru_minflt || ru->ru_majflt) { diff --git a/libc/sysv/calls/__sys_accept.S b/libc/sysv/calls/__sys_accept.S index aea6f98da..5dcc819bb 100644 --- a/libc/sysv/calls/__sys_accept.S +++ b/libc/sysv/calls/__sys_accept.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall __sys_accept,0x81e81ea1d281e82b,202,30,globl,hidden +.scall __sys_accept,0x81e81ea1d281e82b,2250,30,globl,hidden diff --git a/libc/sysv/calls/__sys_accept4.S b/libc/sysv/calls/__sys_accept4.S index 9f2da2e78..3abde7f9f 100644 --- a/libc/sysv/calls/__sys_accept4.S +++ b/libc/sysv/calls/__sys_accept4.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall __sys_accept4,0xfff85da1dffff920,242,4095,globl,hidden +.scall __sys_accept4,0xfff85da1dffff920,2290,4095,globl,hidden diff --git a/libc/sysv/calls/__sys_clock_nanosleep.S b/libc/sysv/calls/__sys_clock_nanosleep.S index eabb1b1a8..afd1b3a9f 100644 --- a/libc/sysv/calls/__sys_clock_nanosleep.S +++ b/libc/sysv/calls/__sys_clock_nanosleep.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall __sys_clock_nanosleep,0x9ddfff8f4ffff8e6,115,4095,globl,hidden +.scall __sys_clock_nanosleep,0x9ddfff8f4ffff8e6,2163,4095,globl,hidden diff --git a/libc/sysv/calls/__sys_connect.S b/libc/sysv/calls/__sys_connect.S index e93013fe7..1a15cc582 100644 --- a/libc/sysv/calls/__sys_connect.S +++ b/libc/sysv/calls/__sys_connect.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall __sys_connect,0x862862862286282a,203,98,globl,hidden +.scall __sys_connect,0x862862862286282a,2251,98,globl,hidden diff --git a/libc/sysv/calls/__sys_fcntl_cp.S b/libc/sysv/calls/__sys_fcntl_cp.S index 51b916310..9f40c679f 100644 --- a/libc/sysv/calls/__sys_fcntl_cp.S +++ b/libc/sysv/calls/__sys_fcntl_cp.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall __sys_fcntl_cp,0x85c85c85c285c848,25,92,globl,hidden +.scall __sys_fcntl_cp,0x85c85c85c285c848,2073,92,globl,hidden diff --git a/libc/sysv/calls/__sys_openat.S b/libc/sysv/calls/__sys_openat.S index cc7ee2864..7ea349977 100644 --- a/libc/sysv/calls/__sys_openat.S +++ b/libc/sysv/calls/__sys_openat.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall __sys_openat,0x9d49419f329cf901,56,463,globl,hidden +.scall __sys_openat,0x9d49419f329cf901,2104,463,globl,hidden diff --git a/libc/sysv/calls/__sys_wait4.S b/libc/sysv/calls/__sys_wait4.S index 2abc6cc30..8ae56c856 100644 --- a/libc/sysv/calls/__sys_wait4.S +++ b/libc/sysv/calls/__sys_wait4.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall __sys_wait4,0x9c180b807280783d,260,7,globl,hidden +.scall __sys_wait4,0x9c180b807280783d,2308,7,globl,hidden diff --git a/libc/sysv/calls/sys_copy_file_range.S b/libc/sysv/calls/sys_copy_file_range.S index 07ceac3b6..3e9e27103 100644 --- a/libc/sysv/calls/sys_copy_file_range.S +++ b/libc/sysv/calls/sys_copy_file_range.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_copy_file_range,0xffffffa39ffff946,285,4095,globl,hidden +.scall sys_copy_file_range,0xffffffa39ffff946,2333,4095,globl,hidden diff --git a/libc/sysv/calls/sys_epoll_pwait.S b/libc/sysv/calls/sys_epoll_pwait.S index 9d18029f5..9dae95e60 100644 --- a/libc/sysv/calls/sys_epoll_pwait.S +++ b/libc/sysv/calls/sys_epoll_pwait.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_epoll_pwait,0xfffffffffffff919,22,4095,globl,hidden +.scall sys_epoll_pwait,0xfffffffffffff919,2070,4095,globl,hidden diff --git a/libc/sysv/calls/sys_fdatasync.S b/libc/sysv/calls/sys_fdatasync.S index 79b80f3ba..baa67bf9f 100644 --- a/libc/sysv/calls/sys_fdatasync.S +++ b/libc/sysv/calls/sys_fdatasync.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_fdatasync,0x8f185fa2628bb84b,83,187,globl,hidden +.scall sys_fdatasync,0x8f185fa2628bb84b,2131,187,globl,hidden diff --git a/libc/sysv/calls/sys_flock.S b/libc/sysv/calls/sys_flock.S index 108261031..e71251303 100644 --- a/libc/sysv/calls/sys_flock.S +++ b/libc/sysv/calls/sys_flock.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_flock,0x8838838832883849,32,131,globl,hidden +.scall sys_flock,0x8838838832883849,2080,131,globl,hidden diff --git a/libc/sysv/calls/sys_fstatfs.S b/libc/sysv/calls/sys_fstatfs.S index 54fb26954..5ed6773e7 100644 --- a/libc/sysv/calls/sys_fstatfs.S +++ b/libc/sysv/calls/sys_fstatfs.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_fstatfs,0x89e840a2c295a88a,44,346,globl,hidden +.scall sys_fstatfs,0x89e840a2c295a88a,2092,346,globl,hidden diff --git a/libc/sysv/calls/sys_fsync.S b/libc/sysv/calls/sys_fsync.S index 8732bc3c2..a56a2dee9 100644 --- a/libc/sysv/calls/sys_fsync.S +++ b/libc/sysv/calls/sys_fsync.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_fsync,0x85f85f85f285f84a,82,95,globl,hidden +.scall sys_fsync,0x85f85f85f285f84a,2130,95,globl,hidden diff --git a/libc/sysv/calls/sys_ftruncate.S b/libc/sysv/calls/sys_ftruncate.S index 72a0a5271..0c4e53bce 100644 --- a/libc/sysv/calls/sys_ftruncate.S +++ b/libc/sysv/calls/sys_ftruncate.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_ftruncate,0x8c98a89e028c984d,46,201,globl,hidden +.scall sys_ftruncate,0x8c98a89e028c984d,2094,201,globl,hidden diff --git a/libc/sysv/calls/sys_futex_cp.S b/libc/sysv/calls/sys_futex_cp.S index 022649c12..32bafc3fd 100644 --- a/libc/sysv/calls/sys_futex_cp.S +++ b/libc/sysv/calls/sys_futex_cp.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_futex_cp,0x8a68539c6ffff8ca,98,4095,globl,hidden +.scall sys_futex_cp,0x8a68539c6ffff8ca,2146,4095,globl,hidden diff --git a/libc/sysv/calls/sys_ioctl_cp.S b/libc/sysv/calls/sys_ioctl_cp.S index 755d6ef9e..4b669a395 100644 --- a/libc/sysv/calls/sys_ioctl_cp.S +++ b/libc/sysv/calls/sys_ioctl_cp.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_ioctl_cp,0x8368368362836810,29,54,globl,hidden +.scall sys_ioctl_cp,0x8368368362836810,2077,54,globl,hidden diff --git a/libc/sysv/calls/sys_msgrcv.S b/libc/sysv/calls/sys_msgrcv.S index 3860fc01d..a45439189 100644 --- a/libc/sysv/calls/sys_msgrcv.S +++ b/libc/sysv/calls/sys_msgrcv.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_msgrcv,0x8e38e38e32905846,188,261,globl +.scall sys_msgrcv,0x8e38e38e32905846,2236,261,globl diff --git a/libc/sysv/calls/sys_msgsnd.S b/libc/sysv/calls/sys_msgsnd.S index 7262e2b40..47d3d14d7 100644 --- a/libc/sysv/calls/sys_msgsnd.S +++ b/libc/sysv/calls/sys_msgsnd.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_msgsnd,0x8e28e28e22904845,189,260,globl +.scall sys_msgsnd,0x8e28e28e22904845,2237,260,globl diff --git a/libc/sysv/calls/sys_msync.S b/libc/sysv/calls/sys_msync.S index a4461481a..176825271 100644 --- a/libc/sysv/calls/sys_msync.S +++ b/libc/sysv/calls/sys_msync.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_msync,0x915900841284181a,227,65,globl,hidden +.scall sys_msync,0x915900841284181a,2275,65,globl,hidden diff --git a/libc/sysv/calls/sys_nanosleep.S b/libc/sysv/calls/sys_nanosleep.S index 7d8488688..f898fc252 100644 --- a/libc/sysv/calls/sys_nanosleep.S +++ b/libc/sysv/calls/sys_nanosleep.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_nanosleep,0x9ae85b8f0ffff823,101,4095,globl,hidden +.scall sys_nanosleep,0x9ae85b8f0ffff823,2149,4095,globl,hidden diff --git a/libc/sysv/calls/sys_ppoll.S b/libc/sysv/calls/sys_ppoll.S index 88c0025d5..65cb3fb20 100644 --- a/libc/sysv/calls/sys_ppoll.S +++ b/libc/sysv/calls/sys_ppoll.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_ppoll,0xfff86da21ffff90f,73,4095,globl,hidden +.scall sys_ppoll,0xfff86da21ffff90f,2121,4095,globl,hidden diff --git a/libc/sysv/calls/sys_pread.S b/libc/sysv/calls/sys_pread.S index 76ab54a36..5fbd8e7a8 100644 --- a/libc/sysv/calls/sys_pread.S +++ b/libc/sysv/calls/sys_pread.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_pread,0x8ad8a99db2899811,67,153,globl,hidden +.scall sys_pread,0x8ad8a99db2899811,2115,153,globl,hidden diff --git a/libc/sysv/calls/sys_preadv.S b/libc/sysv/calls/sys_preadv.S index 4995aaed0..520b7863c 100644 --- a/libc/sysv/calls/sys_preadv.S +++ b/libc/sysv/calls/sys_preadv.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_preadv,0x9218ab9212a1c927,69,540,globl,hidden +.scall sys_preadv,0x9218ab9212a1c927,2117,540,globl,hidden diff --git a/libc/sysv/calls/sys_pselect.S b/libc/sysv/calls/sys_pselect.S index ffd50cd85..efdbd8746 100644 --- a/libc/sysv/calls/sys_pselect.S +++ b/libc/sysv/calls/sys_pselect.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_pselect,0x9b486ea0a298a90e,72,394,globl,hidden +.scall sys_pselect,0x9b486ea0a298a90e,2120,394,globl,hidden diff --git a/libc/sysv/calls/sys_pwrite.S b/libc/sysv/calls/sys_pwrite.S index 00d8fc5ca..d6c9faaeb 100644 --- a/libc/sysv/calls/sys_pwrite.S +++ b/libc/sysv/calls/sys_pwrite.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_pwrite,0x8ae8aa9dc289a812,68,154,globl,hidden +.scall sys_pwrite,0x8ae8aa9dc289a812,2116,154,globl,hidden diff --git a/libc/sysv/calls/sys_pwritev.S b/libc/sysv/calls/sys_pwritev.S index c9692bf80..20bad99e3 100644 --- a/libc/sysv/calls/sys_pwritev.S +++ b/libc/sysv/calls/sys_pwritev.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_pwritev,0x9228ac9222a1d928,70,541,globl,hidden +.scall sys_pwritev,0x9228ac9222a1d928,2118,541,globl,hidden diff --git a/libc/sysv/calls/sys_read.S b/libc/sysv/calls/sys_read.S index 81668006a..f2b2c33af 100644 --- a/libc/sysv/calls/sys_read.S +++ b/libc/sysv/calls/sys_read.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_read,0x8038038032803800,63,3,globl,hidden +.scall sys_read,0x8038038032803800,2111,3,globl,hidden diff --git a/libc/sysv/calls/sys_readv.S b/libc/sysv/calls/sys_readv.S index 65984cba7..b046861c9 100644 --- a/libc/sysv/calls/sys_readv.S +++ b/libc/sysv/calls/sys_readv.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_readv,0x8788788782878813,65,120,globl,hidden +.scall sys_readv,0x8788788782878813,2113,120,globl,hidden diff --git a/libc/sysv/calls/sys_recvfrom.S b/libc/sysv/calls/sys_recvfrom.S index b40f1179f..018780247 100644 --- a/libc/sysv/calls/sys_recvfrom.S +++ b/libc/sysv/calls/sys_recvfrom.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_recvfrom,0x81d81d81d281d82d,207,29,globl,hidden +.scall sys_recvfrom,0x81d81d81d281d82d,2255,29,globl,hidden diff --git a/libc/sysv/calls/sys_recvmsg.S b/libc/sysv/calls/sys_recvmsg.S index 17e42ef7f..e5e7cb0ab 100644 --- a/libc/sysv/calls/sys_recvmsg.S +++ b/libc/sysv/calls/sys_recvmsg.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_recvmsg,0x81b81b81b281b82f,212,27,globl,hidden +.scall sys_recvmsg,0x81b81b81b281b82f,2260,27,globl,hidden diff --git a/libc/sysv/calls/sys_sendmsg.S b/libc/sysv/calls/sys_sendmsg.S index 129044bb4..c3974195a 100644 --- a/libc/sysv/calls/sys_sendmsg.S +++ b/libc/sysv/calls/sys_sendmsg.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_sendmsg,0x81c81c81c281c82e,211,28,globl,hidden +.scall sys_sendmsg,0x81c81c81c281c82e,2259,28,globl,hidden diff --git a/libc/sysv/calls/sys_sendto.S b/libc/sysv/calls/sys_sendto.S index 731958593..11b36eb49 100644 --- a/libc/sysv/calls/sys_sendto.S +++ b/libc/sysv/calls/sys_sendto.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_sendto,0x885885885288582c,206,133,globl,hidden +.scall sys_sendto,0x885885885288582c,2254,133,globl,hidden diff --git a/libc/sysv/calls/sys_sigsuspend.S b/libc/sysv/calls/sys_sigsuspend.S index 6e9e59834..9465007a0 100644 --- a/libc/sysv/calls/sys_sigsuspend.S +++ b/libc/sysv/calls/sys_sigsuspend.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_sigsuspend,0x92686f955286f882,133,111,globl,hidden +.scall sys_sigsuspend,0x92686f955286f882,2181,111,globl,hidden diff --git a/libc/sysv/calls/sys_sigtimedwait.S b/libc/sysv/calls/sys_sigtimedwait.S index 481b92ca2..e3ec9a648 100644 --- a/libc/sysv/calls/sys_sigtimedwait.S +++ b/libc/sysv/calls/sys_sigtimedwait.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_sigtimedwait,0x9affff959ffff880,137,4095,globl,hidden +.scall sys_sigtimedwait,0x9affff959ffff880,2185,4095,globl,hidden diff --git a/libc/sysv/calls/sys_statfs.S b/libc/sysv/calls/sys_statfs.S index 871a0b25a..7473757d5 100644 --- a/libc/sysv/calls/sys_statfs.S +++ b/libc/sysv/calls/sys_statfs.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_statfs,0x89d83fa2b2959889,43,345,globl,hidden +.scall sys_statfs,0x89d83fa2b2959889,2091,345,globl,hidden diff --git a/libc/sysv/calls/sys_truncate.S b/libc/sysv/calls/sys_truncate.S index 4a3fcf6d0..c8c6a557e 100644 --- a/libc/sysv/calls/sys_truncate.S +++ b/libc/sysv/calls/sys_truncate.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_truncate,0x8c88a79df28c884c,45,200,globl,hidden +.scall sys_truncate,0x8c88a79df28c884c,2093,200,globl,hidden diff --git a/libc/sysv/calls/sys_write.S b/libc/sysv/calls/sys_write.S index 41eec3036..74c681ce2 100644 --- a/libc/sysv/calls/sys_write.S +++ b/libc/sysv/calls/sys_write.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_write,0x8048048042804801,64,4,globl,hidden +.scall sys_write,0x8048048042804801,2112,4,globl,hidden diff --git a/libc/sysv/calls/sys_writev.S b/libc/sysv/calls/sys_writev.S index 8ec662b3c..49a5df2cf 100644 --- a/libc/sysv/calls/sys_writev.S +++ b/libc/sysv/calls/sys_writev.S @@ -1,2 +1,2 @@ #include "libc/sysv/macros.internal.h" -.scall sys_writev,0x8798798792879814,66,121,globl,hidden +.scall sys_writev,0x8798798792879814,2114,121,globl,hidden diff --git a/libc/sysv/macros.internal.h b/libc/sysv/macros.internal.h index 20c53f379..fa0139b21 100644 --- a/libc/sysv/macros.internal.h +++ b/libc/sysv/macros.internal.h @@ -35,62 +35,12 @@ .endif .endfn \name,\kw1,\kw2 #elif defined(__aarch64__) - .ifc \arm_linux,4095 - .ifc \arm_xnu,4095 -// return enosys(); .ftrace1 \name: .ftrace2 - b enosys + mov x8,#\arm_linux + mov x16,#\arm_xnu + b systemfive .endfn \name,\kw1,\kw2 - .else -// return IsXnu() ? syscall(x16, ...) : syscall(x8, ...); - .ftrace1 -\name: .ftrace2 - adrp x9,__hostos - ldr w9,[x9,#:lo12:__hostos] - tbz x9,#3,1f // !IsXnu() - mov x16,#\arm_xnu // apple ordinal - mov x9,#0 // clear carry flag - adds x9,x9,#0 // clear carry flag - svc #0 // issue system call - bcs 1f - b _sysret -1: neg x0,x0 - b _sysret - .hidden _sysret - .endfn \name,\kw1,\kw2 - .endif - .else - .ifc \arm_xnu,4095 -// return IsLinux() ? syscall(x8, ...) : enosys(); - .ftrace1 -\name: .ftrace2 - adrp x9,__hostos - ldr w9,[x9,#:lo12:__hostos] - tbz x9,#0,1f // !IsLinux() - mov x8,#\arm_linux // systemd ordinal - svc #0 // issue system call - mov x1,#\arm_linux - b _sysret - .hidden _sysret -1: b enosys - .endfn \name,\kw1,\kw2 - .else - .ftrace1 -\name: .ftrace2 - mov x16,#\arm_xnu // apple ordinal - mov x8,#\arm_linux // systemd ordinal - mov x9,#0 // clear carry flag - adds x9,x9,#0 // clear carry flag - svc #0 // issue system call - bcs 1f - b _sysret -1: neg x0,x0 - b _sysret - .hidden _sysret - .endfn \name,\kw1,\kw2 - .endif - .endif #else #error "architecture unsupported" #endif diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index 14e4f0dc8..adfbea1ee 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -34,30 +34,30 @@ dir=libc/sysv/calls # 9.1+│ │ │ │ │ │ # Symbol ┌┴┐┌┴┐┌┴┐│┬┴┐┌┴┐ Arm64 Directives & Commentary scall sys_exit 0x00100100120010e7 0x05e globl hidden # a.k.a. exit_group -scall sys_read 0x8038038032803800 0x03f globl hidden -scall sys_write 0x8048048042804801 0x040 globl hidden +scall sys_read 0x8038038032803800 0x83f globl hidden +scall sys_write 0x8048048042804801 0x840 globl hidden scall sys_close 0x0060060062006003 0x039 globl hidden scall __sys_stat 0x1b7026fff2152004 0x04f globl hidden # FreeBSD 11→12 fumble; use sys_fstatat(); blocked on Android scall __sys_fstat 0x1b80352272153005 0x050 globl hidden # needs __stat2linux() scall __sys_lstat 0x1b90280282154006 0xfff globl hidden # needs __stat2linux(); blocked on Android scall __sys_poll 0x8d18fc8d128e6807 0xfff globl hidden -scall sys_ppoll 0xfff86da21ffff90f 0x049 globl hidden # consider INTON/INTOFF tutorial in examples/unbourne.c +scall sys_ppoll 0xfff86da21ffff90f 0x849 globl hidden # consider INTON/INTOFF tutorial in examples/unbourne.c scall sys_lseek 0x0c70a61de20c7008 0x03e globl hidden # netbsd:evilpad, OpenBSD 7.3+ scall __sys_mmap 0x0c50311dd20c5009 0x0de globl hidden # netbsd:pad, OpenBSD 7.3+ -scall sys_msync 0x915900841284181a 0x0e3 globl hidden +scall sys_msync 0x915900841284181a 0x8e3 globl hidden scall sys_mprotect 0x04a04a04a204a00a 0x0e2 globl hidden scall __sys_munmap 0x049049049204900b 0x0d7 globl hidden scall sys_sigaction 0x15402e1a0202e00d 0x086 globl hidden # rt_sigaction on Lunix; __sigaction_sigtramp() on NetBSD scall __sys_sigprocmask 0x125030154214900e 0x087 globl hidden # a.k.a. rt_sigprocmask, openbsd:byvalue, a.k.a. pthread_sigmask scall sys_ioctl 0x0360360362036010 0x01d globl hidden -scall sys_ioctl_cp 0x8368368362836810 0x01d globl hidden # intended for TCSBRK -scall sys_pread 0x8ad8a99db2899811 0x043 globl hidden # a.k.a. pread64; netbsd:pad, OpenBSD 7.3+ -scall sys_pwrite 0x8ae8aa9dc289a812 0x044 globl hidden # a.k.a. pwrite64; netbsd:pad, OpenBSD 7.3+ -scall sys_readv 0x8788788782878813 0x041 globl hidden -scall sys_writev 0x8798798792879814 0x042 globl hidden +scall sys_ioctl_cp 0x8368368362836810 0x81d globl hidden # intended for TCSBRK +scall sys_pread 0x8ad8a99db2899811 0x843 globl hidden # a.k.a. pread64; netbsd:pad, OpenBSD 7.3+ +scall sys_pwrite 0x8ae8aa9dc289a812 0x844 globl hidden # a.k.a. pwrite64; netbsd:pad, OpenBSD 7.3+ +scall sys_readv 0x8788788782878813 0x841 globl hidden +scall sys_writev 0x8798798792879814 0x842 globl hidden scall __sys_pipe 0x02a10721e202a016 0x03b globl hidden # NOTE: pipe2() on FreeBSD and Linux Aarch64; XNU is pipe(void)→eax:edx scall sys_select 0x9a184785d285d817 0xfff globl hidden -scall sys_pselect 0x9b486ea0a298a90e 0x048 globl hidden # pselect6() on gnu/systemd +scall sys_pselect 0x9b486ea0a298a90e 0x848 globl hidden # pselect6() on gnu/systemd scall sys_sched_yield 0x15e12a14bf25d018 0x07c globl hidden # select() on XNU (previously swtch() but removed in 12.4) scall __sys_mremap 0x19bffffffffff019 0x0d8 globl hidden scall sys_mincore 0x04e04e04e204e01b 0x0e8 globl hidden @@ -68,20 +68,20 @@ scall sys_shmctl 0x1bb128200210701f 0x0c3 globl # no wrapper scall sys_dup 0x0290290292029020 0x017 globl hidden scall sys_dup2 0x05a05a05a205a021 0x018 globl hidden # dup3() on linux aarch64 (doesn't behave same if oldfd==newfd) scall sys_pause 0xfffffffffffff022 0xfff globl hidden -scall sys_nanosleep 0x9ae85b8f0ffff823 0x065 globl hidden -scall __sys_clock_nanosleep 0x9ddfff8f4ffff8e6 0x073 globl hidden +scall sys_nanosleep 0x9ae85b8f0ffff823 0x865 globl hidden +scall __sys_clock_nanosleep 0x9ddfff8f4ffff8e6 0x873 globl hidden scall sys_getitimer 0x1aa0460562056024 0x066 globl hidden scall sys_setitimer 0x1a90450532053026 0x067 globl hidden scall sys_alarm 0xfffffffffffff025 0xfff globl hidden scall sys_getpid 0x0140140142014027 0x0ac globl hidden # netbsd returns ppid in edx scall sys_sendfile 0xffffff1892151028 0x047 globl hidden # Linux vs. XNU/BSD ABIs very different scall __sys_socket 0x18a0610612061029 0x0c6 globl hidden -scall __sys_connect 0x862862862286282a 0x0cb globl hidden -scall __sys_accept 0x81e81ea1d281e82b 0x0ca globl hidden # accept4 on freebsd -scall sys_sendto 0x885885885288582c 0x0ce globl hidden -scall sys_recvfrom 0x81d81d81d281d82d 0x0cf globl hidden -scall sys_sendmsg 0x81c81c81c281c82e 0x0d3 globl hidden -scall sys_recvmsg 0x81b81b81b281b82f 0x0d4 globl hidden +scall __sys_connect 0x862862862286282a 0x8cb globl hidden +scall __sys_accept 0x81e81ea1d281e82b 0x8ca globl hidden # accept4 on freebsd +scall sys_sendto 0x885885885288582c 0x8ce globl hidden +scall sys_recvfrom 0x81d81d81d281d82d 0x8cf globl hidden +scall sys_sendmsg 0x81c81c81c281c82e 0x8d3 globl hidden +scall sys_recvmsg 0x81b81b81b281b82f 0x8d4 globl hidden scall sys_shutdown 0x0860860862086030 0x0d2 globl hidden scall __sys_bind 0x0680680682068031 0x0c8 globl hidden scall sys_listen 0x06a06a06a206a032 0x0c9 globl hidden @@ -94,14 +94,14 @@ scall __sys_fork 0x0020020022002039 0xfff globl hidden # xnu needs eax&=~-edx b #scall vfork 0x042042042204203a 0xfff globl # this syscall is from the moon so we implement it by hand in libc/runtime/vfork.S; probably removed from XNU in 12.5 scall sys_posix_spawn 0x1daffffff20f4fff 0xfff globl hidden # good luck figuring out how xnu defines this scall __sys_execve 0x03b03b03b203b03b 0x0dd globl hidden -scall __sys_wait4 0x9c180b807280783d 0x104 globl hidden +scall __sys_wait4 0x9c180b807280783d 0x904 globl hidden scall sys_kill 0x02507a025202503e 0x081 globl hidden # kill(pid, sig, 1) b/c xnu scall sys_killpg 0x092fff092fffffff 0xfff globl hidden scall sys_clone 0x11fffffffffff038 0x0dc globl hidden scall sys_tkill 0x13e0771b121480c8 0x082 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 0x083 globl hidden # thr_kill2() on FreeBSD scall sys_futex 0x0a60531c6ffff0ca 0x062 globl hidden # raises SIGSYS on NetBSD; _umtx_op() on FreeBSD -scall sys_futex_cp 0x8a68539c6ffff8ca 0x062 globl hidden # intended for futex wait ops +scall sys_futex_cp 0x8a68539c6ffff8ca 0x862 globl hidden # intended for futex wait ops scall sys_set_robust_list 0x0a7ffffffffff111 0x063 globl # no wrapper scall sys_get_robust_list 0x0a8ffffffffff112 0x064 globl # no wrapper scall sys_uname 0x0a4fff0a4ffff03f 0x0a0 globl hidden @@ -110,16 +110,16 @@ scall sys_semop 0x0de1220de2100041 0x0c1 globl # no wrapper scall sys_semctl 0xfff1271fe20fe042 0x0bf globl # no wrapper scall sys_shmdt 0x0e60e60e62108043 0x0c5 globl # no wrapper scall sys_msgget 0x0e10e10e12103044 0x0ba globl # no wrapper -scall sys_msgsnd 0x8e28e28e22904845 0x0bd globl # no wrapper -scall sys_msgrcv 0x8e38e38e32905846 0x0bc globl # no wrapper +scall sys_msgsnd 0x8e28e28e22904845 0x8bd globl # no wrapper +scall sys_msgrcv 0x8e38e38e32905846 0x8bc globl # no wrapper scall sys_msgctl 0x1bc1291ff2102047 0x0bb globl # no wrapper scall __sys_fcntl 0x05c05c05c205c048 0x019 globl hidden -scall __sys_fcntl_cp 0x85c85c85c285c848 0x019 globl hidden # intended for F_SETLKW and F_OFD_SETLKW -scall sys_flock 0x8838838832883849 0x020 globl hidden -scall sys_fsync 0x85f85f85f285f84a 0x052 globl hidden -scall sys_fdatasync 0x8f185fa2628bb84b 0x053 globl hidden # fsync() on openbsd -scall sys_truncate 0x8c88a79df28c884c 0x02d globl hidden # netbsd:pad, OpenBSD 7.3+ -scall sys_ftruncate 0x8c98a89e028c984d 0x02e globl hidden # netbsd:pad, OpenBSD 7.3+ +scall __sys_fcntl_cp 0x85c85c85c285c848 0x819 globl hidden # intended for F_SETLKW and F_OFD_SETLKW +scall sys_flock 0x8838838832883849 0x820 globl hidden +scall sys_fsync 0x85f85f85f285f84a 0x852 globl hidden +scall sys_fdatasync 0x8f185fa2628bb84b 0x853 globl hidden # fsync() on openbsd +scall sys_truncate 0x8c88a79df28c884c 0x82d globl hidden # netbsd:pad, OpenBSD 7.3+ +scall sys_ftruncate 0x8c98a89e028c984d 0x82e globl hidden # netbsd:pad, OpenBSD 7.3+ scall sys_getcwd 0x128130146ffff04f 0x011 globl hidden scall sys_chdir 0x00c00c00c200c050 0x031 globl hidden scall sys_fchdir 0x00d00d00d200d051 0x032 globl hidden @@ -154,14 +154,14 @@ scall sys_setresgid 0xfff11c138ffff077 0x095 globl hidden # polyfilled for xnu scall sys_getresuid 0xfff119168ffff076 0x094 globl hidden # semantics aren't well-defined scall sys_getresgid 0xfff11b169ffff078 0x096 globl hidden # semantics aren't well-defined scall sys_sigpending 0x124034157203407f 0x088 globl hidden # a.k.a. rt_sigpending on linux -scall sys_sigsuspend 0x92686f955286f882 0x085 globl hidden # a.k.a. rt_sigsuspend on Linux; openbsd:byvalue, sigsuspend_nocancel on XNU +scall sys_sigsuspend 0x92686f955286f882 0x885 globl hidden # a.k.a. rt_sigsuspend on Linux; openbsd:byvalue, sigsuspend_nocancel on XNU scall sys_sigaltstack 0x1191200352035083 0x084 globl hidden scall sys_mknod 0x1c200e00e200e085 0xfff globl hidden scall sys_mknodat 0x1cc14022fffff103 0x021 globl # no wrapper; FreeBSD 12+ scall sys_mkfifo 0x0840840842084fff 0xfff globl hidden scall sys_mkfifoat 0x1cb13f1f1fffffff 0xfff globl # no wrapper -scall sys_statfs 0x89d83fa2b2959889 0x02b globl hidden -scall sys_fstatfs 0x89e840a2c295a88a 0x02c globl hidden +scall sys_statfs 0x89d83fa2b2959889 0x82b globl hidden +scall sys_fstatfs 0x89e840a2c295a88a 0x82c globl hidden scall sys_getpriority 0x064064064206408c 0x08d globl hidden scall sys_setpriority 0x060060060206008d 0x08c globl hidden # modern nice() scall sys_mlock 0x0cb0cb0cb20cb095 0x0e4 globl # no wrapper @@ -182,7 +182,7 @@ scall sys_setfsuid 0xfffffffffffff07a 0x097 globl hidden scall sys_setfsgid 0xfffffffffffff07b 0x098 globl hidden scall sys_capget 0xfffffffffffff07d 0x05a globl # no wrapper scall sys_capset 0xfffffffffffff07e 0x05b globl # no wrapper -scall sys_sigtimedwait 0x9affff959ffff880 0x089 globl hidden +scall sys_sigtimedwait 0x9affff959ffff880 0x889 globl hidden scall sys_sigqueue 0xffffff1c8fffffff 0xfff globl hidden scall sys_sigqueueinfo 0x0f5ffffffffff081 0x08a globl hidden # a.k.a. rt_sigqueueinfo on linux scall sys_personality 0xfffffffffffff087 0x05c globl # no wrapper @@ -272,7 +272,7 @@ scall sys_ioprio_get 0xfffffffffffff0fc 0x01f globl scall sys_inotify_init 0xfffffffffffff0fd 0xfff globl # no wrapper scall sys_inotify_add_watch 0xfffffffffffff0fe 0xfff globl # no wrapper scall sys_inotify_rm_watch 0xfffffffffffff0ff 0xfff globl # no wrapper -scall __sys_openat 0x9d49419f329cf901 0x038 globl hidden # Linux 2.6.16+ (c. 2007) +scall __sys_openat 0x9d49419f329cf901 0x838 globl hidden # Linux 2.6.16+ (c. 2007) scall __sys_openat_nc 0x1d41411f321d0101 0x038 globl hidden # openat_nocancel() on xnu scall sys_mkdirat 0x1cd13e1f021db102 0x022 globl hidden scall sys_fchownat 0x1d013b1eb21d4104 0x036 globl hidden # @asyncsignalsafe @@ -296,15 +296,15 @@ scall sys_vmsplice 0xfffffffffffff116 0x04b globl hidden scall sys_migrate_pages 0xfffffffffffff100 0x0ee globl # no wrapper; numa numa yay scall sys_move_pages 0xfffffffffffff117 0x0ef globl # no wrapper; NOTE: We view Red Hat versions as "epochs" for all distros. #──────────────────────RHEL 5.0 LIMIT──────────────────────────────── # ←┬─ last distro with gplv2 licensed compiler c. 2007 -scall sys_preadv 0x9218ab9212a1c927 0x045 globl hidden # ├─ last distro with system v shell script init -scall sys_pwritev 0x9228ac9222a1d928 0x046 globl hidden # ├─ rob landley unleashes busybox gpl lawsuits +scall sys_preadv 0x9218ab9212a1c927 0x845 globl hidden # ├─ last distro with system v shell script init +scall sys_pwritev 0x9228ac9222a1d928 0x846 globl hidden # ├─ rob landley unleashes busybox gpl lawsuits scall __sys_utimensat 0x1d3054223ffff118 0x058 globl hidden # ├─ python modules need this due to pep513 scall sys_fallocate 0xfffffffffffff91d 0x02f globl # ├─ end of life 2020-11-30 (extended) scall sys_posix_fallocate 0x9dffffa12fffffff 0xfff globl hidden # └─ cosmopolitan supports rhel5+ -scall __sys_accept4 0xfff85da1dffff920 0x0f2 globl hidden # Linux 2.6.28+ +scall __sys_accept4 0xfff85da1dffff920 0x8f2 globl hidden # Linux 2.6.28+ scall __sys_dup3 0x1c6066fffffff124 0x018 globl hidden # Linux 2.6.27+ scall __sys_pipe2 0x1c506521effff125 0x03b globl hidden # Linux 2.6.27+ -scall sys_epoll_pwait 0xfffffffffffff919 0x016 globl hidden +scall sys_epoll_pwait 0xfffffffffffff919 0x816 globl hidden scall sys_epoll_create1 0xfffffffffffff123 0x014 globl hidden scall sys_perf_event_open 0xfffffffffffff12a 0x0f1 globl # no wrapper scall sys_inotify_init1 0xfffffffffffff126 0x01a globl # no wrapper @@ -345,7 +345,7 @@ scall sys_execveat 0xfffffffffffff142 0x119 globl # no wrapper scall sys_userfaultfd 0xfffffffffffff143 0x11a globl # no wrapper; Linux 4.3+ (c. 2015) scall sys_membarrier 0xfffffffffffff144 0x11b globl # no wrapper; Linux 4.3+ (c. 2015) scall sys_mlock2 0xfffffffffffff145 0x11c globl # no wrapper; Linux 4.5+ (c. 2016) -scall sys_copy_file_range 0xffffffa39ffff946 0x11d globl hidden # Linux 4.5+ (c. 2016), FreeBSD 13+ +scall sys_copy_file_range 0xffffffa39ffff946 0x91d globl hidden # Linux 4.5+ (c. 2016), FreeBSD 13+ scall sys_preadv2 0xfffffffffffff147 0x11e globl # no wrapper scall sys_pwritev2 0xfffffffffffff148 0x11f globl # no wrapper scall sys_pkey_mprotect 0xfffffffffffff149 0x120 globl # no wrapper diff --git a/libc/sysv/sysv.c b/libc/sysv/sysv.c new file mode 100644 index 000000000..4a47693fe --- /dev/null +++ b/libc/sysv/sysv.c @@ -0,0 +1,157 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or 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 "libc/calls/syscall-sysv.internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/intrin/atomic.h" +#include "libc/intrin/weaken.h" +#include "libc/thread/posixthread.internal.h" +#include "libc/thread/tls.h" +#ifndef __x86_64__ + +// todo(jart): dismal llvm +register long x0 asm("x0"); +register long x1 asm("x1"); +register long x2 asm("x2"); +register long x3 asm("x3"); +register long x4 asm("x4"); +register long x5 asm("x5"); +register long sysv_ordinal asm("x8"); +register long xnu_ordinal asm("x16"); +register long cosmo_tls_register asm("x28"); + +void report_cancellation_point(void); + +dontinline long systemfive_cancel(void) { + return _pthread_cancel_sys(); +} + +// special region of executable memory where cancellation is safe +dontinline long systemfive_cancellable(void) { + + // check (1) this is a cancellation point + // plus (2) cancellations aren't disabled + struct PosixThread *pth = 0; + struct CosmoTib *tib = __get_tls(); + if (cosmo_tls_register && // + _weaken(_pthread_cancel_sys) && // + !(tib->tib_flags & PT_NOCANCEL) && // + (pth = (struct PosixThread *)tib->tib_pthread)) { + // check if cancellation is already pending + if (atomic_load_explicit(&pth->cancelled, memory_order_acquire)) { + return systemfive_cancel(); + } +#if IsModeDbg() + if (!(tib->tib_flags & PT_INCANCEL)) { + if (_weaken(report_cancellation_point)) { + _weaken(report_cancellation_point)(); + } + __builtin_trap(); + } +#endif + } + + // invoke cancellable system call + // this works for both linux and bsd + asm volatile("mov\tx9,0\n\t" // clear carry flag + "adds\tx9,x9,0\n\t" // clear carry flag + "svc\t0\n" + "systemfive_cancellable_end:\n\t" + ".globl\tsystemfive_cancellable_end\n\t" + "bcs\t1f\n\t" + "b\t2f\n1:\t" + "neg\tx0,x0\n2:" + : /* global output */ + : /* global inputs */ + : "x9", "memory"); + + // if it succeeded then we're done + if (x0 < -4095ul) { + return x0; + } + + // check if i/o call was interrupted by sigthr + if (pth && x0 == -EINTR && + atomic_load_explicit(&pth->cancelled, memory_order_acquire)) { + return systemfive_cancel(); + } + + // otherwise go down error path + return _sysret(x0); +} + +/** + * System Five System Call Support. + * + * This supports POSIX thread cancellation only when the caller flips a + * bit in TLS storage that indicates we're inside a cancellation point. + * + * @param x0 is first argument + * @param x1 is second argument + * @param x2 is third argument + * @param x3 is fourth argument + * @param x4 is fifth argument + * @param x5 is sixth argument + * @param sysv_ordinal is linux ordinal + * @param xnu_ordinal is xnu ordinal + * @return x0 + */ +long systemfive(void) { + + // handle special cases + if (IsLinux()) { + if (sysv_ordinal == 0xfff) { + return _sysret(-ENOSYS); + } + if (sysv_ordinal & 0x800) { + sysv_ordinal &= ~0x800; + return systemfive_cancellable(); + } + } + if (IsXnu()) { + if (xnu_ordinal == 0xfff) { + return _sysret(-ENOSYS); + } + if (xnu_ordinal & 0x800) { + xnu_ordinal &= ~0x800; + return systemfive_cancellable(); + } + } + + // invoke non-blocking system call + // this works for both linux and bsd + asm volatile("mov\tx9,0\n\t" // clear carry flag + "adds\tx9,x9,0\n\t" // clear carry flag + "svc\t0\n\t" + "bcs\t1f\n\t" + "b\t2f\n1:\t" + "neg\tx0,x0\n2:" + : /* global output */ + : /* global inputs */ + : "x9", "memory"); + + // check result + if (x0 < -4095ul) { + return x0; + } else { + return _sysret(x0); + } +} + +#endif /* __x86_64__ */ diff --git a/libc/sysv/sysv.mk b/libc/sysv/sysv.mk index ca89ad843..30f97f15d 100644 --- a/libc/sysv/sysv.mk +++ b/libc/sysv/sysv.mk @@ -41,6 +41,7 @@ LIBC_SYSV_A_FILES := \ libc/sysv/syscall.S \ libc/sysv/systemfive.S \ libc/sysv/sysret.c \ + libc/sysv/sysv.c \ libc/sysv/errno.c \ libc/sysv/errfun.S \ libc/sysv/errfun2.c \ @@ -73,6 +74,7 @@ $(LIBC_SYSV_A).pkg: \ $(LIBC_SYSV_A_OBJS) \ $(foreach x,$(LIBC_SYSV_A_DIRECTDEPS),$($(x)_A).pkg) +o/$(MODE)/libc/sysv/sysv.o \ o/$(MODE)/libc/sysv/errno.o \ o/$(MODE)/libc/sysv/sysret.o \ o/$(MODE)/libc/sysv/errfun2.o \ @@ -80,6 +82,22 @@ o/$(MODE)/libc/sysv/sysret.o: private \ CFLAGS += \ $(NO_MAGIC) +ifeq ($(ARCH),aarch64) +o/$(MODE)/libc/sysv/sysv.o: private \ + CFLAGS += \ + -ffixed-x0 \ + -ffixed-x1 \ + -ffixed-x2 \ + -ffixed-x3 \ + -ffixed-x4 \ + -ffixed-x5 \ + -ffixed-x8 \ + -ffixed-x16 \ + -fomit-frame-pointer \ + -foptimize-sibling-calls \ + -Os +endif + #─────────────────────────────────────────────────────────────────────────────── LIBC_SYSV_CALLS = \ diff --git a/libc/thread/posixthread.internal.h b/libc/thread/posixthread.internal.h index fa618b15f..17f9f17d8 100644 --- a/libc/thread/posixthread.internal.h +++ b/libc/thread/posixthread.internal.h @@ -97,8 +97,8 @@ void _pthread_free(struct PosixThread *); void _pthread_onfork_prepare(void); void _pthread_onfork_parent(void); void _pthread_onfork_child(void); +long _pthread_cancel_sys(void); void _pthread_ungarbage(void); -int _pthread_cancel_sys(void); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/thread/pthread_cancel.c b/libc/thread/pthread_cancel.c index 8dd2d3d1c..07dbe8ab5 100644 --- a/libc/thread/pthread_cancel.c +++ b/libc/thread/pthread_cancel.c @@ -21,11 +21,13 @@ #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/siginfo.h" #include "libc/calls/struct/sigset.h" +#include "libc/calls/struct/ucontext.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/calls/ucontext.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" +#include "libc/intrin/kprintf.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/sa.h" @@ -34,14 +36,13 @@ #include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" -#ifdef __x86_64__ int systemfive_cancel(void); extern const char systemfive_cancellable[]; extern const char systemfive_cancellable_end[]; -int _pthread_cancel_sys(void) { +long _pthread_cancel_sys(void) { struct PosixThread *pt; pt = (struct PosixThread *)__get_tls()->tib_pthread; if (!(pt->flags & (PT_NOCANCEL | PT_MASKED)) || (pt->flags & PT_ASYNC)) { @@ -60,9 +61,9 @@ static void OnSigThr(int sig, siginfo_t *si, void *ctx) { !(pt->flags & PT_NOCANCEL) && atomic_load_explicit(&pt->cancelled, memory_order_acquire)) { sigaddset(&uc->uc_sigmask, sig); - if (systemfive_cancellable <= (char *)uc->uc_mcontext.rip && - (char *)uc->uc_mcontext.rip < systemfive_cancellable_end) { - uc->uc_mcontext.rip = (intptr_t)systemfive_cancel; + if (systemfive_cancellable <= (char *)uc->uc_mcontext.PC && + (char *)uc->uc_mcontext.PC < systemfive_cancellable_end) { + uc->uc_mcontext.PC = (intptr_t)systemfive_cancel; } else if (pt->flags & PT_ASYNC) { pthread_exit(PTHREAD_CANCELED); } else { @@ -302,8 +303,6 @@ errno_t pthread_cancel(pthread_t thread) { return rc; } -#endif /* __x86_64__ */ - /** * Creates cancellation point in calling thread. * diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 12b8ee5a3..7dbcb559e 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" +#include "libc/atomic.h" #include "libc/calls/blocksigs.internal.h" #include "libc/calls/calls.h" #include "libc/calls/struct/sigaltstack.h" @@ -28,6 +29,7 @@ #include "libc/intrin/bits.h" #include "libc/intrin/bsr.h" #include "libc/intrin/dll.h" +#include "libc/intrin/popcnt.h" #include "libc/log/internal.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" @@ -58,6 +60,7 @@ static unsigned long roundup2pow(unsigned long x) { } void _pthread_free(struct PosixThread *pt) { + static atomic_uint freed; if (pt->flags & PT_STATIC) return; free(pt->tls); if ((pt->flags & PT_OWNSTACK) && // @@ -69,6 +72,9 @@ void _pthread_free(struct PosixThread *pt) { free(pt->altstack); } free(pt); + if (popcnt(atomic_fetch_add_explicit(&freed, 1, memory_order_acq_rel)) == 1) { + malloc_trim(0); + } } void pthread_kill_siblings_np(void) { diff --git a/libc/thread/pthread_decimate_np.c b/libc/thread/pthread_decimate_np.c index a94c8eb7b..4ba4c97a9 100644 --- a/libc/thread/pthread_decimate_np.c +++ b/libc/thread/pthread_decimate_np.c @@ -16,19 +16,18 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/atomic.h" #include "libc/intrin/atomic.h" #include "libc/intrin/dll.h" #include "libc/runtime/runtime.h" #include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" -#include "third_party/dlmalloc/dlmalloc.h" /** * Releases memory of detached threads that have terminated. */ void pthread_decimate_np(void) { - bool empty; struct Dll *e; struct PosixThread *pt; enum PosixThreadStatus status; @@ -46,9 +45,5 @@ StartOver: goto StartOver; } } - empty = dll_is_empty(_pthread_list); pthread_spin_unlock(&_pthread_lock); - if (empty) { - dlmalloc_trim(0); - } } diff --git a/libc/thread/thread.mk b/libc/thread/thread.mk index e190de4d1..0f7d2eb57 100644 --- a/libc/thread/thread.mk +++ b/libc/thread/thread.mk @@ -34,7 +34,6 @@ LIBC_THREAD_A_DIRECTDEPS = \ LIBC_STR \ LIBC_SYSV \ LIBC_SYSV_CALLS \ - THIRD_PARTY_DLMALLOC \ THIRD_PARTY_NSYNC \ THIRD_PARTY_NSYNC_MEM diff --git a/libc/thread/tls.h b/libc/thread/tls.h index cfa40e197..77d31fe77 100644 --- a/libc/thread/tls.h +++ b/libc/thread/tls.h @@ -44,9 +44,15 @@ extern unsigned __tls_index; #ifdef __x86_64__ extern bool __tls_enabled; #define __tls_enabled_set(x) __tls_enabled = x -#else -#define __tls_enabled true +#elif defined(__aarch64__) +#define __tls_enabled \ + ({ \ + register struct CosmoTib *_t asm("x28"); \ + !!_t; \ + }) #define __tls_enabled_set(x) (void)0 +#else +#error "unsupported architecture" #endif void __require_tls(void); diff --git a/test/libc/thread/pthread_cancel_test.c b/test/libc/thread/pthread_cancel_test.c index a9b0d7334..522f34d03 100644 --- a/test/libc/thread/pthread_cancel_test.c +++ b/test/libc/thread/pthread_cancel_test.c @@ -21,6 +21,7 @@ #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/intrin/kprintf.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/nexgen32e.h" @@ -29,7 +30,6 @@ #include "libc/testlib/testlib.h" #include "libc/thread/thread.h" #include "libc/thread/thread2.h" -#ifdef __x86_64__ int pfds[2]; pthread_cond_t cv; @@ -229,12 +229,14 @@ void *CpuBoundWorker(void *arg) { (void)wontleak2; ASSERT_EQ(0, pthread_setspecific(key, (void *)31337)); ASSERT_EQ(0, pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0)); -#ifdef __x86_64__ for (;;) { +#ifdef __x86_64__ TortureStack(); +#else + CheckStackIsAligned(); +#endif is_in_infinite_loop = true; } -#endif pthread_cleanup_pop(1); free(wouldleak); return 0; @@ -282,5 +284,3 @@ TEST(pthread_cancel, self_asynchronous_takesImmediateEffect) { ASSERT_SYS(0, 0, close(pfds[1])); ASSERT_SYS(0, 0, close(pfds[0])); } - -#endif /* __x86_64__ */ diff --git a/tool/emacs/cosmo-c-keywords.el b/tool/emacs/cosmo-c-keywords.el index dbf1e11d7..f9fac4166 100644 --- a/tool/emacs/cosmo-c-keywords.el +++ b/tool/emacs/cosmo-c-keywords.el @@ -204,7 +204,6 @@ "__vector_size__" "__ms_abi__" "__sysv_abi__" - "systemfive" "__mode__" "__seg_fs" "__seg_gs"))